static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) { struct ifla_vf_mac *vf_mac; struct ifla_vf_vlan *vf_vlan; struct ifla_vf_tx_rate *vf_tx_rate; struct rtattr *vf[IFLA_VF_MAX+1]; SPRINT_BUF(b1); if (vfinfo->rta_type != IFLA_VF_INFO) { fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type); return; } parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo); vf_mac = RTA_DATA(vf[IFLA_VF_MAC]); vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]); vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]); fprintf(fp, "\n vf %d MAC %s", vf_mac->vf, ll_addr_n2a((unsigned char *)&vf_mac->mac, ETH_ALEN, 0, b1, sizeof(b1))); if (vf_vlan->vlan) fprintf(fp, ", vlan %d", vf_vlan->vlan); if (vf_vlan->qos) fprintf(fp, ", qos %d", vf_vlan->qos); if (vf_tx_rate->rate) fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate); }
static void print_maddr(FILE *fp, struct ma_info *list) { fprintf(fp, "\t"); if (list->addr.family == AF_PACKET) { SPRINT_BUF(b1); fprintf(fp, "link %s", ll_addr_n2a((unsigned char*)list->addr.data, list->addr.bytelen, 0, b1, sizeof(b1))); } else { char abuf[256]; switch(list->addr.family) { case AF_INET: fprintf(fp, "inet "); break; case AF_INET6: fprintf(fp, "inet6 "); break; default: fprintf(fp, "family %d ", list->addr.family); break; } fprintf(fp, "%s", format_host(list->addr.family, -1, list->addr.data, abuf, sizeof(abuf))); } if (list->users != 1) fprintf(fp, " users %d", list->users); if (list->features) fprintf(fp, " %s", list->features); fprintf(fp, "\n"); }
static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { SPRINT_BUF(b1); if (!tb) return; if (tb[IFLA_BOND_SLAVE_STATE]) print_slave_state(f, tb[IFLA_BOND_SLAVE_STATE]); if (tb[IFLA_BOND_SLAVE_MII_STATUS]) print_slave_mii_status(f, tb[IFLA_BOND_SLAVE_MII_STATUS]); if (tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT]) fprintf(f, "link_failure_count %d ", rta_getattr_u32(tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT])); if (tb[IFLA_BOND_SLAVE_PERM_HWADDR]) fprintf(f, "perm_hwaddr %s ", ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_SLAVE_PERM_HWADDR]), RTA_PAYLOAD(tb[IFLA_BOND_SLAVE_PERM_HWADDR]), 0, b1, sizeof(b1))); if (tb[IFLA_BOND_SLAVE_QUEUE_ID]) fprintf(f, "queue_id %d ", rta_getattr_u16(tb[IFLA_BOND_SLAVE_QUEUE_ID])); if (tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID]) fprintf(f, "ad_aggregator_id %d ", rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID])); }
static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { SPRINT_BUF(b1); if (!tb) return; if (tb[IFLA_HSR_SLAVE1] && RTA_PAYLOAD(tb[IFLA_HSR_SLAVE1]) < sizeof(__u32)) return; if (tb[IFLA_HSR_SLAVE2] && RTA_PAYLOAD(tb[IFLA_HSR_SLAVE2]) < sizeof(__u32)) return; if (tb[IFLA_HSR_SEQ_NR] && RTA_PAYLOAD(tb[IFLA_HSR_SEQ_NR]) < sizeof(__u16)) return; if (tb[IFLA_HSR_SUPERVISION_ADDR] && RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]) < ETH_ALEN) return; if (tb[IFLA_HSR_SLAVE1]) print_string(PRINT_ANY, "slave1", "slave1 %s ", ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1]))); else print_null(PRINT_ANY, "slave1", "slave1 %s ", "<none>"); if (tb[IFLA_HSR_SLAVE2]) print_string(PRINT_ANY, "slave2", "slave2 %s ", ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2]))); else print_null(PRINT_ANY, "slave2", "slave2 %s ", "<none>"); if (tb[IFLA_HSR_SEQ_NR]) print_int(PRINT_ANY, "seq_nr", "sequence %d ", rta_getattr_u16(tb[IFLA_HSR_SEQ_NR])); if (tb[IFLA_HSR_SUPERVISION_ADDR]) print_string(PRINT_ANY, "supervision_addr", "supervision %s ", ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]), RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]), ARPHRD_VOID, b1, sizeof(b1))); }
static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) { struct ifla_vf_mac *vf_mac; struct ifla_vf_vlan *vf_vlan; struct ifla_vf_tx_rate *vf_tx_rate; struct ifla_vf_spoofchk *vf_spoofchk; struct rtattr *vf[IFLA_VF_MAX+1]; struct rtattr *tmp; SPRINT_BUF(b1); if (vfinfo->rta_type != IFLA_VF_INFO) { fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type); return; } parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo); vf_mac = RTA_DATA(vf[IFLA_VF_MAC]); vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]); vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]); /* Check if the spoof checking vf info type is supported by * this kernel. */ tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] + vf[IFLA_VF_TX_RATE]->rta_len); if (tmp->rta_type != IFLA_VF_SPOOFCHK) vf_spoofchk = NULL; else vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]); fprintf(fp, "\n vf %d MAC %s", vf_mac->vf, ll_addr_n2a((unsigned char *)&vf_mac->mac, ETH_ALEN, 0, b1, sizeof(b1))); if (vf_vlan->vlan) fprintf(fp, ", vlan %d", vf_vlan->vlan); if (vf_vlan->qos) fprintf(fp, ", qos %d", vf_vlan->qos); if (vf_tx_rate->rate) fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate); if (vf_spoofchk && vf_spoofchk->setting != -1) { if (vf_spoofchk->setting) fprintf(fp, ", spoof checking on"); else fprintf(fp, ", spoof checking off"); } }
const char *rt_addr_n2a_r(int af, int len, const void *addr, char *buf, int buflen) { switch (af) { case AF_INET: case AF_INET6: return inet_ntop(af, addr, buf, buflen); case AF_MPLS: return mpls_ntop(af, addr, buf, buflen); case AF_IPX: return ipx_ntop(af, addr, buf, buflen); case AF_DECnet: { struct dn_naddr dna = { 2, { 0, 0, } }; memcpy(dna.a_addr, addr, 2); return dnet_ntop(af, &dna, buf, buflen); } case AF_PACKET: return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen); case AF_BRIDGE: { const union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; } *sa = addr; switch (sa->sa.sa_family) { case AF_INET: return inet_ntop(AF_INET, &sa->sin.sin_addr, buf, buflen); case AF_INET6: return inet_ntop(AF_INET6, &sa->sin6.sin6_addr, buf, buflen); } /* fallthrough */ } default: return "???"; } }
const char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen) { switch (af) { case AF_INET: case AF_INET6: return inet_ntop(af, addr, buf, buflen); case AF_MPLS: return mpls_ntop(af, addr, buf, buflen); case AF_IPX: return ipx_ntop(af, addr, buf, buflen); case AF_DECnet: { struct dn_naddr dna = { 2, { 0, 0, }}; memcpy(dna.a_addr, addr, 2); return dnet_ntop(af, &dna, buf, buflen); } case AF_PACKET: return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen); default: return "???"; } }
int print_neigh(struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDA_MAX+1]; static int logit = 1; __u8 protocol = 0; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH && n->nlmsg_type != RTM_GETNEIGH) { fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) return 0; if (filter.family && filter.family != r->ndm_family) return 0; if (filter.index && filter.index != r->ndm_ifindex) return 0; if (!(filter.state&r->ndm_state) && !(r->ndm_flags & NTF_PROXY) && !(r->ndm_flags & NTF_EXT_LEARNED) && (r->ndm_state || !(filter.state&0x100)) && (r->ndm_family != AF_DECnet)) return 0; if (filter.master && !(n->nlmsg_flags & NLM_F_DUMP_FILTERED)) { if (logit) { logit = 0; fprintf(fp, "\nWARNING: Kernel does not support filtering by master device\n\n"); } } parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (inet_addr_match_rta(&filter.pfx, tb[NDA_DST])) return 0; if (tb[NDA_PROTOCOL]) protocol = rta_getattr_u8(tb[NDA_PROTOCOL]); if (filter.protocol && filter.protocol != protocol) return 0; if (filter.unused_only && tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); if (ci->ndm_refcnt) return 0; } if (filter.flushb) { struct nlmsghdr *fn; if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { if (flush_update()) return -1; } fn = (struct nlmsghdr *)(filter.flushb + NLMSG_ALIGN(filter.flushp)); memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELNEIGH; fn->nlmsg_flags = NLM_F_REQUEST; fn->nlmsg_seq = ++rth.seq; filter.flushp = (((char *)fn) + n->nlmsg_len) - filter.flushb; filter.flushed++; if (show_stats < 2) return 0; } open_json_object(NULL); if (n->nlmsg_type == RTM_DELNEIGH) print_bool(PRINT_ANY, "deleted", "Deleted ", true); else if (n->nlmsg_type == RTM_GETNEIGH) print_null(PRINT_ANY, "miss", "%s ", "miss"); if (tb[NDA_DST]) { const char *dst; int family = r->ndm_family; if (family == AF_BRIDGE) { if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr)) family = AF_INET6; else family = AF_INET; } dst = format_host_rta(family, tb[NDA_DST]); print_color_string(PRINT_ANY, ifa_family_color(family), "dst", "%s ", dst); } if (!filter.index && r->ndm_ifindex) { if (!is_json_context()) fprintf(fp, "dev "); print_color_string(PRINT_ANY, COLOR_IFNAME, "dev", "%s ", ll_index_to_name(r->ndm_ifindex)); } if (tb[NDA_LLADDR]) { const char *lladdr; SPRINT_BUF(b1); lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]), ll_index_to_type(r->ndm_ifindex), b1, sizeof(b1)); if (!is_json_context()) fprintf(fp, "lladdr "); print_color_string(PRINT_ANY, COLOR_MAC, "lladdr", "%s", lladdr); } if (r->ndm_flags & NTF_ROUTER) print_null(PRINT_ANY, "router", " %s", "router"); if (r->ndm_flags & NTF_PROXY) print_null(PRINT_ANY, "proxy", " %s", "proxy"); if (r->ndm_flags & NTF_EXT_LEARNED) print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn"); if (show_stats) { if (tb[NDA_CACHEINFO]) print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO])); if (tb[NDA_PROBES]) print_uint(PRINT_ANY, "probes", " probes %u", rta_getattr_u32(tb[NDA_PROBES])); } if (r->ndm_state) print_neigh_state(r->ndm_state); if (protocol) { SPRINT_BUF(b1); print_string(PRINT_ANY, "protocol", " proto %s ", rtnl_rtprot_n2a(protocol, b1, sizeof(b1))); } print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); fflush(stdout); return 0; }
int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr * tb[NDA_MAX+1]; char abuf[256]; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH && n->nlmsg_type != RTM_GETNEIGH) { fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) return 0; if (filter.family && filter.family != r->ndm_family) return 0; if (filter.index && filter.index != r->ndm_ifindex) return 0; if (!(filter.state&r->ndm_state) && !(r->ndm_flags & NTF_PROXY) && (r->ndm_state || !(filter.state&0x100)) && (r->ndm_family != AF_DECnet)) return 0; parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (tb[NDA_DST]) { if (filter.pfx.family) { inet_prefix dst; memset(&dst, 0, sizeof(dst)); dst.family = r->ndm_family; memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) return 0; } } if (filter.unused_only && tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); if (ci->ndm_refcnt) return 0; } if (filter.flushb) { struct nlmsghdr *fn; if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { if (flush_update()) return -1; } fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELNEIGH; fn->nlmsg_flags = NLM_F_REQUEST; fn->nlmsg_seq = ++rth.seq; filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; filter.flushed++; if (show_stats < 2) return 0; } if (n->nlmsg_type == RTM_DELNEIGH) fprintf(fp, "delete "); else if (n->nlmsg_type == RTM_GETNEIGH) fprintf(fp, "miss "); if (tb[NDA_DST]) { fprintf(fp, "%s ", format_host(r->ndm_family, RTA_PAYLOAD(tb[NDA_DST]), RTA_DATA(tb[NDA_DST]), abuf, sizeof(abuf))); } if (!filter.index && r->ndm_ifindex) fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex)); if (tb[NDA_LLADDR]) { SPRINT_BUF(b1); fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]), ll_index_to_type(r->ndm_ifindex), b1, sizeof(b1))); } if (r->ndm_flags & NTF_ROUTER) { fprintf(fp, " router"); } if (r->ndm_flags & NTF_PROXY) { fprintf(fp, " proxy"); } if (tb[NDA_CACHEINFO] && show_stats) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); int hz = get_user_hz(); if (ci->ndm_refcnt) printf(" ref %d", ci->ndm_refcnt); fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz, ci->ndm_confirmed/hz, ci->ndm_updated/hz); } if (tb[NDA_PROBES] && show_stats) { __u32 p = rta_getattr_u32(tb[NDA_PROBES]); fprintf(fp, " probes %u", p); } if (r->ndm_state) { int nud = r->ndm_state; fprintf(fp, " "); #define PRINT_FLAG(f) if (nud & NUD_##f) { \ nud &= ~NUD_##f; fprintf(fp, #f "%s", nud ? "," : ""); } PRINT_FLAG(INCOMPLETE); PRINT_FLAG(REACHABLE); PRINT_FLAG(STALE); PRINT_FLAG(DELAY); PRINT_FLAG(PROBE); PRINT_FLAG(FAILED); PRINT_FLAG(NOARP); PRINT_FLAG(PERMANENT); #undef PRINT_FLAG } fprintf(fp, "\n"); fflush(fp); return 0; }
int my_print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; int len = n->nlmsg_len; unsigned m_flag = 0; unsigned char b1[1024]; if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) return 0; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) return -1; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: nil ifname\n"); return -1; } if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: %s", ifi->ifi_index, tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_LINK]) { int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else { fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } } else { fprintf(fp, ": "); } print_link_flags(fp, ifi->ifi_flags, m_flag); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } #endif print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); { fprintf(fp, "%s", _SL_); fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); if (tb[IFLA_ADDRESS]) { fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifi->ifi_type, b1, sizeof(b1))); } if (tb[IFLA_BROADCAST]) { if (ifi->ifi_flags&IFF_POINTOPOINT) fprintf(fp, " peer "); else fprintf(fp, " brd "); fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), RTA_PAYLOAD(tb[IFLA_BROADCAST]), ifi->ifi_type, b1, sizeof(b1))); } } if (tb[IFLA_STATS]) { struct rtnl_link_stats slocal; struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); if (((unsigned long)s) & (sizeof(unsigned long)-1)) { memcpy(&slocal, s, sizeof(slocal)); s = &slocal; } fprintf(fp, "%s", _SL_); fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", s->rx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", s->rx_bytes, s->rx_packets, s->rx_errors, s->rx_dropped, s->rx_over_errors, s->multicast ); if (s->rx_compressed) fprintf(fp, " %-7u", s->rx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", s->rx_length_errors, s->rx_crc_errors, s->rx_frame_errors, s->rx_fifo_errors, s->rx_missed_errors ); } fprintf(fp, "%s", _SL_); fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", s->tx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", s->tx_bytes, s->tx_packets, s->tx_errors, s->tx_dropped, s->tx_carrier_errors, s->collisions); if (s->tx_compressed) fprintf(fp, " %-7u", s->tx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); fprintf(fp, " %-7u %-7u %-7u %-7u", s->tx_aborted_errors, s->tx_fifo_errors, s->tx_window_errors, s->tx_heartbeat_errors ); } } fprintf(fp, "\n"); fflush(fp); return 0; }
int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = arg; struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr * tb[NDA_MAX+1]; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (r->ndm_family != AF_BRIDGE) return 0; if (filter_index && filter_index != r->ndm_ifindex) return 0; parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (n->nlmsg_type == RTM_DELNEIGH) fprintf(fp, "Deleted "); if (tb[NDA_LLADDR]) { SPRINT_BUF(b1); fprintf(fp, "%s ", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]), ll_index_to_type(r->ndm_ifindex), b1, sizeof(b1))); } if (!filter_index && r->ndm_ifindex) fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex)); if (tb[NDA_DST]) { SPRINT_BUF(abuf); fprintf(fp, "dst %s ", format_host(AF_INET, RTA_PAYLOAD(tb[NDA_DST]), RTA_DATA(tb[NDA_DST]), abuf, sizeof(abuf))); } if (show_stats && tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); int hz = get_user_hz(); fprintf(fp, " used %d/%d", ci->ndm_used/hz, ci->ndm_updated/hz); } if (r->ndm_flags & NTF_SELF) fprintf(fp, "self "); if (r->ndm_flags & NTF_MASTER) fprintf(fp, "master "); fprintf(fp, "%s\n", state_n2a(r->ndm_state)); return 0; }
static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { unsigned ifindex; if (!tb) return; if (tb[IFLA_BOND_MODE]) { const char *mode = get_name(mode_tbl, rta_getattr_u8(tb[IFLA_BOND_MODE])); fprintf(f, "mode %s ", mode); } if (tb[IFLA_BOND_ACTIVE_SLAVE] && (ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) { char buf[IFNAMSIZ]; const char *n = if_indextoname(ifindex, buf); if (n) fprintf(f, "active_slave %s ", n); else fprintf(f, "active_slave %u ", ifindex); } if (tb[IFLA_BOND_MIIMON]) fprintf(f, "miimon %u ", rta_getattr_u32(tb[IFLA_BOND_MIIMON])); if (tb[IFLA_BOND_UPDELAY]) fprintf(f, "updelay %u ", rta_getattr_u32(tb[IFLA_BOND_UPDELAY])); if (tb[IFLA_BOND_DOWNDELAY]) fprintf(f, "downdelay %u ", rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY])); if (tb[IFLA_BOND_USE_CARRIER]) fprintf(f, "use_carrier %u ", rta_getattr_u8(tb[IFLA_BOND_USE_CARRIER])); if (tb[IFLA_BOND_ARP_INTERVAL]) fprintf(f, "arp_interval %u ", rta_getattr_u32(tb[IFLA_BOND_ARP_INTERVAL])); if (tb[IFLA_BOND_ARP_IP_TARGET]) { struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1]; char buf[INET_ADDRSTRLEN]; int i; parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS, tb[IFLA_BOND_ARP_IP_TARGET]); if (iptb[0]) fprintf(f, "arp_ip_target "); for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) { if (iptb[i]) fprintf(f, "%s", rt_addr_n2a(AF_INET, RTA_PAYLOAD(iptb[i]), RTA_DATA(iptb[i]), buf, INET_ADDRSTRLEN)); if (i < BOND_MAX_ARP_TARGETS-1 && iptb[i+1]) fprintf(f, ","); } if (iptb[0]) fprintf(f, " "); } if (tb[IFLA_BOND_ARP_VALIDATE]) { const char *arp_validate = get_name(arp_validate_tbl, rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE])); fprintf(f, "arp_validate %s ", arp_validate); } if (tb[IFLA_BOND_ARP_ALL_TARGETS]) { const char *arp_all_targets = get_name(arp_all_targets_tbl, rta_getattr_u32(tb[IFLA_BOND_ARP_ALL_TARGETS])); fprintf(f, "arp_all_targets %s ", arp_all_targets); } if (tb[IFLA_BOND_PRIMARY] && (ifindex = rta_getattr_u32(tb[IFLA_BOND_PRIMARY]))) { char buf[IFNAMSIZ]; const char *n = if_indextoname(ifindex, buf); if (n) fprintf(f, "primary %s ", n); else fprintf(f, "primary %u ", ifindex); } if (tb[IFLA_BOND_PRIMARY_RESELECT]) { const char *primary_reselect = get_name(primary_reselect_tbl, rta_getattr_u8(tb[IFLA_BOND_PRIMARY_RESELECT])); fprintf(f, "primary_reselect %s ", primary_reselect); } if (tb[IFLA_BOND_FAIL_OVER_MAC]) { const char *fail_over_mac = get_name(fail_over_mac_tbl, rta_getattr_u8(tb[IFLA_BOND_FAIL_OVER_MAC])); fprintf(f, "fail_over_mac %s ", fail_over_mac); } if (tb[IFLA_BOND_XMIT_HASH_POLICY]) { const char *xmit_hash_policy = get_name(xmit_hash_policy_tbl, rta_getattr_u8(tb[IFLA_BOND_XMIT_HASH_POLICY])); fprintf(f, "xmit_hash_policy %s ", xmit_hash_policy); } if (tb[IFLA_BOND_RESEND_IGMP]) fprintf(f, "resend_igmp %u ", rta_getattr_u32(tb[IFLA_BOND_RESEND_IGMP])); if (tb[IFLA_BOND_NUM_PEER_NOTIF]) fprintf(f, "num_grat_arp %u ", rta_getattr_u8(tb[IFLA_BOND_NUM_PEER_NOTIF])); if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE]) fprintf(f, "all_slaves_active %u ", rta_getattr_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE])); if (tb[IFLA_BOND_MIN_LINKS]) fprintf(f, "min_links %u ", rta_getattr_u32(tb[IFLA_BOND_MIN_LINKS])); if (tb[IFLA_BOND_LP_INTERVAL]) fprintf(f, "lp_interval %u ", rta_getattr_u32(tb[IFLA_BOND_LP_INTERVAL])); if (tb[IFLA_BOND_PACKETS_PER_SLAVE]) fprintf(f, "packets_per_slave %u ", rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE])); if (tb[IFLA_BOND_AD_LACP_RATE]) { const char *lacp_rate = get_name(lacp_rate_tbl, rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE])); fprintf(f, "lacp_rate %s ", lacp_rate); } if (tb[IFLA_BOND_AD_SELECT]) { const char *ad_select = get_name(ad_select_tbl, rta_getattr_u8(tb[IFLA_BOND_AD_SELECT])); fprintf(f, "ad_select %s ", ad_select); } if (tb[IFLA_BOND_AD_INFO]) { struct rtattr *adtb[IFLA_BOND_AD_INFO_MAX + 1]; parse_rtattr_nested(adtb, IFLA_BOND_AD_INFO_MAX, tb[IFLA_BOND_AD_INFO]); if (adtb[IFLA_BOND_AD_INFO_AGGREGATOR]) fprintf(f, "ad_aggregator %d ", rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_AGGREGATOR])); if (adtb[IFLA_BOND_AD_INFO_NUM_PORTS]) fprintf(f, "ad_num_ports %d ", rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_NUM_PORTS])); if (adtb[IFLA_BOND_AD_INFO_ACTOR_KEY]) fprintf(f, "ad_actor_key %d ", rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_ACTOR_KEY])); if (adtb[IFLA_BOND_AD_INFO_PARTNER_KEY]) fprintf(f, "ad_partner_key %d ", rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_PARTNER_KEY])); if (adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]) { unsigned char *p = RTA_DATA(adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]); SPRINT_BUF(b); fprintf(f, "ad_partner_mac %s ", ll_addr_n2a(p, ETH_ALEN, 0, b, sizeof(b))); } } if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]) { fprintf(f, "ad_actor_sys_prio %u ", rta_getattr_u16(tb[IFLA_BOND_AD_ACTOR_SYS_PRIO])); } if (tb[IFLA_BOND_AD_USER_PORT_KEY]) { fprintf(f, "ad_user_port_key %u ", rta_getattr_u16(tb[IFLA_BOND_AD_USER_PORT_KEY])); } if (tb[IFLA_BOND_AD_ACTOR_SYSTEM]) { /* We assume the l2 address is an Ethernet MAC address */ SPRINT_BUF(b1); fprintf(f, "ad_actor_system %s ", ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_AD_ACTOR_SYSTEM]), RTA_PAYLOAD(tb[IFLA_BOND_AD_ACTOR_SYSTEM]), 1 /*ARPHDR_ETHER*/, b1, sizeof(b1))); } if (tb[IFLA_BOND_TLB_DYNAMIC_LB]) { fprintf(f, "tlb_dynamic_lb %u ", rta_getattr_u8(tb[IFLA_BOND_TLB_DYNAMIC_LB])); } }
int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ifinfomsg *ifi = NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; int len = n->nlmsg_len; unsigned m_flag = 0; if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) return 0; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) return -1; if (filter.ifindex && ifi->ifi_index != filter.ifindex) return 0; if (filter.up && !(ifi->ifi_flags&IFF_UP)) return 0; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); } if (filter.label && (!filter.family || filter.family == AF_PACKET) && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) return 0; if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: %s", ifi->ifi_index, tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_LINK]) { SPRINT_BUF(b1); int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else { fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } } else { fprintf(fp, ": "); } print_link_flags(fp, ifi->ifi_flags, m_flag); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } #endif if (tb[IFLA_OPERSTATE]) print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE])); if (filter.showqueue) print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME])); if (!filter.family || filter.family == AF_PACKET) { SPRINT_BUF(b1); fprintf(fp, "%s", _SL_); fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); if (tb[IFLA_ADDRESS]) { fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifi->ifi_type, b1, sizeof(b1))); } if (tb[IFLA_BROADCAST]) { if (ifi->ifi_flags&IFF_POINTOPOINT) fprintf(fp, " peer "); else fprintf(fp, " brd "); fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), RTA_PAYLOAD(tb[IFLA_BROADCAST]), ifi->ifi_type, b1, sizeof(b1))); } } if (do_link && tb[IFLA_LINKINFO] && show_details) print_linktype(fp, tb[IFLA_LINKINFO]); if (do_link && tb[IFLA_IFALIAS]) fprintf(fp,"\n alias %s", (const char *) RTA_DATA(tb[IFLA_IFALIAS])); if (do_link && tb[IFLA_STATS64] && show_stats) { struct rtnl_link_stats64 slocal; struct rtnl_link_stats64 *s = RTA_DATA(tb[IFLA_STATS64]); if (((unsigned long)s) & (sizeof(unsigned long)-1)) { memcpy(&slocal, s, sizeof(slocal)); s = &slocal; } fprintf(fp, "%s", _SL_); fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", s->rx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu", (unsigned long long)s->rx_bytes, (unsigned long long)s->rx_packets, (unsigned long long)s->rx_errors, (unsigned long long)s->rx_dropped, (unsigned long long)s->rx_over_errors, (unsigned long long)s->multicast); if (s->rx_compressed) fprintf(fp, " %-7llu", (unsigned long long)s->rx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); fprintf(fp, " %-7llu %-7llu %-7llu %-7llu %-7llu", (unsigned long long)s->rx_length_errors, (unsigned long long)s->rx_crc_errors, (unsigned long long)s->rx_frame_errors, (unsigned long long)s->rx_fifo_errors, (unsigned long long)s->rx_missed_errors); } fprintf(fp, "%s", _SL_); fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", s->tx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu", (unsigned long long)s->tx_bytes, (unsigned long long)s->tx_packets, (unsigned long long)s->tx_errors, (unsigned long long)s->tx_dropped, (unsigned long long)s->tx_carrier_errors, (unsigned long long)s->collisions); if (s->tx_compressed) fprintf(fp, " %-7llu", (unsigned long long)s->tx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); fprintf(fp, " %-7llu %-7llu %-7llu %-7llu", (unsigned long long)s->tx_aborted_errors, (unsigned long long)s->tx_fifo_errors, (unsigned long long)s->tx_window_errors, (unsigned long long)s->tx_heartbeat_errors); } } if (do_link && !tb[IFLA_STATS64] && tb[IFLA_STATS] && show_stats) { struct rtnl_link_stats slocal; struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); if (((unsigned long)s) & (sizeof(unsigned long)-1)) { memcpy(&slocal, s, sizeof(slocal)); s = &slocal; } fprintf(fp, "%s", _SL_); fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", s->rx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", s->rx_bytes, s->rx_packets, s->rx_errors, s->rx_dropped, s->rx_over_errors, s->multicast ); if (s->rx_compressed) fprintf(fp, " %-7u", s->rx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", s->rx_length_errors, s->rx_crc_errors, s->rx_frame_errors, s->rx_fifo_errors, s->rx_missed_errors ); } fprintf(fp, "%s", _SL_); fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", s->tx_compressed ? "compressed" : "", _SL_); fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", s->tx_bytes, s->tx_packets, s->tx_errors, s->tx_dropped, s->tx_carrier_errors, s->collisions); if (s->tx_compressed) fprintf(fp, " %-7u", s->tx_compressed); if (show_stats > 1) { fprintf(fp, "%s", _SL_); fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); fprintf(fp, " %-7u %-7u %-7u %-7u", s->tx_aborted_errors, s->tx_fifo_errors, s->tx_window_errors, s->tx_heartbeat_errors ); } } if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) { struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST]; int rem = RTA_PAYLOAD(vflist); for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) print_vfinfo(fp, i); } fprintf(fp, "\n"); fflush(fp); return 0; }
static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg) { struct tc_ife *p = NULL; struct rtattr *tb[TCA_IFE_MAX + 1]; __u16 ife_type = 0; __u32 mmark = 0; __u16 mtcindex = 0; __u32 mprio = 0; int has_optional = 0; SPRINT_BUF(b2); if (arg == NULL) return -1; parse_rtattr_nested(tb, TCA_IFE_MAX, arg); if (tb[TCA_IFE_PARMS] == NULL) { fprintf(f, "[NULL ife parameters]"); return -1; } p = RTA_DATA(tb[TCA_IFE_PARMS]); fprintf(f, "ife %s ", p->flags & IFE_ENCODE ? "encode" : "decode"); print_action_control(f, "action ", p->action, " "); if (tb[TCA_IFE_TYPE]) { ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]); has_optional = 1; fprintf(f, "type 0x%X ", ife_type); } if (has_optional) fprintf(f, "\n\t "); if (tb[TCA_IFE_METALST]) { struct rtattr *metalist[IFE_META_MAX + 1]; int len = 0; parse_rtattr_nested(metalist, IFE_META_MAX, tb[TCA_IFE_METALST]); if (metalist[IFE_META_SKBMARK]) { len = RTA_PAYLOAD(metalist[IFE_META_SKBMARK]); if (len) { mmark = rta_getattr_u32(metalist[IFE_META_SKBMARK]); fprintf(f, "use mark %u ", mmark); } else fprintf(f, "allow mark "); } if (metalist[IFE_META_TCINDEX]) { len = RTA_PAYLOAD(metalist[IFE_META_TCINDEX]); if (len) { mtcindex = rta_getattr_u16(metalist[IFE_META_TCINDEX]); fprintf(f, "use tcindex %d ", mtcindex); } else fprintf(f, "allow tcindex "); } if (metalist[IFE_META_PRIO]) { len = RTA_PAYLOAD(metalist[IFE_META_PRIO]); if (len) { mprio = rta_getattr_u32(metalist[IFE_META_PRIO]); fprintf(f, "use prio %u ", mprio); } else fprintf(f, "allow prio "); } } if (tb[TCA_IFE_DMAC]) { has_optional = 1; fprintf(f, "dst %s ", ll_addr_n2a(RTA_DATA(tb[TCA_IFE_DMAC]), RTA_PAYLOAD(tb[TCA_IFE_DMAC]), 0, b2, sizeof(b2))); } if (tb[TCA_IFE_SMAC]) { has_optional = 1; fprintf(f, "src %s ", ll_addr_n2a(RTA_DATA(tb[TCA_IFE_SMAC]), RTA_PAYLOAD(tb[TCA_IFE_SMAC]), 0, b2, sizeof(b2))); } fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt, p->bindcnt); if (show_stats) { if (tb[TCA_IFE_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_IFE_TM]); print_tm(f, tm); } } fprintf(f, "\n"); return 0; }
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { if (!tb) return; if (tb[IFLA_BR_FORWARD_DELAY]) print_uint(PRINT_ANY, "forward_delay", "forward_delay %u ", rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY])); if (tb[IFLA_BR_HELLO_TIME]) print_uint(PRINT_ANY, "hello_time", "hello_time %u ", rta_getattr_u32(tb[IFLA_BR_HELLO_TIME])); if (tb[IFLA_BR_MAX_AGE]) print_uint(PRINT_ANY, "max_age", "max_age %u ", rta_getattr_u32(tb[IFLA_BR_MAX_AGE])); if (tb[IFLA_BR_AGEING_TIME]) print_uint(PRINT_ANY, "ageing_time", "ageing_time %u ", rta_getattr_u32(tb[IFLA_BR_AGEING_TIME])); if (tb[IFLA_BR_STP_STATE]) print_uint(PRINT_ANY, "stp_state", "stp_state %u ", rta_getattr_u32(tb[IFLA_BR_STP_STATE])); if (tb[IFLA_BR_PRIORITY]) print_uint(PRINT_ANY, "priority", "priority %u ", rta_getattr_u16(tb[IFLA_BR_PRIORITY])); if (tb[IFLA_BR_VLAN_FILTERING]) print_uint(PRINT_ANY, "vlan_filtering", "vlan_filtering %u ", rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING])); if (tb[IFLA_BR_VLAN_PROTOCOL]) { SPRINT_BUF(b1); print_string(PRINT_ANY, "vlan_protocol", "vlan_protocol %s ", ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]), b1, sizeof(b1))); } if (tb[IFLA_BR_BRIDGE_ID]) { char bridge_id[32]; br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id, sizeof(bridge_id)); print_string(PRINT_ANY, "bridge_id", "bridge_id %s ", bridge_id); } if (tb[IFLA_BR_ROOT_ID]) { char root_id[32]; br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id, sizeof(root_id)); print_string(PRINT_ANY, "root_id", "designated_root %s ", root_id); } if (tb[IFLA_BR_ROOT_PORT]) print_uint(PRINT_ANY, "root_port", "root_port %u ", rta_getattr_u16(tb[IFLA_BR_ROOT_PORT])); if (tb[IFLA_BR_ROOT_PATH_COST]) print_uint(PRINT_ANY, "root_path_cost", "root_path_cost %u ", rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST])); if (tb[IFLA_BR_TOPOLOGY_CHANGE]) print_uint(PRINT_ANY, "topology_change", "topology_change %u ", rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE])); if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]) print_uint(PRINT_ANY, "topology_change_detected", "topology_change_detected %u ", rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])); if (tb[IFLA_BR_HELLO_TIMER]) _bridge_print_timer(f, "hello_timer", tb[IFLA_BR_HELLO_TIMER]); if (tb[IFLA_BR_TCN_TIMER]) _bridge_print_timer(f, "tcn_timer", tb[IFLA_BR_TCN_TIMER]); if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]) _bridge_print_timer(f, "topology_change_timer", tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]); if (tb[IFLA_BR_GC_TIMER]) _bridge_print_timer(f, "gc_timer", tb[IFLA_BR_GC_TIMER]); if (tb[IFLA_BR_VLAN_DEFAULT_PVID]) print_uint(PRINT_ANY, "vlan_default_pvid", "vlan_default_pvid %u ", rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID])); if (tb[IFLA_BR_VLAN_STATS_ENABLED]) print_uint(PRINT_ANY, "vlan_stats_enabled", "vlan_stats_enabled %u ", rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED])); if (tb[IFLA_BR_GROUP_FWD_MASK]) print_0xhex(PRINT_ANY, "group_fwd_mask", "group_fwd_mask %#llx ", rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK])); if (tb[IFLA_BR_GROUP_ADDR]) { SPRINT_BUF(mac); print_string(PRINT_ANY, "group_addr", "group_address %s ", ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]), RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]), 1 /*ARPHDR_ETHER*/, mac, sizeof(mac))); } if (tb[IFLA_BR_MCAST_SNOOPING]) print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING])); if (tb[IFLA_BR_MCAST_ROUTER]) print_uint(PRINT_ANY, "mcast_router", "mcast_router %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER])); if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]) print_uint(PRINT_ANY, "mcast_query_use_ifaddr", "mcast_query_use_ifaddr %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])); if (tb[IFLA_BR_MCAST_QUERIER]) print_uint(PRINT_ANY, "mcast_querier", "mcast_querier %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER])); if (tb[IFLA_BR_MCAST_HASH_ELASTICITY]) print_uint(PRINT_ANY, "mcast_hash_elasticity", "mcast_hash_elasticity %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY])); if (tb[IFLA_BR_MCAST_HASH_MAX]) print_uint(PRINT_ANY, "mcast_hash_max", "mcast_hash_max %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX])); if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]) print_uint(PRINT_ANY, "mcast_last_member_cnt", "mcast_last_member_count %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])); if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]) print_uint(PRINT_ANY, "mcast_startup_query_cnt", "mcast_startup_query_count %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])); if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]) print_lluint(PRINT_ANY, "mcast_last_member_intvl", "mcast_last_member_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])); if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]) print_lluint(PRINT_ANY, "mcast_membership_intvl", "mcast_membership_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])); if (tb[IFLA_BR_MCAST_QUERIER_INTVL]) print_lluint(PRINT_ANY, "mcast_querier_intvl", "mcast_querier_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL])); if (tb[IFLA_BR_MCAST_QUERY_INTVL]) print_lluint(PRINT_ANY, "mcast_query_intvl", "mcast_query_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL])); if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) print_lluint(PRINT_ANY, "mcast_query_response_intvl", "mcast_query_response_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])); if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) print_lluint(PRINT_ANY, "mcast_startup_query_intvl", "mcast_startup_query_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])); if (tb[IFLA_BR_MCAST_STATS_ENABLED]) print_uint(PRINT_ANY, "mcast_stats_enabled", "mcast_stats_enabled %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_STATS_ENABLED])); if (tb[IFLA_BR_MCAST_IGMP_VERSION]) print_uint(PRINT_ANY, "mcast_igmp_version", "mcast_igmp_version %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_IGMP_VERSION])); if (tb[IFLA_BR_MCAST_MLD_VERSION]) print_uint(PRINT_ANY, "mcast_mld_version", "mcast_mld_version %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_MLD_VERSION])); if (tb[IFLA_BR_NF_CALL_IPTABLES]) print_uint(PRINT_ANY, "nf_call_iptables", "nf_call_iptables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES])); if (tb[IFLA_BR_NF_CALL_IP6TABLES]) print_uint(PRINT_ANY, "nf_call_ip6tables", "nf_call_ip6tables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES])); if (tb[IFLA_BR_NF_CALL_ARPTABLES]) print_uint(PRINT_ANY, "nf_call_arptables", "nf_call_arptables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES])); }
static void read_dev_mcast(struct ma_info **result_p) { char buf[256]; FILE *fp = fopen("/proc/net/dev_mcast", "r"); if (!fp) return; while (fgets(buf, sizeof(buf), fp)) { char hexa[256]; struct ma_info m = { .addr.family = AF_PACKET }; int len; int st; sscanf(buf, "%d%s%d%d%s", &m.index, m.name, &m.users, &st, hexa); if (filter.dev && strcmp(filter.dev, m.name)) continue; len = parse_hex(hexa, (unsigned char *)&m.addr.data, sizeof(m.addr.data)); if (len >= 0) { struct ma_info *ma = malloc(sizeof(m)); memcpy(ma, &m, sizeof(m)); ma->addr.bytelen = len; ma->addr.bitlen = len<<3; if (st) ma->features = "static"; maddr_ins(result_p, ma); } } fclose(fp); } static void read_igmp(struct ma_info **result_p) { struct ma_info m = { .addr.family = AF_INET, .addr.bitlen = 32, .addr.bytelen = 4, }; char buf[256]; FILE *fp = fopen("/proc/net/igmp", "r"); if (!fp) return; if (!fgets(buf, sizeof(buf), fp)) { fclose(fp); return; } while (fgets(buf, sizeof(buf), fp)) { struct ma_info *ma; size_t len; if (buf[0] != '\t') { sscanf(buf, "%d%s", &m.index, m.name); len = strlen(m.name); if (m.name[len - 1] == ':') len--; continue; } if (filter.dev && strncmp(filter.dev, m.name, len)) continue; sscanf(buf, "%08x%d", (__u32 *)&m.addr.data, &m.users); ma = malloc(sizeof(m)); memcpy(ma, &m, sizeof(m)); maddr_ins(result_p, ma); } fclose(fp); } static void read_igmp6(struct ma_info **result_p) { char buf[256]; FILE *fp = fopen("/proc/net/igmp6", "r"); if (!fp) return; while (fgets(buf, sizeof(buf), fp)) { char hexa[256]; struct ma_info m = { .addr.family = AF_INET6 }; int len; sscanf(buf, "%d%s%s%d", &m.index, m.name, hexa, &m.users); if (filter.dev && strcmp(filter.dev, m.name)) continue; len = parse_hex(hexa, (unsigned char *)&m.addr.data, sizeof(m.addr.data)); if (len >= 0) { struct ma_info *ma = malloc(sizeof(m)); memcpy(ma, &m, sizeof(m)); ma->addr.bytelen = len; ma->addr.bitlen = len<<3; maddr_ins(result_p, ma); } } fclose(fp); } static void print_maddr(FILE *fp, struct ma_info *list) { fprintf(fp, "\t"); if (list->addr.family == AF_PACKET) { SPRINT_BUF(b1); fprintf(fp, "link %s", ll_addr_n2a((unsigned char *)list->addr.data, list->addr.bytelen, 0, b1, sizeof(b1))); } else { switch (list->addr.family) { case AF_INET: fprintf(fp, "inet "); break; case AF_INET6: fprintf(fp, "inet6 "); break; default: fprintf(fp, "family %d ", list->addr.family); break; } fprintf(fp, "%s", format_host(list->addr.family, -1, list->addr.data)); } if (list->users != 1) fprintf(fp, " users %d", list->users); if (list->features) fprintf(fp, " %s", list->features); fprintf(fp, "\n"); } static void print_mlist(FILE *fp, struct ma_info *list) { int cur_index = 0; for (; list; list = list->next) { if (oneline) { cur_index = list->index; fprintf(fp, "%d:\t%s%s", cur_index, list->name, _SL_); } else if (cur_index != list->index) { cur_index = list->index; fprintf(fp, "%d:\t%s\n", cur_index, list->name); } print_maddr(fp, list); } }
int main(int argc, char **argv) { int opt; int do_list = 0; char *do_load = NULL; while ((opt = getopt(argc, argv, "h?b:lf:a:n:p:kR:B:")) != EOF) { switch (opt) { case 'b': dbname = optarg; break; case 'f': if (do_load) { fprintf(stderr, "Duplicate option -f\n"); usage(); } do_load = optarg; break; case 'l': do_list = 1; break; case 'a': active_probing = atoi(optarg); break; case 'n': negative_timeout = atoi(optarg); break; case 'k': no_kernel_broadcasts = 1; break; case 'p': if ((poll_timeout = 1000 * strtod(optarg, NULL)) < 100) { fprintf(stderr,"Invalid poll timeout\n"); exit(-1); } break; case 'R': if ((broadcast_rate = atoi(optarg)) <= 0 || (broadcast_rate = 1000/broadcast_rate) <= 0) { fprintf(stderr, "Invalid ARP rate\n"); exit(-1); } break; case 'B': if ((broadcast_burst = atoi(optarg)) <= 0 || (broadcast_burst = 1000*broadcast_burst) <= 0) { fprintf(stderr, "Invalid ARP burst\n"); exit(-1); } break; case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; if (argc > 0) { ifnum = argc; ifnames = argv; ifvec = malloc(argc*sizeof(int)); if (!ifvec) { perror("malloc"); exit(-1); } } if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(-1); } if (ifnum) { int i; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); for (i=0; i<ifnum; i++) { strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ); if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) { perror("ioctl(SIOCGIFINDEX)"); exit(-1);; } ifvec[i] = ifr.ifr_ifindex; } } dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL); if (dbase == NULL) { perror("db_open"); exit(-1); } if (do_load) { char buf[128]; FILE *fp; struct dbkey k; DBT dbkey, dbdat; dbkey.data = &k; dbkey.size = sizeof(k); if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) { fp = stdin; } else if ((fp = fopen(do_load, "r")) == NULL) { perror("fopen"); goto do_abort; } buf[sizeof(buf)-1] = 0; while (fgets(buf, sizeof(buf)-1, fp)) { __u8 b1[6]; char ipbuf[128]; char macbuf[128]; if (buf[0] == '#') continue; if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) { fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load); goto do_abort; } if (strncmp(macbuf, "FAILED:", 7) == 0) continue; if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) { fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf); goto do_abort; } if (ll_addr_a2n((char *) b1, 6, macbuf) != 6) goto do_abort; dbdat.size = 6; if (dbase->put(dbase, &dbkey, &dbdat, 0)) { perror("hash->put"); goto do_abort; } } dbase->sync(dbase, 0); if (fp != stdin) fclose(fp); } if (do_list) { DBT dbkey, dbdat; printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC"); while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) { struct dbkey *key = dbkey.data; if (handle_if(key->iface)) { if (!IS_NEG(dbdat.data)) { char b1[18]; printf("%-8d %-15s %s\n", key->iface, inet_ntoa(*(struct in_addr*)&key->addr), ll_addr_n2a(dbdat.data, 6, ARPHRD_ETHER, b1, 18)); } else { printf("%-8d %-15s FAILED: %dsec ago\n", key->iface, inet_ntoa(*(struct in_addr*)&key->addr), NEG_AGE(dbdat.data)); } } } } if (do_load || do_list) goto out; pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0); if (pset[0].fd < 0) { perror("socket"); exit(-1); } if (1) { struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ARP); sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0); if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { perror("bind"); goto do_abort; } } if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) { perror("rtnl_open"); goto do_abort; } pset[1].fd = rth.fd; load_initial_table(); if (daemon(0, 0)) { perror("arpd: daemon"); goto do_abort; } openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); catch_signal(SIGINT, sig_exit); catch_signal(SIGTERM, sig_exit); catch_signal(SIGHUP, sig_sync); catch_signal(SIGUSR1, sig_stats); #define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP) pset[0].events = EVENTS; pset[0].revents = 0; pset[1].events = EVENTS; pset[1].revents = 0; sigsetjmp(env, 1); for (;;) { in_poll = 1; if (do_exit) break; if (do_sync) { in_poll = 0; dbase->sync(dbase, 0); do_sync = 0; in_poll = 1; } if (do_stats) send_stats(); if (poll(pset, 2, poll_timeout) > 0) { in_poll = 0; if (pset[0].revents&EVENTS) get_arp_pkt(); if (pset[1].revents&EVENTS) get_kern_msg(); } else { do_sync = 1; } } undo_sysctl_adjustments(); out: dbase->close(dbase); exit(0); do_abort: dbase->close(dbase); exit(-1); }
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { if (!tb) return; if (tb[IFLA_BR_FORWARD_DELAY]) fprintf(f, "forward_delay %u ", rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY])); if (tb[IFLA_BR_HELLO_TIME]) fprintf(f, "hello_time %u ", rta_getattr_u32(tb[IFLA_BR_HELLO_TIME])); if (tb[IFLA_BR_MAX_AGE]) fprintf(f, "max_age %u ", rta_getattr_u32(tb[IFLA_BR_MAX_AGE])); if (tb[IFLA_BR_AGEING_TIME]) fprintf(f, "ageing_time %u ", rta_getattr_u32(tb[IFLA_BR_AGEING_TIME])); if (tb[IFLA_BR_STP_STATE]) fprintf(f, "stp_state %u ", rta_getattr_u32(tb[IFLA_BR_STP_STATE])); if (tb[IFLA_BR_PRIORITY]) fprintf(f, "priority %u ", rta_getattr_u16(tb[IFLA_BR_PRIORITY])); if (tb[IFLA_BR_VLAN_FILTERING]) fprintf(f, "vlan_filtering %u ", rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING])); if (tb[IFLA_BR_VLAN_PROTOCOL]) { SPRINT_BUF(b1); fprintf(f, "vlan_protocol %s ", ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]), b1, sizeof(b1))); } if (tb[IFLA_BR_BRIDGE_ID]) { char bridge_id[32]; br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id, sizeof(bridge_id)); fprintf(f, "bridge_id %s ", bridge_id); } if (tb[IFLA_BR_ROOT_ID]) { char root_id[32]; br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id, sizeof(root_id)); fprintf(f, "designated_root %s ", root_id); } if (tb[IFLA_BR_ROOT_PORT]) fprintf(f, "root_port %u ", rta_getattr_u16(tb[IFLA_BR_ROOT_PORT])); if (tb[IFLA_BR_ROOT_PATH_COST]) fprintf(f, "root_path_cost %u ", rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST])); if (tb[IFLA_BR_TOPOLOGY_CHANGE]) fprintf(f, "topology_change %u ", rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE])); if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]) fprintf(f, "topology_change_detected %u ", rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])); if (tb[IFLA_BR_HELLO_TIMER]) { struct timeval tv; __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_HELLO_TIMER])); fprintf(f, "hello_timer %4i.%.2i ", (int)tv.tv_sec, (int)tv.tv_usec/10000); } if (tb[IFLA_BR_TCN_TIMER]) { struct timeval tv; __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_TCN_TIMER])); fprintf(f, "tcn_timer %4i.%.2i ", (int)tv.tv_sec, (int)tv.tv_usec/10000); } if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]) { unsigned long jiffies; struct timeval tv; jiffies = rta_getattr_u64(tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]); __jiffies_to_tv(&tv, jiffies); fprintf(f, "topology_change_timer %4i.%.2i ", (int)tv.tv_sec, (int)tv.tv_usec/10000); } if (tb[IFLA_BR_GC_TIMER]) { struct timeval tv; __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_GC_TIMER])); fprintf(f, "gc_timer %4i.%.2i ", (int)tv.tv_sec, (int)tv.tv_usec/10000); } if (tb[IFLA_BR_VLAN_DEFAULT_PVID]) fprintf(f, "vlan_default_pvid %u ", rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID])); if (tb[IFLA_BR_GROUP_FWD_MASK]) fprintf(f, "group_fwd_mask %#x ", rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK])); if (tb[IFLA_BR_GROUP_ADDR]) { SPRINT_BUF(mac); fprintf(f, "group_address %s ", ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]), RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]), 1 /*ARPHDR_ETHER*/, mac, sizeof(mac))); } if (tb[IFLA_BR_MCAST_SNOOPING]) fprintf(f, "mcast_snooping %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING])); if (tb[IFLA_BR_MCAST_ROUTER]) fprintf(f, "mcast_router %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER])); if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]) fprintf(f, "mcast_query_use_ifaddr %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])); if (tb[IFLA_BR_MCAST_QUERIER]) fprintf(f, "mcast_querier %u ", rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER])); if (tb[IFLA_BR_MCAST_HASH_ELASTICITY]) fprintf(f, "mcast_hash_elasticity %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY])); if (tb[IFLA_BR_MCAST_HASH_MAX]) fprintf(f, "mcast_hash_max %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX])); if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]) fprintf(f, "mcast_last_member_count %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])); if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]) fprintf(f, "mcast_startup_query_count %u ", rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])); if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]) fprintf(f, "mcast_last_member_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])); if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]) fprintf(f, "mcast_membership_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])); if (tb[IFLA_BR_MCAST_QUERIER_INTVL]) fprintf(f, "mcast_querier_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL])); if (tb[IFLA_BR_MCAST_QUERY_INTVL]) fprintf(f, "mcast_query_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL])); if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) fprintf(f, "mcast_query_response_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])); if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) fprintf(f, "mcast_startup_query_interval %llu ", rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])); if (tb[IFLA_BR_NF_CALL_IPTABLES]) fprintf(f, "nf_call_iptables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES])); if (tb[IFLA_BR_NF_CALL_IP6TABLES]) fprintf(f, "nf_call_ip6tables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES])); if (tb[IFLA_BR_NF_CALL_ARPTABLES]) fprintf(f, "nf_call_arptables %u ", rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES])); }
json_t* make_interface_file() { json_t *interfaces_json = json_object(); json_t *ifTable_json = json_object(); json_t *ifEntry_array = json_array(); struct rtnl_handle rth = { .fd = -1 }; if (rtnl_open(&rth, 0) < 0) { exit(1); } if (rtnl_wilddump_request(&rth, AF_PACKET, RTM_GETLINK) < 0) { perror("Cannot send dump request"); exit(1); } struct nlmsg_list *linfo = NULL; if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { fprintf(stderr, "Dump terminated\n"); exit(1); } struct nlmsg_list *l, *n; for (l = linfo; l; l = n) { n = l->next; struct nlmsghdr *nlhdr = &(l->h); struct ifinfomsg *ifimsg = NLMSG_DATA(nlhdr); // Process Data of Netlink Message as ifinfomsg if (ifimsg->ifi_family != AF_UNSPEC && ifimsg->ifi_family != AF_INET6) { printf("error family: %d\n", ifimsg->ifi_family); continue; } // Add Each Parameter to json file json_t *interface_json = json_object(); json_t *linux_json = json_object(); json_object_set_new(interface_json, "ifIndex", json_integer(ifimsg->ifi_index)); json_object_set_new(linux_json, "ifi_type", json_integer(ifimsg->ifi_type)); json_object_set_new(linux_json, "ifi_flags", json_integer(ifimsg->ifi_flags)); // Analyze rtattr Message int len = nlhdr->nlmsg_len - NLMSG_LENGTH(sizeof(*ifimsg));; struct rtattr *tb[IFLA_MAX+1]; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifimsg), len); if (tb[IFLA_IFNAME]) { // printf("\n%s\n", (char *)RTA_DATA(tb[IFLA_IFNAME])); json_object_set_new(interface_json, "ifDscr", json_string((char *)RTA_DATA(tb[IFLA_IFNAME]))); } if (tb[IFLA_MTU]) { // printf("%d\n", *(int *)RTA_DATA(tb[IFLA_MTU])); json_object_set_new(interface_json, "ifMtu", json_integer(*(int *)RTA_DATA(tb[IFLA_MTU]))); } static const char *oper_states[] = { "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN", "TESTING", "DORMANT", "UP" }; if (tb[IFLA_OPERSTATE]) { __u8 state = *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]); if (state >= sizeof(oper_states)/sizeof(oper_states[0])){ fprintf(stderr, "state %#x ", state); } else{ // printf("state %s ", oper_states[state]); json_object_set_new(interface_json, "ifOperStatus", json_string(oper_states[state])); } } if (tb[IFLA_ADDRESS]) { char abuf[64]; json_object_set_new(interface_json, "ifPhysAddress", json_string(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifimsg->ifi_type, abuf, sizeof(abuf)))); } json_object_set_new(interface_json, "linux", linux_json); json_array_append(ifEntry_array, interface_json); } json_object_set_new(ifTable_json, "ifEntry", ifEntry_array); json_object_set_new(interfaces_json, "ifTable", ifTable_json); free(l); rtnl_close(&rth); return interfaces_json; }
static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who, const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg) { FILE *fp = (FILE*)arg; struct ifinfomsg *ifi = NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; int len = n->nlmsg_len; unsigned m_flag = 0; if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) return 0; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) return -1; if (filter.ifindex && ifi->ifi_index != filter.ifindex) return 0; if (filter.up && !(ifi->ifi_flags&IFF_UP)) return 0; memset(tb, 0, sizeof(tb)); parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (tb[IFLA_IFNAME] == NULL) { bb_error_msg("nil ifname"); return -1; } if (filter.label && (!filter.family || filter.family == AF_PACKET) && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0) ) { return 0; } if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: %s", ifi->ifi_index, tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_LINK]) { SPRINT_BUF(b1); int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else { fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } } else { fprintf(fp, ": "); } print_link_flags(fp, ifi->ifi_flags, m_flag); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } #endif if (filter.showqueue) print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); if (!filter.family || filter.family == AF_PACKET) { SPRINT_BUF(b1); fprintf(fp, "%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); if (tb[IFLA_ADDRESS]) { fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifi->ifi_type, b1, sizeof(b1))); } if (tb[IFLA_BROADCAST]) { if (ifi->ifi_flags&IFF_POINTOPOINT) fprintf(fp, " peer "); else fprintf(fp, " brd "); fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), RTA_PAYLOAD(tb[IFLA_BROADCAST]), ifi->ifi_type, b1, sizeof(b1))); } } fputc('\n', fp); fflush(fp); return 0; }
int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr * tb[NDA_MAX+1]; char abuf[256]; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*r)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) return 0; if (filter.family && filter.family != r->ndm_family) return 0; if (filter.index && filter.index != r->ndm_ifindex) return 0; if (!(filter.state&r->ndm_state) && (r->ndm_state || !(filter.state&0x100)) && (r->ndm_family != AF_DECnet)) return 0; memset(tb, 0, sizeof(tb)); parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (tb[NDA_DST]) { if (filter.pfx.family) { inet_prefix dst; memset(&dst, 0, sizeof(dst)); dst.family = r->ndm_family; memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) return 0; } } if (filter.unused_only && tb[NDA_CACHEINFO]) { struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); if (ci->ndm_refcnt) return 0; } if (filter.flushb) { struct nlmsghdr *fn; if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { if (flush_update()) return -1; } fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELNEIGH; fn->nlmsg_flags = NLM_F_REQUEST; fn->nlmsg_seq = ++filter.rth->seq; filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; filter.flushed++; if (show_stats < 2) return 0; } if (tb[NDA_DST]) { fprintf(fp, "%s ", format_host(r->ndm_family, RTA_PAYLOAD(tb[NDA_DST]), RTA_DATA(tb[NDA_DST]), abuf, sizeof(abuf))); } if (!filter.index && r->ndm_ifindex) fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex)); if (tb[NDA_LLADDR]) { SPRINT_BUF(b1); fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]), ll_index_to_type(r->ndm_ifindex), b1, sizeof(b1))); } if (r->ndm_flags & NTF_ROUTER) { fprintf(fp, " router"); } if (tb[NDA_CACHEINFO] && show_stats) { static int hz; struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); if (!hz) hz = get_hz(); if (ci->ndm_refcnt) printf(" ref %d", ci->ndm_refcnt); fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz, ci->ndm_confirmed/hz, ci->ndm_updated/hz); } if (r->ndm_state) { SPRINT_BUF(b1); fprintf(fp, " nud %s", nud_state_n2a(r->ndm_state, b1, sizeof(b1))); } fprintf(fp, "\n"); fflush(fp); return 0; }
int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ifinfomsg *ifi = NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; int len = n->nlmsg_len; unsigned m_flag = 0; if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) return 0; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) return -1; if (filter.ifindex && ifi->ifi_index != filter.ifindex) return 0; if (filter.up && !(ifi->ifi_flags&IFF_UP)) return 0; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); } if (filter.label && (!filter.family || filter.family == AF_PACKET) && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) return 0; if (tb[IFLA_GROUP]) { int group = *(int*)RTA_DATA(tb[IFLA_GROUP]); if (filter.group != -1 && group != filter.group) return -1; } if (tb[IFLA_MASTER]) { int master = *(int*)RTA_DATA(tb[IFLA_MASTER]); if (filter.master > 0 && master != filter.master) return -1; } else if (filter.master > 0) return -1; if (filter.kind) { if (tb[IFLA_LINKINFO]) { char *kind = parse_link_kind(tb[IFLA_LINKINFO]); if (strcmp(kind, filter.kind)) return -1; } else { return -1; } } if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: ", ifi->ifi_index); color_fprintf(fp, COLOR_IFNAME, "%s", tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_LINK]) { SPRINT_BUF(b1); int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else { if (tb[IFLA_LINK_NETNSID]) fprintf(fp, "@if%d: ", iflink); else { fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } } } else { fprintf(fp, ": "); } print_link_flags(fp, ifi->ifi_flags, m_flag); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC])); if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } if (tb[IFLA_PHYS_PORT_ID]) { SPRINT_BUF(b1); fprintf(fp, "portid %s ", hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]), RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]), b1, sizeof(b1))); } if (tb[IFLA_OPERSTATE]) print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); if (do_link && tb[IFLA_LINKMODE]) print_linkmode(fp, tb[IFLA_LINKMODE]); if (tb[IFLA_GROUP]) { SPRINT_BUF(b1); int group = *(int*)RTA_DATA(tb[IFLA_GROUP]); fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1))); } if (filter.showqueue) print_queuelen(fp, tb); if (!filter.family || filter.family == AF_PACKET || show_details) { SPRINT_BUF(b1); fprintf(fp, "%s", _SL_); fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); if (tb[IFLA_ADDRESS]) { color_fprintf(fp, COLOR_MAC, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifi->ifi_type, b1, sizeof(b1))); } if (tb[IFLA_BROADCAST]) { if (ifi->ifi_flags&IFF_POINTOPOINT) fprintf(fp, " peer "); else fprintf(fp, " brd "); fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), RTA_PAYLOAD(tb[IFLA_BROADCAST]), ifi->ifi_type, b1, sizeof(b1))); } } if (tb[IFLA_LINK_NETNSID]) { int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]); if (id >= 0) fprintf(fp, " link-netnsid %d", id); else fprintf(fp, " link-netnsid unknown"); } if (tb[IFLA_PROMISCUITY] && show_details) fprintf(fp, " promiscuity %u ", *(int*)RTA_DATA(tb[IFLA_PROMISCUITY])); if (tb[IFLA_LINKINFO] && show_details) print_linktype(fp, tb[IFLA_LINKINFO]); if (do_link && tb[IFLA_AF_SPEC] && show_details) print_af_spec(fp, tb[IFLA_AF_SPEC]); if ((do_link || show_details) && tb[IFLA_IFALIAS]) { fprintf(fp, "%s alias %s", _SL_, rta_getattr_str(tb[IFLA_IFALIAS])); } if (do_link && show_stats) { fprintf(fp, "%s", _SL_); __print_link_stats(fp, tb); } if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) { struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST]; int rem = RTA_PAYLOAD(vflist); for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) print_vfinfo(fp, i); } fprintf(fp, "\n"); fflush(fp); return 1; }
int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; struct ifinfomsg *ifi = NLMSG_DATA(n); struct rtattr * tb[IFLA_MAX+1]; int len = n->nlmsg_len; unsigned m_flag = 0; if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) return 0; len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) return -1; if (filter.ifindex && ifi->ifi_index != filter.ifindex) return 0; if (filter.up && !(ifi->ifi_flags&IFF_UP)) return 0; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); } if (filter.label && (!filter.family || filter.family == AF_PACKET) && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) return 0; if (tb[IFLA_GROUP]) { int group = *(int*)RTA_DATA(tb[IFLA_GROUP]); if (group != filter.group) return -1; } if (n->nlmsg_type == RTM_DELLINK) fprintf(fp, "Deleted "); fprintf(fp, "%d: %s", ifi->ifi_index, tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>"); if (tb[IFLA_LINK]) { SPRINT_BUF(b1); int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) fprintf(fp, "@NONE: "); else { fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } } else { fprintf(fp, ": "); } print_link_flags(fp, ifi->ifi_flags, m_flag); if (tb[IFLA_MTU]) fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC])); if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } if (tb[IFLA_OPERSTATE]) print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); if (do_link && tb[IFLA_LINKMODE]) print_linkmode(fp, tb[IFLA_LINKMODE]); if (filter.showqueue) print_queuelen(fp, tb); if (!filter.family || filter.family == AF_PACKET) { SPRINT_BUF(b1); fprintf(fp, "%s", _SL_); fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); if (tb[IFLA_ADDRESS]) { fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifi->ifi_type, b1, sizeof(b1))); } if (tb[IFLA_BROADCAST]) { if (ifi->ifi_flags&IFF_POINTOPOINT) fprintf(fp, " peer "); else fprintf(fp, " brd "); fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), RTA_PAYLOAD(tb[IFLA_BROADCAST]), ifi->ifi_type, b1, sizeof(b1))); } } if (do_link && tb[IFLA_LINKINFO] && show_details) print_linktype(fp, tb[IFLA_LINKINFO]); if (do_link && tb[IFLA_IFALIAS]) fprintf(fp,"\n alias %s", rta_getattr_str(tb[IFLA_IFALIAS])); if (do_link && show_stats) { if (tb[IFLA_STATS64]) print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64])); else if (tb[IFLA_STATS]) print_link_stats(fp, RTA_DATA(tb[IFLA_STATS])); } if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) { struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST]; int rem = RTA_PAYLOAD(vflist); for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) print_vfinfo(fp, i); } fprintf(fp, "\n"); fflush(fp); return 0; }