免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2086 | 回复: 7

求助RARP协议的运用 [复制链接]

论坛徽章:
0
发表于 2006-04-12 14:30 |显示全部楼层
在局域网中获知了网卡的物理地址,如00-13-D3-23-C3-E7.
如何通过编程实现获得对方的IP地址等。

目前比较困惑的是socket创建时,参数及socket的属性如何设置;报文如何组建。
希望有识者提示。
先谢了。

论坛徽章:
0
发表于 2006-04-12 14:45 |显示全部楼层
可以参考一下 arping 的源代码,它可以通过 MAC 反查 IP

论坛徽章:
0
发表于 2006-04-12 15:27 |显示全部楼层
谢谢,arping使用了libnet,libnet比较复杂,研读中。

论坛徽章:
0
发表于 2006-04-12 16:06 |显示全部楼层
原帖由 platinum 于 2006-4-12 14:45 发表
可以参考一下 arping 的源代码,它可以通过 MAC 反查 IP

白金兄,你的arping 版本是多少呢?我看了你另外的贴子:arping -c number -a MAC
可是我的RH9.0自带的arping并不支持-a参数,我对知道MAC反查IP技术很感兴趣,想看看它是如何实现的,呵呵,因为按我的理解:

ARP协议:192.168.0.1,请问你的MAC是多少?
RARP协议:我的MAC地址A:A:A:A:A:A,请问我的IP地址是多少?
免费ARP:谁的IP地址是192.168.0.1,请告诉我(我也是192.168.0.1)

并没有协议来支持反查:“A:A:A:A:A:A,请问你的IP地址是多少?”,急切想知道它的原理是怎么样的?呵呵!

论坛徽章:
0
发表于 2006-04-12 16:10 |显示全部楼层
我的 arping 随着我硬盘的报废一起没有了
我不知道 RARP 的原理,但是我知道它不像 ARP 那样简单,必须有特定条件才能用

论坛徽章:
0
发表于 2006-04-12 16:13 |显示全部楼层
原帖由 platinum 于 2006-4-12 16:10 发表
我的 arping 随着我硬盘的报废一起没有了
我不知道 RARP 的原理,但是我知道它不像 ARP 那样简单,必须有特定条件才能用


反查应该不是RARP协议,因为RARP是“我的MAC地址A:A:A:A:A:A,请问我的IP地址是多少?”—— 一般用于无盘工作站起动的时候,向RARP服务器询问自己的IP地址。

而楼主需要的是,“A:A:A:A:A:A,请问你的IP地址是多少?”

两者有质的区别。

我再找找源码了……

论坛徽章:
0
发表于 2006-04-15 13:13 |显示全部楼层
可不可以吧自己设成a:a:a:a:a:a 然后问我的 IP是多少?

论坛徽章:
0
发表于 2006-04-17 18:09 |显示全部楼层
试着用RARP协议求解,发现不能实现,以下用ARP协议遍历本地局域网的IP的实现方法,望各位提出意见。
以下是完整代码:
#include    <sys/socket.h>
#include    <sys/ioctl.h>
#include    <unistd.h>
#include    <netinet/if_ether.h>
#include    <netinet/ip.h>
#include    <netinet/udp.h>
#include    <netinet/tcp.h>
#include    <net/if.h>
#include    <netdb.h>
#include    <errno.h>

int socket_init(void);
int check_arp(char *, u_char *, char *);

int main(int argc, char *argv[])
{
    struct sockaddr_in    in_addr;
    struct ethhdr         *eth_hdr;
    int                   sock, recv_len, addr_len;
    char                  buffer[65535];

    struct sockaddr_in        my_ip;
    u_char                                ip_addr[4], hw_addr[6];
    unsigned int                ip_min, ip_max;
    int                                        ret = 0;

    memset(&in_addr, 0x0, sizeof(struct sockaddr_in));

    if(argc < 2)
    {
        printf("The parameter is not specified\n");
        exit(-1);
    }
       
    get_host_addr(hw_addr,&my_ip);
    memcpy(ip_addr, (void *)(&my_ip.sin_addr), 4);

    ip_min = inet_addr(inet_ntoa(my_ip.sin_addr)) & 0x00ffffff;
    ip_max = inet_addr(inet_ntoa(my_ip.sin_addr)) | 0xff000000;

    sock = socket_init();

    while(1)
    {
        if(ip_min >= ip_max)
            break;
        
        arp_send(sock, ip_addr, hw_addr, ip_min);

        addr_len = sizeof(in_addr);
        recv_len = recvfrom(sock, buffer, sizeof(buffer), 0,
            (struct sockaddr *)&in_addr, &addr_len);

        eth_hdr = (struct ethhdr *)buffer;

        switch(ntohs(eth_hdr->h_proto))
        {
            default:
                break;
            case 0x0806:    //ARP packet
                                ret = check_arp(buffer, hw_addr, argv[1]);
                                if(ret == 0) goto Exit;
                break;
        }
        memset(buffer, 0x0, sizeof(buffer));
                ip_min = ip_min + 0x01000000;
    }
Exit:
    close(sock);
    return 0;
}


