int accept_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; if (timestamp) print_timestamp(fp); if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) { print_route(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) { ll_remember_index(who, n, NULL); print_linkinfo(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) { print_addrinfo(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH) { print_neigh(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWPREFIX) { print_prefix(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) { print_rule(who, n, arg); return 0; } if (n->nlmsg_type == 15) { char *tstr; time_t secs = ((__u32*)NLMSG_DATA(n))[0]; long usecs = ((__u32*)NLMSG_DATA(n))[1]; tstr = asctime(localtime(&secs)); tstr[strlen(tstr)-1] = 0; fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs); return 0; } if (n->nlmsg_type == RTM_NEWQDISC || n->nlmsg_type == RTM_DELQDISC || n->nlmsg_type == RTM_NEWTCLASS || n->nlmsg_type == RTM_DELTCLASS || n->nlmsg_type == RTM_NEWTFILTER || n->nlmsg_type == RTM_DELTFILTER) return 0; if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { fprintf(fp, "Unknown message: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); } return 0; }
static int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { struct nlmsg_list **linfo = (struct nlmsg_list**)arg; struct nlmsg_list *h; struct nlmsg_list **lp; h = malloc(n->nlmsg_len+sizeof(void*)); if (h == NULL) return -1; memcpy(&h->h, n, n->nlmsg_len); h->next = NULL; for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */; *lp = h; ll_remember_index(who, n, NULL); return 0; }
static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { struct nlmsg_chain *lchain = (struct nlmsg_chain *)arg; struct nlmsg_list *h; h = malloc(n->nlmsg_len+sizeof(void*)); if (h == NULL) return -1; memcpy(&h->h, n, n->nlmsg_len); h->next = NULL; if (lchain->tail) lchain->tail->next = h; else lchain->head = h; lchain->tail = h; ll_remember_index(who, n, NULL); return 0; }
static int accept_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) { struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (r->rtm_flags & RTM_F_CLONED) return 0; if (timestamp) print_timestamp(fp); if (r->rtm_family == RTNL_FAMILY_IPMR || r->rtm_family == RTNL_FAMILY_IP6MR) { if (prefix_banner) fprintf(fp, "[MROUTE]"); print_mroute(who, n, arg); return 0; } else { if (prefix_banner) fprintf(fp, "[ROUTE]"); print_route(who, n, arg); return 0; } } if (timestamp) print_timestamp(fp); if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) { ll_remember_index(who, n, NULL); if (prefix_banner) fprintf(fp, "[LINK]"); print_linkinfo(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) { if (prefix_banner) fprintf(fp, "[ADDR]"); print_addrinfo(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) { if (prefix_banner) fprintf(fp, "[ADDRLABEL]"); print_addrlabel(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH || n->nlmsg_type == RTM_GETNEIGH) { if (preferred_family) { struct ndmsg *r = NLMSG_DATA(n); if (r->ndm_family != preferred_family) return 0; } if (prefix_banner) fprintf(fp, "[NEIGH]"); print_neigh(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWPREFIX) { if (prefix_banner) fprintf(fp, "[PREFIX]"); print_prefix(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) { if (prefix_banner) fprintf(fp, "[RULE]"); print_rule(who, n, arg); return 0; } if (n->nlmsg_type == RTM_NEWNETCONF) { if (prefix_banner) fprintf(fp, "[NETCONF]"); print_netconf(who, n, arg); return 0; } if (n->nlmsg_type == NLMSG_TSTAMP) { print_nlmsg_timestamp(fp, n); return 0; } if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { fprintf(fp, "Unknown message: type=0x%08x(%d) flags=0x%08x(%d)" "len=0x%08x(%d)\n", n->nlmsg_type, n->nlmsg_type, n->nlmsg_flags, n->nlmsg_flags, n->nlmsg_len, n->nlmsg_len); } return 0; }