summaryrefslogtreecommitdiffstats
path: root/freebsd/sbin
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-06 16:20:21 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-11 10:08:08 +0100
commit66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch)
tree48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sbin
parentDefine __GLOBL1() and __GLOBL() (diff)
downloadrtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sbin')
-rw-r--r--freebsd/sbin/dhclient/clparse.c6
-rw-r--r--freebsd/sbin/dhclient/packet.c2
-rw-r--r--freebsd/sbin/dhclient/parse.c12
-rw-r--r--freebsd/sbin/ifconfig/af_inet.c7
-rw-r--r--freebsd/sbin/ifconfig/af_inet6.c13
-rw-r--r--freebsd/sbin/ifconfig/af_nd6.c80
-rw-r--r--freebsd/sbin/ifconfig/ifconfig.c67
-rw-r--r--freebsd/sbin/ifconfig/ifconfig.h1
-rw-r--r--freebsd/sbin/ifconfig/ifgif.c24
-rw-r--r--freebsd/sbin/ifconfig/iflagg.c7
-rw-r--r--freebsd/sbin/ifconfig/ifmedia.c4
-rw-r--r--freebsd/sbin/ping/ping.c50
-rw-r--r--freebsd/sbin/ping6/ping6.c184
-rw-r--r--freebsd/sbin/route/keywords1
-rw-r--r--freebsd/sbin/route/route.c557
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);