This paste expires on 2023-07-17 02:10:24.590433. Repaste, or download this paste. . Pasted through web.

#include <err.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#define NB_COLS 8
#define GROUP_DIV 2
#define COL_SIZE 4
#define CEILDIV(_x, _n) ({ \
        __auto_type x = (_x); \
        __auto_type n = (_n); \
        (x + (n - 1)) / n; \
    })
#define __unused __attribute__((__unused__))
void hexdump(void *buf, int len)
{
    for (int i = 0; i < CEILDIV(len, NB_COLS * COL_SIZE); i++)
    {
        printf("%04X |", NB_COLS * COL_SIZE * i);
        for (int j = 0; j < NB_COLS; j++)
        {
            if (i * NB_COLS * COL_SIZE + j * COL_SIZE >= len)
                break;
            printf(" ");
            if (j > 0 && ((j % (NB_COLS / GROUP_DIV)) == 0))
            {
                printf("| ");
            }
            for (int k = 0; k < COL_SIZE; k++)
            {
                if (i * NB_COLS * COL_SIZE + j * COL_SIZE + k >= len)
                    break;
                printf("%02X", ((uint8_t *)buf)[i * NB_COLS * COL_SIZE + j * COL_SIZE + k]);
            }
        }
        printf("\n");
    }
}
int main(int argc __unused, char *argv[] __unused)
{
    int fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
    if (fd < 0) err(1, "Can't open netlink socket");
    struct sockaddr_nl sa;
    memset(&sa, 0, sizeof (sa));
    sa.nl_family = AF_NETLINK;
    if (bind(fd, (struct sockaddr *)&sa, sizeof (sa)) < 0)
        err(1, "Cannot bind socket");
    int group = RTNLGRP_LINK;
    if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof (group)) < 0)
        err(1, "Cannot join RTNLGRP_LINK");
    
    for (;;)
    {
        char buf[8192];
        struct iovec iov[] = {
            {.iov_base = buf, .iov_len = sizeof (buf)}
        };
        struct sockaddr_nl sa;
        struct msghdr msg = {&sa, sizeof (sa), iov, sizeof (iov) / sizeof (*iov), NULL, 0, 0};
        int len = recvmsg(fd, &msg, 0);
        if (len < 0)
            err(1, "Cannot receive netlink message");
        if (msg.msg_flags & MSG_TRUNC)
            errx(1, "Receive buffer too small");
        if (len > 0)
        {
            printf("received data (%dB):\n", len);
            hexdump(buf, len);
        }
        for (struct nlmsghdr *nh = (void *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len))
        {
            if (nh->nlmsg_type == NLMSG_NOOP)
                continue;
            else if (nh->nlmsg_type == NLMSG_ERROR)
            {
                errx(1, "Error");
            }
            else if (nh->nlmsg_type == NLMSG_DONE)
            {
                printf("Done\n");
                break; // Done with multipart message
            }
            
            printf("Message type:\t%02X\n", nh->nlmsg_type);
            printf("Message flags:\t%02X\n", nh->nlmsg_flags);
            printf("Message seq:\t%u\n", nh->nlmsg_seq);
            if (nh->nlmsg_type == RTM_NEWLINK)
            {
                printf("RTM_NEWLINK\n");
            }
            else if (nh->nlmsg_type == RTM_DELLINK)
            {
                printf("RTM_DELLINK\n");
            }
        }
        
        printf("=======================\n");
    }
    
    return 0;
}
Filename: None. Size: 3kb. View raw, , hex, or download this file.