0
votes

I am pretty new to networking and I have been trying to understand ARP requests. I've been using mininet and wireshark in order to test what I'm doing.

When I use mininet to generate 2 hosts (h1 and h2) and a switch, my ARP broadcast is immediately responded with an ARP reply, everything works correctly.

When I use a given router.py script that generates the following on mininet -

*** Creating network
*** Adding controller
*** Adding hosts:
h1x1 h1x2 h2x1 h2x2 h3x1 h3x2 r0 
*** Adding switches:
s1 s2 s3 
*** Adding links:
(h1x1, s1) (h1x2, s1) (h2x1, s2) (h2x2, s2) (h3x1, s3) (h3x2, s3) (s1, r0) (s2, r0) (s3, r0) 
*** Configuring hosts
h1x1 h1x2 h2x1 h2x2 h3x1 h3x2 r0 
*** Starting controller
c0 
*** Starting 3 switches
s1 s2 s3 ...
*** Routing Table on Router:
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 r0-eth3
172.16.0.0      0.0.0.0         255.240.0.0     U     0      0        0 r0-eth2
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 r0-eth1
// ./a.out Send <InterfaceName>  <DestIP> <RouterIP> <Message>
mininet> h1x1 ./a.out Send h1x1-eth0 10.0.0.1 192.168.1.100 'This is a test'

This is how I run my command on mininet to run the ARP request.

When I try to run the ARP request using destination IP 10.0.0.1 and the router IP 192.168.1.00 my ARP request broadcasts normally, but I do not get the ARP reply, instead I get a series of ICMPv6 responses.

enter image description here

Here is how I am creating my ARP header

struct arp_hdr construstArpRequest(char if_name[], int sockfd, struct in_addr dst, struct ifreq if_hwaddr) {
    printf("Constructing ARP request --\n");
    struct arp_hdr arphdr;
    arphdr.ar_hrd = htons(0x0001);
    arphdr.ar_pro = htons(0x0800);
    arphdr.ar_hln = 6;
    arphdr.ar_pln = 4;
    arphdr.ar_op = htons(0x0001);

    unsigned long sip = get_ip_saddr(if_name, sockfd); // source IP
    memcpy(arphdr.ar_sip, &sip, 4); // source IP
    memcpy(arphdr.ar_tip, &dst.s_addr, 4); // taget IP
    memset(arphdr.ar_tha, 0, 6); // taget HA
    memcpy(arphdr.ar_sha, if_hwaddr.ifr_hwaddr.sa_data, 6); // source HA

    return arphdr;
}

And I create my ARP request

        int sockfd = -1;
        if((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0){
            perror("socket() failed!");
        }

        // connect to an internet frame
        struct ifreq if_hwaddr;
        memset(&if_hwaddr, 0, sizeof(struct ifreq));
        strncpy(if_hwaddr.ifr_name, interfaceName, IFNAMSIZ-1);
        if(ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0){
            perror("SIOCGIFHWADDR");
        }

        struct arp_hdr arpRequest;
        arpRequest = construstArpRequest(interfaceName, sockfd, router_ip, if_hwaddr);

If I need to include code about how I am actually sending the request, I can but not sure if it is necessary code. Throughout my research I have come across some answers saying that you will not get the broadcast response because you are running it over a network, it that's the case, how do you get the target MAC address?

1

1 Answers

1
votes

ARP requests are for IPv4 only, and use broadcast (IPv6 does not have broadcast, and it uses NDP, not ARP), but routers do not forward broadcasts to a different network.

A source host will mask the destination address with its configured mask to determine if the destination address is on the same network. If the destination is on the same network, it will use ARP (either in the ARP table, or send a new ARP request) to determine the destination host data-link address and use that to build the data-link frame. If the destination is on a different network, the source host will use ARP (either in the ARP table, or send a new ARP request) to determine the data-link address of its configured gateway, and it will use the gateway data-link address to build the data-link frame.

You are trying to use an ARP request for a host on a different network, and that will not work. Trying to send an ARP request for a destination on a different network will get no response, and you are seeing that (you need to implement a timeout for your ARP requests, and send an error message up the network stack to the requesting process when it times out).

The IPv6 traffic you see is normal IPv6 maintenance traffic that periodically happens on a LAN where IPv6 is configured.