/* * Copyright mcmanus@ducksong.com 2008, Under terms of GPLv2 * Slightly modified by Paul Wouters 2010 */ #include #include #include #include #include #include int main() { struct sockaddr_nl addr; int nls,len,rtl; char buffer[4096]; struct nlmsghdr *nlh; struct ifaddrmsg *ifa; struct rtattr *rth; if ((nls = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) perror ("socket failure\n"); memset (&addr,0,sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_groups = RTMGRP_IPV4_IFADDR; if (bind(nls, (struct sockaddr *)&addr, sizeof(addr)) == -1) perror ("bind failure\n"); nlh = (struct nlmsghdr *)buffer; while ((len = recv (nls,nlh,4096,0)) > 0) { for (;(NLMSG_OK (nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE); nlh = NLMSG_NEXT(nlh, len)) { switch(nlh->nlmsg_type) { default: fprintf(stdout,"unknown kind of announcement from NETLINK_ROUTE\n"); continue; /* some other kind of announcement */ case RTM_DELADDR: case RTM_NEWADDR: ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh); rth = IFA_RTA (ifa); rtl = IFA_PAYLOAD (nlh); for (;rtl && RTA_OK (rth, rtl); rth = RTA_NEXT (rth,rtl)) { char name[IFNAMSIZ]; uint32_t ipaddr; if (rth->rta_type != IFA_LOCAL) continue; ipaddr = * ((uint32_t *)RTA_DATA(rth)); ipaddr = htonl(ipaddr); if(nlh->nlmsg_type == RTM_DELADDR) fprintf (stdout,"%s removed %X\n",if_indextoname(ifa->ifa_index,name),ipaddr); else if(nlh->nlmsg_type == RTM_NEWADDR) fprintf (stdout,"%s added %X\n",if_indextoname(ifa->ifa_index,name),ipaddr); else fprintf (stdout,"%s changed?? %X\n",if_indextoname(ifa->ifa_index,name),ipaddr); } } } } }