#include #include #include #include #include #include #include #include #include #include struct iovec { void *iov_base; /* Pointer to data. */ size_t iov_len; /* Length of data. */ }; main() { int status; int ret = 0; int error; struct sockaddr_nl bind_addr; int rtnetlink_sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); bind_addr.nl_family = AF_NETLINK; bind_addr.nl_pad = 0; bind_addr.nl_pid = getpid(); bind_addr.nl_groups = ~0U; if (bind(rtnetlink_sk, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) < 0) { perror("bind"); } while (1) { char buf[4096]; struct iovec iov = { buf, sizeof buf }; struct sockaddr_nl snl; struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0}; struct nlmsghdr *h; status = recvmsg (rtnetlink_sk, &msg, 0); if (status < 0) { if (errno == EINTR) continue; if (errno == EWOULDBLOCK) break; continue; } if (status == 0) { return -1; } if (msg.msg_namelen != sizeof snl) { return -1; } for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, status); h = NLMSG_NEXT (h, status)) { /* Finish of reading. */ if (h->nlmsg_type == NLMSG_DONE) return ret; /* Error handling. */ if (h->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h); if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr))) { printf("Received error message that to with invalid length\n"); return ; } return ; } /* OK we received netlink message. */ switch (h->nlmsg_type) { case RTM_NEWLINK: { printf("We are in NEWLINK ...\n"); break; } case RTM_DELLINK: { printf("We are in DELLINK ...\n"); break; } default: break; } } /* After error care. */ if (msg.msg_flags & MSG_TRUNC) { continue; } if (status) { return -1; } } return ret; }