DF-3349 / mtrace.c
/* * DF-3349 event tracer: listen on PF_ROUTE and report RTM_NEWMADDR / * RTM_DELMADDR events with the link-level address printed. * Build: cc -O -o mtrace mtrace.c ; Run: ./mtrace <seconds> */ #include <sys/socket.h> #include <net/if.h> #include <net/route.h> #include <net/if_dl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { int secs = argc > 1 ? atoi(argv[1]) : 10; int s = socket(PF_ROUTE, SOCK_RAW, 0); char buf[8192]; struct timeval tv = { secs, 0 }; setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); printf("listening %ds for RTM_NEWMADDR/RTM_DELMADDR...\n", secs); fflush(stdout); for (;;) { ssize_t n = read(s, buf, sizeof(buf)); if (n <= 0) break; struct rt_msghdr *rtm = (struct rt_msghdr *)buf; if (rtm->rtm_type != RTM_NEWMADDR && rtm->rtm_type != RTM_DELMADDR) continue; struct ifma_msghdr *ifam = (struct ifma_msghdr *)buf; unsigned char *p = buf + sizeof(struct ifma_msghdr); if (p + 2 < (unsigned char *)buf + rtm->rtm_msglen && p[1] == AF_LINK) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)p; printf("%s: ifindex=%u %02x:%02x:%02x:%02x:%02x:%02x\n", rtm->rtm_type == RTM_NEWMADDR ? "NEWMADDR" : "DELMADDR", ifam->ifmam_index, sdl->sdl_data[0]&0xff, sdl->sdl_data[1]&0xff, sdl->sdl_data[2]&0xff, sdl->sdl_data[3]&0xff, sdl->sdl_data[4]&0xff, sdl->sdl_data[5]&0xff); } else { printf("%s: (non-AF_LINK)\n", rtm->rtm_type == RTM_NEWMADDR ? "NEWMADDR" : "DELMADDR"); } fflush(stdout); } printf("listener done\n"); return (0); } |