Date: Mon, 18 Jul 2005 22:46:00 GMT From: soc-anders <soc-anders@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 80485 for review Message-ID: <200507182246.j6IMk0d1092404@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80485 Change 80485 by soc-anders@soc-anders_gimli on 2005/07/18 22:45:43 When listing interfaces, the '-I' flag did not work correctly, now it should :) Parsing of messages is done in a safer manner. Affected files ... .. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#5 edit Differences ... ==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#5 (text+ko) ==== @@ -60,6 +60,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <err.h> #define IFCLEANUP @@ -174,7 +175,7 @@ struct ifa_msghdr *ifam; struct sockaddr *addr, *mask, *brd; u_long if_mtu; - int if_index; + int if_index = -1; if (_interval) { sidewaysintpr((unsigned)_interval, ifnetaddr); @@ -232,48 +233,69 @@ if (ifm->ifm_type == RTM_IFINFO) { struct sockaddr_dl *sdl; if (!(ifm->ifm_addrs & RTA_IFP)) { - printf("Missing IFP\n"); - exit(1); + errx(1, "Interface information missing"); } sa = (struct sockaddr *)(cur + sizeof(*ifm)); addr = sa; sdl = (struct sockaddr_dl *)sa; strlcpy(name, sdl->sdl_data, sdl->sdl_nlen+1); cur += ifm->ifm_msglen; - if (interface != 0 && (strcmp(name, interface) != 0)) - continue; + if (interface != 0 && (strcmp(name, interface) != 0)) { + if_index = -1; + continue; + } + + if (pfunc) { + (*pfunc)(name); + continue; + } + if ((ifm->ifm_flags & IFF_UP) == 0) { cp = index(name, '\0'); *cp++ = '*'; *cp = '\0'; - } + } if_mtu = ifm->ifm_data.ifi_mtu; if_index = ifm->ifm_index; } else if (ifm->ifm_type == RTM_NEWADDR) { int addrs = ifm->ifm_addrs; + char *msgend; + int i; + + if (if_index < 0) { + cur += ifm->ifm_msglen; + continue; + } ifam = (struct ifa_msghdr *)cur; + msgend = cur + ifm->ifm_msglen; cur += sizeof(*ifam); - - while (addrs != 0) { + for (i = 0; addrs != 0 && i < RTAX_MAX && cur < msgend; + addrs &= ~(1<<i), i++) { + if (!(addrs & 1<<i)) + continue; sa = (struct sockaddr *)cur; cur += SA_SIZE(sa); if (sa->sa_len == 0) continue; - if (addrs & RTA_NETMASK) { + switch (1<<i) { + case RTA_NETMASK: mask = sa; - addrs &= ~RTA_NETMASK; - } else if (addrs & RTA_IFA) { + break; + case RTA_IFA: addr = sa; - addrs &= ~RTA_IFA; - } else if (addrs & RTA_BRD) { + break; + case RTA_BRD: brd = sa; - addrs &= ~RTA_BRD; + break; + default: + break; } } + cur = msgend; } else { - printf("Unknown message type: %d\n", ifm->ifm_type); + warnx("Unexpected message type: %d\n", ifm->ifm_type); cur += ifm->ifm_msglen; continue; } @@ -299,7 +321,7 @@ drops = ifm->ifm_data.ifi_iqdrops; } - if (af != AF_UNSPEC && sa->sa_family != af) + if (af != AF_UNSPEC && addr->sa_family != af) continue; if (Wflag) @@ -362,8 +384,8 @@ break; case AF_APPLETALK: - printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); - printf("%-11.11s ",atalk_print(sa,0x0b) ); + printf("atalk:%-12.12s ",atalk_print(addr,0x10) ); + printf("%-11.11s ",atalk_print(addr,0x0b) ); break; case AF_LINK: { @@ -377,11 +399,11 @@ } goto hexprint; default: - m = printf("(%d)", sa->sa_family); - for (cp = sa->sa_len + (char *)sa; - --cp > sa->sa_data && (*cp == 0);) {} - n = cp - sa->sa_data + 1; - cp = sa->sa_data; + m = printf("(%d)", addr->sa_family); + for (cp = addr->sa_len + (char *)addr; + --cp > addr->sa_data && (*cp == 0);) {} + n = cp - addr->sa_data + 1; + cp = addr->sa_data; hexprint: while (--n >= 0) m += printf("%02x%c", *cp++ & 0xff, @@ -469,10 +491,9 @@ mib[5] = if_index; if (sysctl(mib, 6, NULL, &mlen, NULL, 0) < 0) continue; - if ((mbuf = malloc(mlen)) == NULL) { - printf("malloc\n"); - exit(1); - } + if ((mbuf = malloc(mlen)) == NULL) + err(1, NULL); + if (sysctl(mib, 6, mbuf, &mlen, NULL, 0) < 0) { free(mbuf); continue; @@ -482,24 +503,33 @@ mend = mcur + mlen; while (mcur < mend) { ifmam = (struct ifma_msghdr *)mcur; + if (ifmam->ifmam_type != RTM_NEWMADDR) { + warnx("Unexpected message type: %d", ifmam->ifmam_type); + mcur += ifmam->ifmam_msglen; + continue; + } + int addrs = ifmam->ifmam_addrs; + int i; + char *msgend = mcur + ifmam->ifmam_msglen; + mcur += sizeof(*ifmam); - while (addrs != 0) { - struct sockaddr *tmp = - (struct sockaddr *)mcur; - mcur += SA_SIZE(tmp); - if (addrs & RTA_GATEWAY) - addrs &= ~RTA_GATEWAY; - else if (addrs & RTA_IFP) - addrs &= ~RTA_IFP; - else if (addrs & RTA_IFA) { - bcopy(tmp, &msa, tmp->sa_len); - addrs &= ~RTA_IFA; - } else { - printf("UNEXPECTED: %x\n", addrs); + + for (i = 0; addrs != 0 && i < RTAX_MAX && mcur < msgend; + addrs &= ~(1<<i), i++) { + if (!(addrs & 1<<i)) + continue; + sa = (struct sockaddr *)mcur; + mcur += SA_SIZE(sa); + + if (sa->sa_len == 0) continue; - } + + if (1<<i == RTA_IFA) + bcopy(sa, &msa, sa->sa_len); } + mcur = msgend; + fmt = 0; switch (msa.sa.sa_family) { case AF_INET:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507182246.j6IMk0d1092404>