Created
May 17, 2019 09:18
-
-
Save pandax381/d19cad747e777de15b48b4b5663c106c to your computer and use it in GitHub Desktop.
Detect add/delete IP address to interface on Linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <signal.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#include <linux/rtnetlink.h> | |
#include <linux/if.h> | |
static volatile sig_atomic_t terminate; | |
static int | |
process_rtm_addr (struct nlmsghdr *hdr) { | |
struct ifaddrmsg *msg; | |
size_t n; | |
struct rtattr *rta; | |
char local[INET6_ADDRSTRLEN] = {0}, *label = NULL, *dir; | |
msg = NLMSG_DATA(hdr); | |
n = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg)); | |
for (rta = IFA_RTA(msg); RTA_OK(rta, n); rta = RTA_NEXT(rta, n)) { | |
switch (rta->rta_type) { | |
case IFA_LOCAL: | |
inet_ntop(msg->ifa_family, RTA_DATA(rta), local, sizeof(local)); | |
break; | |
case IFA_LABEL: | |
label = (char *)RTA_DATA(rta); | |
break; | |
} | |
} | |
dir = (hdr->nlmsg_type == RTM_NEWADDR) ? "add" : "del"; | |
if (label) { | |
fprintf(stderr, "%s: %s %s/%u\n", label, dir, local, msg->ifa_prefixlen); | |
} else { | |
fprintf(stderr, "(%d): %s %s/%u\n", msg->ifa_index, dir, local, msg->ifa_prefixlen); | |
} | |
return 0; | |
} | |
static void | |
on_signal (int signum) { | |
(void)signum; | |
terminate = 1; | |
} | |
int | |
main (int argc, char *argv[]) { | |
struct sigaction sig; | |
int soc; | |
struct sockaddr_nl sa; | |
char buf[4096]; | |
ssize_t n; | |
struct nlmsghdr *hdr; | |
(void)argc, (void)argv; | |
memset(&sig, 0, sizeof(sig)); | |
sig.sa_handler = on_signal; | |
if (sigaction(SIGINT, &sig, NULL) == -1) { | |
perror("sigaction"); | |
return -1; | |
} | |
if (sigaction(SIGTERM, &sig, NULL) == -1) { | |
perror("sigaction"); | |
return -1; | |
} | |
soc = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); | |
if (soc == -1) { | |
perror("socket"); | |
return -1; | |
} | |
memset(&sa, 0, sizeof(sa)); | |
sa.nl_family = AF_NETLINK; | |
sa.nl_pid = 0; | |
sa.nl_groups = RTMGRP_IPV4_IFADDR; | |
if (bind(soc, (struct sockaddr *)&sa, sizeof(sa)) == -1) { | |
perror("bind"); | |
close(soc); | |
return -1; | |
} | |
while (!terminate) { | |
n = recv(soc, buf, sizeof(buf), 0); | |
if (n == -1) { | |
if (errno == EINTR) { | |
continue; | |
} | |
perror("recv"); | |
close(soc); | |
return -1; | |
} | |
if (!n) { | |
fprintf(stderr, "EOF\n"); | |
break; | |
} | |
for (hdr = (struct nlmsghdr *)buf; NLMSG_OK(hdr, n); hdr = NLMSG_NEXT(hdr, n)) { | |
switch (hdr->nlmsg_type) { | |
case RTM_NEWADDR: | |
case RTM_DELADDR: | |
process_rtm_addr(hdr); | |
break; | |
default: | |
fprintf(stderr, "Unknown Type (%u)\n", hdr->nlmsg_type); | |
break; | |
} | |
} | |
} | |
close(soc); | |
return 0; | |
} |
Author
pandax381
commented
May 17, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment