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
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.