Search code examples
linuxnetworkingethernet

Dummy Ethernet Device in Linux Not Working With ARP


I want a dummy ethernet device in Linux that responds as a normal ethernet device would, but that I can connect to in software. I attempted to generate a dummy device using the following commands:

ip link del dummy99
ip link add dummy99 type dummy
ifconfig dummy99 hw ether C8:55:44:33:22:11
ifconfig dummy99 192.168.99.1 up

This creates a device, and I can send pings to 192.168.99.2, and they are addressed to the same MAC address that I set this port to instead of sending an ARP request to dummy99.

How can I make Linux assume that there's a whole network connected to dummy99 instead of assume the whole network has the MAC address of the interface?

enter image description here

I've tried also creating a bridge device, to bridge the two devices, but no configuration of setting IP causes the system to both (1) genrate ARP packets for the IP to find, and (2) actually knows how to route the ARP replies in a way Linux can find.

Here's an example configuration, which sends ARP packets, that my application replies to, but Linux never seems to see them.

ip link del dummy99
ip link add dummy99 type dummy
ifconfig dummy99 hw ether C8:55:44:33:22:11
ifconfig dummy99 up

ip tuntap del tap99 mode tap
ip tuntap add tap99 mode tap
ifconfig tap99 up

ip link del br99 type bridge
ip link add br99 type bridge
ip link set tap99 master br99
ip link set dummy99 master br99
ifconfig br99 up

ifconfig br99 192.168.99.1 up

enter image description here

Note that even though the ARP replies are present, Linux still does not add this as a viable path to the table.


Solution

  • The answer appears to be that you can't do this like a normal ethernet device. You have to create a TAP device, as follows:

        rawpsock = open("/dev/net/tun", O_RDWR);
        if(rawpsock == -1) {
            perror("tapdev: tapdev_init: open");
            exit(1);
        }
        struct ifreq ifr;
        memset(&ifr, 0, sizeof(ifr));
        int err;
        ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
        strncpy(ifr.ifr_name, "tap4", IFNAMSIZ);
        if( (err = ioctl(rawpsock, TUNSETIFF, (void *) &ifr)) < 0 ) {
            close(rawpsock);
            return err;
        }
    
        system( "ifconfig tap4 192.168.99.1 up" );
    

    Then you MUST use read/write to read/write from the file handle. You CANNOT use normal raw socket access to access the handle data.