linux ARP recvfrom information

谁都会走 提交于 2019-12-13 04:23:01

问题


If I send an ARP package can I find out from recv what is the IP adress of the sender ?I ask this because i send multiple packages to different hosts with child processes and I receive the response to all the child processes so I'm asking if there is a way to know what child sent what package.Thank you.

struct ether_arp req;
struct sockaddr_ll addr={0};
struct ifreq inter;
int sock;//I check usinginter if the interface is correct
sock=socket(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP));
 if (sock==-1) {
 printf("%s",strerror(errno));
}
if (ioctl(sock,SIOCGIFINDEX,&inter)==-1) {
printf("%s",strerror(errno));
return ;//for the interface index
addr.sll_family=AF_PACKET;
addr.sll_ifindex=index;
addr.sll_halen=ETHER_ADDR_LEN;
addr.sll_protocol=htons(ETH_P_ARP);
memcpy(addr.sll_addr,ether_broadcast_addr,ETHER_ADDR_LEN);
req.arp_hrd=htons(ARPHRD_ETHER);
req.arp_pro=htons(ETH_P_IP);
req.arp_hln=ETHER_ADDR_LEN;
req.arp_pln=sizeof(in_addr_t);
req.arp_op=htons(ARPOP_REQUEST);
......................  
 memcpy(&req.arp_spa,&target_ip_addr.s_addr,sizeof(req.arp_spa));//this way I save the   source IP
.......
if (sendto(sock,&req,sizeof(req),0,(struct sockaddr*)&addr,sizeof(addr))==-1) {
printf("%s",strerror(errno));
}THis is how I send it

There is a little more code but i don't think it is relevant


回答1:


You can't use recvfrom to discover the ip address of the sender, because ARP packet got no network layer.

If you want to know which host, with his relative mac address and ip address, replied to your requests you have to dissect the packet that's made like this:

Look here for further infos about single fields: ARP Message Format

The 32 bits you're looking for are into Sender Protocol Address

This is an hypotetic code snippet that shows ip numbers of hosts arp-replying to your ARP REQUESTS.

DISCLAIMER: i didn't test it but it should give you an idea.

/* buf is buffer containing the ethernet frame */
char buf[65535];

/* arp frame points to the arp data inside the ethernet frame */
struct ether_arp *arp_frame;

/* skipping the 14 bytes of ethernet frame header */
arp_frame = (struct ether_arp *) (buf + 14);

/* read until we got an arp packet or socket got a problem */
while (recv(sock, buf, sizeof(buf), 0))
{
    /* skip to the next frame if it's not an ARP packet */
    if ((((buf[12]) << 8) + buf[13]) != ETH_P_ARP) 
        continue;

    /* skip to the next frame if it's not an ARP REPLY */
    if (ntohs (arp_frame->arp_op) != ARPOP_REPLY)
        continue;

    /* got an arp reply! this is where i'm printing what you need             */
    /* ... and YES... spa of arp_spa field stands for Sender Protocol Address */
    printf("I got an arp reply from host with ip: %u.%u.%u.%u\n", arp_frame->arp_spa[0],
                                                                  arp_frame->arp_spa[1],
                                                                  arp_frame->arp_spa[2], 
                                                                  arp_frame->arp_spa[3]);

    /* break? */
    break;    
}

And this is a full WORKING example of a mini program listening for ARP-REPLIES.

arp-reply-catcher.c source



来源:https://stackoverflow.com/questions/14253639/linux-arp-recvfrom-information

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!