int flush_bridgerule(char *brdg, char *member) { int ifs; ifs = socket(AF_INET, SOCK_DGRAM, 0); if (ifs < 0) { printf("%% socket: %s\n", strerror(errno)); return(1); } if (!is_bridge(ifs, brdg)) { printf("%% %s is not a bridge\n", brdg); close(ifs); return(1); } if (!is_valid_ifname(member) || is_bridge(ifs, member)) { printf("%% %s is not a valid interface\n", member); close(ifs); return(1); } bridge_flushrule(ifs, brdg, member); close(ifs); return(0); }
int brstatic(char *ifname, int ifs, int argc, char **argv) { int set; if (NO_ARG(argv[0])) { set = 0; argv++; argc--; } else set = 1; argv++; argc--; if ((set && argc != 2) || ((!set && argc <1) || (!set && argc > 2))) { printf("%% static <mac address> <member>\n"); printf("%% no static <mac address> [member]\n"); return(0); } if (argv[1] && (!is_valid_ifname(argv[1]) || is_bridge(ifs, argv[1]))) { printf("%% invalid member: %s\n", argv[1]); return(0); } if (set) bridge_addaddr(ifs, ifname, argv[1], argv[0]); else bridge_deladdr(ifs, ifname, argv[0]); return(0); }
int brpri(char *ifname, int ifs, int argc, char **argv) { int set, val; const char *errmsg = NULL; struct brd *x; if (NO_ARG(argv[0])) { set = 0; argv++; argc--; } else set = 1; x = (struct brd *) genget(argv[0], (char **)brds, sizeof(struct brd)); if (x == 0) { printf("%% Internal error - Invalid argument %s\n", argv[0]); return 0; } else if (Ambiguous(x)) { printf("%% Internal error - Ambiguous argument %s\n", argv[0]); return 0; } argv++; argc--; /* * the ifpriority value is ignored for 'no ifpriority' but * we allow it anyways to retain compatibility with the * set form of this command */ if ((set && argc != 2) || (!set && (argc < 1 || argc > 2))) { printf("%% %s <member> <%s>\n", x->name, x->descr); printf("%% no %s <member> [%s]\n", x->name, x->descr); return(0); } if (!is_valid_ifname(argv[0]) || is_bridge(ifs, argv[0])) { printf("%% invalid member name: %s", argv[0]); return(0); } errno = 0; val = strtonum(argv[1], 0, 0xff, &errmsg); if (errmsg) { printf("%% invalid priority %s: %s\n", argv[1], errmsg); return (0); } switch(x->type) { case BRPRI_IFPRIORITY: if (set) { if (val > 0xff) { printf("%% %s exceeds limit\n", x->name); return(0); } bridge_ifprio(ifs, ifname, argv[0], val); } else { bridge_ifprio(ifs, ifname, argv[0], DEFAULT_IFPRIORITY); } break; case BRPRI_IFCOST: if (set) { if (val > 65535) { printf("%% %s exceeds limit\n", x->name); return(0); } bridge_ifcost(ifs, ifname, argv[0], val); } else { bridge_ifcost(ifs, ifname, argv[0], DEFAULT_IFCOST); } break; } return(0); }
int brport(char *ifname, int ifs, int argc, char **argv) { int set, i; struct brc *x; if (NO_ARG(argv[0])) { set = 0; argv++; argc--; } else set = 1; x = (struct brc *) genget(argv[0], (char **)brps, sizeof(struct brc)); if (x == 0) { printf("%% Internal error - Invalid argument %s\n", argv[0]); return 0; } else if (Ambiguous(x)) { printf("%% Internal error - Ambiguous argument %s\n", argv[0]); return 0; } argv++; argc--; if (argc == 0) { printf("%% %s <if> [if]...\n", x->name); printf("%% no %s <if> [if]...\n", x->name); return(0); } for (i = 0; i < argc; i++) { if (!is_valid_ifname(argv[i]) || is_bridge(ifs, argv[i])) { printf("%% Invalid interface name %s\n", argv[i]); continue; } switch(x->type) { case BRPORT_MEMBER: if (set) { /* adding a member activates a bridge */ set_ifflag(ifs, ifname, IFF_UP); bridge_add(ifs, ifname, argv[i]); } else bridge_delete(ifs, ifname, argv[i]); break; case BRPORT_SPAN: if (set) bridge_addspan(ifs, ifname, argv[i]); else bridge_delspan(ifs, ifname, argv[i]); break; case BRPORT_BLOCKNONIP: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_BLOCKNONIP); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_BLOCKNONIP); break; case BRPORT_DISCOVER: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_DISCOVER); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_DISCOVER); break; case BRPORT_LEARN: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_LEARNING); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_LEARNING); break; case BRPORT_STP: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_STP); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_STP); break; } } return(0); }
/* * Parse a rule definition and send it upwards. * * Syntax: * {block|pass} {in|out|in/out} on {ifs} [src {mac}] [dst {mac}] */ int bridge_rule(int s, char *brdg, int targc, char **targv, int ln) { char **argv = targv; int argc = targc; struct ifbrlreq rule; struct ether_addr *ea, *dea; short sec; if (argc == 0) { printf("%% Invalid rule\n"); return (EX_USAGE); } rule.ifbr_tagname[0] = 0; rule.ifbr_flags = 0; rule.ifbr_action = 0; strlcpy(rule.ifbr_name, brdg, sizeof(rule.ifbr_name)); sec = 1; if (strcmp(argv[0], "block") == 0) rule.ifbr_action = BRL_ACTION_BLOCK; else if (strcmp(argv[0], "pass") == 0) rule.ifbr_action = BRL_ACTION_PASS; else goto bad_rule; argc--; argv++; sec++; /* 2 */ if (argc == 0) { bridge_badrule(targc, targv, ln, sec); return (EX_USAGE); } if (strcmp(argv[0], "in") == 0) rule.ifbr_flags |= BRL_FLAG_IN; else if (strcmp(argv[0], "out") == 0) rule.ifbr_flags |= BRL_FLAG_OUT; else if (strcmp(argv[0], "in/out") == 0) rule.ifbr_flags |= BRL_FLAG_IN | BRL_FLAG_OUT; else goto bad_rule; argc--; argv++; sec++; /* 3 */ if (argc == 0 || strcmp(argv[0], "on")) goto bad_rule; argc--; argv++; sec++; /* 4 */ if (argc == 0 || !is_valid_ifname(argv[0])) goto bad_rule; strlcpy(rule.ifbr_ifsname, argv[0], sizeof(rule.ifbr_ifsname)); argc--; argv++; sec++; /* 5 */ while (argc) { if (strcmp(argv[0], "dst") == 0) { if (rule.ifbr_flags & BRL_FLAG_DSTVALID) goto bad_rule; rule.ifbr_flags |= BRL_FLAG_DSTVALID; dea = &rule.ifbr_dst; } else if (strcmp(argv[0], "src") == 0) { if (rule.ifbr_flags & BRL_FLAG_SRCVALID) goto bad_rule; rule.ifbr_flags |= BRL_FLAG_SRCVALID; dea = &rule.ifbr_src; } else if (strcmp(argv[0], "tag") == 0) { if (argc < 2) { printf("%% missing tag name\n"); goto bad_rule; } if (rule.ifbr_tagname[0]) { printf("%% tag already defined\n"); goto bad_rule; } if (strlcpy(rule.ifbr_tagname, argv[1], PF_TAG_NAME_SIZE) > PF_TAG_NAME_SIZE) { printf("%% tag name too long\n"); goto bad_rule; } dea = NULL; } else goto bad_rule; argc--; argv++; sec++; if (argc == 0) goto bad_rule; if (dea != NULL) { ea = ether_aton(argv[0]); if (ea == NULL) { printf("%% Invalid address: %s\n", argv[0]); return (0); } bcopy(ea, dea, sizeof(*dea)); } argc--; argv++; sec++; } if (ioctl(s, SIOCBRDGARL, &rule) < 0) { printf("%% unable to add rule: SIOCBRDGARL: %s\n", strerror(errno)); return (EX_IOERR); } return (0); bad_rule: bridge_badrule(targc, targv, ln, sec); return (EX_USAGE); }
int intsyncdev(char *ifname, int ifs, int argc, char **argv) { struct ifreq ifr; struct pfsyncreq preq; int set; if (NO_ARG(argv[0])) { set = 0; argc--; argv++; } else set = 1; argc--; argv++; if ((!set && argc > 1) || (set && argc != 1)) { printf("%% syncdev <if>\n"); printf("%% no syncdev [if]\n"); return (0); } if (!MIN_ARG(ifname, "pfsync")) { printf("%% syncdev is only for pfsync devices\n"); return 0; } bzero((char *) &preq, sizeof(struct pfsyncreq)); ifr.ifr_data = (caddr_t) & preq; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(ifs, SIOCGETPFSYNC, (caddr_t) & ifr) == -1) { printf("%% intsyncdev: SIOCGETPFSYNC: %s\n", strerror(errno)); return (0); } if (argv[0]) if (!is_valid_ifname(argv[0])) { printf("%% Interface not found: %s\n", argv[0]); return (0); } if (set) { strlcpy(preq.pfsyncr_syncdev, argv[0], sizeof(preq.pfsyncr_syncdev)); set_ifflag(ifs, ifname, IFF_UP); } else bzero((char *) &preq.pfsyncr_syncdev, sizeof(preq.pfsyncr_syncdev)); if (ioctl(ifs, SIOCSETPFSYNC, (caddr_t) & ifr) == -1) { if (errno == ENOBUFS) printf("%% Invalid synchronization interface: %s\n", argv[0]); else printf("%% intsyncdev: SIOCSETPFSYNC: %s\n", strerror(errno)); } return (0); }
int show_int(int argc, char **argv) { struct ifaddrs *ifap, *ifa; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct sockaddr_in sin, sin2, sin3; struct timeval tv; struct vlanreq vreq; short tmp; int ifs, br, flags, days, hours, mins, pntd; int ippntd = 0; time_t c; char *type, *lladdr, *ifname = NULL; const char *carp; char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE]; if (argc == 3) ifname = argv[2]; /* * Show all interfaces when no ifname specified. */ if (ifname == NULL) { if ((ifn_list = if_nameindex()) == NULL) { printf("%% show_int: if_nameindex failed\n"); return 1; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { char *args[] = { NULL, NULL, ifnp->if_name }; show_int(3, args); } if_freenameindex(ifn_list); return(0); } else if (!is_valid_ifname(ifname)) { printf("%% interface %s not found\n", ifname); return(1); } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% show_int: %s\n", strerror(errno)); return(1); } if (!(br = is_bridge(ifs, (char *)ifname))) br = 0; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* * Show up/down status and last change time */ flags = get_ifflags(ifname, ifs); ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno)); close(ifs); return(1); } printf("%% %s", ifname); /* description */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) printf(" (%s)", ifrdesc.ifr_data); putchar('\n'); printf(" %s is %s", br ? "Bridge" : "Interface", flags & IFF_UP ? "up" : "down"); if (if_lastchange.tv_sec) { gettimeofday(&tv, (struct timezone *)0); c = difftime(tv.tv_sec, if_lastchange.tv_sec); days = c / SECSPERDAY; c %= SECSPERDAY; hours = c / SECSPERHOUR; c %= SECSPERHOUR; mins = c / SECSPERMIN; c %= SECSPERMIN; printf(" (last change "); if (days) printf("%id ", days); printf("%02i:%02i:%02i)", hours, mins, c); } printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down"); printf("\n"); type = iftype(if_type); printf(" Interface type %s", type); if (flags & IFF_BROADCAST) printf(" (Broadcast)"); else if (flags & IFF_POINTOPOINT) printf(" (PointToPoint)"); if ((lladdr = get_hwdaddr(ifname)) != NULL) printf(", hardware address %s", lladdr); printf("\n"); media_status(ifs, ifname, " Media type "); /* * Print interface IP address, and broadcast or * destination if available. But, don't print broadcast * if it is what we would expect given the ip and netmask! */ if (getifaddrs(&ifap) != 0) { printf("%% show_int: getifaddrs failed: %s\n", strerror(errno)); return(1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET, print the IP and * related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; if (ifa->ifa_addr->sa_family != AF_INET) continue; memcpy(&sin, ifa->ifa_addr, sizeof(struct sockaddr_in)); memcpy(&sin2, ifa->ifa_netmask, sizeof(struct sockaddr_in)); if (sin.sin_addr.s_addr == 0 || sin2.sin_addr.s_addr == 0) continue; if (!ippntd) printf(" Internet address"); printf("%s %s", ippntd ? "," : "", netname4(sin.sin_addr.s_addr, &sin2)); ippntd = 1; if (flags & IFF_POINTOPOINT) { memcpy(&sin3, ifa->ifa_dstaddr, sizeof(struct sockaddr_in)); printf(" (Destination %s)", inet_ntoa(sin3.sin_addr)); } else if (flags & IFF_BROADCAST) { memcpy(&sin3, ifa->ifa_broadaddr, sizeof(struct sockaddr_in)); /* * no reason to show the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sin3.sin_addr.s_addr) != in4_brdaddr(sin.sin_addr.s_addr, sin2.sin_addr.s_addr)) printf(" (Broadcast %s)", inet_ntoa(sin3.sin_addr)); } } if (ippntd) { ippntd = 0; printf("\n"); } freeifaddrs(ifap); if (!br) { if (phys_status(ifs, ifname, tmp_str, tmp_str2, sizeof(tmp_str), sizeof(tmp_str2)) > 0) printf(" Tunnel source %s destination %s\n", tmp_str, tmp_str2); if ((carp = carp_state(ifs, ifname)) != NULL) printf(" CARP state %s\n", carp); /* * Display MTU, line rate, and ALTQ token rate info * (if available) */ printf(" MTU %u bytes", if_mtu); if (if_baudrate) printf(", Line Rate %qu %s\n", MBPS(if_baudrate) ? MBPS(if_baudrate) : if_baudrate / 1000, MBPS(if_baudrate) ? "Mbps" : "Kbps"); else printf("\n"); memset(&vreq, 0, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) != -1) if(vreq.vlr_tag || (vreq.vlr_parent[0] != '\0')) printf(" 802.1Q vlan tag %d, parent %s\n", vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ? "<none>" : vreq.vlr_parent); } if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != NULL) { printf(" SSID %s", tmp_str); if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != NULL) printf(", key %s", tmp_str); if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str), POWERSAVE) != NULL)) printf(", powersaving (%s ms)\n", tmp_str); printf("\n"); } /* * Display remaining info from if_data structure */ printf(" %qu packets input, %qu bytes, %qu errors, %qu drops\n", if_ipackets, if_ibytes, if_ierrors, if_iqdrops); printf(" %qu packets output, %qu bytes, %qu errors, %qu unsupported\n", if_opackets, if_obytes, if_oerrors, if_noproto); if (if_ibytes && if_ipackets && (if_ibytes / if_ipackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf(" %qu input", if_ibytes / if_ipackets); pntd = 1; } else pntd = 0; if (if_obytes && if_opackets && (if_obytes / if_opackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf("%s%qu output", pntd ? ", " : " ", if_obytes / if_opackets); pntd = 1; } if (pntd) printf(" (average bytes/packet)\n"); switch(if_type) { /* * These appear to be the only interface types to increase collision * count in the OpenBSD 3.2 kernel. */ case IFT_ETHER: case IFT_SLIP: case IFT_PROPVIRTUAL: case IFT_IEEE80211: printf(" %qu collisions\n", if_collisions); break; default: break; } if(verbose) { if (flags) { printf(" Flags:\n "); bprintf(stdout, flags, ifnetflags); printf("\n"); } if (br) { if ((tmp = bridge_list(ifs, ifname, " ", tmp_str, sizeof(tmp_str), SHOW_STPSTATE))) { printf(" STP member state%s:\n", tmp > 1 ? "s" : ""); printf("%s", tmp_str); } bridge_addrs(ifs, ifname, " ", " "); } media_supported(ifs, ifname, " ", " "); } close(ifs); return(0); }
int intvlan(char *ifname, int ifs, int argc, char **argv) { const char *errmsg = NULL; struct ifreq ifr; struct vlanreq vreq, preq; int set; if (NO_ARG(argv[0])) { set = 0; argc--; argv++; } else set = 1; argc--; argv++; if ((set && (argc < 3 || argc > 5)) || (!set && argc > 5) || argc == 4 || (argc > 3 && !isprefix(argv[1], "parent")) || (argc > 5 && !isprefix(argv[3], "priority"))) { printf("%% vlan <tag> parent <parent interface> [priority <priority>]\n"); printf("%% no vlan [tag] [parent <parent interface>] [priority <priority>]\n"); return 0; } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); bzero(&vreq, sizeof(vreq)); bzero(&preq, sizeof(preq)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) == -1) { switch(errno) { case ENOTTY: printf("%% This interface does not support vlan" " tagging\n"); break; default: printf("%% intvlan: SIOCGETVLAN: %s\n", strerror(errno)); } return(0); } if (set) { if (!is_valid_ifname(argv[2]) || is_bridge(ifs, argv[2])) { printf("%% Invalid vlan parent %s\n", argv[2]); return 0; } strlcpy(vreq.vlr_parent, argv[2], sizeof(vreq.vlr_parent)); vreq.vlr_tag = strtonum(argv[0], 0, 4096, &errmsg); if (errmsg) { printf("%% Invalid vlan tag %s: %s", argv[0], errmsg); return 0; } if (vreq.vlr_tag != EVL_VLANOFTAG(vreq.vlr_tag)) { printf("%% Invalid vlan tag %s\n", argv[0]); return 0; } if (argc == 5) { preq.vlr_tag = strtonum(argv[4], 0, 7, &errmsg); if (errmsg) { printf("%% Invalid vlan priority %s: %s\n", argv[4], errmsg); return 0; } } } else { bzero(&vreq.vlr_parent, sizeof(vreq.vlr_parent)); vreq.vlr_tag = 0; } if (ioctl(ifs, SIOCSETVLAN, (caddr_t)&ifr) == -1) { switch(errno) { case EBUSY: printf("%% Please disconnect the current vlan parent" " before setting a new one\n"); return 0; break; default: printf("%% intvlan: SIOCSETVLAN: %s\n", strerror(errno)); return 0; } } ifr.ifr_data = (caddr_t)&preq; if (ioctl(ifs, SIOCSETVLANPRIO, (caddr_t)&ifr) == -1) printf("%% intvlan: SIOCSETVLANPRIO: %s\n", strerror(errno)); return 0; }
int show_int(int argc, char **argv) { struct ifaddrs *ifap, *ifa; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct sockaddr_in *sin = NULL, *sinmask = NULL, *sindest; struct sockaddr_in6 *sin6 = NULL, *sin6mask = NULL, *sin6dest; struct timeval tv; short tmp; int ifs, br, flags, days, hours, mins, pntd; int ippntd = 0; int physrt, physttl; time_t c; char *type, *lladdr, *ifname = NULL; char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE]; if (argc == 3) ifname = argv[2]; /* * Show all interfaces when no ifname specified. */ if (ifname == NULL) { if ((ifn_list = if_nameindex()) == NULL) { printf("%% show_int: if_nameindex failed\n"); return 0; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { char *args[] = { NULL, NULL, ifnp->if_name }; show_int(3, args); } if_freenameindex(ifn_list); return(0); } else if (!is_valid_ifname(ifname)) { printf("%% interface %s not found\n", ifname); return(1); } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% show_int: %s\n", strerror(errno)); return(1); } if (!(br = is_bridge(ifs, (char *)ifname))) br = 0; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* * Show up/down status and last change time */ flags = get_ifflags(ifname, ifs); ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno)); close(ifs); return(1); } printf("%% %s", ifname); /* description */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) printf(" (%s)", ifrdesc.ifr_data); putchar('\n'); printf(" %s is %s", br ? "Bridge" : "Interface", flags & IFF_UP ? "up" : "down"); if (if_data.ifi_lastchange.tv_sec) { gettimeofday(&tv, (struct timezone *)0); c = difftime(tv.tv_sec, if_data.ifi_lastchange.tv_sec); days = c / (24 * 60 * 60); c %= (24 * 60 * 60); hours = c / (60 * 60); c %= (60 * 60); mins = c / 60; c %= 60; printf(" (last change "); if (days) printf("%id ", days); printf("%02i:%02i:%02i)", hours, mins, (int)c); } printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down"); printf("\n"); type = iftype(if_data.ifi_type); printf(" Interface type %s", type); if (flags & IFF_BROADCAST) printf(" (Broadcast)"); else if (flags & IFF_POINTOPOINT) printf(" (PointToPoint)"); if ((lladdr = get_hwdaddr(ifname)) != NULL) printf(", hardware address %s", lladdr); printf("\n"); show_trunk(ifs, ifname); media_status(ifs, ifname, " Media type "); /* * Print interface IP address, and broadcast or * destination if available. But, don't print broadcast * if it is what we would expect given the ip and netmask! */ if (getifaddrs(&ifap) != 0) { printf("%% show_int: getifaddrs failed: %s\n", strerror(errno)); return(1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET, print the IP and * related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: sin = (struct sockaddr_in *)ifa->ifa_addr; sinmask = (struct sockaddr_in *)ifa->ifa_netmask; if (sin->sin_addr.s_addr == INADDR_ANY) continue; break; case AF_INET6: sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; in6_fillscopeid(sin6); break; default: continue; } if (!ippntd) printf(" Internet address"); printf("%s %s", ippntd ? "," : "", ifa->ifa_addr->sa_family == AF_INET ? netname4(sin->sin_addr.s_addr, sinmask) : netname6(sin6, sin6mask)); ippntd = 1; switch (ifa->ifa_addr->sa_family) { case AF_INET: if (flags & IFF_POINTOPOINT) { sindest = (struct sockaddr_in *) ifa->ifa_dstaddr; printf(" (Destination %s)", routename4(sindest->sin_addr.s_addr)); } else if (flags & IFF_BROADCAST) { sindest = (struct sockaddr_in *) ifa->ifa_broadaddr; /* * no reason to show the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sindest->sin_addr.s_addr) != in4_brdaddr(sin->sin_addr.s_addr, sinmask->sin_addr.s_addr) && ntohl(sindest->sin_addr.s_addr) != INADDR_ANY) printf(" (Broadcast %s)", inet_ntoa(sindest->sin_addr)); } break; case AF_INET6: if (flags & IFF_POINTOPOINT) { sin6dest = (struct sockaddr_in6 *) ifa->ifa_dstaddr; in6_fillscopeid(sin6dest); printf(" (Destination %s)", routename6(sin6dest)); } break; default: printf(" unknown"); break; } } if (ippntd) { printf("\n"); } freeifaddrs(ifap); if (!br) { if (phys_status(ifs, ifname, tmp_str, tmp_str2, sizeof(tmp_str), sizeof(tmp_str2)) > 0) { printf(" Tunnel source %s destination %s", tmp_str, tmp_str2); if (((physrt = get_physrtable(ifs, ifname)) != 0)) printf(" destination rdomain %i", physrt); if (((physttl = get_physttl(ifs, ifname)) != 0)) printf(" ttl %i", physttl); printf("\n"); } carp_state(ifs, ifname); printf(" "); show_vnet_parent(ifs, ifname); if (ioctl(ifs, SIOCGIFRDOMAIN, (caddr_t)&ifr) != -1) printf(" rdomain %d,", ifr.ifr_rdomainid); /* * Display MTU, line rate */ printf(" MTU %u bytes", if_data.ifi_mtu); if (ioctl(ifs, SIOCGIFHARDMTU, (caddr_t)&ifr) != -1) { if (ifr.ifr_hardmtu) printf(" (hardmtu %u)", ifr.ifr_hardmtu); } if (if_data.ifi_baudrate) printf(", Line Rate %qu %s", MBPS(if_data.ifi_baudrate) ? MBPS(if_data.ifi_baudrate) : if_data.ifi_baudrate / 1000, MBPS(if_data.ifi_baudrate) ? "Mbps" : "Kbps"); printf("\n"); } if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != 0) { printf(" SSID %s", tmp_str); if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != 0) printf(", key %s", tmp_str); if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str), POWERSAVE)) != 0) printf(", powersaving (%s ms)\n", tmp_str); printf("\n"); } /* * Display remaining info from if_data structure */ printf(" %qu packets input, %qu bytes, %qu errors, %qu drops\n", if_data.ifi_ipackets, if_data.ifi_ibytes, if_data.ifi_ierrors, if_data.ifi_iqdrops); printf(" %qu packets output, %qu bytes, %qu errors, %qu unsupported\n", if_data.ifi_opackets, if_data.ifi_obytes, if_data.ifi_oerrors, if_data.ifi_noproto); if (if_data.ifi_ibytes && if_data.ifi_ipackets && (if_data.ifi_ibytes / if_data.ifi_ipackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf(" %qu input", if_data.ifi_ibytes / if_data.ifi_ipackets); pntd = 1; } else pntd = 0; if (if_data.ifi_obytes && if_data.ifi_opackets && (if_data.ifi_obytes / if_data.ifi_opackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf("%s%qu output", pntd ? ", " : " ", if_data.ifi_obytes / if_data.ifi_opackets); pntd = 1; } if (pntd) printf(" (average bytes/packet)\n"); switch(if_data.ifi_type) { /* * These appear to be the only interface types to increase collision * count in the OpenBSD 3.2 kernel. */ case IFT_ETHER: case IFT_SLIP: case IFT_PROPVIRTUAL: case IFT_IEEE80211: printf(" %qu collisions\n", if_data.ifi_collisions); break; default: break; } if(verbose) { if (flags) { printf(" Flags:\n "); bprintf(stdout, flags, ifnetflags); printf("\n"); } printifhwfeatures(ifs, ifname); if (br) { if ((tmp = bridge_list(ifs, ifname, " ", tmp_str, sizeof(tmp_str), SHOW_STPSTATE))) { printf(" STP member state%s:\n", tmp > 1 ? "s" : ""); printf("%s", tmp_str); } bridge_addrs(ifs, ifname, " ", " "); } media_supported(ifs, ifname, " ", " "); } close(ifs); return(0); }
int intvlan(char *ifname, int ifs, int argc, char **argv) { #ifndef SIOCSIFPARENT /* 5.9- */ const char *errmsg = NULL; struct ifreq ifr; struct vlanreq vreq; #endif int set; if (NO_ARG(argv[0])) { set = 0; argc--; argv++; } else set = 1; argc--; argv++; if ((set && argc != 3) || (!set && argc > 3) || (argc == 3 && !isprefix(argv[1], "parent"))) { printf("%% vlan <tag> parent <parent interface>\n"); printf("%% no vlan [tag] [parent <parent interface>]\n"); return 0; } #ifndef SIOCSIFPARENT /* 5.9- */ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); bzero(&vreq, sizeof(vreq)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) == -1) { switch(errno) { case ENOTTY: printf("%% This interface does not support vlan" " tagging\n"); break; default: printf("%% intvlan: SIOCGETVLAN: %s\n", strerror(errno)); } return(0); } #endif if (set) { if (!is_valid_ifname(argv[2]) || is_bridge(ifs, argv[2])) { printf("%% Invalid vlan parent %s\n", argv[2]); return 0; } #ifndef SIOCSIFPARENT /* 5.9- */ strlcpy(vreq.vlr_parent, argv[2], sizeof(vreq.vlr_parent)); vreq.vlr_tag = strtonum(argv[0], 0, 4095, &errmsg); if (errmsg) { printf("%% Invalid vlan tag %s: %s", argv[0], errmsg); return 0; } if (vreq.vlr_tag != EVL_VLANOFTAG(vreq.vlr_tag)) { printf("%% Invalid vlan tag %s\n", argv[0]); return 0; } } else { bzero(&vreq.vlr_parent, sizeof(vreq.vlr_parent)); vreq.vlr_tag = 0; #endif } #ifdef SIOCSIFPARENT /* 6.0+ */ if (set) { char *vnet_argv[] = { "vnetid", argv[0], '\0' }; char *par_argv[] = { "parent", argv[2], '\0' }; intparent(ifname, ifs, 2, par_argv); intvnetid(ifname, ifs, 2, vnet_argv); } else { char *vnet_argv[] = { "no", "vnetid" }; char *par_argv[] = { "no", "parent" }; intparent(ifname, ifs, 2, par_argv); intvnetid(ifname, ifs, 2, vnet_argv); } #else if (ioctl(ifs, SIOCSETVLAN, (caddr_t)&ifr) == -1) { switch(errno) { case EBUSY: printf("%% Please disconnect the current vlan parent" " before setting a new one\n"); return 0; break; default: printf("%% intvlan: SIOCSETVLAN: %s\n", strerror(errno)); return 0; } } #endif return 0; }