diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-06 16:20:21 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-11 10:08:08 +0100 |
commit | 66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch) | |
tree | 48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sbin | |
parent | Define __GLOBL1() and __GLOBL() (diff) | |
download | rtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2 |
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sbin')
-rw-r--r-- | freebsd/sbin/dhclient/clparse.c | 6 | ||||
-rw-r--r-- | freebsd/sbin/dhclient/packet.c | 2 | ||||
-rw-r--r-- | freebsd/sbin/dhclient/parse.c | 12 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/af_inet.c | 7 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/af_inet6.c | 13 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/af_nd6.c | 80 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/ifconfig.c | 67 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/ifconfig.h | 1 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/ifgif.c | 24 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/iflagg.c | 7 | ||||
-rw-r--r-- | freebsd/sbin/ifconfig/ifmedia.c | 4 | ||||
-rw-r--r-- | freebsd/sbin/ping/ping.c | 50 | ||||
-rw-r--r-- | freebsd/sbin/ping6/ping6.c | 184 | ||||
-rw-r--r-- | freebsd/sbin/route/keywords | 1 | ||||
-rw-r--r-- | freebsd/sbin/route/route.c | 557 |
15 files changed, 655 insertions, 360 deletions
diff --git a/freebsd/sbin/dhclient/clparse.c b/freebsd/sbin/dhclient/clparse.c index 7fb278dd..b52bc473 100644 --- a/freebsd/sbin/dhclient/clparse.c +++ b/freebsd/sbin/dhclient/clparse.c @@ -875,6 +875,7 @@ parse_string_list(FILE *cfile, struct string_list **lp, int multiple) { int token; char *val; + size_t valsize; struct string_list *cur, *tmp; /* Find the last medium in the media list. */ @@ -892,10 +893,11 @@ parse_string_list(FILE *cfile, struct string_list **lp, int multiple) return; } - tmp = new_string_list(strlen(val) + 1); + valsize = strlen(val) + 1; + tmp = new_string_list(valsize); if (tmp == NULL) error("no memory for string list entry."); - strlcpy(tmp->string, val, strlen(val) + 1); + memcpy(tmp->string, val, valsize); tmp->next = NULL; /* Store this medium at the end of the media list. */ diff --git a/freebsd/sbin/dhclient/packet.c b/freebsd/sbin/dhclient/packet.c index f5366d3c..e4fa0e86 100644 --- a/freebsd/sbin/dhclient/packet.c +++ b/freebsd/sbin/dhclient/packet.c @@ -130,7 +130,7 @@ assemble_udp_ip_header(unsigned char *buf, int *bufix, u_int32_t from, ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len); ip.ip_id = 0; ip.ip_off = 0; - ip.ip_ttl = 16; + ip.ip_ttl = 128; ip.ip_p = IPPROTO_UDP; ip.ip_sum = 0; ip.ip_src.s_addr = from; diff --git a/freebsd/sbin/dhclient/parse.c b/freebsd/sbin/dhclient/parse.c index 5996ca36..19d407ea 100644 --- a/freebsd/sbin/dhclient/parse.c +++ b/freebsd/sbin/dhclient/parse.c @@ -118,6 +118,7 @@ char * parse_string(FILE *cfile) { char *val, *s; + size_t valsize; int token; token = next_token(&val, cfile); @@ -126,10 +127,11 @@ parse_string(FILE *cfile) skip_to_semi(cfile); return (NULL); } - s = malloc(strlen(val) + 1); + valsize = strlen(val) + 1; + s = malloc(valsize); if (!s) error("no memory for string %s.", val); - strlcpy(s, val, strlen(val) + 1); + memcpy(s, val, valsize); if (!parse_semi(cfile)) return (NULL); @@ -244,6 +246,7 @@ parse_numeric_aggregate(FILE *cfile, unsigned char *buf, int *max, unsigned char *bufp = buf, *s = NULL; int token, count = 0; char *val, *t; + size_t valsize; pair c = NULL; if (!bufp && *max) { @@ -290,10 +293,11 @@ parse_numeric_aggregate(FILE *cfile, unsigned char *buf, int *max, convert_num(s, val, base, size); s += size / 8; } else { - t = malloc(strlen(val) + 1); + valsize = strlen(val) + 1; + t = malloc(valsize); if (!t) error("no temp space for number."); - strlcpy(t, val, strlen(val) + 1); + memcpy(t, val, valsize); c = cons(t, c); } } while (++count != *max); diff --git a/freebsd/sbin/ifconfig/af_inet.c b/freebsd/sbin/ifconfig/af_inet.c index 5d0a3d27..0e6ace11 100644 --- a/freebsd/sbin/ifconfig/af_inet.c +++ b/freebsd/sbin/ifconfig/af_inet.c @@ -206,9 +206,16 @@ void #endif /* __rtems__ */ inet_ctor(void) { + +#ifndef RESCUE + if (!feature_present("inet")) + return; +#endif + #ifdef __rtems__ memset(&in_addreq, 0, sizeof(in_addreq)); memset(&in_ridreq, 0, sizeof(in_ridreq)); #endif /* __rtems__ */ + af_register(&af_inet); } diff --git a/freebsd/sbin/ifconfig/af_inet6.c b/freebsd/sbin/ifconfig/af_inet6.c index 894c0493..f74d3e8b 100644 --- a/freebsd/sbin/ifconfig/af_inet6.c +++ b/freebsd/sbin/ifconfig/af_inet6.c @@ -72,6 +72,7 @@ static int explicit_prefix = 0; extern void setnd6flags(const char *, int, int, const struct afswtch *); extern void setnd6defif(const char *, int, int, const struct afswtch *); +extern void nd6_status(int); static char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/ @@ -510,6 +511,8 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags), DEF_CMD("accept_rtadv", ND6_IFF_ACCEPT_RTADV, setnd6flags), DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV, setnd6flags), + DEF_CMD("no_radr", ND6_IFF_NO_RADR, setnd6flags), + DEF_CMD("-no_radr", -ND6_IFF_NO_RADR, setnd6flags), DEF_CMD("defaultif", 1, setnd6defif), DEF_CMD("-defaultif", -1, setnd6defif), DEF_CMD("ifdisabled", ND6_IFF_IFDISABLED, setnd6flags), @@ -518,6 +521,10 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags), DEF_CMD("prefer_source",ND6_IFF_PREFER_SOURCE, setnd6flags), DEF_CMD("-prefer_source",-ND6_IFF_PREFER_SOURCE,setnd6flags), + DEF_CMD("auto_linklocal",ND6_IFF_AUTO_LINKLOCAL,setnd6flags), + DEF_CMD("-auto_linklocal",-ND6_IFF_AUTO_LINKLOCAL,setnd6flags), + DEF_CMD("no_prefer_iface",ND6_IFF_NO_PREFER_IFACE,setnd6flags), + DEF_CMD("-no_prefer_iface",-ND6_IFF_NO_PREFER_IFACE,setnd6flags), DEF_CMD_ARG("pltime", setip6pltime), DEF_CMD_ARG("vltime", setip6vltime), DEF_CMD("eui64", 0, setip6eui64), @@ -529,6 +536,7 @@ static struct afswtch af_inet6 = { .af_status = in6_status, .af_getaddr = in6_getaddr, .af_getprefix = in6_getprefix, + .af_other_status = nd6_status, .af_postproc = in6_postproc, .af_status_tunnel = in6_status_tunnel, .af_settunnel = in6_set_tunnel, @@ -564,6 +572,11 @@ inet6_ctor(void) #define N(a) (sizeof(a) / sizeof(a[0])) size_t i; +#ifndef RESCUE + if (!feature_present("inet6")) + return; +#endif + for (i = 0; i < N(inet6_cmds); i++) cmd_register(&inet6_cmds[i]); af_register(&af_inet6); diff --git a/freebsd/sbin/ifconfig/af_nd6.c b/freebsd/sbin/ifconfig/af_nd6.c index 2fc62941..a1e930b0 100644 --- a/freebsd/sbin/ifconfig/af_nd6.c +++ b/freebsd/sbin/ifconfig/af_nd6.c @@ -60,11 +60,12 @@ static const char rcsid[] = #define MAX_SYSCTL_TRY 5 #define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ "\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \ - "\020DEFAULTIF" + "\007NO_RADR\010NO_PREFER_IFACE\020DEFAULTIF" static int isnd6defif(int); void setnd6flags(const char *, int, int, const struct afswtch *); void setnd6defif(const char *, int, int, const struct afswtch *); +void nd6_status(int); void setnd6flags(const char *dummyaddr __unused, @@ -138,74 +139,25 @@ isnd6defif(int s) return (ndifreq.ifindex == ifindex); } -static void +void nd6_status(int s) { struct in6_ndireq nd; - struct rt_msghdr *rtm; - size_t needed; - char *buf, *next; - int mib[6], ntry; int s6; int error; - int isinet6, isdefif; - - /* Check if the interface has at least one IPv6 address. */ - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = AF_INET6; - mib[4] = NET_RT_IFLIST; - mib[5] = if_nametoindex(ifr.ifr_name); - - /* Try to prevent a race between two sysctls. */ - ntry = 0; - do { - error = sysctl(mib, 6, NULL, &needed, NULL, 0); - if (error) { - warn("sysctl(NET_RT_IFLIST)/estimate"); - return; - } - buf = malloc(needed); - if (buf == NULL) { - warn("malloc for sysctl(NET_RT_IFLIST) failed"); - return; - } - if ((error = sysctl(mib, 6, buf, &needed, NULL, 0)) < 0) { - if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { - warn("sysctl(NET_RT_IFLIST)/get"); - free(buf); - return; - } - free(buf); - buf = NULL; - } - } while (buf == NULL); - - isinet6 = 0; - for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - - if (rtm->rtm_version != RTM_VERSION) - continue; - if (rtm->rtm_type == RTM_NEWADDR) { - isinet6 = 1; - break; - } - } - free(buf); - if (!isinet6) - return; + int isdefif; memset(&nd, 0, sizeof(nd)); strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - warn("socket(AF_INET6, SOCK_DGRAM)"); + if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) + warn("socket(AF_INET6, SOCK_DGRAM)"); return; } error = ioctl(s6, SIOCGIFINFO_IN6, &nd); if (error) { - warn("ioctl(SIOCGIFINFO_IN6)"); + if (errno != EPFNOSUPPORT) + warn("ioctl(SIOCGIFINFO_IN6)"); close(s6); return; } @@ -217,19 +169,3 @@ nd6_status(int s) (unsigned int)(nd.ndi.flags | (isdefif << 15)), ND6BITS); putchar('\n'); } - -static struct afswtch af_nd6 = { - .af_name = "nd6", - .af_af = AF_LOCAL, - .af_other_status= nd6_status, -}; - -#ifndef __rtems__ -static __constructor void -#else /* __rtems__ */ -void -#endif /* __rtems__ */ -nd6_ctor(void) -{ - af_register(&af_nd6); -} diff --git a/freebsd/sbin/ifconfig/ifconfig.c b/freebsd/sbin/ifconfig/ifconfig.c index 0772b647..6c7b8a36 100644 --- a/freebsd/sbin/ifconfig/ifconfig.c +++ b/freebsd/sbin/ifconfig/ifconfig.c @@ -175,7 +175,6 @@ int rtems_bsd_command_ifconfig(int argc, char *argv[]) lagg_ctor(); link_ctor(); mac_ctor(); - nd6_ctor(); pfsync_ctor(); vlan_ctor(); @@ -198,7 +197,7 @@ main(int argc, char *argv[]) struct ifaddrs *ifap, *ifa; struct ifreq paifr; const struct sockaddr_dl *sdl; - char options[1024], *cp; + char options[1024], *cp, *namecp = NULL; const char *ifname; struct option *p; size_t iflen; @@ -279,8 +278,10 @@ main(int argc, char *argv[]) ifindex = 0; if (argc == 1) { afp = af_getbyname(*argv); - if (afp == NULL) + if (afp == NULL) { + warnx("Address family '%s' unknown.", *argv); usage(); + } if (afp->af_name != NULL) argc--, argv++; /* leave with afp non-zero */ @@ -354,7 +355,7 @@ main(int argc, char *argv[]) sdl = (const struct sockaddr_dl *) ifa->ifa_addr; else sdl = NULL; - if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0) + if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !namesonly) continue; iflen = strlcpy(name, ifa->ifa_name, sizeof(name)); if (iflen >= sizeof(name)) { @@ -370,16 +371,34 @@ main(int argc, char *argv[]) continue; if (uponly && (ifa->ifa_flags & IFF_UP) == 0) continue; - ifindex++; /* * Are we just listing the interfaces? */ if (namesonly) { + if (namecp == cp) + continue; + if (afp != NULL) { + /* special case for "ether" address family */ + if (!strcmp(afp->af_name, "ether")) { + if (sdl == NULL || + (sdl->sdl_type != IFT_ETHER && + sdl->sdl_type != IFT_L2VLAN && + sdl->sdl_type != IFT_BRIDGE) || + sdl->sdl_alen != ETHER_ADDR_LEN) + continue; + } else { + if (ifa->ifa_addr->sa_family != afp->af_af) + continue; + } + } + namecp = cp; + ifindex++; if (ifindex > 1) printf(" "); fputs(name, stdout); continue; } + ifindex++; if (argc > 0) ifconfig(argc, argv, 0, afp); @@ -525,7 +544,30 @@ ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp) int s; strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); - afp = uafp != NULL ? uafp : af_getbyname("inet"); + afp = NULL; + if (uafp != NULL) + afp = uafp; + /* + * This is the historical "accident" allowing users to configure IPv4 + * addresses without the "inet" keyword which while a nice feature has + * proven to complicate other things. We cannot remove this but only + * make sure we will never have a similar implicit default for IPv6 or + * any other address familiy. We need a fallback though for + * ifconfig IF up/down etc. to work without INET support as people + * never used ifconfig IF link up/down, etc. either. + */ +#ifndef RESCUE +#ifdef INET + if (afp == NULL && feature_present("inet")) + afp = af_getbyname("inet"); +#endif +#endif + if (afp == NULL) + afp = af_getbyname("link"); + if (afp == NULL) { + warnx("Please specify an address_family."); + usage(); + } top: ifr.ifr_addr.sa_family = afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? @@ -928,7 +970,8 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp) #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ -"\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" +"\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \ +"\26RXCSUM_IPV6\27TXCSUM_IPV6" /* * Print the status of the interface. If an address family was @@ -1192,6 +1235,10 @@ static struct cmd basic_cmds[] = { DEF_CMD("-monitor", -IFF_MONITOR, setifflags), DEF_CMD("staticarp", IFF_STATICARP, setifflags), DEF_CMD("-staticarp", -IFF_STATICARP, setifflags), + DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap), + DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap), + DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap), + DEF_CMD("-txcsum6", -IFCAP_TXCSUM_IPV6, setifcap), DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), DEF_CMD("-rxcsum", -IFCAP_RXCSUM, setifcap), DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), @@ -1200,8 +1247,14 @@ static struct cmd basic_cmds[] = { DEF_CMD("-netcons", -IFCAP_NETCONS, setifcap), DEF_CMD("polling", IFCAP_POLLING, setifcap), DEF_CMD("-polling", -IFCAP_POLLING, setifcap), + DEF_CMD("tso6", IFCAP_TSO6, setifcap), + DEF_CMD("-tso6", -IFCAP_TSO6, setifcap), + DEF_CMD("tso4", IFCAP_TSO4, setifcap), + DEF_CMD("-tso4", -IFCAP_TSO4, setifcap), DEF_CMD("tso", IFCAP_TSO, setifcap), DEF_CMD("-tso", -IFCAP_TSO, setifcap), + DEF_CMD("toe", IFCAP_TOE, setifcap), + DEF_CMD("-toe", -IFCAP_TOE, setifcap), DEF_CMD("lro", IFCAP_LRO, setifcap), DEF_CMD("-lro", -IFCAP_LRO, setifcap), DEF_CMD("wol", IFCAP_WOL, setifcap), diff --git a/freebsd/sbin/ifconfig/ifconfig.h b/freebsd/sbin/ifconfig/ifconfig.h index 46d8382e..074e810e 100644 --- a/freebsd/sbin/ifconfig/ifconfig.h +++ b/freebsd/sbin/ifconfig/ifconfig.h @@ -166,7 +166,6 @@ void inet_ctor(void); void lagg_ctor(void); void link_ctor(void); void mac_ctor(void); -void nd6_ctor(void); void pfsync_ctor(void); void vlan_ctor(void); diff --git a/freebsd/sbin/ifconfig/ifgif.c b/freebsd/sbin/ifconfig/ifgif.c index 6386751e..e55933a5 100644 --- a/freebsd/sbin/ifconfig/ifgif.c +++ b/freebsd/sbin/ifconfig/ifgif.c @@ -53,38 +53,22 @@ static const char rcsid[] = #include "ifconfig.h" -static void gif_status(int); +#define GIFBITS "\020\1ACCEPT_REV_ETHIP_VER\5SEND_REV_ETHIP_VER" -static const struct { - const char *label; - u_int mask; -} gif_opts[] = { - { "ACCEPT_REV_ETHIP_VER", GIF_ACCEPT_REVETHIP }, - { "SEND_REV_ETHIP_VER", GIF_SEND_REVETHIP }, -}; +static void gif_status(int); static void gif_status(int s) { int opts; - int nopts = 0; - size_t i; ifr.ifr_data = (caddr_t)&opts; if (ioctl(s, GIFGOPTS, &ifr) == -1) return; if (opts == 0) return; - - printf("\toptions=%d<", opts); - for (i=0; i < sizeof(gif_opts)/sizeof(gif_opts[0]); i++) { - if (opts & gif_opts[i].mask) { - if (nopts++) - printf(","); - printf("%s", gif_opts[i].label); - } - } - printf(">\n"); + printb("\toptions", opts, GIFBITS); + putchar('\n'); } static void diff --git a/freebsd/sbin/ifconfig/iflagg.c b/freebsd/sbin/ifconfig/iflagg.c index 6e2a726e..56970e57 100644 --- a/freebsd/sbin/ifconfig/iflagg.c +++ b/freebsd/sbin/ifconfig/iflagg.c @@ -42,7 +42,8 @@ setlaggport(const char *val, int d, int s, const struct afswtch *afp) strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname)); strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname)); - if (ioctl(s, SIOCSLAGGPORT, &rp)) + /* Don't choke if the port is already in this lagg. */ + if (ioctl(s, SIOCSLAGGPORT, &rp) && errno != EEXIST) err(1, "SIOCSLAGGPORT"); } @@ -99,10 +100,8 @@ setlagghash(const char *val, int d, int s, const struct afswtch *afp) rf.rf_flags |= LAGG_F_HASHL3; else if (strcmp(tok, "l4") == 0) rf.rf_flags |= LAGG_F_HASHL4; - else { - free(str); + else errx(1, "Invalid lagghash option: %s", tok); - } } free(str); if (rf.rf_flags == 0) diff --git a/freebsd/sbin/ifconfig/ifmedia.c b/freebsd/sbin/ifconfig/ifmedia.c index b7296131..0ad008ee 100644 --- a/freebsd/sbin/ifconfig/ifmedia.c +++ b/freebsd/sbin/ifconfig/ifmedia.c @@ -47,10 +47,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. diff --git a/freebsd/sbin/ping/ping.c b/freebsd/sbin/ping/ping.c index 6adc03aa..b45efa6b 100644 --- a/freebsd/sbin/ping/ping.c +++ b/freebsd/sbin/ping/ping.c @@ -219,7 +219,7 @@ static void pr_retip(struct ip *); static void status(int); static void stopit(int); #endif /* __rtems__ */ -static void tvsub(struct timeval *, struct timeval *); +static void tvsub(struct timeval *, const struct timeval *); static void usage(void) __dead2; #ifdef __rtems__ @@ -268,12 +268,10 @@ int rtems_bsd_command_ping(int argc, char *argv[]) } #endif /* __rtems__ */ int -main(argc, argv) - int argc; #ifndef __rtems__ - char *const *argv; +main(int argc, char *const *argv) #else /* __rtems__ */ - char **argv; +main(int argc, char **argv) #endif /* __rtems__ */ { struct sockaddr_in from, sock_in; @@ -998,8 +996,7 @@ main(argc, argv) * to be called from a signal handler. */ void -stopit(sig) - int sig __unused; +stopit(int sig __unused) { /* @@ -1095,11 +1092,7 @@ pinger(void) * program to be run without having intermingled output (or statistics!). */ static void -pr_pack(buf, cc, from, tv) - char *buf; - int cc; - struct sockaddr_in *from; - struct timeval *tv; +pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) { struct in_addr ina; u_char *cp, *dp; @@ -1363,9 +1356,7 @@ pr_pack(buf, cc, from, tv) * Checksum routine for Internet Protocol family headers (C Version) */ u_short -in_cksum(addr, len) - u_short *addr; - int len; +in_cksum(u_short *addr, int len) { int nleft, sum; u_short *w; @@ -1409,8 +1400,7 @@ in_cksum(addr, len) * be >= in. */ static void -tvsub(out, in) - struct timeval *out, *in; +tvsub(struct timeval *out, const struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { @@ -1427,8 +1417,7 @@ tvsub(out, in) */ static void -status(sig) - int sig __unused; +status(int sig __unused) { siginfo_p = 1; @@ -1436,7 +1425,7 @@ status(sig) #endif /* __rtems__ */ static void -check_status() +check_status(void) { if (siginfo_p) { @@ -1456,7 +1445,7 @@ check_status() * Print out statistics, and give up. */ static void -finish() +finish(void) { (void)signal(SIGINT, SIG_IGN); @@ -1515,8 +1504,7 @@ static char *ttab[] = { * Print a descriptive string about an ICMP header. */ static void -pr_icmph(icp) - struct icmp *icp; +pr_icmph(struct icmp *icp) { switch(icp->icmp_type) { @@ -1663,8 +1651,7 @@ pr_icmph(icp) * Print an IP header with options. */ static void -pr_iph(ip) - struct ip *ip; +pr_iph(struct ip *ip) { u_char *cp; int hlen; @@ -1696,8 +1683,7 @@ pr_iph(ip) * a hostname. */ static char * -pr_addr(ina) - struct in_addr ina; +pr_addr(struct in_addr ina) { struct hostent *hp; static char buf[16 + 3 + MAXHOSTNAMELEN]; @@ -1716,8 +1702,7 @@ pr_addr(ina) * Dump some info on a returned (via ICMP) IP packet. */ static void -pr_retip(ip) - struct ip *ip; +pr_retip(struct ip *ip) { u_char *cp; int hlen; @@ -1735,7 +1720,7 @@ pr_retip(ip) } static char * -pr_ntime (n_time timestamp) +pr_ntime(n_time timestamp) { static char buf[10]; int hour, min, sec; @@ -1751,8 +1736,7 @@ pr_ntime (n_time timestamp) } static void -fill(bp, patp) - char *bp, *patp; +fill(char *bp, char *patp) { char *cp; int pat[16]; @@ -1788,7 +1772,7 @@ fill(bp, patp) #define SECOPT "" #endif static void -usage() +usage(void) { (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", diff --git a/freebsd/sbin/ping6/ping6.c b/freebsd/sbin/ping6/ping6.c index b927f110..b2ad6336 100644 --- a/freebsd/sbin/ping6/ping6.c +++ b/freebsd/sbin/ping6/ping6.c @@ -48,10 +48,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -79,10 +75,11 @@ static const char copyright[] = #if 0 static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; #endif -static const char rcsid[] = - "$FreeBSD$"; #endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure round-trip-delays and packet loss across network paths. @@ -235,6 +232,13 @@ static char *hostname; static int ident; /* process id to identify our packets */ static u_int8_t nonce[8]; /* nonce field for node information */ static int hoplimit; /* hoplimit */ +static u_char *packet; +#ifdef HAVE_POLL_H +static struct pollfd fdmaskp[1]; +#else +static fd_set *fdmaskp = NULL; +static int fdmasks; +#endif /* counters */ static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ @@ -265,8 +269,8 @@ static volatile sig_atomic_t seenint; static volatile sig_atomic_t seeninfo; #endif -static u_char *packet; -static struct cmsghdr *cm; +/* For control (ancillary) data received from recvmsg() */ +static struct cmsghdr cm[CONTROLLEN]; static int main(int, char *[]); static void fill(char *, char *); @@ -300,7 +304,7 @@ static void tvsub(struct timeval *, struct timeval *); static int setpolicy(int, char *); #endif #endif -static char *nigroup(char *); +static char *nigroup(char *, int); static void usage(void); #ifdef __rtems__ @@ -336,9 +340,7 @@ int rtems_bsd_command_ping6(int argc, char **argv) #ifdef SIGINFO seeninfo = 0; #endif - packet = NULL; - cm = NULL; exit_code = rtems_bsd_program_call_main("ping6", main, argc, argv); @@ -352,15 +354,11 @@ int rtems_bsd_command_ping6(int argc, char **argv) freeaddrinfo(res); } - free(cm); - return exit_code; } #endif /* __rtems__ */ int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { struct itimerval itimer; struct sockaddr_in6 from; @@ -373,14 +371,9 @@ main(argc, argv) struct timeval timeout, *tv; #endif struct addrinfo hints; -#ifdef HAVE_POLL_H - struct pollfd fdmaskp[1]; -#else - fd_set *fdmaskp; - int fdmasks; -#endif int cc, i; int ch, hold, packlen, preload, optval, ret_ga; + int nig_oldmcprefix = -1; u_char *datap; char *e, *target, *ifname = NULL, *gateway = NULL; int ip6optlen = 0; @@ -572,6 +565,7 @@ main(argc, argv) break; case 'N': options |= F_NIGROUP; + nig_oldmcprefix++; break; case 'o': options |= F_ONCE; @@ -687,7 +681,7 @@ main(argc, argv) } if (options & F_NIGROUP) { - target = nigroup(argv[argc - 1]); + target = nigroup(argv[argc - 1], nig_oldmcprefix); if (target == NULL) { usage(); /*NOTREACHED*/ @@ -1164,11 +1158,6 @@ main(argc, argv) seeninfo = 0; #endif - /* For control (ancillary) data received from recvmsg() */ - cm = (struct cmsghdr *)malloc(CONTROLLEN); - if (cm == NULL) - err(1, "malloc"); - for (;;) { struct msghdr m; struct iovec iov[2]; @@ -1282,12 +1271,27 @@ main(argc, argv) } } summary(); + + if (res != NULL) { + freeaddrinfo(res); + res = NULL; + } + + if(packet != NULL) { + free(packet); + packet = NULL; + } + +#ifndef HAVE_POLL_H + if(fdmaskp != NULL) + free(fdmaskp); +#endif + exit(nreceived == 0 ? 2 : 0); } void -onsignal(sig) - int sig; +onsignal(int sig) { switch (sig) { @@ -1310,7 +1314,7 @@ onsignal(sig) * This routine transmits another ping6. */ void -retransmit() +retransmit(void) { struct itimerval itimer; @@ -1346,7 +1350,7 @@ retransmit() * byte-order, to compute the round-trip time. */ size_t -pingerlen() +pingerlen(void) { size_t l; @@ -1365,7 +1369,7 @@ pingerlen() } int -pinger() +pinger(void) { struct icmp6_hdr *icp; struct iovec iov[2]; @@ -1480,8 +1484,7 @@ pinger() } int -myechoreply(icp) - const struct icmp6_hdr *icp; +myechoreply(const struct icmp6_hdr *icp) { if (ntohs(icp->icmp6_id) == ident) return 1; @@ -1490,8 +1493,7 @@ myechoreply(icp) } int -mynireply(nip) - const struct icmp6_nodeinfo *nip; +mynireply(const struct icmp6_nodeinfo *nip) { if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), nonce + sizeof(u_int16_t), @@ -1502,12 +1504,9 @@ mynireply(nip) } char * -dnsdecode(sp, ep, base, buf, bufsiz) - const u_char **sp; - const u_char *ep; - const u_char *base; /*base for compressed name*/ - char *buf; - size_t bufsiz; +dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf, + size_t bufsiz) + /*base for compressed name*/ { int i; const u_char *cp; @@ -1572,10 +1571,7 @@ dnsdecode(sp, ep, base, buf, bufsiz) * program to be run without having intermingled output (or statistics!). */ void -pr_pack(buf, cc, mhdr) - u_char *buf; - int cc; - struct msghdr *mhdr; +pr_pack(u_char *buf, int cc, struct msghdr *mhdr) { #define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) struct icmp6_hdr *icp; @@ -1856,8 +1852,7 @@ pr_pack(buf, cc, mhdr) } void -pr_exthdrs(mhdr) - struct msghdr *mhdr; +pr_exthdrs(struct msghdr *mhdr) { ssize_t bufsize; void *bufp; @@ -2032,10 +2027,7 @@ pr_rthdr(void *extbuf, size_t bufsize __unused) #endif /* USE_RFC2292BIS */ int -pr_bitrange(v, soff, ii) - u_int32_t v; - int soff; - int ii; +pr_bitrange(u_int32_t v, int soff, int ii) { int off; int i; @@ -2081,9 +2073,8 @@ pr_bitrange(v, soff, ii) } void -pr_suptypes(ni, nilen) - struct icmp6_nodeinfo *ni; /* ni->qtype must be SUPTYPES */ - size_t nilen; +pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen) + /* ni->qtype must be SUPTYPES */ { size_t clen; u_int32_t v; @@ -2148,9 +2139,8 @@ pr_suptypes(ni, nilen) } void -pr_nodeaddr(ni, nilen) - struct icmp6_nodeinfo *ni; /* ni->qtype must be NODEADDR */ - int nilen; +pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen) + /* ni->qtype must be NODEADDR */ { u_char *cp = (u_char *)(ni + 1); char ntop_buf[INET6_ADDRSTRLEN]; @@ -2215,8 +2205,7 @@ pr_nodeaddr(ni, nilen) } int -get_hoplim(mhdr) - struct msghdr *mhdr; +get_hoplim(struct msghdr *mhdr) { struct cmsghdr *cm; @@ -2235,8 +2224,7 @@ get_hoplim(mhdr) } struct in6_pktinfo * -get_rcvpktinfo(mhdr) - struct msghdr *mhdr; +get_rcvpktinfo(struct msghdr *mhdr) { struct cmsghdr *cm; @@ -2255,8 +2243,7 @@ get_rcvpktinfo(mhdr) } int -get_pathmtu(mhdr) - struct msghdr *mhdr; +get_pathmtu(struct msghdr *mhdr) { #ifdef IPV6_RECVPATHMTU struct cmsghdr *cm; @@ -2316,8 +2303,7 @@ get_pathmtu(mhdr) * be >= in. */ void -tvsub(out, in) - struct timeval *out, *in; +tvsub(struct timeval *out, struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; @@ -2332,11 +2318,21 @@ tvsub(out, in) */ /* ARGSUSED */ void -onint(notused) - int notused; +onint(int notused __unused) { summary(); + if (res != NULL) + freeaddrinfo(res); + + if(packet != NULL) + free(packet); + +#ifndef HAVE_POLL_H + if(fdmaskp != NULL) + free(fdmaskp); +#endif + (void)signal(SIGINT, SIG_DFL); (void)kill(getpid(), SIGINT); @@ -2349,7 +2345,7 @@ onint(notused) * Print out statistics. */ void -summary() +summary(void) { (void)printf("\n--- %s ping6 statistics ---\n", hostname); @@ -2397,9 +2393,7 @@ static const char *nircode[] = { * Print a descriptive string about an ICMP header. */ void -pr_icmph(icp, end) - struct icmp6_hdr *icp; - u_char *end; +pr_icmph(struct icmp6_hdr *icp, u_char *end) { char ntop_buf[INET6_ADDRSTRLEN]; struct nd_redirect *red; @@ -2629,8 +2623,7 @@ pr_icmph(icp, end) * Print an IP6 header. */ void -pr_iph(ip6) - struct ip6_hdr *ip6; +pr_iph(struct ip6_hdr *ip6) { u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; u_int8_t tc; @@ -2658,9 +2651,7 @@ pr_iph(ip6) * a hostname. */ const char * -pr_addr(addr, addrlen) - struct sockaddr *addr; - int addrlen; +pr_addr(struct sockaddr *addr, int addrlen) { static char buf[NI_MAXHOST]; int flag = 0; @@ -2679,9 +2670,7 @@ pr_addr(addr, addrlen) * Dump some info on a returned (via ICMPv6) IPv6 packet. */ void -pr_retip(ip6, end) - struct ip6_hdr *ip6; - u_char *end; +pr_retip(struct ip6_hdr *ip6, u_char *end) { u_char *cp = (u_char *)ip6, nh; int hlen; @@ -2761,8 +2750,7 @@ pr_retip(ip6, end) } void -fill(bp, patp) - char *bp, *patp; +fill(char *bp, char *patp) { int ii, jj, kk; int pat[16]; @@ -2795,9 +2783,7 @@ fill(bp, patp) #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC int -setpolicy(so, policy) - int so; - char *policy; +setpolicy(int so __unused, char *policy) { char *buf; @@ -2818,8 +2804,7 @@ setpolicy(so, policy) #endif char * -nigroup(name) - char *name; +nigroup(char *name, int nig_oldmcprefix) { char *p; char *q; @@ -2829,6 +2814,7 @@ nigroup(name) size_t l; char hbuf[NI_MAXHOST]; struct in6_addr in6; + int valid; p = strchr(name, '.'); if (!p) @@ -2844,7 +2830,7 @@ nigroup(name) *q = tolower(*(unsigned char *)q); } - /* generate 8 bytes of pseudo-random value. */ + /* generate 16 bytes of pseudo-random value. */ memset(&ctxt, 0, sizeof(ctxt)); MD5Init(&ctxt); c = l & 0xff; @@ -2852,9 +2838,23 @@ nigroup(name) MD5Update(&ctxt, (unsigned char *)name, l); MD5Final(digest, &ctxt); - if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1) + if (nig_oldmcprefix) { + /* draft-ietf-ipngwg-icmp-name-lookup */ + valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6); + } else { + /* RFC 4620 */ + valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6); + } + if (valid != 1) return NULL; /*XXX*/ - bcopy(digest, &in6.s6_addr[12], 4); + + if (nig_oldmcprefix) { + /* draft-ietf-ipngwg-icmp-name-lookup */ + bcopy(digest, &in6.s6_addr[12], 4); + } else { + /* RFC 4620 */ + bcopy(digest, &in6.s6_addr[13], 3); + } if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) return NULL; @@ -2863,7 +2863,7 @@ nigroup(name) } void -usage() +usage(void) { (void)fprintf(stderr, #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC) diff --git a/freebsd/sbin/route/keywords b/freebsd/sbin/route/keywords index 8817f305..adfba7cf 100644 --- a/freebsd/sbin/route/keywords +++ b/freebsd/sbin/route/keywords @@ -10,6 +10,7 @@ del delete dst expire +fib flush gateway genmask diff --git a/freebsd/sbin/route/route.c b/freebsd/sbin/route/route.c index 8bf976f9..cc5c7d05 100644 --- a/freebsd/sbin/route/route.c +++ b/freebsd/sbin/route/route.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include <sys/ioctl.h> #include <sys/sysctl.h> #include <rtems/bsd/sys/types.h> +#include <sys/queue.h> #include <net/if.h> #include <net/route.h> @@ -85,8 +86,15 @@ static const struct keytab { {0, 0} }; +struct fibl { + TAILQ_ENTRY(fibl) fl_next; + + int fl_num; + int fl_error; + int fl_errno; +}; + struct rt_ctx { - struct ortentry route; union sockunion { struct sockaddr sa; struct sockaddr_in sin; @@ -102,11 +110,13 @@ struct rt_ctx { int pid, rtm_addrs; int s; int forcehost, forcenet, nflag, af, qflag, tflag; - int iflag, verbose, aflen; + int verbose, aflen; int locking, lockrest, debugonly; struct rt_metrics rt_metrics; u_long rtm_inits; uid_t uid; + int defaultfib; + int numfibs; char domain[MAXHOSTNAMELEN + 1]; int domain_initialized; int rtm_seq; @@ -116,6 +126,7 @@ struct rt_ctx { struct rt_msghdr m_rtm; char m_space[512]; } m_rtmsg; + TAILQ_HEAD(fibl_head_t, fibl) fibl_head; }; #ifndef __rtems__ @@ -128,7 +139,8 @@ static int atalk_aton(const char *, struct at_addr *); static char *atalk_ntoa(struct at_addr, char [20]); static void bprintf(FILE *, int, const char *); static void flushroutes(struct rt_ctx *, int argc, char *argv[]); -static int getaddr(struct rt_ctx *, int, char *, struct hostent **); +static int flushroutes_fib(struct rt_ctx *, int); +static int getaddr(struct rt_ctx *, int, char *, struct hostent **, int); static int keyword(const char *); static void inet_makenetandmask(struct rt_ctx *, u_long, struct sockaddr_in *, u_long); #ifdef INET6 @@ -136,21 +148,27 @@ static int inet6_makenetandmask(struct rt_ctx *, struct sockaddr_in6 *, const ch #endif static void interfaces(struct rt_ctx *); static void mask_addr(struct rt_ctx *); -static void monitor(struct rt_ctx *); +static void monitor(struct rt_ctx *, int, char *[]); static const char *netname(struct rt_ctx *, struct sockaddr *); static void newroute(struct rt_ctx *, int, char **); +static int newroute_fib(struct rt_ctx *, int, char *, int); static void pmsg_addrs(struct rt_ctx *, char *, int, size_t); static void pmsg_common(struct rt_ctx *, struct rt_msghdr *, size_t); static int prefixlen(struct rt_ctx *, const char *); -static void print_getmsg(struct rt_ctx *, struct rt_msghdr *, int); +static void print_getmsg(struct rt_ctx *, struct rt_msghdr *, int, int); static void print_rtmsg(struct rt_ctx *, struct rt_msghdr *, size_t); static const char *routename(struct rt_ctx *, struct sockaddr *); -static int rtmsg(struct rt_ctx *, int, int); +static int rtmsg(struct rt_ctx *, int, int, int); static void set_metric(struct rt_ctx *, char *, int); +static int set_sofib(struct rt_ctx *, int); +static int set_procfib(int); static void sockaddr(char *, struct sockaddr *); static void sodump(sup, const char *); extern char *iso_ntoa(void); +static int fiboptlist_csv(struct rt_ctx *, const char *, struct fibl_head_t *); +static int fiboptlist_range(struct rt_ctx *, const char *, struct fibl_head_t *); + static void usage(const char *) __dead2; void @@ -189,16 +207,24 @@ int rtems_bsd_command_route(int argc, char *argv[]) c = calloc(1, sizeof(*c)); if (c != NULL) { struct main_ctx mc; + struct fibl *fl; + struct fibl *tfl; mc.argc = argc; mc.argv = argv; mc.c = c; c->aflen = sizeof(struct sockaddr_in); + TAILQ_INIT(&c->fibl_head); exit_code = rtems_bsd_program_call("route", call_main, &mc); close(c->s); + + TAILQ_FOREACH_SAFE(fl, &c->fibl_head, fl_next, tfl) { + free(fl); + } + free(c); } else { exit_code = EXIT_FAILURE; @@ -217,6 +243,7 @@ main(int argc, char **argv) struct rt_ctx *c; #endif /* __rtems__ */ int ch; + size_t len; #ifdef __rtems__ struct getopt_data getopt_data; memset(&getopt_data, 0, sizeof(getopt_data)); @@ -267,6 +294,17 @@ main(int argc, char **argv) c->s = socket(PF_ROUTE, SOCK_RAW, 0); if (c->s < 0) err(EX_OSERR, "socket"); + + len = sizeof(c->numfibs); + if (sysctlbyname("net.fibs", (void *)&c->numfibs, &len, NULL, 0) == -1) + c->numfibs = -1; + + len = sizeof(c->defaultfib); + if (c->numfibs != -1 && + sysctlbyname("net.my_fibnum", (void *)&c->defaultfib, &len, NULL, + 0) == -1) + c->defaultfib = -1; + if (*argv != NULL) switch (keyword(*argv)) { case K_GET: @@ -282,7 +320,7 @@ main(int argc, char **argv) /* NOTREACHED */ case K_MONITOR: - monitor(c); + monitor(c, argc, argv); /* NOTREACHED */ case K_FLUSH: @@ -294,6 +332,136 @@ main(int argc, char **argv) /* NOTREACHED */ } +static int +set_sofib(struct rt_ctx *c, int fib) +{ + + if (fib < 0) + return (0); + return (setsockopt(c->s, SOL_SOCKET, SO_SETFIB, (void *)&fib, + sizeof(fib))); +} + +static int +set_procfib(int fib) +{ + + if (fib < 0) + return (0); + return (setfib(fib)); +} + +static int +fiboptlist_range(struct rt_ctx *c, const char *arg, struct fibl_head_t *flh) +{ + struct fibl *fl; + char *str0, *str, *token, *endptr; + int fib[2], i, error; + + str0 = str = strdup(arg); + error = 0; + i = 0; + while ((token = strsep(&str, "-")) != NULL) { + switch (i) { + case 0: + case 1: + errno = 0; + fib[i] = strtol(token, &endptr, 0); + if (errno == 0) { + if (*endptr != '\0' || + fib[i] < 0 || + (c->numfibs != -1 && fib[i] > c->numfibs - 1)) + errno = EINVAL; + } + if (errno) + error = 1; + break; + default: + error = 1; + } + if (error) + goto fiboptlist_range_ret; + i++; + } + if (fib[0] >= fib[1]) { + error = 1; + goto fiboptlist_range_ret; + } + for (i = fib[0]; i <= fib[1]; i++) { + fl = calloc(1, sizeof(*fl)); + if (fl == NULL) { + error = 1; + goto fiboptlist_range_ret; + } + fl->fl_num = i; + TAILQ_INSERT_TAIL(flh, fl, fl_next); + } +fiboptlist_range_ret: + free(str0); + return (error); +} + +#define ALLSTRLEN 64 +static int +fiboptlist_csv(struct rt_ctx *c, const char *arg, struct fibl_head_t *flh) +{ + struct fibl *fl; + char *str0, *str, *token, *endptr; + int fib, error; + + if (strcmp("all", arg) == 0) { + str = calloc(1, ALLSTRLEN); + if (str == NULL) { + error = 1; + goto fiboptlist_csv_ret; + } + if (c->numfibs > 1) + snprintf(str, ALLSTRLEN - 1, "%d-%d", 0, c->numfibs - 1); + else + snprintf(str, ALLSTRLEN - 1, "%d", 0); + } else if (strcmp("default", arg) == 0) { + str0 = str = calloc(1, ALLSTRLEN); + if (str == NULL) { + error = 1; + goto fiboptlist_csv_ret; + } + snprintf(str, ALLSTRLEN - 1, "%d", c->defaultfib); + } else + str0 = str = strdup(arg); + + error = 0; + while ((token = strsep(&str, ",")) != NULL) { + if (*token != '-' && strchr(token, '-') != NULL) { + error = fiboptlist_range(c, token, flh); + if (error) + goto fiboptlist_csv_ret; + } else { + errno = 0; + fib = strtol(token, &endptr, 0); + if (errno == 0) { + if (*endptr != '\0' || + fib < 0 || + (c->numfibs != -1 && fib > c->numfibs - 1)) + errno = EINVAL; + } + if (errno) { + error = 1; + goto fiboptlist_csv_ret; + } + fl = calloc(1, sizeof(*fl)); + if (fl == NULL) { + error = 1; + goto fiboptlist_csv_ret; + } + fl->fl_num = fib; + TAILQ_INSERT_TAIL(flh, fl, fl_next); + } + } +fiboptlist_csv_ret: + free(str0); + return (error); +} + /* * Purge all entries in the routing tables not * associated with network interfaces. @@ -301,38 +469,71 @@ main(int argc, char **argv) static void flushroutes(struct rt_ctx *c, int argc, char *argv[]) { - size_t needed; - int mib[6], rlen, seqno, count = 0; - char *buf, *next, *lim; - struct rt_msghdr *rtm; + struct fibl *fl; + int error; if (c->uid != 0 && !c->debugonly) { errx(EX_NOPERM, "must be root to alter routing table"); } shutdown(c->s, SHUT_RD); /* Don't want to read back our messages */ - if (argc > 1) { + + TAILQ_INIT(&c->fibl_head); + while (argc > 1) { + argc--; argv++; - if (argc == 2 && **argv == '-') - switch (keyword(*argv + 1)) { - case K_INET: - c->af = AF_INET; - break; + if (**argv != '-') + usage(*argv); + switch (keyword(*argv + 1)) { + case K_INET: + c->af = AF_INET; + break; #ifdef INET6 - case K_INET6: - c->af = AF_INET6; - break; + case K_INET6: + c->af = AF_INET6; + break; #endif - case K_ATALK: - c->af = AF_APPLETALK; - break; - case K_LINK: - c->af = AF_LINK; - break; - default: - goto bad; - } else -bad: usage(*argv); + case K_ATALK: + c->af = AF_APPLETALK; + break; + case K_LINK: + c->af = AF_LINK; + break; + case K_FIB: + if (!--argc) + usage(*argv); + error = fiboptlist_csv(c, *++argv, &c->fibl_head); + if (error) + errx(EX_USAGE, "invalid fib number: %s", *argv); + break; + default: + usage(*argv); + } + } + if (TAILQ_EMPTY(&c->fibl_head)) { + error = fiboptlist_csv(c, "default", &c->fibl_head); + if (error) + errx(EX_OSERR, "fiboptlist_csv failed."); + } + TAILQ_FOREACH(fl, &c->fibl_head, fl_next) + flushroutes_fib(c, fl->fl_num); +} + +static int +flushroutes_fib(struct rt_ctx *c, int fib) +{ + struct rt_msghdr *rtm; + size_t needed; + char *buf, *next, *lim; + int mib[6], rlen, seqno, count = 0; + int error; + + error = set_sofib(c, fib); + error += set_procfib(fib); + if (error) { + warn("fib number %d is ignored", fib); + return (error); } + retry: mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -390,14 +591,18 @@ retry: print_rtmsg(c, rtm, rlen); else { struct sockaddr *sa = (struct sockaddr *)(rtm + 1); - (void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? + + printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ? routename(c, sa) : netname(c, sa)); sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); - (void) printf("%-20.20s ", routename(c, sa)); - (void) printf("done\n"); + printf("%-20.20s ", routename(c, sa)); + if (fib >= 0) + printf("-fib %-3d ", fib); + printf("done\n"); } } free(buf); + return (error); } static const char * @@ -547,8 +752,8 @@ netname(struct rt_ctx *c, struct sockaddr *sa) * Guess at the subnet mask, assuming reasonable * width subnet fields. */ - while (in.s_addr & ~mask) - mask |= mask >> subnetshift; + while (in.s_addr &~ mask) + mask = (long)mask >> subnetshift; net = in.s_addr & mask; while ((mask & 1) == 0) mask >>= 1, net >>= 1; @@ -660,18 +865,32 @@ set_metric(struct rt_ctx *c, char *value, int key) *valp = atoi(value); } +#define F_ISHOST 0x01 +#define F_FORCENET 0x02 +#define F_FORCEHOST 0x04 +#define F_PROXY 0x08 +#define F_INTERFACE 0x10 + static void newroute(struct rt_ctx *c, int argc, char **argv) { + struct hostent *hp; + struct fibl *fl; char *cmd; - const char *dest = "", *gateway = "", *errmsg; - int ishost = 0, proxy = 0, ret, attempts, oerrno, flags = RTF_STATIC; - int key; - struct hostent *hp = 0; + const char *dest, *gateway, *errmsg; + int key, error, flags, nrflags, fibnum; if (c->uid != 0) { errx(EX_NOPERM, "must be root to alter routing table"); } + + dest = NULL; + gateway = NULL; + flags = RTF_STATIC; + nrflags = 0; + hp = NULL; + TAILQ_INIT(&c->fibl_head); + cmd = argv[0]; if (*cmd != 'g' && *cmd != 's') shutdown(c->s, SHUT_RD); /* Don't want to read back our messages */ @@ -703,7 +922,7 @@ newroute(struct rt_ctx *c, int argc, char **argv) break; case K_IFACE: case K_INTERFACE: - c->iflag++; + nrflags |= F_INTERFACE; break; case K_NOSTATIC: flags &= ~RTF_STATIC; @@ -715,7 +934,7 @@ newroute(struct rt_ctx *c, int argc, char **argv) c->lockrest = 1; break; case K_HOST: - c->forcehost++; + nrflags |= F_FORCEHOST; break; case K_REJECT: flags |= RTF_REJECT; @@ -730,7 +949,7 @@ newroute(struct rt_ctx *c, int argc, char **argv) flags |= RTF_PROTO2; break; case K_PROXY: - proxy = 1; + nrflags |= F_PROXY; break; case K_XRESOLVE: flags |= RTF_XRESOLVE; @@ -744,49 +963,59 @@ newroute(struct rt_ctx *c, int argc, char **argv) case K_NOSTICK: flags &= ~RTF_STICKY; break; + case K_FIB: + if (!--argc) + usage(NULL); + error = fiboptlist_csv(c, *++argv, &c->fibl_head); + if (error) + errx(EX_USAGE, + "invalid fib number: %s", *argv); + break; case K_IFA: if (!--argc) usage(NULL); - (void) getaddr(c, RTA_IFA, *++argv, 0); + getaddr(c, RTA_IFA, *++argv, 0, nrflags); break; case K_IFP: if (!--argc) usage(NULL); - (void) getaddr(c, RTA_IFP, *++argv, 0); + getaddr(c, RTA_IFP, *++argv, 0, nrflags); break; case K_GENMASK: if (!--argc) usage(NULL); - (void) getaddr(c, RTA_GENMASK, *++argv, 0); + getaddr(c, RTA_GENMASK, *++argv, 0, nrflags); break; case K_GATEWAY: if (!--argc) usage(NULL); - (void) getaddr(c, RTA_GATEWAY, *++argv, 0); + getaddr(c, RTA_GATEWAY, *++argv, 0, nrflags); + gateway = *argv; break; case K_DST: if (!--argc) usage(NULL); - ishost = getaddr(c, RTA_DST, *++argv, &hp); + if (getaddr(c, RTA_DST, *++argv, &hp, nrflags)) + nrflags |= F_ISHOST; dest = *argv; break; case K_NETMASK: if (!--argc) usage(NULL); - (void) getaddr(c, RTA_NETMASK, *++argv, 0); + getaddr(c, RTA_NETMASK, *++argv, 0, nrflags); /* FALLTHROUGH */ case K_NET: - c->forcenet++; + nrflags |= F_FORCENET; break; case K_PREFIXLEN: if (!--argc) usage(NULL); if (prefixlen(c, *++argv) == -1) { - c->forcenet = 0; - ishost = 1; + nrflags &= ~F_FORCENET; + nrflags |= F_ISHOST; } else { - c->forcenet = 1; - ishost = 0; + nrflags |= F_FORCENET; + nrflags &= ~F_ISHOST; } break; case K_MTU: @@ -808,18 +1037,20 @@ newroute(struct rt_ctx *c, int argc, char **argv) } else { if ((c->rtm_addrs & RTA_DST) == 0) { dest = *argv; - ishost = getaddr(c, RTA_DST, *argv, &hp); + if (getaddr(c, RTA_DST, *argv, &hp, nrflags)) + nrflags |= F_ISHOST; } else if ((c->rtm_addrs & RTA_GATEWAY) == 0) { gateway = *argv; - (void) getaddr(c, RTA_GATEWAY, *argv, &hp); + getaddr(c, RTA_GATEWAY, *argv, &hp, nrflags); } else { - (void) getaddr(c, RTA_NETMASK, *argv, 0); - c->forcenet = 1; + getaddr(c, RTA_NETMASK, *argv, 0, nrflags); + nrflags |= F_FORCENET; } } } - if (c->forcehost) { - ishost = 1; + + if (nrflags & F_FORCEHOST) { + nrflags |= F_ISHOST; #ifdef INET6 if (c->af == AF_INET6) { c->rtm_addrs &= ~RTA_NETMASK; @@ -827,71 +1058,125 @@ newroute(struct rt_ctx *c, int argc, char **argv) } #endif } - if (c->forcenet) - ishost = 0; + if (nrflags & F_FORCENET) + nrflags &= ~F_ISHOST; flags |= RTF_UP; - if (ishost) + if (nrflags & F_ISHOST) flags |= RTF_HOST; - if (c->iflag == 0) + if ((nrflags & F_INTERFACE) == 0) flags |= RTF_GATEWAY; - if (proxy) { + if (nrflags & F_PROXY) { c->so_dst.sinarp.sin_other = SIN_PROXY; flags |= RTF_ANNOUNCE; } - for (attempts = 1; ; attempts++) { - errno = 0; - if ((ret = rtmsg(c, *cmd, flags)) == 0) - break; - if (errno != ENETUNREACH && errno != ESRCH) - break; - if (c->af == AF_INET && *gateway != '\0' && - hp != NULL && hp->h_addr_list[1] != NULL) { - hp->h_addr_list++; - memmove(&c->so_gate.sin.sin_addr, hp->h_addr_list[0], - MIN((size_t)hp->h_length, - sizeof(c->so_gate.sin.sin_addr))); - } else - break; + if (dest == NULL) + dest = ""; + if (gateway == NULL) + gateway = ""; + + if (TAILQ_EMPTY(&c->fibl_head)) { + error = fiboptlist_csv(c, "default", &c->fibl_head); + if (error) + errx(EX_OSERR, "fiboptlist_csv failed."); + } + error = 0; + TAILQ_FOREACH(fl, &c->fibl_head, fl_next) { + fl->fl_error = newroute_fib(c, fl->fl_num, cmd, flags); + if (fl->fl_error) + fl->fl_errno = errno; + error += fl->fl_error; } if (*cmd == 'g' || *cmd == 's') - exit(ret != 0); + exit(error); + + error = 0; if (!c->qflag) { - oerrno = errno; - (void) printf("%s %s %s", cmd, ishost? "host" : "net", dest); - if (*gateway) { - (void) printf(": gateway %s", gateway); - if (attempts > 1 && ret == 0 && c->af == AF_INET) - (void) printf(" (%s)", - inet_ntoa(((struct sockaddr_in *)&c->route.rt_gateway)->sin_addr)); + fibnum = 0; + TAILQ_FOREACH(fl, &c->fibl_head, fl_next) { + if (fl->fl_error == 0) + fibnum++; } - if (ret == 0) { - (void) printf("\n"); - } else { - switch (oerrno) { - case ESRCH: - errmsg = "not in table"; - break; - case EBUSY: - errmsg = "entry in use"; - break; - case ENOBUFS: - errmsg = "not enough memory"; - break; - case EADDRINUSE: - /* handle recursion avoidance in rt_setgate() */ - errmsg = "gateway uses the same route"; - break; - case EEXIST: - errmsg = "route already in table"; - break; - default: - errmsg = strerror(oerrno); - break; + if (fibnum > 0) { + int firstfib = 1; + + printf("%s %s %s", cmd, + (nrflags & F_ISHOST) ? "host" : "net", dest); + if (*gateway) + printf(": gateway %s", gateway); + + if (c->numfibs > 1) { + TAILQ_FOREACH(fl, &c->fibl_head, fl_next) { + if (fl->fl_error == 0 + && fl->fl_num >= 0) { + if (firstfib) { + printf(" fib "); + firstfib = 0; + } + printf("%d", fl->fl_num); + if (fibnum-- > 1) + printf(","); + } + } + } + printf("\n"); + } + + fibnum = 0; + TAILQ_FOREACH(fl, &c->fibl_head, fl_next) { + if (fl->fl_error != 0) { + printf("%s %s %s", cmd, (nrflags & F_ISHOST) + ? "host" : "net", dest); + if (*gateway) + printf(": gateway %s", gateway); + + if (fl->fl_num >= 0) + printf(" fib %d", fl->fl_num); + + switch (fl->fl_errno) { + case ESRCH: + errmsg = "not in table"; + break; + case EBUSY: + errmsg = "entry in use"; + break; + case ENOBUFS: + errmsg = "not enough memory"; + break; + case EADDRINUSE: + /* + * handle recursion avoidance + * in rt_setgate() + */ + errmsg = "gateway uses the same route"; + break; + case EEXIST: + errmsg = "route already in table"; + break; + default: + errmsg = strerror(fl->fl_errno); + break; + } + printf(": %s\n", errmsg); + error = 1; } - (void) printf(": %s\n", errmsg); } } - exit(ret != 0); + exit(error); +} + +static int +newroute_fib(struct rt_ctx *c, int fib, char *cmd, int flags) +{ + int error; + + error = set_sofib(c, fib); + if (error) { + warn("fib number %d is ignored", fib); + return (error); + } + + error = rtmsg(c, *cmd, flags, fib); + return (error); } static void @@ -977,7 +1262,7 @@ inet6_makenetandmask(struct rt_ctx *c, struct sockaddr_in6 *sin6, const char *pl * returning 1 if a host address, 0 if a network address. */ static int -getaddr(struct rt_ctx *c, int which, char *str, struct hostent **hpp) +getaddr(struct rt_ctx *c, int which, char *str, struct hostent **hpp, int nrflags) { sup su; struct hostent *hp; @@ -998,7 +1283,7 @@ getaddr(struct rt_ctx *c, int which, char *str, struct hostent **hpp) break; case RTA_GATEWAY: su = &c->so_gate; - if (c->iflag) { + if (nrflags & F_INTERFACE) { struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl = NULL; @@ -1058,7 +1343,7 @@ getaddr(struct rt_ctx *c, int which, char *str, struct hostent **hpp) #if 0 bzero(su, sizeof(*su)); /* for readability */ #endif - getaddr(c, RTA_NETMASK, str, 0); + getaddr(c, RTA_NETMASK, str, 0, nrflags); break; #if 0 case RTA_NETMASK: @@ -1253,10 +1538,39 @@ retry2: } static void -monitor(struct rt_ctx *c) +monitor(struct rt_ctx *c, int argc, char *argv[]) { - int n; - char msg[2048]; + int n, fib, error; + char msg[2048], *endptr; + + fib = c->defaultfib; + while (argc > 1) { + argc--; + argv++; + if (**argv != '-') + usage(*argv); + switch (keyword(*argv + 1)) { + case K_FIB: + if (!--argc) + usage(*argv); + errno = 0; + fib = strtol(*++argv, &endptr, 0); + if (errno == 0) { + if (*endptr != '\0' || + fib < 0 || + (c->numfibs != -1 && fib > c->numfibs - 1)) + errno = EINVAL; + } + if (errno) + errx(EX_USAGE, "invalid fib number: %s", *argv); + break; + default: + usage(*argv); + } + } + error = set_sofib(c, fib); + if (error) + errx(EX_USAGE, "invalid fib number: %d", fib); c->verbose = 1; if (c->debugonly) { @@ -1273,7 +1587,7 @@ monitor(struct rt_ctx *c) } static int -rtmsg(struct rt_ctx *c, int cmd, int flags) +rtmsg(struct rt_ctx *c, int cmd, int flags, int fib) { int rlen; char *cp = c->m_rtmsg.m_space; @@ -1335,7 +1649,7 @@ rtmsg(struct rt_ctx *c, int cmd, int flags) if (l < 0) warn("read from routing socket"); else - print_getmsg(c, &rtm, l); + print_getmsg(c, &rtm, l, fib); } #undef rtm return (0); @@ -1495,6 +1809,7 @@ print_rtmsg(struct rt_ctx *c, struct rt_msghdr *rtm, size_t msglen) break; } printf("\n"); + fflush(stdout); break; default: @@ -1512,7 +1827,7 @@ badlen: } static void -print_getmsg(struct rt_ctx *c, struct rt_msghdr *rtm, int msglen) +print_getmsg(struct rt_ctx *c, struct rt_msghdr *rtm, int msglen, int fib) { struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL; struct sockaddr_dl *ifp = NULL; @@ -1572,6 +1887,8 @@ print_getmsg(struct rt_ctx *c, struct rt_msghdr *rtm, int msglen) } if (gate && rtm->rtm_flags & RTF_GATEWAY) (void)printf(" gateway: %s\n", routename(c, gate)); + if (fib >= 0) + (void)printf(" fib: %u\n", (unsigned int)fib); if (ifp) (void)printf(" interface: %.*s\n", ifp->sdl_nlen, ifp->sdl_data); |