int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ndtmsg *ndtm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDTA_MAX+1]; struct rtattr *tpb[NDTPA_MAX+1]; int ret; if (n->nlmsg_type != RTM_NEWNEIGHTBL) { fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*ndtm)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (preferred_family && preferred_family != ndtm->ndtm_family) return 0; parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm))); if (tb[NDTA_NAME]) { char *name = RTA_DATA(tb[NDTA_NAME]); if (strlen(filter.name) > 0 && strcmp(filter.name, name)) return 0; } if (tb[NDTA_PARMS]) { parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]), RTA_PAYLOAD(tb[NDTA_PARMS])); if (tpb[NDTPA_IFINDEX]) { __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]); if (filter.index && filter.index != ifindex) return 0; } else { if (filter.index && filter.index != NONE_DEV) return 0; } } if (ndtm->ndtm_family == AF_INET) fprintf(fp, "inet "); else if (ndtm->ndtm_family == AF_INET6) fprintf(fp, "inet6 "); else if (ndtm->ndtm_family == AF_DECnet) fprintf(fp, "dnet "); else fprintf(fp, "(%d) ", ndtm->ndtm_family); if (tb[NDTA_NAME]) { char *name = RTA_DATA(tb[NDTA_NAME]); fprintf(fp, "%s ", name); } fprintf(fp, "%s", _SL_); ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] || tb[NDTA_GC_INTERVAL]); if (ret) fprintf(fp, " "); if (tb[NDTA_THRESH1]) { __u32 thresh1 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH1]); fprintf(fp, "thresh1 %u ", thresh1); } if (tb[NDTA_THRESH2]) { __u32 thresh2 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH2]); fprintf(fp, "thresh2 %u ", thresh2); } if (tb[NDTA_THRESH3]) { __u32 thresh3 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH3]); fprintf(fp, "thresh3 %u ", thresh3); } if (tb[NDTA_GC_INTERVAL]) { __u64 gc_int = *(__u64 *)RTA_DATA(tb[NDTA_GC_INTERVAL]); fprintf(fp, "gc_int %llu ", gc_int); } if (ret) fprintf(fp, "%s", _SL_); if (tb[NDTA_CONFIG] && show_stats) { struct ndt_config *ndtc = RTA_DATA(tb[NDTA_CONFIG]); fprintf(fp, " "); fprintf(fp, "config "); fprintf(fp, "key_len %u ", ndtc->ndtc_key_len); fprintf(fp, "entry_size %u ", ndtc->ndtc_entry_size); fprintf(fp, "entries %u ", ndtc->ndtc_entries); fprintf(fp, "%s", _SL_); fprintf(fp, " "); fprintf(fp, "last_flush %s ", ntable_strtime_delta(ndtc->ndtc_last_flush)); fprintf(fp, "last_rand %s ", ntable_strtime_delta(ndtc->ndtc_last_rand)); fprintf(fp, "%s", _SL_); fprintf(fp, " "); fprintf(fp, "hash_rnd %u ", ndtc->ndtc_hash_rnd); fprintf(fp, "hash_mask %08x ", ndtc->ndtc_hash_mask); fprintf(fp, "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc); fprintf(fp, "proxy_qlen %u ", ndtc->ndtc_proxy_qlen); fprintf(fp, "%s", _SL_); } if (tb[NDTA_PARMS]) { if (tpb[NDTPA_IFINDEX]) { __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]); fprintf(fp, " "); fprintf(fp, "dev %s ", ll_index_to_name(ifindex)); fprintf(fp, "%s", _SL_); } fprintf(fp, " "); if (tpb[NDTPA_REFCNT]) { __u32 refcnt = *(__u32 *)RTA_DATA(tpb[NDTPA_REFCNT]); fprintf(fp, "refcnt %u ", refcnt); } if (tpb[NDTPA_REACHABLE_TIME]) { __u64 reachable = *(__u64 *)RTA_DATA(tpb[NDTPA_REACHABLE_TIME]); fprintf(fp, "reachable %llu ", reachable); } if (tpb[NDTPA_BASE_REACHABLE_TIME]) { __u64 breachable = *(__u64 *)RTA_DATA(tpb[NDTPA_BASE_REACHABLE_TIME]); fprintf(fp, "base_reachable %llu ", breachable); } if (tpb[NDTPA_RETRANS_TIME]) { __u64 retrans = *(__u64 *)RTA_DATA(tpb[NDTPA_RETRANS_TIME]); fprintf(fp, "retrans %llu ", retrans); } fprintf(fp, "%s", _SL_); fprintf(fp, " "); if (tpb[NDTPA_GC_STALETIME]) { __u64 gc_stale = *(__u64 *)RTA_DATA(tpb[NDTPA_GC_STALETIME]); fprintf(fp, "gc_stale %llu ", gc_stale); } if (tpb[NDTPA_DELAY_PROBE_TIME]) { __u64 delay_probe = *(__u64 *)RTA_DATA(tpb[NDTPA_DELAY_PROBE_TIME]); fprintf(fp, "delay_probe %llu ", delay_probe); } if (tpb[NDTPA_QUEUE_LEN]) { __u32 queue = *(__u32 *)RTA_DATA(tpb[NDTPA_QUEUE_LEN]); fprintf(fp, "queue %u ", queue); } fprintf(fp, "%s", _SL_); fprintf(fp, " "); if (tpb[NDTPA_APP_PROBES]) { __u32 aprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_APP_PROBES]); fprintf(fp, "app_probes %u ", aprobe); } if (tpb[NDTPA_UCAST_PROBES]) { __u32 uprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_UCAST_PROBES]); fprintf(fp, "ucast_probes %u ", uprobe); } if (tpb[NDTPA_MCAST_PROBES]) { __u32 mprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_MCAST_PROBES]); fprintf(fp, "mcast_probes %u ", mprobe); } fprintf(fp, "%s", _SL_); fprintf(fp, " "); if (tpb[NDTPA_ANYCAST_DELAY]) { __u64 anycast_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_ANYCAST_DELAY]); fprintf(fp, "anycast_delay %llu ", anycast_delay); } if (tpb[NDTPA_PROXY_DELAY]) { __u64 proxy_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_PROXY_DELAY]); fprintf(fp, "proxy_delay %llu ", proxy_delay); } if (tpb[NDTPA_PROXY_QLEN]) { __u32 pqueue = *(__u32 *)RTA_DATA(tpb[NDTPA_PROXY_QLEN]); fprintf(fp, "proxy_queue %u ", pqueue); } if (tpb[NDTPA_LOCKTIME]) { __u64 locktime = *(__u64 *)RTA_DATA(tpb[NDTPA_LOCKTIME]); fprintf(fp, "locktime %llu ", locktime); } fprintf(fp, "%s", _SL_); } if (tb[NDTA_STATS] && show_stats) { struct ndt_stats *ndts = RTA_DATA(tb[NDTA_STATS]); fprintf(fp, " "); fprintf(fp, "stats "); fprintf(fp, "allocs %llu ", ndts->ndts_allocs); fprintf(fp, "destroys %llu ", ndts->ndts_destroys); fprintf(fp, "hash_grows %llu ", ndts->ndts_hash_grows); fprintf(fp, "%s", _SL_); fprintf(fp, " "); fprintf(fp, "res_failed %llu ", ndts->ndts_res_failed); fprintf(fp, "lookups %llu ", ndts->ndts_lookups); fprintf(fp, "hits %llu ", ndts->ndts_hits); fprintf(fp, "%s", _SL_); fprintf(fp, " "); fprintf(fp, "rcv_probes_mcast %llu ", ndts->ndts_rcv_probes_mcast); fprintf(fp, "rcv_probes_ucast %llu ", ndts->ndts_rcv_probes_ucast); fprintf(fp, "%s", _SL_); fprintf(fp, " "); fprintf(fp, "periodic_gc_runs %llu ", ndts->ndts_periodic_gc_runs); fprintf(fp, "forced_gc_runs %llu ", ndts->ndts_forced_gc_runs); fprintf(fp, "%s", _SL_); } fprintf(fp, "\n"); fflush(fp); return 0; }
static int print_ntable(struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct ndtmsg *ndtm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDTA_MAX+1]; struct rtattr *tpb[NDTPA_MAX+1]; int ret; if (n->nlmsg_type != RTM_NEWNEIGHTBL) { fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*ndtm)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (preferred_family && preferred_family != ndtm->ndtm_family) return 0; parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm))); if (tb[NDTA_NAME]) { const char *name = rta_getattr_str(tb[NDTA_NAME]); if (filter.name && strcmp(filter.name, name)) return 0; } if (tb[NDTA_PARMS]) { parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]), RTA_PAYLOAD(tb[NDTA_PARMS])); if (tpb[NDTPA_IFINDEX]) { __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]); if (filter.index && filter.index != ifindex) return 0; } else { if (filter.index && filter.index != NONE_DEV) return 0; } } open_json_object(NULL); print_string(PRINT_ANY, "family", "%s ", family_name(ndtm->ndtm_family)); if (tb[NDTA_NAME]) { const char *name = rta_getattr_str(tb[NDTA_NAME]); print_string(PRINT_ANY, "name", "%s ", name); } print_nl(); ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] || tb[NDTA_GC_INTERVAL]); if (ret) print_string(PRINT_FP, NULL, " ", NULL); if (tb[NDTA_THRESH1]) { __u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]); print_uint(PRINT_ANY, "thresh1", "thresh1 %u ", thresh1); } if (tb[NDTA_THRESH2]) { __u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]); print_uint(PRINT_ANY, "thresh2", "thresh2 %u ", thresh2); } if (tb[NDTA_THRESH3]) { __u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]); print_uint(PRINT_ANY, "thresh3", "thresh3 %u ", thresh3); } if (tb[NDTA_GC_INTERVAL]) { __u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]); print_u64(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int); } if (ret) print_nl(); if (tb[NDTA_CONFIG] && show_stats) print_ndtconfig(RTA_DATA(tb[NDTA_CONFIG])); if (tb[NDTA_PARMS]) print_ndtparams(tpb); if (tb[NDTA_STATS] && show_stats) print_ndtstats(RTA_DATA(tb[NDTA_STATS])); print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); fflush(fp); return 0; }