void conf_interfaces(FILE *output, char *only) { FILE *dhcpif, *llfile; int ifs, flags, ippntd, br; #define LLPREFIX "/var/run/lladdr" char leasefile[sizeof(LEASEPREFIX)+1+IFNAMSIZ]; char *lladdr, llorig[IFNAMSIZ]; char llfn[sizeof(LLPREFIX)+IFNAMSIZ]; char ifdescr[IFDESCRSIZE]; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct vlanreq vreq; if ((ifn_list = if_nameindex()) == NULL) { printf("%% conf_interfaces: if_nameindex failed\n"); return; } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% conf_interfaces socket: %s\n", strerror(errno)); if_freenameindex(ifn_list); return; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { strlcpy(ifr.ifr_name, ifnp->if_name, sizeof(ifr.ifr_name)); if (only && !isprefix(only, ifnp->if_name)) /* only display interfaces which start with ... */ continue; if (!only) { /* interface prefixes to exclude on generic run */ if (isprefix("pfsync", ifnp->if_name)) continue; } if (ioctl(ifs, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { printf("%% conf: SIOCGIFFLAGS: %s\n", strerror(errno)); continue; } flags = ifr.ifr_flags; ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% conf: SIOCGIFDATA: %s\n", strerror(errno)); continue; } /* * Keep in mind that the order in which things are displayed * here is important. For instance, we want to setup the * vlan tag before setting the IP address since the vlan * must know what parent to inherit the parent interface * flags from before it is brought up. Another example of * this would be that we need to setup the members on a * bridge before we setup flags on them. */ /* * set interface/bridge mode */ if (!(br = is_bridge(ifs, ifnp->if_name))) br = 0; fprintf(output, "%s %s\n", br ? "bridge" : "interface", ifnp->if_name); /* * description, if available * copied straight from ifconfig.c */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifnp->if_name, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) fprintf(output, " description %s\n", ifrdesc.ifr_data); /* * print lladdr if necessary */ if ((lladdr = get_hwdaddr(ifnp->if_name)) != NULL) { /* We assume lladdr only useful if we can get_hwdaddr */ snprintf(llfn, sizeof(llfn), "%s.%s", LLPREFIX, ifnp->if_name); if ((llfile = fopen(llfn, "r"))) { fgets(llorig, sizeof(llorig), llfile); if (strcmp(llorig, lladdr) != 0) { fprintf(output, " lladdr %s\n", lladdr); } fclose(llfile); } } /* * print vlan tag, parent if available. if a tag is set * but there is no parent, discard. */ bzero(&vreq, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) != -1) { struct vlanreq preq; bzero(&preq, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&preq; ioctl(ifs, SIOCGETVLANPRIO, (caddr_t)&ifr); if(vreq.vlr_tag && (vreq.vlr_parent[0] != '\0')) { fprintf(output, " vlan %d parent %s", vreq.vlr_tag, vreq.vlr_parent); if(preq.vlr_tag > 0) fprintf(output, " priority %d", preq.vlr_tag); fprintf(output, "\n"); } } conf_intrtlabel(output, ifs, ifnp->if_name); conf_intgroup(output, ifs, ifnp->if_name); snprintf(leasefile, sizeof(leasefile), "%s.%s", LEASEPREFIX, ifnp->if_name); if ((dhcpif = fopen(leasefile, "r"))) { fprintf(output, " ip dhcp\n"); fclose(dhcpif); ippntd = 1; } else { ippntd = conf_ifaddrs(output, ifnp->if_name, flags); } if (br) { conf_brcfg(output, ifs, ifn_list, ifnp->if_name); } else { char tmp[24]; conf_media_status(output, ifs, ifnp->if_name); conf_ifmetrics(output, ifs, if_data, ifnp->if_name); conf_pfsync(output, ifs, ifnp->if_name); conf_carp(output, ifs, ifnp->if_name); conf_trunk(output, ifs, ifnp->if_name); if (timeslot_status(ifs, ifnp->if_name, tmp, sizeof(tmp)) == 1) fprintf(output, " timeslots %s\n", tmp); if (conf_dhcrelay(ifnp->if_name, tmp, sizeof(tmp)) != NULL) fprintf(output, " dhcrelay %s\n", tmp); } /* * print various flags */ if (flags & IFF_DEBUG) fprintf(output, " debug\n"); if (flags & (IFF_LINK0|IFF_LINK1|IFF_LINK2)) { fprintf(output, " link "); if(flags & IFF_LINK0) fprintf(output, "0 "); if(flags & IFF_LINK1) fprintf(output, "1 "); if(flags & IFF_LINK2) fprintf(output, "2"); fprintf(output, "\n"); } if (flags & IFF_NOARP) fprintf(output, " no arp\n"); /* * ip X/Y turns the interface up (just like 'no shutdown') * ...but if we never had an ip address set and the interface * is up, we need to save this state explicitly. */ if (!ippntd && (flags & IFF_UP)) fprintf(output, " no shutdown\n"); else if (!(flags & IFF_UP)) fprintf(output, " shutdown\n"); fprintf(output, "!\n"); } close(ifs); if_freenameindex(ifn_list); }
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 intlladdr(char *ifname, int ifs, int argc, char **argv) { char *lladdr, llorig[IFNAMSIZ+1]; struct ether_addr *addr; struct ifreq ifr; FILE *llfile; #define LLPREFIX "/var/run/lladdr" char llfn[sizeof(LLPREFIX)+IFNAMSIZ+1]; int set; if (NO_ARG(argv[0])) { argv++; argc--; set = 0; } else set = 1; if (set && argc < 2) { printf ("%% lladdr <link level address>\n"); printf ("%% no lladdr\n"); return(1); } if ((lladdr = get_hwdaddr(ifname)) == NULL) { printf("%% Failed to retrieve current link level address\n"); return(1); } /* * the expectation here is that, on first run of the lladdr command, * after system boot, /var/run/lladdr.%s will not exist and so we * will ALWAYS create it with the interface's current lladdr. * this file is used if 'no lladdr' is ever specified, that way * we know exactly what address to revert back to. also, conf_lladdr * always knows about the default address this way. finally, because * the output to /var/run/lladdr.%s is generated from get_hwdaddr, * and the comparisons will be with new data generated from get_hwdaddr * it will always have the same case and format for easy comparison. */ snprintf(llfn, sizeof(llfn), "%s.%s", LLPREFIX, ifname); if ((llfile = fopen(llfn, "r")) == NULL) { /* llfn not around? create it */ if (set && ((llfile = fopen(llfn, "w")) != NULL)) { fprintf(llfile, "%s", lladdr); fclose(llfile); } else if (set) { printf("%% Failed to open %s for writing: %s\n", llfn, strerror(errno)); return(1); } else { switch(errno) { case ENOENT: printf("%% No saved lladdr to revert back\n"); break; default: printf("%% Failed to read %s: %s\n", llfn, strerror(errno)); } return(1); } } else { fgets(llorig, sizeof(llorig), llfile); fclose(llfile); if (!set && unlink(llfn) != 0) printf("%% Failed to remove %s: %s\n", llfn, strerror(errno)); } /* At this point, llorig will always represent the booted lladdr */ addr = ether_aton(set ? argv[1] : llorig); /* XXX Non-ethernet type ? */ if(addr == NULL) { /* XXX Non-ethernet... */ if (set) { printf("%% MAC addresses must be six hexadecimal " "fields, up to two digits each,\n"); printf("%% separated with colons (1:23:45:ab:cd:ef)\n"); return(1); } else { printf("%% %s corrupted, unable to retrieve original " "lladdr\n", llfn); return(1); } } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; /* XXX */ ifr.ifr_addr.sa_family = AF_LINK; bcopy(addr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); if(ioctl(ifs, SIOCSIFLLADDR, (caddr_t)&ifr) < 0) { switch(errno) { case EINVAL: printf("%% Requested link level address denied\n"); break; default: printf("%% intlladdr: SIOCSIFLLADDR: %s\n", strerror(errno)); } return(1); } return(0); }
void conf_interfaces(FILE *output, char *only) { int ifs, flags, ippntd, br; char *lladdr; char ifdescr[IFDESCRSIZE]; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; if ((ifn_list = if_nameindex()) == NULL) { printf("%% conf_interfaces: if_nameindex failed\n"); return; } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% conf_interfaces socket: %s\n", strerror(errno)); if_freenameindex(ifn_list); return; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { if (only && !isprefix(only, ifnp->if_name)) /* only display interfaces which start with ... */ continue; if (!only && islateif(ifnp->if_name)) /* interface prefixes to exclude on generic run */ continue; strlcpy(ifr.ifr_name, ifnp->if_name, sizeof(ifr.ifr_name)); if (ioctl(ifs, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { printf("%% conf: SIOCGIFFLAGS: %s\n", strerror(errno)); continue; } flags = ifr.ifr_flags; ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% conf: SIOCGIFDATA: %s\n", strerror(errno)); continue; } /* The output order is important! */ /* set interface/bridge mode */ if (!(br = is_bridge(ifs, ifnp->if_name))) br = 0; fprintf(output, "%s %s\n", br ? "bridge" : "interface", ifnp->if_name); /* * description, if available * copied straight from ifconfig.c */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifnp->if_name, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) fprintf(output, " description %s\n", ifrdesc.ifr_data); if ((lladdr = get_hwdaddr(ifnp->if_name)) != NULL) conf_db_single(output, "lladdr", lladdr, ifnp->if_name); conf_db_single(output, "rtadvd", NULL, ifnp->if_name); conf_vnetid(output, ifs, ifnp->if_name); conf_parent(output, ifs, ifnp->if_name); conf_rdomain(output, ifs, ifnp->if_name); conf_intrtlabel(output, ifs, ifnp->if_name); conf_intgroup(output, ifs, ifnp->if_name); conf_carp(output, ifs, ifnp->if_name); ippntd = conf_ifaddr_dhcp(output, ifnp->if_name, flags); if (br) { conf_brcfg(output, ifs, ifn_list, ifnp->if_name); } else { char tmp[24]; conf_media_status(output, ifs, ifnp->if_name); conf_ifmetrics(output, ifs, if_data, ifnp->if_name); conf_keepalive(output, ifs, ifnp->if_name); conf_pfsync(output, ifs, ifnp->if_name); conf_trunk(output, ifs, ifnp->if_name); conf_pflow(output, ifs, ifnp->if_name); conf_ifxflags(output, ifs, ifnp->if_name); if (timeslot_status(ifs, ifnp->if_name, tmp, sizeof(tmp)) == 1) fprintf(output, " timeslots %s\n", tmp); if (conf_dhcrelay(ifnp->if_name, tmp, sizeof(tmp)) > 0) fprintf(output, " dhcrelay %s\n", tmp); conf_sppp(output, ifs, ifnp->if_name); conf_pppoe(output, ifs, ifnp->if_name); } conf_ifflags(output, flags, ifnp->if_name, ippntd); } close(ifs); if_freenameindex(ifn_list); }
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 intlladdr(char *ifname, int ifs, int argc, char **argv) { StringList *hwdaddr; char *lladdr, llorig[sizeof("00:00:00:00:00:00") + 1]; struct ether_addr *addr; struct ifreq ifr; int set; if (NO_ARG(argv[0])) { argv++; argc--; set = 0; } else set = 1; if (set && argc < 2) { printf ("%% lladdr <link level address|random>\n"); printf ("%% no lladdr\n"); return(0); } if ((lladdr = get_hwdaddr(ifname)) == NULL) { printf("%% Failed to retrieve current link level address\n"); return(1); } hwdaddr = sl_init(); if (db_select_flag_x_ctl(hwdaddr, "lladdr", ifname) < 0) { printf("%% database failure select flag x ctl\n"); sl_free(hwdaddr, 1); return(1); } if (hwdaddr->sl_cur > 0) { strlcpy(llorig, hwdaddr->sl_str[0], sizeof(llorig)); if (!set && db_delete_flag_x_ctl("lladdr", ifname) < 0) { printf("%% database delete failure\n"); sl_free(hwdaddr, 1); return(1); } } else { strlcpy(llorig, lladdr, sizeof(llorig)); if (set && db_insert_flag_x("lladdr", ifname, 0, DB_X_ENABLE, llorig) < 0) { printf("%% database delete failure\n"); sl_free(hwdaddr, 1); return(1); } if (!set) { printf("%% No stored lladdr to reinstate\n"); sl_free(hwdaddr, 1); return(1); } } sl_free(hwdaddr, 1); /* At this point, llorig will always represent the booted lladdr */ if (set && isprefix(argv[1], "random")) { struct ether_addr eabuf; arc4random_buf(&eabuf, sizeof eabuf); eabuf.ether_addr_octet[0] &= 0xfc; addr = &eabuf; } else { addr = ether_aton(set ? argv[1] : llorig); if (addr == NULL) { if (set) { printf("%% MAC addresses are six hexadecimal " "fields, up to two digits each,\n" " %% separated with colons" " (1:23:45:ab:cd:ef)\n"); return(1); } else { printf("%% database corrupted, unable to " " retrieve original lladdr\n"); return(1); } } } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; ifr.ifr_addr.sa_family = AF_LINK; bcopy(addr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); if(ioctl(ifs, SIOCSIFLLADDR, (caddr_t)&ifr) < 0) { switch(errno) { case EINVAL: printf("%% Requested link level address denied\n"); break; default: printf("%% intlladdr: SIOCSIFLLADDR: %s\n", strerror(errno)); } return(1); } return(0); }