Search code examples
c++linuxarpnetlink

Monitoring ARP table changes


I'm trying to monitor my ARP table in linux using c++ and so far the only solution I have is polling the /proc/net/arp every interval and compare to the previous state.

Can I use netlink sockets in order to receive events from the kernel on these changes?

I have look around and cannot find a straight answer, I found tolls like ip-monitor but didn't found out how they get this data.

If netlink socket cannot provide this information, is there any other way to extract this with events and not polling?


Solution

  • I was able to find how to get events on ARP table changes using netlink socket, the only thing that I have missing is how to extract the ARP details from the event but for now this will do:

    int sock;
    static struct sockaddr_nl g_addr;
    
    /* Zeroing addr */
    bzero(&g_addr, sizeof(g_addr));
    g_addr.nl_family = AF_NETLINK;
    g_addr.nl_groups = nl_mgrp(RTNLGRP_NEIGH);
    
    if ((sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
        printf("socket() error: %s", strerror(errno));
        return -1;
    }
    
    if (bind(sock, (struct sockaddr *) &g_addr, sizeof(g_addr)) < 0) {
        printf("bind() error: %s", strerror(errno));
        return -1;
    }
    
    char buffer[4096];
    int received_bytes = 0;
    
    while (true) {
        received_bytes = recv(sock, buffer, sizeof(buffer), 0);
        if (received_bytes > 0) {
            printf("Event\n");
            // How to parse the event
        }
    }