int socket_init()
{
   struct    ifreq    ifr;
   int   sock;
   memset(&ifr, 0x0, sizeof(struct ifreq));

   if((sock = socket(AF_INET, SOCK_PACKET, htons(0x0003))) < 0)
   {
       printf("Failed to socket(errno=%d)\n", errno);
       exit(-1);
   }

   strcpy(ifr.ifr_name, "eth0");
   if(ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
   {
       printf("Failed to ioctl(errno=%d)\n", errno);
       exit(-1);
   }


   ifr.ifr_flags |= IFF_PROMISC;
   if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
   {
       printf("Failed to ioctl(errno=%d)\n", errno);
       exit(-1);
   }
   return sock;
}


int arp_send(sock,my_ip,hw_addr,ip)
    int             sock;
    u_char          my_ip[4],hw_addr[6];
    unsigned int    ip;
{
    struct ethhdr       *eth_hdr;
    struct ether_arp    *arp;
    struct sockaddr     sa;

    u_char          *arp_packet;
    unsigned int    pack_len;


    pack_len = sizeof(struct ethhdr) + sizeof(struct ether_arp);
    arp_packet = (u_char *)malloc(pack_len);
    eth_hdr = (struct ethhdr *)arp_packet;
    arp = (struct ether_arp *)(arp_packet + sizeof(struct ethhdr));


    memset(eth_hdr->h_dest, 0xfffffff, sizeof(eth_hdr->h_dest));
    memcpy(eth_hdr->h_source, hw_addr, 6);
    eth_hdr->h_proto = htons(ETHERTYPE_ARP);

    arp->arp_hrd = htons(ARPHRD_ETHER);
    arp->arp_pro = htons(0x0800);
    arp->arp_hln = 6;
    arp->arp_pln = 4;
    arp->arp_op = htons(ARPOP_REQUEST);

    memcpy(arp->arp_sha, hw_addr, 6);
    memcpy(arp->arp_spa, my_ip, 4);

    memset(arp->arp_tha, 0xfffffff, sizeof(arp->arp_tha));
    memcpy(arp->arp_tpa, (void *)&ip, 4);

    strcpy(sa.sa_data, "eth0");
    if(sendto(sock, arp_packet, pack_len, 0, &sa, sizeof(sa)) < 0)
    {
       printf("Failed to sendto(errno=%d)\n", errno);
       exit(-1);
    }

    free(arp_packet);
    return 0;
}


int check_arp(char *buff, u_char *hw_addr, char *dhw_addr)
{
   struct ethhdr       *eth_hdr;
   struct ether_arp    *arp;
   u_char                                shw_addr[24];


   memset(shw_addr, 0, sizeof(shw_addr));
   eth_hdr = (struct ethhdr *)buff;
   arp =(struct ether_arp *)(buff + sizeof(struct ethhdr));

   if(arp->arp_op != htons(ARPOP_REPLY))
       return -1;
    if(memcmp(arp->arp_tha, hw_addr, 6)  != 0)
        return -1;
   
        sprintf(shw_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
                arp->arp_sha[0], arp->arp_sha[1], arp->arp_sha[2],
        arp->arp_sha[3], arp->arp_sha[4], arp->arp_sha[5]);

        if(!strcmp(shw_addr, dhw_addr))
        {
                printf("%-12s:[%02x:%02x:%02x:%02x:%02x:%02x]\n%-12s:[%d.%d.%d.%d]\n",
                "HWaddr",
                arp->arp_sha[0], arp->arp_sha[1], arp->arp_sha[2],
                arp->arp_sha[3], arp->arp_sha[4], arp->arp_sha[5],
                "inet addr",
                arp->arp_spa[0],arp->arp_spa[1],arp->arp_spa[2],arp->arp_spa[3]);
                return 0;
        }

   return -1;
}


int get_host_addr(hw_addr,my_ip)
   struct sockaddr_in *my_ip;
   u_char *hw_addr;
{
   struct ifreq    ifr;
   int sock;
   if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
   {
       printf("Failed to socket(errno=%d)\n", errno);
       exit(-1);
   }

   strcpy(ifr.ifr_name, "eth0");

   if(ioctl(sock, SIOCGIFADDR, &ifr) < 0)
   {
       printf("Failed to ioctl(errno=%d)\n", errno);
       exit(-1);
   }

   my_ip->sin_addr = ((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr;

   if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
   {
       printf("Failed to ioctl(errno=%d)\n", errno);
       exit(-1);
   }
   memcpy(hw_addr, ifr.ifr_hwaddr.sa_data, 6);

   close(sock);
   return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP