求助RARP协议的运用
在局域网中获知了网卡的物理地址,如00-13-D3-23-C3-E7.
如何通过编程实现获得对方的IP地址等。
目前比较困惑的是socket创建时,参数及socket的属性如何设置;报文如何组建。
希望有识者提示。
先谢了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在局域网中获知了网卡的物理地址,如00-13-D3-23-C3-E7.
如何通过编程实现获得对方的IP地址等。
目前比较困惑的是socket创建时,参数及socket的属性如何设置;报文如何组建。
希望有识者提示。
先谢了。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
试着用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 specifiedn");
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;
}
可不可以吧自己设成a:a:a:a:a:a 然后问我的 IP是多少?
反查应该不是RARP协议,因为RARP是“我的MAC地址A:A:A:A:A:A,请问我的IP地址是多少?”—— 一般用于无盘工作站起动的时候,向RARP服务器询问自己的IP地址。
而楼主需要的是,“A:A:A:A:A:A,请问你的IP地址是多少?”
两者有质的区别。
我再找找源码了……
我的 arping 随着我硬盘的报废一起没有了
我不知道 RARP 的原理,但是我知道它不像 ARP 那样简单,必须有特定条件才能用
白金兄,你的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地址是多少?”,急切想知道它的原理是怎么样的?呵呵!
谢谢,arping使用了libnet,libnet比较复杂,研读中。
可以参考一下 arping 的源代码,它可以通过 MAC 反查 IP