commit e3ae3f878d741da0faea82a868ab22cd453cf8e0 from: smytht via: GitHub date: Sun Mar 12 20:19:46 2023 UTC Merge pull request #59 from stspdotname/showbridge add a "show bridge" command commit - e2bc7ed3866b0b4e75de711c534f5d187e1d3d45 commit + e3ae3f878d741da0faea82a868ab22cd453cf8e0 blob - 466ff2ef225f9867bc2af333a122be8e53db54c0 blob + 957f80a5b029774b2090aa6cee5d016469084a0e --- bridge.c +++ bridge.c @@ -76,6 +76,7 @@ int bridge_confaddrs(int, char *, char *, FILE *); int bridge_protect(const char *, int, const char *, const char *); int bridge_unprotect(const char *, int, const char *); void brprotect_usage(void); +int show_bridge(char *); char *stpstates[] = { "disabled", @@ -1643,3 +1644,115 @@ brprotect(char *ifname, int ifs, int argc, char **argv else return bridge_unprotect(ifname, ifs, argv[1]); } + +int +show_bridge(char *ifname) +{ + struct if_nameindex *ifn_list, *ifnp; + int ifs, flags, totlen, len, found_bridge = 0, header_shown = 0; + char buf[1024], *p, *member; + struct ifreq ifr; + char ifdescr[IFDESCRSIZE], *description; + + if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("%% show_bridge: socket: %s\n", strerror(errno)); + return 0; + } + + if (ifname) { + if (!is_valid_ifname(ifname) || !is_bridge(ifs, ifname)) { + printf("%% interface %s is not a bridge\n", ifname); + close(ifs); + return 0; + } + } + + if ((ifn_list = if_nameindex()) == NULL) { + printf("%% show_vlan: if_nameindex failed\n"); + close(ifs); + return 0; + } + + for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { + if (ifname) { + if (strcmp(ifname, ifnp->if_name) != 0) + continue; + found_bridge = 1; + } else if (!is_bridge(ifs, ifnp->if_name)) + continue; + + if (!header_shown) { + puts("% Bridge Status Member Interfaces"); + header_shown = 1; + } + if (bridge_list(ifs, ifnp->if_name, NULL, buf, sizeof(buf), + MEMBER) == 0) + buf[0] = '\0'; + + flags = get_ifflags(ifnp->if_name, ifs); + + len = printf(" %-9s %-7s", ifnp->if_name, + (flags & IFF_UP) ? "up" : "down"); + if (len < 0) { + printf("\n%% show_bridge: printf failed: %s\n", + strerror(errno)); + goto out; + } + totlen = len; + + p = buf; + while ((member = strsep(&p, " ")) != NULL) { + if (totlen + strlen(member) >= 80) { + printf("\n "); + len = 19; + totlen = len; + } + + len = printf(" %s", member); + if (len < 0) { + printf("\n%% show_bridge: printf failed: %s\n", + strerror(errno)); + goto out; + } + totlen += len; + } + printf("\n"); + + memset(&ifr, 0, sizeof(ifr)); + if (strlcpy(ifr.ifr_name, ifnp->if_name, + sizeof(ifr.ifr_name)) >= sizeof(ifr.ifr_name)) { + printf("%% %s: interface name is too long\n", + ifnp->if_name); + continue; + } + + ifr.ifr_data = (caddr_t)&ifdescr; + if (ioctl(ifs, SIOCGIFDESCR, &ifr) == 0 && + ifr.ifr_data[0] != '\0') + description = ifr.ifr_data; + else + description = "-"; + printf(" Description: %s\n", description); + + if (found_bridge) + break; + } +out: + if_freenameindex(ifn_list); + close(ifs); + return 0; +} + +int +show_bridges(int argc, char **argv) +{ + switch (argc) { + case 2: + show_bridge(NULL); + break; + case 3: + show_bridge(argv[2]); + break; + } + return 0; +} blob - f1bf08371228e7adba03257740a3c587c0f3d35b blob + 2dd877fc0ca63a5f36fa0cefeedc8773d776bf6d --- commands.c +++ commands.c @@ -168,6 +168,7 @@ Menu showlist[] = { { "arp", "ARP table", CMPL0 0, 0, 0, 1, pr_arp }, { "ndp", "NDP table", CMPL0 0, 0, 0, 1, pr_ndp }, { "vlan", "802.1Q/802.1ad VLANs", CMPL0 0, 0, 0, 1, show_vlans }, + { "bridge", "Ethernet bridges", CMPL0 0, 0, 0, 1, show_bridges }, { "kernel", "Kernel statistics", CMPL(ta) (char **)stts, sizeof(struct stt), 0, 1, pr_kernel }, { "bgp", "BGP information", CMPL(ta) (char **)bgcs, sizeof(struct prot1), 0, 4, pr_prot1 }, { "ospf", "OSPF information", CMPL(ta) (char **)oscs, sizeof(struct prot1), 0, 3, pr_prot1 }, blob - ee19c6a2191be0ed569d12fdb514e512a8fbda74 blob + fc8626fcc61c9c24599265d53954d9ef7b542bb2 --- externs.h +++ externs.h @@ -453,6 +453,7 @@ int flush_bridgedyn(char *); int flush_bridgeall(char *); int flush_bridgerule(char *, char*); int brprotect(char *, int, int, char **); +int show_bridges(int, char **); /* tunnel.c */ int inttunnel(char *, int, int, char **);