summaryrefslogtreecommitdiffstats
path: root/freebsd/sbin
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-09-24 11:05:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-11-13 10:47:04 +0100
commita5ddb0ea69f21c16b7697a935d7a0c16bb3cffcf (patch)
treedb091fb0f7d091804482156c9f3f55879ac93d5b /freebsd/sbin
parenttest/syscalls01: Fix sporadic test failures (diff)
downloadrtems-libbsd-a5ddb0ea69f21c16b7697a935d7a0c16bb3cffcf.tar.bz2
Update to FreeBSD head 2019-09-24
Git mirror commit 6b0307a0a5184339393f555d5d424190d8a8277a.
Diffstat (limited to 'freebsd/sbin')
-rw-r--r--freebsd/sbin/dhclient/dhclient.c13
-rw-r--r--freebsd/sbin/dhclient/options.c3
-rw-r--r--freebsd/sbin/dhclient/packet.c4
-rw-r--r--freebsd/sbin/ifconfig/af_inet.c8
-rw-r--r--freebsd/sbin/ifconfig/af_inet6.c38
-rw-r--r--freebsd/sbin/ifconfig/af_nd6.c2
-rw-r--r--freebsd/sbin/ifconfig/ifconfig.c132
-rw-r--r--freebsd/sbin/ifconfig/ifgre.c25
-rw-r--r--freebsd/sbin/ifconfig/ifgroup.c4
-rw-r--r--freebsd/sbin/ifconfig/ifieee80211.c259
-rw-r--r--freebsd/sbin/ifconfig/iflagg.c4
-rw-r--r--freebsd/sbin/ifconfig/ifmedia.c32
-rw-r--r--freebsd/sbin/ifconfig/ifpfsync.c6
-rw-r--r--freebsd/sbin/ifconfig/sfp.c69
-rw-r--r--freebsd/sbin/pfctl/parse.c1
-rw-r--r--freebsd/sbin/pfctl/parse.y17
-rw-r--r--freebsd/sbin/pfctl/pfctl.c7
-rw-r--r--freebsd/sbin/pfctl/pfctl.h1
-rw-r--r--freebsd/sbin/pfctl/pfctl_altq.c550
-rw-r--r--freebsd/sbin/pfctl/pfctl_optimize.c20
-rw-r--r--freebsd/sbin/pfctl/pfctl_parser.c145
-rw-r--r--freebsd/sbin/pfctl/pfctl_parser.h26
-rw-r--r--freebsd/sbin/pfctl/rtems-bsd-pfctl-pfctl_altq-data.h3
-rw-r--r--freebsd/sbin/ping/ping.c386
-rw-r--r--freebsd/sbin/ping/utils.c100
-rw-r--r--freebsd/sbin/ping/utils.h38
-rw-r--r--freebsd/sbin/ping6/ping6.c555
-rw-r--r--freebsd/sbin/ping6/rtems-bsd-ping6-data.h1
-rw-r--r--freebsd/sbin/ping6/rtems-bsd-ping6-namespace.h1
-rw-r--r--freebsd/sbin/ping6/rtems-bsd-ping6-ping6-data.h1
-rw-r--r--freebsd/sbin/sysctl/sysctl.c19
31 files changed, 1569 insertions, 901 deletions
diff --git a/freebsd/sbin/dhclient/dhclient.c b/freebsd/sbin/dhclient/dhclient.c
index 2aedd2f7..3b5b8849 100644
--- a/freebsd/sbin/dhclient/dhclient.c
+++ b/freebsd/sbin/dhclient/dhclient.c
@@ -865,6 +865,7 @@ bind_lease(struct interface_info *ip)
opt = &ip->client->new->options[DHO_INTERFACE_MTU];
if (opt->len == sizeof(u_int16_t)) {
u_int16_t mtu = 0;
+ u_int16_t old_mtu = 0;
bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
ACTION_SUPERSEDE);
@@ -873,12 +874,19 @@ bind_lease(struct interface_info *ip)
else
mtu = be16dec(opt->data);
+ if (ip->client->active) {
+ opt = &ip->client->active->options[DHO_INTERFACE_MTU];
+ if (opt->len == sizeof(u_int16_t)) {
+ old_mtu = be16dec(opt->data);
+ }
+ }
+
if (mtu < MIN_MTU) {
/* Treat 0 like a user intentionally doesn't want to change MTU and,
* therefore, warning is not needed */
if (!supersede || mtu != 0)
warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
- } else {
+ } else if (ip->client->state != S_RENEWING || mtu != old_mtu) {
interface_set_mtu_unpriv(privfd, mtu);
}
}
@@ -2350,7 +2358,8 @@ priv_script_go(void)
if (ip)
script_flush_env(ip->client);
- return (wstatus & 0xff);
+ return (WIFEXITED(wstatus) ?
+ WEXITSTATUS(wstatus) : 128 + WTERMSIG(wstatus));
}
void
diff --git a/freebsd/sbin/dhclient/options.c b/freebsd/sbin/dhclient/options.c
index b31ab32a..a38d6440 100644
--- a/freebsd/sbin/dhclient/options.c
+++ b/freebsd/sbin/dhclient/options.c
@@ -898,6 +898,5 @@ do_packet(struct interface_info *interface, struct dhcp_packet *packet,
/* Free the data associated with the options. */
for (i = 0; i < 256; i++)
- if (tp.options[i].len && tp.options[i].data)
- free(tp.options[i].data);
+ free(tp.options[i].data);
}
diff --git a/freebsd/sbin/dhclient/packet.c b/freebsd/sbin/dhclient/packet.c
index b3c719b2..51f7e1ab 100644
--- a/freebsd/sbin/dhclient/packet.c
+++ b/freebsd/sbin/dhclient/packet.c
@@ -185,7 +185,7 @@ decode_udp_ip_header(unsigned char *buf, int bufix, struct sockaddr_in *from,
ip_packets_seen++;
if (wrapsum(checksum(buf + bufix, ip_len, 0)) != 0) {
ip_packets_bad_checksum++;
- if (ip_packets_seen > 4 &&
+ if (ip_packets_seen > 4 && ip_packets_bad_checksum != 0 &&
(ip_packets_seen / ip_packets_bad_checksum) < 2) {
note("%d bad IP checksums seen in %d packets",
ip_packets_bad_checksum, ip_packets_seen);
@@ -237,7 +237,7 @@ decode_udp_ip_header(unsigned char *buf, int bufix, struct sockaddr_in *from,
udp_packets_seen++;
if (usum && usum != sum) {
udp_packets_bad_checksum++;
- if (udp_packets_seen > 4 &&
+ if (udp_packets_seen > 4 && udp_packets_bad_checksum != 0 &&
(udp_packets_seen / udp_packets_bad_checksum) < 2) {
note("%d bad udp checksums in %d packets",
udp_packets_bad_checksum, udp_packets_seen);
diff --git a/freebsd/sbin/ifconfig/af_inet.c b/freebsd/sbin/ifconfig/af_inet.c
index 050ceb80..a6e95683 100644
--- a/freebsd/sbin/ifconfig/af_inet.c
+++ b/freebsd/sbin/ifconfig/af_inet.c
@@ -119,16 +119,16 @@ in_status(int s __unused, const struct ifaddrs *ifa)
if (cidr == 0)
break;
}
- printf("/%d ", cidr);
+ printf("/%d", cidr);
} else if (f_inet != NULL && strcmp(f_inet, "dotted") == 0)
- printf(" netmask %s ", inet_ntoa(sin->sin_addr));
+ printf(" netmask %s", inet_ntoa(sin->sin_addr));
else
- printf(" netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr));
+ printf(" netmask 0x%lx", (unsigned long)ntohl(sin->sin_addr.s_addr));
if (ifa->ifa_flags & IFF_BROADCAST) {
sin = (struct sockaddr_in *)ifa->ifa_broadaddr;
if (sin != NULL && sin->sin_addr.s_addr != 0)
- printf("broadcast %s ", inet_ntoa(sin->sin_addr));
+ printf(" broadcast %s", inet_ntoa(sin->sin_addr));
}
print_vhid(ifa, " ");
diff --git a/freebsd/sbin/ifconfig/af_inet6.c b/freebsd/sbin/ifconfig/af_inet6.c
index cae6c326..f3b1b6bc 100644
--- a/freebsd/sbin/ifconfig/af_inet6.c
+++ b/freebsd/sbin/ifconfig/af_inet6.c
@@ -259,49 +259,49 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
if (sin == NULL)
sin = &null_sin;
if (f_inet6 != NULL && strcmp(f_inet6, "cidr") == 0)
- printf("/%d ", prefix(&sin->sin6_addr,
+ printf("/%d", prefix(&sin->sin6_addr,
sizeof(struct in6_addr)));
else
- printf(" prefixlen %d ", prefix(&sin->sin6_addr,
+ printf(" prefixlen %d", prefix(&sin->sin6_addr,
sizeof(struct in6_addr)));
if ((flags6 & IN6_IFF_ANYCAST) != 0)
- printf("anycast ");
+ printf(" anycast");
if ((flags6 & IN6_IFF_TENTATIVE) != 0)
- printf("tentative ");
+ printf(" tentative");
if ((flags6 & IN6_IFF_DUPLICATED) != 0)
- printf("duplicated ");
+ printf(" duplicated");
if ((flags6 & IN6_IFF_DETACHED) != 0)
- printf("detached ");
+ printf(" detached");
if ((flags6 & IN6_IFF_DEPRECATED) != 0)
- printf("deprecated ");
+ printf(" deprecated");
if ((flags6 & IN6_IFF_AUTOCONF) != 0)
- printf("autoconf ");
+ printf(" autoconf");
if ((flags6 & IN6_IFF_TEMPORARY) != 0)
- printf("temporary ");
+ printf(" temporary");
if ((flags6 & IN6_IFF_PREFER_SOURCE) != 0)
- printf("prefer_source ");
+ printf(" prefer_source");
if (((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id)
- printf("scopeid 0x%x ",
+ printf(" scopeid 0x%x",
((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id);
if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) {
- printf("pltime ");
+ printf(" pltime");
if (lifetime.ia6t_preferred) {
- printf("%s ", lifetime.ia6t_preferred < now.tv_sec
+ printf(" %s", lifetime.ia6t_preferred < now.tv_sec
? "0" :
sec2str(lifetime.ia6t_preferred - now.tv_sec));
} else
- printf("infty ");
+ printf(" infty");
- printf("vltime ");
+ printf(" vltime");
if (lifetime.ia6t_expire) {
- printf("%s ", lifetime.ia6t_expire < now.tv_sec
+ printf(" %s", lifetime.ia6t_expire < now.tv_sec
? "0" :
sec2str(lifetime.ia6t_expire - now.tv_sec));
} else
- printf("infty ");
+ printf(" infty");
}
print_vhid(ifa, " ");
@@ -524,6 +524,10 @@ static struct cmd inet6_cmds[] = {
DEF_CMD_ARG("pltime", setip6pltime),
DEF_CMD_ARG("vltime", setip6vltime),
DEF_CMD("eui64", 0, setip6eui64),
+#ifdef EXPERIMENTAL
+ DEF_CMD("ipv6_only", ND6_IFF_IPV6_ONLY_MANUAL,setnd6flags),
+ DEF_CMD("-ipv6_only", -ND6_IFF_IPV6_ONLY_MANUAL,setnd6flags),
+#endif
};
static struct afswtch af_inet6 = {
diff --git a/freebsd/sbin/ifconfig/af_nd6.c b/freebsd/sbin/ifconfig/af_nd6.c
index 964c96b0..c900e787 100644
--- a/freebsd/sbin/ifconfig/af_nd6.c
+++ b/freebsd/sbin/ifconfig/af_nd6.c
@@ -73,7 +73,7 @@ static const char rcsid[] =
#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \
"\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \
"\007NO_RADR\010NO_PREFER_IFACE\011NO_DAD" \
- "\012IPV6_ONLY" \
+ "\012IPV6_ONLY\013IPV6_ONLY_MANUAL" \
"\020DEFAULTIF"
#else
#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \
diff --git a/freebsd/sbin/ifconfig/ifconfig.c b/freebsd/sbin/ifconfig/ifconfig.c
index 1e79e0cd..2a04b8cf 100644
--- a/freebsd/sbin/ifconfig/ifconfig.c
+++ b/freebsd/sbin/ifconfig/ifconfig.c
@@ -86,6 +86,7 @@ static const char rcsid[] =
#ifdef JAIL
#include <jail.h>
#endif
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -129,6 +130,8 @@ static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
static void tunnel_status(int s);
static _Noreturn void usage(void);
+static int getifflags(const char *ifname, int us);
+
static struct afswtch *af_getbyname(const char *name);
static struct afswtch *af_getbyfamily(int af);
static void af_other_status(int);
@@ -146,6 +149,39 @@ struct ifa_order_elt {
TAILQ_HEAD(ifa_queue, ifa_order_elt);
+static struct module_map_entry {
+ const char *ifname;
+ const char *kldname;
+} module_map[] = {
+ {
+ .ifname = "tun",
+ .kldname = "if_tuntap",
+ },
+ {
+ .ifname = "tap",
+ .kldname = "if_tuntap",
+ },
+ {
+ .ifname = "vmnet",
+ .kldname = "if_tuntap",
+ },
+ {
+ .ifname = "ipsec",
+ .kldname = "ipsec",
+ },
+ {
+ /*
+ * This mapping exists because there is a conflicting enc module
+ * in CAM. ifconfig's guessing behavior will attempt to match
+ * the ifname to a module as well as if_${ifname} and clash with
+ * CAM enc. This is an assertion of the correct module to load.
+ */
+ .ifname = "enc",
+ .kldname = "if_enc",
+ },
+};
+
+
void
opt_register(struct option *p)
{
@@ -437,6 +473,7 @@ main(int argc, char *argv[])
const char *ifname;
struct option *p;
size_t iflen;
+ int flags;
#ifdef __rtems__
struct getopt_data getopt_data;
memset(&getopt_data, 0, sizeof(getopt_data));
@@ -607,6 +644,25 @@ main(int argc, char *argv[])
argc--, argv++;
}
+ /*
+ * Check for a requested configuration action on a single interface,
+ * which doesn't require building, sorting, and searching the entire
+ * system address list
+ */
+ if ((argc > 0) && (ifname != NULL)) {
+ iflen = strlcpy(name, ifname, sizeof(name));
+ if (iflen >= sizeof(name)) {
+ warnx("%s: interface name too long, skipping", ifname);
+ } else {
+ flags = getifflags(name, -1);
+ if (!(((flags & IFF_CANTCONFIG) != 0) ||
+ (downonly && (flags & IFF_UP) != 0) ||
+ (uponly && (flags & IFF_UP) == 0)))
+ ifconfig(argc, argv, 0, afp);
+ }
+ goto done;
+ }
+
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
@@ -690,6 +746,7 @@ main(int argc, char *argv[])
printf("\n");
freeifaddrs(ifap);
+done:
freeformat();
exit(exit_code);
}
@@ -1101,6 +1158,28 @@ setifdstaddr(const char *addr, int param __unused, int s,
afp->af_getaddr(addr, DSTADDR);
}
+static int
+getifflags(const char *ifname, int us)
+{
+ struct ifreq my_ifr;
+ int s;
+
+ memset(&my_ifr, 0, sizeof(my_ifr));
+ (void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name));
+ if (us < 0) {
+ if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
+ err(1, "socket(family AF_LOCAL,SOCK_DGRAM");
+ } else
+ s = us;
+ if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
+ Perror("ioctl (SIOCGIFFLAGS)");
+ exit(1);
+ }
+ if (us < 0)
+ close(s);
+ return ((my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16));
+}
+
/*
* Note: doing an SIOCIGIFFLAGS scribbles on the union portion
* of the ifreq structure, which may confuse other parts of ifconfig.
@@ -1112,20 +1191,14 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp)
struct ifreq my_ifr;
int flags;
- memset(&my_ifr, 0, sizeof(my_ifr));
- (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name));
-
- if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
- Perror("ioctl (SIOCGIFFLAGS)");
- exit(1);
- }
- flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16);
-
+ flags = getifflags(name, s);
if (value < 0) {
value = -value;
flags &= ~value;
} else
flags |= value;
+ memset(&my_ifr, 0, sizeof(my_ifr));
+ (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name));
my_ifr.ifr_flags = flags & 0xffff;
my_ifr.ifr_flagshigh = flags >> 16;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0)
@@ -1265,7 +1338,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
"\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
"\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \
-"\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP"
+"\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP\33NOMAP\34TXTLS4\35TXTLS6"
/*
* Print the status of the interface. If an address family was
@@ -1451,7 +1524,7 @@ print_vhid(const struct ifaddrs *ifa, const char *s)
if (ifd->ifi_vhid == 0)
return;
- printf("vhid %d ", ifd->ifi_vhid);
+ printf(" vhid %d", ifd->ifi_vhid);
}
void
@@ -1460,9 +1533,11 @@ ifmaybeload(const char *name)
#ifndef __rtems__
#define MOD_PREFIX_LEN 3 /* "if_" */
struct module_stat mstat;
- int fileid, modid;
+ int i, fileid, modid;
char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp;
const char *cp;
+ struct module_map_entry *mme;
+ bool found;
/* loading suppressed by the user */
if (noload)
@@ -1476,9 +1551,24 @@ ifmaybeload(const char *name)
break;
}
- /* turn interface and unit into module name */
- strlcpy(ifkind, "if_", sizeof(ifkind));
- strlcat(ifkind, ifname, sizeof(ifkind));
+ /* Either derive it from the map or guess otherwise */
+ *ifkind = '\0';
+ found = false;
+ for (i = 0; i < nitems(module_map); ++i) {
+ mme = &module_map[i];
+ if (strcmp(mme->ifname, ifname) == 0) {
+ strlcpy(ifkind, mme->kldname, sizeof(ifkind));
+ found = true;
+ break;
+ }
+ }
+
+ /* We didn't have an alias for it... we'll guess. */
+ if (!found) {
+ /* turn interface and unit into module name */
+ strlcpy(ifkind, "if_", sizeof(ifkind));
+ strlcat(ifkind, ifname, sizeof(ifkind));
+ }
/* scan files in kernel */
mstat.version = sizeof(struct module_stat);
@@ -1494,8 +1584,12 @@ ifmaybeload(const char *name)
} else {
cp = mstat.name;
}
- /* already loaded? */
- if (strcmp(ifname, cp) == 0 ||
+ /*
+ * Is it already loaded? Don't compare with ifname if
+ * we were specifically told which kld to use. Doing
+ * so could lead to conflicts not trivially solved.
+ */
+ if ((!found && strcmp(ifname, cp) == 0) ||
strcmp(ifkind, cp) == 0)
return;
}
@@ -1550,6 +1644,8 @@ static struct cmd basic_cmds[] = {
DEF_CMD("-link2", -IFF_LINK2, setifflags),
DEF_CMD("monitor", IFF_MONITOR, setifflags),
DEF_CMD("-monitor", -IFF_MONITOR, setifflags),
+ DEF_CMD("nomap", IFCAP_NOMAP, setifcap),
+ DEF_CMD("-nomap", -IFCAP_NOMAP, setifcap),
DEF_CMD("staticarp", IFF_STATICARP, setifflags),
DEF_CMD("-staticarp", -IFF_STATICARP, setifflags),
DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap),
@@ -1576,6 +1672,8 @@ static struct cmd basic_cmds[] = {
DEF_CMD("-toe", -IFCAP_TOE, setifcap),
DEF_CMD("lro", IFCAP_LRO, setifcap),
DEF_CMD("-lro", -IFCAP_LRO, setifcap),
+ DEF_CMD("txtls", IFCAP_TXTLS, setifcap),
+ DEF_CMD("-txtls", -IFCAP_TXTLS, setifcap),
DEF_CMD("wol", IFCAP_WOL, setifcap),
DEF_CMD("-wol", -IFCAP_WOL, setifcap),
DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap),
diff --git a/freebsd/sbin/ifconfig/ifgre.c b/freebsd/sbin/ifconfig/ifgre.c
index 2adc6d76..092e70c2 100644
--- a/freebsd/sbin/ifconfig/ifgre.c
+++ b/freebsd/sbin/ifconfig/ifgre.c
@@ -56,15 +56,16 @@ __FBSDID("$FreeBSD$");
#include "rtems-bsd-ifconfig-ifgre-data.h"
#endif /* __rtems__ */
-#define GREBITS "\020\01ENABLE_CSUM\02ENABLE_SEQ"
+#define GREBITS "\020\01ENABLE_CSUM\02ENABLE_SEQ\03UDPENCAP"
static void gre_status(int s);
static void
gre_status(int s)
{
- uint32_t opts = 0;
+ uint32_t opts, port;
+ opts = 0;
ifr.ifr_data = (caddr_t)&opts;
if (ioctl(s, GREGKEY, &ifr) == 0)
if (opts != 0)
@@ -72,6 +73,11 @@ gre_status(int s)
opts = 0;
if (ioctl(s, GREGOPTS, &ifr) != 0 || opts == 0)
return;
+
+ port = 0;
+ ifr.ifr_data = (caddr_t)&port;
+ if (ioctl(s, GREGPORT, &ifr) == 0 && port != 0)
+ printf("\tudpport: %u\n", port);
printb("\toptions", opts, GREBITS);
putchar('\n');
}
@@ -89,6 +95,18 @@ setifgrekey(const char *val, int dummy __unused, int s,
}
static void
+setifgreport(const char *val, int dummy __unused, int s,
+ const struct afswtch *afp)
+{
+ uint32_t udpport = strtol(val, NULL, 0);
+
+ strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ ifr.ifr_data = (caddr_t)&udpport;
+ if (ioctl(s, GRESPORT, (caddr_t)&ifr) < 0)
+ warn("ioctl (set udpport)");
+}
+
+static void
setifgreopts(const char *val, int d, int s, const struct afswtch *afp)
{
uint32_t opts;
@@ -113,10 +131,13 @@ setifgreopts(const char *val, int d, int s, const struct afswtch *afp)
static struct cmd gre_cmds[] = {
DEF_CMD_ARG("grekey", setifgrekey),
+ DEF_CMD_ARG("udpport", setifgreport),
DEF_CMD("enable_csum", GRE_ENABLE_CSUM, setifgreopts),
DEF_CMD("-enable_csum",-GRE_ENABLE_CSUM,setifgreopts),
DEF_CMD("enable_seq", GRE_ENABLE_SEQ, setifgreopts),
DEF_CMD("-enable_seq",-GRE_ENABLE_SEQ, setifgreopts),
+ DEF_CMD("udpencap", GRE_UDPENCAP, setifgreopts),
+ DEF_CMD("-udpencap",-GRE_UDPENCAP, setifgreopts),
};
static struct afswtch af_gre = {
.af_name = "af_gre",
diff --git a/freebsd/sbin/ifconfig/ifgroup.c b/freebsd/sbin/ifconfig/ifgroup.c
index a487f060..fc1b826c 100644
--- a/freebsd/sbin/ifconfig/ifgroup.c
+++ b/freebsd/sbin/ifconfig/ifgroup.c
@@ -135,9 +135,9 @@ getifgroups(int s)
len -= sizeof(struct ifg_req);
if (strcmp(ifg->ifgrq_group, "all")) {
if (cnt == 0)
- printf("\tgroups: ");
+ printf("\tgroups:");
cnt++;
- printf("%s ", ifg->ifgrq_group);
+ printf(" %s", ifg->ifgrq_group);
}
}
if (cnt)
diff --git a/freebsd/sbin/ifconfig/ifieee80211.c b/freebsd/sbin/ifconfig/ifieee80211.c
index fa407957..08c91443 100644
--- a/freebsd/sbin/ifconfig/ifieee80211.c
+++ b/freebsd/sbin/ifconfig/ifieee80211.c
@@ -86,6 +86,7 @@
#include <net80211/ieee80211_superg.h>
#include <net80211/ieee80211_tdma.h>
#include <net80211/ieee80211_mesh.h>
+#include <net80211/ieee80211_wps.h>
#include <assert.h>
#include <ctype.h>
@@ -1539,9 +1540,6 @@ getmodeflags(const char *val)
return flags;
}
-#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT|IEEE80211_CHAN_5GHZ)
-#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT|IEEE80211_CHAN_2GHZ)
-
#define _APPLY(_flags, _base, _param, _v) do { \
if (_flags & IEEE80211_CHAN_HT) { \
if ((_flags & (IEEE80211_CHAN_5GHZ|IEEE80211_CHAN_2GHZ)) == 0) {\
@@ -1731,8 +1729,6 @@ DECL_CMD_FUNC(set80211maxretry, val, d)
}
#undef _APPLY_RATE
#undef _APPLY
-#undef IEEE80211_CHAN_HTA
-#undef IEEE80211_CHAN_HTG
static
DECL_CMD_FUNC(set80211fragthreshold, val, d)
@@ -3141,13 +3137,6 @@ printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
}
}
-/* XXX move to a public include file */
-#define IEEE80211_WPS_DEV_PASS_ID 0x1012
-#define IEEE80211_WPS_SELECTED_REG 0x1041
-#define IEEE80211_WPS_SETUP_STATE 0x1044
-#define IEEE80211_WPS_UUID_E 0x1047
-#define IEEE80211_WPS_VERSION 0x104a
-
#define BE_READ_2(p) \
((u_int16_t) \
((((const u_int8_t *)(p))[1] ) | \
@@ -3169,6 +3158,7 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
"R" /* Registrar-specified */
};
int n;
+ int f;
ie +=6, len -= 4; /* NB: len is payload only */
@@ -3177,6 +3167,7 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
while (len) {
uint16_t tlv_type = BE_READ_2(ie);
uint16_t tlv_len = BE_READ_2(ie + 2);
+ uint16_t cfg_mthd;
/* some devices broadcast invalid WPS frames */
if (tlv_len > len) {
@@ -3189,30 +3180,191 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
ie += 4, len -= 4;
switch (tlv_type) {
- case IEEE80211_WPS_VERSION:
+ case IEEE80211_WPS_ATTR_VERSION:
printf("v:%d.%d", *ie >> 4, *ie & 0xf);
break;
- case IEEE80211_WPS_SETUP_STATE:
- /* Only 1 and 2 are valid */
- if (*ie == 0 || *ie >= 3)
- printf(" state:B");
+ case IEEE80211_WPS_ATTR_AP_SETUP_LOCKED:
+ printf(" ap_setup:%s", *ie ? "locked" :
+ "unlocked");
+ break;
+ case IEEE80211_WPS_ATTR_CONFIG_METHODS:
+ case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
+ if (tlv_type == IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS)
+ printf(" sel_reg_cfg_mthd:");
else
- printf(" st:%s", *ie == 1 ? "N" : "C");
+ printf(" cfg_mthd:" );
+ cfg_mthd = BE_READ_2(ie);
+ f = 0;
+ for (n = 15; n >= 0; n--) {
+ if (f) {
+ printf(",");
+ f = 0;
+ }
+ switch (cfg_mthd & (1 << n)) {
+ case 0:
+ break;
+ case IEEE80211_WPS_CONFIG_USBA:
+ printf("usba");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_ETHERNET:
+ printf("ethernet");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_LABEL:
+ printf("label");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_DISPLAY:
+ if (!(cfg_mthd &
+ (IEEE80211_WPS_CONFIG_VIRT_DISPLAY |
+ IEEE80211_WPS_CONFIG_PHY_DISPLAY)))
+ {
+ printf("display");
+ f++;
+ }
+ break;
+ case IEEE80211_WPS_CONFIG_EXT_NFC_TOKEN:
+ printf("ext_nfc_tokenk");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_INT_NFC_TOKEN:
+ printf("int_nfc_token");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_NFC_INTERFACE:
+ printf("nfc_interface");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_PUSHBUTTON:
+ if (!(cfg_mthd &
+ (IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON |
+ IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON))) {
+ printf("push_button");
+ f++;
+ }
+ break;
+ case IEEE80211_WPS_CONFIG_KEYPAD:
+ printf("keypad");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON:
+ printf("virtual_push_button");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON:
+ printf("physical_push_button");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_P2PS:
+ printf("p2ps");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_VIRT_DISPLAY:
+ printf("virtual_display");
+ f++;
+ break;
+ case IEEE80211_WPS_CONFIG_PHY_DISPLAY:
+ printf("physical_display");
+ f++;
+ break;
+ default:
+ printf("unknown_wps_config<%04x>",
+ cfg_mthd & (1 << n));
+ f++;
+ break;
+ }
+ }
break;
- case IEEE80211_WPS_SELECTED_REG:
- printf(" sel:%s", *ie ? "T" : "F");
+ case IEEE80211_WPS_ATTR_DEV_NAME:
+ printf(" device_name:<%.*s>", tlv_len, ie);
break;
- case IEEE80211_WPS_DEV_PASS_ID:
+ case IEEE80211_WPS_ATTR_DEV_PASSWORD_ID:
n = LE_READ_2(ie);
if (n < nitems(dev_pass_id))
printf(" dpi:%s", dev_pass_id[n]);
break;
- case IEEE80211_WPS_UUID_E:
+ case IEEE80211_WPS_ATTR_MANUFACTURER:
+ printf(" manufacturer:<%.*s>", tlv_len, ie);
+ break;
+ case IEEE80211_WPS_ATTR_MODEL_NAME:
+ printf(" model_name:<%.*s>", tlv_len, ie);
+ break;
+ case IEEE80211_WPS_ATTR_MODEL_NUMBER:
+ printf(" model_number:<%.*s>", tlv_len, ie);
+ break;
+ case IEEE80211_WPS_ATTR_PRIMARY_DEV_TYPE:
+ printf(" prim_dev:");
+ for (n = 0; n < tlv_len; n++)
+ printf("%02x", ie[n]);
+ break;
+ case IEEE80211_WPS_ATTR_RF_BANDS:
+ printf(" rf:");
+ f = 0;
+ for (n = 7; n >= 0; n--) {
+ if (f) {
+ printf(",");
+ f = 0;
+ }
+ switch (*ie & (1 << n)) {
+ case 0:
+ break;
+ case IEEE80211_WPS_RF_BAND_24GHZ:
+ printf("2.4Ghz");
+ f++;
+ break;
+ case IEEE80211_WPS_RF_BAND_50GHZ:
+ printf("5Ghz");
+ f++;
+ break;
+ case IEEE80211_WPS_RF_BAND_600GHZ:
+ printf("60Ghz");
+ f++;
+ break;
+ default:
+ printf("unknown<%02x>",
+ *ie & (1 << n));
+ f++;
+ break;
+ }
+ }
+ break;
+ case IEEE80211_WPS_ATTR_RESPONSE_TYPE:
+ printf(" resp_type:0x%02x", *ie);
+ break;
+ case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR:
+ printf(" sel:%s", *ie ? "T" : "F");
+ break;
+ case IEEE80211_WPS_ATTR_SERIAL_NUMBER:
+ printf(" serial_number:<%.*s>", tlv_len, ie);
+ break;
+ case IEEE80211_WPS_ATTR_UUID_E:
printf(" uuid-e:");
for (n = 0; n < (tlv_len - 1); n++)
printf("%02x-", ie[n]);
printf("%02x", ie[n]);
break;
+ case IEEE80211_WPS_ATTR_VENDOR_EXT:
+ printf(" vendor:");
+ for (n = 0; n < tlv_len; n++)
+ printf("%02x", ie[n]);
+ break;
+ case IEEE80211_WPS_ATTR_WPS_STATE:
+ switch (*ie) {
+ case IEEE80211_WPS_STATE_NOT_CONFIGURED:
+ printf(" state:N");
+ break;
+ case IEEE80211_WPS_STATE_CONFIGURED:
+ printf(" state:C");
+ break;
+ default:
+ printf(" state:B<%02x>", *ie);
+ break;
+ }
+ break;
+ default:
+ printf(" unknown_wps_attr:0x%x", tlv_type);
+ break;
}
ie += tlv_len, len -= tlv_len;
}
@@ -3365,6 +3517,7 @@ iswpsoui(const uint8_t *frm)
static const char *
iename(int elemid)
{
+ static char iename_buf[64];
switch (elemid) {
case IEEE80211_ELEMID_FHPARMS: return " FHPARMS";
case IEEE80211_ELEMID_CFPARMS: return " CFPARMS";
@@ -3382,10 +3535,21 @@ iename(int elemid)
case IEEE80211_ELEMID_MEASREP: return " MEASREP";
case IEEE80211_ELEMID_QUIET: return " QUIET";
case IEEE80211_ELEMID_IBSSDFS: return " IBSSDFS";
+ case IEEE80211_ELEMID_RESERVED_47:
+ return " RESERVED_47";
+ case IEEE80211_ELEMID_MOBILITY_DOMAIN:
+ return " MOBILITY_DOMAIN";
+ case IEEE80211_ELEMID_RRM_ENACAPS:
+ return " RRM_ENCAPS";
+ case IEEE80211_ELEMID_OVERLAP_BSS_SCAN_PARAM:
+ return " OVERLAP_BSS";
case IEEE80211_ELEMID_TPC: return " TPC";
case IEEE80211_ELEMID_CCKM: return " CCKM";
+ case IEEE80211_ELEMID_EXTCAP: return " EXTCAP";
}
- return " ???";
+ snprintf(iename_buf, sizeof(iename_buf), " UNKNOWN_ELEMID_%d",
+ elemid);
+ return (const char *) iename_buf;
}
static void
@@ -4153,7 +4317,10 @@ list_roam(int s)
rp = &roamparams.params[mode];
if (rp->rssi == 0 && rp->rate == 0)
continue;
- if (mode == IEEE80211_MODE_11NA || mode == IEEE80211_MODE_11NG) {
+ if (mode == IEEE80211_MODE_11NA ||
+ mode == IEEE80211_MODE_11NG ||
+ mode == IEEE80211_MODE_VHT_2GHZ ||
+ mode == IEEE80211_MODE_VHT_5GHZ) {
if (rp->rssi & 1)
LINE_CHECK("roam:%-7.7s rssi %2u.5dBm MCS %2u ",
modename[mode], rp->rssi/2,
@@ -4173,6 +4340,21 @@ list_roam(int s)
}
}
+/* XXX TODO: rate-to-string method... */
+static const char*
+get_mcs_mbs_rate_str(uint8_t rate)
+{
+ return (rate & IEEE80211_RATE_MCS) ? "MCS " : "Mb/s";
+}
+
+static uint8_t
+get_rate_value(uint8_t rate)
+{
+ if (rate & IEEE80211_RATE_MCS)
+ return (rate &~ IEEE80211_RATE_MCS);
+ return (rate / 2);
+}
+
static void
list_txparams(int s)
{
@@ -4184,21 +4366,28 @@ list_txparams(int s)
tp = &txparams.params[mode];
if (tp->mgmtrate == 0 && tp->mcastrate == 0)
continue;
- if (mode == IEEE80211_MODE_11NA || mode == IEEE80211_MODE_11NG) {
+ if (mode == IEEE80211_MODE_11NA ||
+ mode == IEEE80211_MODE_11NG ||
+ mode == IEEE80211_MODE_VHT_2GHZ ||
+ mode == IEEE80211_MODE_VHT_5GHZ) {
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- LINE_CHECK("%-7.7s ucast NONE mgmt %2u MCS "
- "mcast %2u MCS maxretry %u",
+ LINE_CHECK("%-7.7s ucast NONE mgmt %2u %s "
+ "mcast %2u %s maxretry %u",
modename[mode],
- tp->mgmtrate &~ IEEE80211_RATE_MCS,
- tp->mcastrate &~ IEEE80211_RATE_MCS,
+ get_rate_value(tp->mgmtrate),
+ get_mcs_mbs_rate_str(tp->mgmtrate),
+ get_rate_value(tp->mcastrate),
+ get_mcs_mbs_rate_str(tp->mcastrate),
tp->maxretry);
else
- LINE_CHECK("%-7.7s ucast %2u MCS mgmt %2u MCS "
- "mcast %2u MCS maxretry %u",
+ LINE_CHECK("%-7.7s ucast %2u MCS mgmt %2u %s "
+ "mcast %2u %s maxretry %u",
modename[mode],
tp->ucastrate &~ IEEE80211_RATE_MCS,
- tp->mgmtrate &~ IEEE80211_RATE_MCS,
- tp->mcastrate &~ IEEE80211_RATE_MCS,
+ get_rate_value(tp->mgmtrate),
+ get_mcs_mbs_rate_str(tp->mgmtrate),
+ get_rate_value(tp->mcastrate),
+ get_mcs_mbs_rate_str(tp->mcastrate),
tp->maxretry);
} else {
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
@@ -4907,7 +5096,9 @@ end:
LINE_CHECK("roam:rssi %u.5", rp->rssi/2);
else
LINE_CHECK("roam:rssi %u", rp->rssi/2);
- LINE_CHECK("roam:rate %u", rp->rate/2);
+ LINE_CHECK("roam:rate %s%u",
+ (rp->rate & IEEE80211_RATE_MCS) ? "MCS " : "",
+ get_rate_value(rp->rate));
} else {
LINE_BREAK();
list_roam(s);
diff --git a/freebsd/sbin/ifconfig/iflagg.c b/freebsd/sbin/ifconfig/iflagg.c
index 4952196a..14a7a7bf 100644
--- a/freebsd/sbin/ifconfig/iflagg.c
+++ b/freebsd/sbin/ifconfig/iflagg.c
@@ -142,6 +142,8 @@ setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
switch (ro.ro_opts) {
case LAGG_OPT_USE_FLOWID:
case -LAGG_OPT_USE_FLOWID:
+ case LAGG_OPT_USE_NUMA:
+ case -LAGG_OPT_USE_NUMA:
case LAGG_OPT_LACP_STRICT:
case -LAGG_OPT_LACP_STRICT:
case LAGG_OPT_LACP_TXTEST:
@@ -315,6 +317,8 @@ static struct cmd lagg_cmds[] = {
DEF_CMD_ARG("lagghash", setlagghash),
DEF_CMD("use_flowid", LAGG_OPT_USE_FLOWID, setlaggsetopt),
DEF_CMD("-use_flowid", -LAGG_OPT_USE_FLOWID, setlaggsetopt),
+ DEF_CMD("use_numa", LAGG_OPT_USE_NUMA, setlaggsetopt),
+ DEF_CMD("-use_numa", -LAGG_OPT_USE_NUMA, setlaggsetopt),
DEF_CMD("lacp_strict", LAGG_OPT_LACP_STRICT, setlaggsetopt),
DEF_CMD("-lacp_strict", -LAGG_OPT_LACP_STRICT, setlaggsetopt),
DEF_CMD("lacp_txtest", LAGG_OPT_LACP_TXTEST, setlaggsetopt),
diff --git a/freebsd/sbin/ifconfig/ifmedia.c b/freebsd/sbin/ifconfig/ifmedia.c
index ac2af8b6..02893547 100644
--- a/freebsd/sbin/ifconfig/ifmedia.c
+++ b/freebsd/sbin/ifconfig/ifmedia.c
@@ -89,6 +89,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -137,18 +138,20 @@ static void
media_status(int s)
{
struct ifmediareq ifmr;
+ struct ifdownreason ifdr;
int *media_list, i;
- int xmedia = 1;
+ bool no_carrier, xmedia;
(void) memset(&ifmr, 0, sizeof(ifmr));
(void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+ xmedia = true;
/*
* Check if interface supports extended media types.
*/
if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
- xmedia = 0;
- if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+ xmedia = false;
+ if (!xmedia && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
@@ -185,6 +188,7 @@ media_status(int s)
putchar('\n');
if (ifmr.ifm_status & IFM_AVALID) {
+ no_carrier = false;
printf("\tstatus: ");
switch (IFM_TYPE(ifmr.ifm_active)) {
case IFM_ETHER:
@@ -192,7 +196,7 @@ media_status(int s)
if (ifmr.ifm_status & IFM_ACTIVE)
printf("active");
else
- printf("no carrier");
+ no_carrier = true;
break;
case IFM_IEEE80211:
@@ -203,9 +207,27 @@ media_status(int s)
else
printf("running");
} else
- printf("no carrier");
+ no_carrier = true;
break;
}
+ if (no_carrier) {
+ printf("no carrier");
+ memset(&ifdr, 0, sizeof(ifdr));
+ strlcpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
+ if (ioctl(s, SIOCGIFDOWNREASON, (caddr_t)&ifdr) == 0) {
+ switch (ifdr.ifdr_reason) {
+ case IFDR_REASON_MSG:
+ printf(" (%s)", ifdr.ifdr_msg);
+ break;
+ case IFDR_REASON_VENDOR:
+ printf(" (vendor code %d)",
+ ifdr.ifdr_vendor);
+ break;
+ default:
+ break;
+ }
+ }
+ }
putchar('\n');
}
diff --git a/freebsd/sbin/ifconfig/ifpfsync.c b/freebsd/sbin/ifconfig/ifpfsync.c
index c2c91687..944a1b26 100644
--- a/freebsd/sbin/ifconfig/ifpfsync.c
+++ b/freebsd/sbin/ifconfig/ifpfsync.c
@@ -207,16 +207,16 @@ pfsync_status(int s)
return;
if (preq.pfsyncr_syncdev[0] != '\0' ||
- preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
+ preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP))
printf("\t");
if (preq.pfsyncr_syncdev[0] != '\0')
printf("pfsync: syncdev: %s ", preq.pfsyncr_syncdev);
- if (preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
+ if (preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP))
printf("syncpeer: %s ", inet_ntoa(preq.pfsyncr_syncpeer));
if (preq.pfsyncr_syncdev[0] != '\0' ||
- preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP) {
+ preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP)) {
printf("maxupd: %d ", preq.pfsyncr_maxupdates);
printf("defer: %s\n", preq.pfsyncr_defer ? "on" : "off");
}
diff --git a/freebsd/sbin/ifconfig/sfp.c b/freebsd/sbin/ifconfig/sfp.c
index 0aa3300d..6444736f 100644
--- a/freebsd/sbin/ifconfig/sfp.c
+++ b/freebsd/sbin/ifconfig/sfp.c
@@ -88,7 +88,7 @@ struct _nv {
const char *find_value(struct _nv *x, int value);
const char *find_zero_bit(struct _nv *x, int value, int sz);
-/* SFF-8024 Rev. 4.1 Table 4-3: Connector Types */
+/* SFF-8024 Rev. 4.6 Table 4-3: Connector Types */
static struct _nv conn[] = {
{ 0x00, "Unknown" },
{ 0x01, "SC" },
@@ -96,18 +96,23 @@ static struct _nv conn[] = {
{ 0x03, "Fibre Channel Style 2 copper" },
{ 0x04, "BNC/TNC" },
{ 0x05, "Fibre Channel coaxial" },
- { 0x06, "FiberJack" },
+ { 0x06, "Fiber Jack" },
{ 0x07, "LC" },
{ 0x08, "MT-RJ" },
{ 0x09, "MU" },
{ 0x0A, "SG" },
{ 0x0B, "Optical pigtail" },
- { 0x0C, "MPO Parallel Optic" },
+ { 0x0C, "MPO 1x12 Parallel Optic" },
+ { 0x0D, "MPO 2x16 Parallel Optic" },
{ 0x20, "HSSDC II" },
{ 0x21, "Copper pigtail" },
{ 0x22, "RJ45" },
{ 0x23, "No separable connector" },
{ 0x24, "MXC 2x16" },
+ { 0x25, "CS optical connector" },
+ { 0x26, "Mini CS optical connector" },
+ { 0x27, "MPO 2x12 Parallel Optic" },
+ { 0x28, "MPO 1x16 Parallel Optic" },
{ 0, NULL }
};
@@ -203,9 +208,61 @@ static struct _nv eth_1040g[] = {
};
#define SFF_8636_EXT_COMPLIANCE 0x80
-/* SFF-8024 Rev. 4.2 table 4-4: Extended Specification Compliance */
+/* SFF-8024 Rev. 4.6 table 4-4: Extended Specification Compliance */
static struct _nv eth_extended_comp[] = {
{ 0xFF, "Reserved" },
+ { 0x55, "128GFC LW" },
+ { 0x54, "128GFC SW" },
+ { 0x53, "128GFC EA" },
+ { 0x52, "64GFC LW" },
+ { 0x51, "64GFC SW" },
+ { 0x50, "64GFC EA" },
+ { 0x4F, "Reserved" },
+ { 0x4E, "Reserved" },
+ { 0x4D, "Reserved" },
+ { 0x4C, "Reserved" },
+ { 0x4B, "Reserved" },
+ { 0x4A, "Reserved" },
+ { 0x49, "Reserved" },
+ { 0x48, "Reserved" },
+ { 0x47, "Reserved" },
+ { 0x46, "200GBASE-LR4" },
+ { 0x45, "50GBASE-LR" },
+ { 0x44, "200G 1550nm PSM4" },
+ { 0x43, "200GBASE-FR4" },
+ { 0x42, "50GBASE-FR or 200GBASE-DR4" },
+ { 0x41, "50GBASE-SR/100GBASE-SR2/200GBASE-SR4" },
+ { 0x40, "50GBASE-CR/100GBASE-CR2/200GBASE-CR4" },
+ { 0x3F, "Reserved" },
+ { 0x3E, "Reserved" },
+ { 0x3D, "Reserved" },
+ { 0x3C, "Reserved" },
+ { 0x3B, "Reserved" },
+ { 0x3A, "Reserved" },
+ { 0x39, "Reserved" },
+ { 0x38, "Reserved" },
+ { 0x37, "Reserved" },
+ { 0x36, "Reserved" },
+ { 0x35, "Reserved" },
+ { 0x34, "Reserved" },
+ { 0x33, "50GAUI/100GAUI-2/200GAUI-4 AOC (BER <2.6e-4)" },
+ { 0x32, "50GAUI/100GAUI-2/200GAUI-4 ACC (BER <2.6e-4)" },
+ { 0x31, "50GAUI/100GAUI-2/200GAUI-4 AOC (BER <1e-6)" },
+ { 0x30, "50GAUI/100GAUI-2/200GAUI-4 ACC (BER <1e-6)" },
+ { 0x2F, "Reserved" },
+ { 0x2E, "Reserved" },
+ { 0x2D, "Reserved" },
+ { 0x2C, "Reserved" },
+ { 0x2B, "Reserved" },
+ { 0x2A, "Reserved" },
+ { 0x29, "Reserved" },
+ { 0x28, "Reserved" },
+ { 0x27, "100G-LR" },
+ { 0x26, "100G-FR" },
+ { 0x25, "100GBASE-DR" },
+ { 0x24, "4WDM-40 MSA" },
+ { 0x23, "4WDM-20 MSA" },
+ { 0x22, "4WDM-10 MSA" },
{ 0x21, "100G PAM4 BiDi" },
{ 0x20, "100G SWDM4" },
{ 0x1F, "40G SWDM4" },
@@ -226,8 +283,8 @@ static struct _nv eth_extended_comp[] = {
{ 0x10, "40GBASE-ER4" },
{ 0x0F, "Reserved" },
{ 0x0E, "Reserved" },
- { 0x0D, "25GBASE-CR CA-N" },
- { 0x0C, "25GBASE-CR CA-S" },
+ { 0x0D, "25GBASE-CR CA-25G-N" },
+ { 0x0C, "25GBASE-CR CA-25G-S" },
{ 0x0B, "100GBASE-CR4 or 25GBASE-CR CA-L" },
{ 0x0A, "Reserved" },
{ 0x09, "Obsolete" },
diff --git a/freebsd/sbin/pfctl/parse.c b/freebsd/sbin/pfctl/parse.c
index 83002a82..9cd303fb 100644
--- a/freebsd/sbin/pfctl/parse.c
+++ b/freebsd/sbin/pfctl/parse.c
@@ -157,6 +157,7 @@ __FBSDID("$FreeBSD$");
#include "pfctl_parser.h"
#include "pfctl.h"
#ifdef __rtems__
+#include <sys/limits.h>
#include "rtems-bsd-pfctl-parse-data.h"
#endif /* __rtems__ */
diff --git a/freebsd/sbin/pfctl/parse.y b/freebsd/sbin/pfctl/parse.y
index 8b6808a6..856f7b2a 100644
--- a/freebsd/sbin/pfctl/parse.y
+++ b/freebsd/sbin/pfctl/parse.y
@@ -4764,6 +4764,8 @@ process_tabledef(char *name, struct table_opts *opts)
{
struct pfr_buffer ab;
struct node_tinit *ti;
+ unsigned long maxcount;
+ size_t s = sizeof(maxcount);
bzero(&ab, sizeof(ab));
ab.pfrb_type = PFRB_ADDRS;
@@ -4791,8 +4793,19 @@ process_tabledef(char *name, struct table_opts *opts)
if (!(pf->opts & PF_OPT_NOACTION) &&
pfctl_define_table(name, opts->flags, opts->init_addr,
pf->anchor->name, &ab, pf->anchor->ruleset.tticket)) {
- yyerror("cannot define table %s: %s", name,
- pfr_strerror(errno));
+
+ if (sysctlbyname("net.pf.request_maxcount", &maxcount, &s,
+ NULL, 0) == -1)
+ maxcount = 65535;
+
+ if (ab.pfrb_size > maxcount)
+ yyerror("cannot define table %s: too many elements.\n"
+ "Consider increasing net.pf.request_maxcount.",
+ name);
+ else
+ yyerror("cannot define table %s: %s", name,
+ pfr_strerror(errno));
+
goto _error;
}
pf->tdirty = 1;
diff --git a/freebsd/sbin/pfctl/pfctl.c b/freebsd/sbin/pfctl/pfctl.c
index 6b57dd00..274ea26f 100644
--- a/freebsd/sbin/pfctl/pfctl.c
+++ b/freebsd/sbin/pfctl/pfctl.c
@@ -2005,6 +2005,7 @@ int
pfctl_set_interface_flags(struct pfctl *pf, char *ifname, int flags, int how)
{
struct pfioc_iface pi;
+ struct node_host *h = NULL, *n = NULL;
if ((loadopt & PFCTL_FLAG_OPTION) == 0)
return (0);
@@ -2013,6 +2014,12 @@ pfctl_set_interface_flags(struct pfctl *pf, char *ifname, int flags, int how)
pi.pfiio_flags = flags;
+ /* Make sure our cache matches the kernel. If we set or clear the flag
+ * for a group this applies to all members. */
+ h = ifa_grouplookup(ifname, 0);
+ for (n = h; n != NULL; n = n->next)
+ pfctl_set_interface_flags(pf, n->ifname, flags, how);
+
if (strlcpy(pi.pfiio_name, ifname, sizeof(pi.pfiio_name)) >=
sizeof(pi.pfiio_name))
errx(1, "pfctl_set_interface_flags: strlcpy");
diff --git a/freebsd/sbin/pfctl/pfctl.h b/freebsd/sbin/pfctl/pfctl.h
index a432f109..f43b71e1 100644
--- a/freebsd/sbin/pfctl/pfctl.h
+++ b/freebsd/sbin/pfctl/pfctl.h
@@ -114,7 +114,6 @@ extern int loadopt;
int check_commit_altq(int, int);
void pfaltq_store(struct pf_altq *);
-struct pf_altq *pfaltq_lookup(const char *);
char *rate2str(double);
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
diff --git a/freebsd/sbin/pfctl/pfctl_altq.c b/freebsd/sbin/pfctl/pfctl_altq.c
index 1220cfc6..7cf72b43 100644
--- a/freebsd/sbin/pfctl/pfctl_altq.c
+++ b/freebsd/sbin/pfctl/pfctl_altq.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#define PFIOC_USE_LATEST
#include <sys/types.h>
+#include <sys/bitset.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
@@ -45,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <inttypes.h>
#include <limits.h>
#include <math.h>
+#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -65,38 +67,44 @@ __FBSDID("$FreeBSD$");
#define is_sc_null(sc) (((sc) == NULL) || ((sc)->m1 == 0 && (sc)->m2 == 0))
-static TAILQ_HEAD(altqs, pf_altq) altqs = TAILQ_HEAD_INITIALIZER(altqs);
-static LIST_HEAD(gen_sc, segment) rtsc, lssc;
+static STAILQ_HEAD(interfaces, pfctl_altq) interfaces = STAILQ_HEAD_INITIALIZER(interfaces);
+static struct hsearch_data queue_map;
+static struct hsearch_data if_map;
+static struct hsearch_data qid_map;
-struct pf_altq *qname_to_pfaltq(const char *, const char *);
-u_int32_t qname_to_qid(const char *);
+static struct pfctl_altq *pfaltq_lookup(char *ifname);
+static struct pfctl_altq *qname_to_pfaltq(const char *, const char *);
+static u_int32_t qname_to_qid(char *);
-static int eval_pfqueue_cbq(struct pfctl *, struct pf_altq *);
+static int eval_pfqueue_cbq(struct pfctl *, struct pf_altq *,
+ struct pfctl_altq *);
static int cbq_compute_idletime(struct pfctl *, struct pf_altq *);
-static int check_commit_cbq(int, int, struct pf_altq *);
+static int check_commit_cbq(int, int, struct pfctl_altq *);
static int print_cbq_opts(const struct pf_altq *);
static int print_codel_opts(const struct pf_altq *,
const struct node_queue_opt *);
-static int eval_pfqueue_priq(struct pfctl *, struct pf_altq *);
-static int check_commit_priq(int, int, struct pf_altq *);
+static int eval_pfqueue_priq(struct pfctl *, struct pf_altq *,
+ struct pfctl_altq *);
+static int check_commit_priq(int, int, struct pfctl_altq *);
static int print_priq_opts(const struct pf_altq *);
-static int eval_pfqueue_hfsc(struct pfctl *, struct pf_altq *);
-static int check_commit_hfsc(int, int, struct pf_altq *);
+static int eval_pfqueue_hfsc(struct pfctl *, struct pf_altq *,
+ struct pfctl_altq *, struct pfctl_altq *);
+static int check_commit_hfsc(int, int, struct pfctl_altq *);
static int print_hfsc_opts(const struct pf_altq *,
const struct node_queue_opt *);
-static int eval_pfqueue_fairq(struct pfctl *, struct pf_altq *);
+static int eval_pfqueue_fairq(struct pfctl *, struct pf_altq *,
+ struct pfctl_altq *, struct pfctl_altq *);
static int print_fairq_opts(const struct pf_altq *,
const struct node_queue_opt *);
-static int check_commit_fairq(int, int, struct pf_altq *);
+static int check_commit_fairq(int, int, struct pfctl_altq *);
static void gsc_add_sc(struct gen_sc *, struct service_curve *);
static int is_gsc_under_sc(struct gen_sc *,
struct service_curve *);
-static void gsc_destroy(struct gen_sc *);
static struct segment *gsc_getentry(struct gen_sc *, double);
static int gsc_add_seg(struct gen_sc *, double, double, double,
double);
@@ -116,59 +124,101 @@ void print_hfsc_sc(const char *, u_int, u_int, u_int,
void print_fairq_sc(const char *, u_int, u_int, u_int,
const struct node_fairq_sc *);
+static __attribute__((constructor)) void
+pfctl_altq_init(void)
+{
+ /*
+ * As hdestroy() will never be called on these tables, it will be
+ * safe to use references into the stored data as keys.
+ */
+ if (hcreate_r(0, &queue_map) == 0)
+ err(1, "Failed to create altq queue map");
+ if (hcreate_r(0, &if_map) == 0)
+ err(1, "Failed to create altq interface map");
+ if (hcreate_r(0, &qid_map) == 0)
+ err(1, "Failed to create altq queue id map");
+}
+
void
pfaltq_store(struct pf_altq *a)
{
- struct pf_altq *altq;
-
+ struct pfctl_altq *altq;
+ ENTRY item;
+ ENTRY *ret_item;
+ size_t key_size;
+
if ((altq = malloc(sizeof(*altq))) == NULL)
- err(1, "malloc");
- memcpy(altq, a, sizeof(struct pf_altq));
- TAILQ_INSERT_TAIL(&altqs, altq, entries);
+ err(1, "queue malloc");
+ memcpy(&altq->pa, a, sizeof(struct pf_altq));
+ memset(&altq->meta, 0, sizeof(altq->meta));
+
+ if (a->qname[0] == 0) {
+ item.key = altq->pa.ifname;
+ item.data = altq;
+ if (hsearch_r(item, ENTER, &ret_item, &if_map) == 0)
+ err(1, "interface map insert");
+ STAILQ_INSERT_TAIL(&interfaces, altq, meta.link);
+ } else {
+ key_size = sizeof(a->ifname) + sizeof(a->qname);
+ if ((item.key = malloc(key_size)) == NULL)
+ err(1, "queue map key malloc");
+ snprintf(item.key, key_size, "%s:%s", a->ifname, a->qname);
+ item.data = altq;
+ if (hsearch_r(item, ENTER, &ret_item, &queue_map) == 0)
+ err(1, "queue map insert");
+
+ item.key = altq->pa.qname;
+ item.data = &altq->pa.qid;
+ if (hsearch_r(item, ENTER, &ret_item, &qid_map) == 0)
+ err(1, "qid map insert");
+ }
}
-struct pf_altq *
-pfaltq_lookup(const char *ifname)
+static struct pfctl_altq *
+pfaltq_lookup(char *ifname)
{
- struct pf_altq *altq;
+ ENTRY item;
+ ENTRY *ret_item;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 &&
- altq->qname[0] == 0)
- return (altq);
- }
- return (NULL);
+ item.key = ifname;
+ if (hsearch_r(item, FIND, &ret_item, &if_map) == 0)
+ return (NULL);
+
+ return (ret_item->data);
}
-struct pf_altq *
+static struct pfctl_altq *
qname_to_pfaltq(const char *qname, const char *ifname)
{
- struct pf_altq *altq;
+ ENTRY item;
+ ENTRY *ret_item;
+ char key[IFNAMSIZ + PF_QNAME_SIZE];
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 &&
- strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0)
- return (altq);
- }
- return (NULL);
+ item.key = key;
+ snprintf(item.key, sizeof(key), "%s:%s", ifname, qname);
+ if (hsearch_r(item, FIND, &ret_item, &queue_map) == 0)
+ return (NULL);
+
+ return (ret_item->data);
}
-u_int32_t
-qname_to_qid(const char *qname)
+static u_int32_t
+qname_to_qid(char *qname)
{
- struct pf_altq *altq;
-
+ ENTRY item;
+ ENTRY *ret_item;
+ uint32_t qid;
+
/*
* We guarantee that same named queues on different interfaces
- * have the same qid, so we do NOT need to limit matching on
- * one interface!
+ * have the same qid.
*/
+ item.key = qname;
+ if (hsearch_r(item, FIND, &ret_item, &qid_map) == 0)
+ return (0);
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0)
- return (altq->qid);
- }
- return (0);
+ qid = *(uint32_t *)ret_item->data;
+ return (qid);
}
void
@@ -327,28 +377,26 @@ eval_pfaltq(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
int
check_commit_altq(int dev, int opts)
{
- struct pf_altq *altq;
- int error = 0;
+ struct pfctl_altq *if_ppa;
+ int error = 0;
/* call the discipline check for each interface. */
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (altq->qname[0] == 0) {
- switch (altq->scheduler) {
- case ALTQT_CBQ:
- error = check_commit_cbq(dev, opts, altq);
- break;
- case ALTQT_PRIQ:
- error = check_commit_priq(dev, opts, altq);
- break;
- case ALTQT_HFSC:
- error = check_commit_hfsc(dev, opts, altq);
- break;
- case ALTQT_FAIRQ:
- error = check_commit_fairq(dev, opts, altq);
- break;
- default:
- break;
- }
+ STAILQ_FOREACH(if_ppa, &interfaces, meta.link) {
+ switch (if_ppa->pa.scheduler) {
+ case ALTQT_CBQ:
+ error = check_commit_cbq(dev, opts, if_ppa);
+ break;
+ case ALTQT_PRIQ:
+ error = check_commit_priq(dev, opts, if_ppa);
+ break;
+ case ALTQT_HFSC:
+ error = check_commit_hfsc(dev, opts, if_ppa);
+ break;
+ case ALTQT_FAIRQ:
+ error = check_commit_fairq(dev, opts, if_ppa);
+ break;
+ default:
+ break;
}
}
return (error);
@@ -362,17 +410,16 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
struct node_queue_opt *opts)
{
/* should be merged with expand_queue */
- struct pf_altq *if_pa, *parent, *altq;
- u_int64_t bwsum;
- int error = 0;
+ struct pfctl_altq *if_ppa, *parent;
+ int error = 0;
/* find the corresponding interface and copy fields used by queues */
- if ((if_pa = pfaltq_lookup(pa->ifname)) == NULL) {
+ if ((if_ppa = pfaltq_lookup(pa->ifname)) == NULL) {
fprintf(stderr, "altq not defined on %s\n", pa->ifname);
return (1);
}
- pa->scheduler = if_pa->scheduler;
- pa->ifbandwidth = if_pa->ifbandwidth;
+ pa->scheduler = if_ppa->pa.scheduler;
+ pa->ifbandwidth = if_ppa->pa.ifbandwidth;
if (qname_to_pfaltq(pa->qname, pa->ifname) != NULL) {
fprintf(stderr, "queue %s already exists on interface %s\n",
@@ -389,7 +436,7 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
pa->parent, pa->qname);
return (1);
}
- pa->parent_qid = parent->qid;
+ pa->parent_qid = parent->pa.qid;
}
if (pa->qlimit == 0)
pa->qlimit = DEFAULT_QLIMIT;
@@ -397,53 +444,56 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
if (pa->scheduler == ALTQT_CBQ || pa->scheduler == ALTQT_HFSC ||
pa->scheduler == ALTQT_FAIRQ) {
pa->bandwidth = eval_bwspec(bw,
- parent == NULL ? pa->ifbandwidth : parent->bandwidth);
+ parent == NULL ? pa->ifbandwidth : parent->pa.bandwidth);
if (pa->bandwidth > pa->ifbandwidth) {
fprintf(stderr, "bandwidth for %s higher than "
"interface\n", pa->qname);
return (1);
}
- /* check the sum of the child bandwidth is under parent's */
- if (parent != NULL) {
- if (pa->bandwidth > parent->bandwidth) {
+ /*
+ * If not HFSC, then check that the sum of the child
+ * bandwidths is less than the parent's bandwidth. For
+ * HFSC, the equivalent concept is to check that the sum of
+ * the child linkshare service curves are under the parent's
+ * linkshare service curve, and that check is performed by
+ * eval_pfqueue_hfsc().
+ */
+ if ((parent != NULL) && (pa->scheduler != ALTQT_HFSC)) {
+ if (pa->bandwidth > parent->pa.bandwidth) {
warnx("bandwidth for %s higher than parent",
pa->qname);
return (1);
}
- bwsum = 0;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname,
- IFNAMSIZ) == 0 &&
- altq->qname[0] != 0 &&
- strncmp(altq->parent, pa->parent,
- PF_QNAME_SIZE) == 0)
- bwsum += altq->bandwidth;
- }
- bwsum += pa->bandwidth;
- if (bwsum > parent->bandwidth) {
- warnx("the sum of the child bandwidth higher"
- " than parent \"%s\"", parent->qname);
+ parent->meta.bwsum += pa->bandwidth;
+ if (parent->meta.bwsum > parent->pa.bandwidth) {
+ warnx("the sum of the child bandwidth (%" PRIu64
+ ") higher than parent \"%s\" (%" PRIu64 ")",
+ parent->meta.bwsum, parent->pa.qname,
+ parent->pa.bandwidth);
}
}
}
if (eval_queue_opts(pa, opts,
- parent == NULL ? pa->ifbandwidth : parent->bandwidth))
+ parent == NULL ? pa->ifbandwidth : parent->pa.bandwidth))
return (1);
+ if (parent != NULL)
+ parent->meta.children++;
+
switch (pa->scheduler) {
case ALTQT_CBQ:
- error = eval_pfqueue_cbq(pf, pa);
+ error = eval_pfqueue_cbq(pf, pa, if_ppa);
break;
case ALTQT_PRIQ:
- error = eval_pfqueue_priq(pf, pa);
+ error = eval_pfqueue_priq(pf, pa, if_ppa);
break;
case ALTQT_HFSC:
- error = eval_pfqueue_hfsc(pf, pa);
+ error = eval_pfqueue_hfsc(pf, pa, if_ppa, parent);
break;
case ALTQT_FAIRQ:
- error = eval_pfqueue_fairq(pf, pa);
+ error = eval_pfqueue_fairq(pf, pa, if_ppa, parent);
break;
default:
break;
@@ -458,7 +508,7 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
#define RM_NS_PER_SEC (1000000000)
static int
-eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa)
+eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa)
{
struct cbq_opts *opts;
u_int ifmtu;
@@ -488,6 +538,11 @@ eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa)
if (pa->parent[0] == 0)
opts->flags |= (CBQCLF_ROOTCLASS | CBQCLF_WRR);
+ if (pa->pq_u.cbq_opts.flags & CBQCLF_ROOTCLASS)
+ if_ppa->meta.root_classes++;
+ if (pa->pq_u.cbq_opts.flags & CBQCLF_DEFCLASS)
+ if_ppa->meta.default_classes++;
+
cbq_compute_idletime(pf, pa);
return (0);
}
@@ -580,33 +635,20 @@ cbq_compute_idletime(struct pfctl *pf, struct pf_altq *pa)
}
static int
-check_commit_cbq(int dev, int opts, struct pf_altq *pa)
+check_commit_cbq(int dev, int opts, struct pfctl_altq *if_ppa)
{
- struct pf_altq *altq;
- int root_class, default_class;
- int error = 0;
+ int error = 0;
/*
* check if cbq has one root queue and one default queue
* for this interface
*/
- root_class = default_class = 0;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (altq->pq_u.cbq_opts.flags & CBQCLF_ROOTCLASS)
- root_class++;
- if (altq->pq_u.cbq_opts.flags & CBQCLF_DEFCLASS)
- default_class++;
- }
- if (root_class != 1) {
- warnx("should have one root queue on %s", pa->ifname);
+ if (if_ppa->meta.root_classes != 1) {
+ warnx("should have one root queue on %s", if_ppa->pa.ifname);
error++;
}
- if (default_class != 1) {
- warnx("should have one default queue on %s", pa->ifname);
+ if (if_ppa->meta.default_classes != 1) {
+ warnx("should have one default queue on %s", if_ppa->pa.ifname);
error++;
}
return (error);
@@ -653,51 +695,37 @@ print_cbq_opts(const struct pf_altq *a)
* PRIQ support functions
*/
static int
-eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa)
+eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa)
{
- struct pf_altq *altq;
if (pa->priority >= PRIQ_MAXPRI) {
warnx("priority out of range: max %d", PRIQ_MAXPRI - 1);
return (-1);
}
- /* the priority should be unique for the interface */
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) == 0 &&
- altq->qname[0] != 0 && altq->priority == pa->priority) {
- warnx("%s and %s have the same priority",
- altq->qname, pa->qname);
- return (-1);
- }
- }
+ if (BIT_ISSET(QPRI_BITSET_SIZE, pa->priority, &if_ppa->meta.qpris)) {
+ warnx("%s does not have a unique priority on interface %s",
+ pa->qname, pa->ifname);
+ return (-1);
+ } else
+ BIT_SET(QPRI_BITSET_SIZE, pa->priority, &if_ppa->meta.qpris);
+ if (pa->pq_u.priq_opts.flags & PRCF_DEFAULTCLASS)
+ if_ppa->meta.default_classes++;
return (0);
}
static int
-check_commit_priq(int dev, int opts, struct pf_altq *pa)
+check_commit_priq(int dev, int opts, struct pfctl_altq *if_ppa)
{
- struct pf_altq *altq;
- int default_class;
- int error = 0;
/*
* check if priq has one default class for this interface
*/
- default_class = 0;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (altq->pq_u.priq_opts.flags & PRCF_DEFAULTCLASS)
- default_class++;
- }
- if (default_class != 1) {
- warnx("should have one default queue on %s", pa->ifname);
- error++;
+ if (if_ppa->meta.default_classes != 1) {
+ warnx("should have one default queue on %s", if_ppa->pa.ifname);
+ return (1);
}
- return (error);
+ return (0);
}
static int
@@ -732,15 +760,15 @@ print_priq_opts(const struct pf_altq *a)
* HFSC support functions
*/
static int
-eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
+eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa,
+ struct pfctl_altq *parent)
{
- struct pf_altq *altq, *parent;
struct hfsc_opts_v1 *opts;
struct service_curve sc;
opts = &pa->pq_u.hfsc_opts;
- if (pa->parent[0] == 0) {
+ if (parent == NULL) {
/* root queue */
opts->lssc_m1 = pa->ifbandwidth;
opts->lssc_m2 = pa->ifbandwidth;
@@ -748,9 +776,21 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
return (0);
}
- LIST_INIT(&rtsc);
- LIST_INIT(&lssc);
+ /* First child initializes the parent's service curve accumulators. */
+ if (parent->meta.children == 1) {
+ LIST_INIT(&parent->meta.rtsc);
+ LIST_INIT(&parent->meta.lssc);
+ }
+ if (parent->pa.pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS) {
+ warnx("adding %s would make default queue %s not a leaf",
+ pa->qname, pa->parent);
+ return (-1);
+ }
+
+ if (pa->pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS)
+ if_ppa->meta.default_classes++;
+
/* if link_share is not specified, use bandwidth */
if (opts->lssc_m2 == 0)
opts->lssc_m2 = pa->bandwidth;
@@ -780,51 +820,22 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
* be smaller than the interface bandwidth, and the upper-limit should
* be larger than the real-time service curve when both are defined.
*/
- parent = qname_to_pfaltq(pa->parent, pa->ifname);
- if (parent == NULL)
- errx(1, "parent %s not found for %s", pa->parent, pa->qname);
-
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
-
- /* if the class has a real-time service curve, add it. */
- if (opts->rtsc_m2 != 0 && altq->pq_u.hfsc_opts.rtsc_m2 != 0) {
- sc.m1 = altq->pq_u.hfsc_opts.rtsc_m1;
- sc.d = altq->pq_u.hfsc_opts.rtsc_d;
- sc.m2 = altq->pq_u.hfsc_opts.rtsc_m2;
- gsc_add_sc(&rtsc, &sc);
- }
-
- if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0)
- continue;
-
- /* if the class has a linkshare service curve, add it. */
- if (opts->lssc_m2 != 0 && altq->pq_u.hfsc_opts.lssc_m2 != 0) {
- sc.m1 = altq->pq_u.hfsc_opts.lssc_m1;
- sc.d = altq->pq_u.hfsc_opts.lssc_d;
- sc.m2 = altq->pq_u.hfsc_opts.lssc_m2;
- gsc_add_sc(&lssc, &sc);
- }
- }
-
+
/* check the real-time service curve. reserve 20% of interface bw */
if (opts->rtsc_m2 != 0) {
/* add this queue to the sum */
sc.m1 = opts->rtsc_m1;
sc.d = opts->rtsc_d;
sc.m2 = opts->rtsc_m2;
- gsc_add_sc(&rtsc, &sc);
+ gsc_add_sc(&parent->meta.rtsc, &sc);
/* compare the sum with 80% of the interface */
sc.m1 = 0;
sc.d = 0;
sc.m2 = pa->ifbandwidth / 100 * 80;
- if (!is_gsc_under_sc(&rtsc, &sc)) {
+ if (!is_gsc_under_sc(&parent->meta.rtsc, &sc)) {
warnx("real-time sc exceeds 80%% of the interface "
"bandwidth (%s)", rate2str((double)sc.m2));
- goto err_ret;
+ return (-1);
}
}
@@ -834,14 +845,14 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
sc.m1 = opts->lssc_m1;
sc.d = opts->lssc_d;
sc.m2 = opts->lssc_m2;
- gsc_add_sc(&lssc, &sc);
+ gsc_add_sc(&parent->meta.lssc, &sc);
/* compare the sum of the children with parent's sc */
- sc.m1 = parent->pq_u.hfsc_opts.lssc_m1;
- sc.d = parent->pq_u.hfsc_opts.lssc_d;
- sc.m2 = parent->pq_u.hfsc_opts.lssc_m2;
- if (!is_gsc_under_sc(&lssc, &sc)) {
+ sc.m1 = parent->pa.pq_u.hfsc_opts.lssc_m1;
+ sc.d = parent->pa.pq_u.hfsc_opts.lssc_d;
+ sc.m2 = parent->pa.pq_u.hfsc_opts.lssc_m2;
+ if (!is_gsc_under_sc(&parent->meta.lssc, &sc)) {
warnx("linkshare sc exceeds parent's sc");
- goto err_ret;
+ return (-1);
}
}
@@ -850,38 +861,30 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
if (opts->ulsc_m1 > pa->ifbandwidth ||
opts->ulsc_m2 > pa->ifbandwidth) {
warnx("upper-limit larger than interface bandwidth");
- goto err_ret;
+ return (-1);
}
if (opts->rtsc_m2 != 0 && opts->rtsc_m2 > opts->ulsc_m2) {
warnx("upper-limit sc smaller than real-time sc");
- goto err_ret;
+ return (-1);
}
}
- gsc_destroy(&rtsc);
- gsc_destroy(&lssc);
-
return (0);
-
-err_ret:
- gsc_destroy(&rtsc);
- gsc_destroy(&lssc);
- return (-1);
}
/*
* FAIRQ support functions
*/
static int
-eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
+eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa,
+ struct pfctl_altq *if_ppa, struct pfctl_altq *parent)
{
- struct pf_altq *altq, *parent;
struct fairq_opts *opts;
struct service_curve sc;
opts = &pa->pq_u.fairq_opts;
- if (pa->parent[0] == 0) {
+ if (pa->parent == NULL) {
/* root queue */
opts->lssc_m1 = pa->ifbandwidth;
opts->lssc_m2 = pa->ifbandwidth;
@@ -889,7 +892,18 @@ eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
return (0);
}
- LIST_INIT(&lssc);
+ /* First child initializes the parent's service curve accumulator. */
+ if (parent->meta.children == 1)
+ LIST_INIT(&parent->meta.lssc);
+
+ if (parent->pa.pq_u.fairq_opts.flags & FARF_DEFAULTCLASS) {
+ warnx("adding %s would make default queue %s not a leaf",
+ pa->qname, pa->parent);
+ return (-1);
+ }
+
+ if (pa->pq_u.fairq_opts.flags & FARF_DEFAULTCLASS)
+ if_ppa->meta.default_classes++;
/* if link_share is not specified, use bandwidth */
if (opts->lssc_m2 == 0)
@@ -906,122 +920,49 @@ eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
* be smaller than the interface bandwidth, and the upper-limit should
* be larger than the real-time service curve when both are defined.
*/
- parent = qname_to_pfaltq(pa->parent, pa->ifname);
- if (parent == NULL)
- errx(1, "parent %s not found for %s", pa->parent, pa->qname);
-
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
-
- if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0)
- continue;
-
- /* if the class has a link-sharing service curve, add it. */
- if (opts->lssc_m2 != 0 && altq->pq_u.fairq_opts.lssc_m2 != 0) {
- sc.m1 = altq->pq_u.fairq_opts.lssc_m1;
- sc.d = altq->pq_u.fairq_opts.lssc_d;
- sc.m2 = altq->pq_u.fairq_opts.lssc_m2;
- gsc_add_sc(&lssc, &sc);
- }
- }
- /* check the link-sharing service curve. */
+ /* check the linkshare service curve. */
if (opts->lssc_m2 != 0) {
- sc.m1 = parent->pq_u.fairq_opts.lssc_m1;
- sc.d = parent->pq_u.fairq_opts.lssc_d;
- sc.m2 = parent->pq_u.fairq_opts.lssc_m2;
- if (!is_gsc_under_sc(&lssc, &sc)) {
+ /* add this queue to the child sum */
+ sc.m1 = opts->lssc_m1;
+ sc.d = opts->lssc_d;
+ sc.m2 = opts->lssc_m2;
+ gsc_add_sc(&parent->meta.lssc, &sc);
+ /* compare the sum of the children with parent's sc */
+ sc.m1 = parent->pa.pq_u.fairq_opts.lssc_m1;
+ sc.d = parent->pa.pq_u.fairq_opts.lssc_d;
+ sc.m2 = parent->pa.pq_u.fairq_opts.lssc_m2;
+ if (!is_gsc_under_sc(&parent->meta.lssc, &sc)) {
warnx("link-sharing sc exceeds parent's sc");
- goto err_ret;
+ return (-1);
}
}
- gsc_destroy(&lssc);
-
return (0);
-
-err_ret:
- gsc_destroy(&lssc);
- return (-1);
}
static int
-check_commit_hfsc(int dev, int opts, struct pf_altq *pa)
+check_commit_hfsc(int dev, int opts, struct pfctl_altq *if_ppa)
{
- struct pf_altq *altq, *def = NULL;
- int default_class;
- int error = 0;
/* check if hfsc has one default queue for this interface */
- default_class = 0;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (altq->parent[0] == 0) /* dummy root */
- continue;
- if (altq->pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS) {
- default_class++;
- def = altq;
- }
- }
- if (default_class != 1) {
- warnx("should have one default queue on %s", pa->ifname);
+ if (if_ppa->meta.default_classes != 1) {
+ warnx("should have one default queue on %s", if_ppa->pa.ifname);
return (1);
}
- /* make sure the default queue is a leaf */
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (strncmp(altq->parent, def->qname, PF_QNAME_SIZE) == 0) {
- warnx("default queue is not a leaf");
- error++;
- }
- }
- return (error);
+ return (0);
}
static int
-check_commit_fairq(int dev __unused, int opts __unused, struct pf_altq *pa)
+check_commit_fairq(int dev __unused, int opts __unused, struct pfctl_altq *if_ppa)
{
- struct pf_altq *altq, *def = NULL;
- int default_class;
- int error = 0;
/* check if fairq has one default queue for this interface */
- default_class = 0;
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (altq->pq_u.fairq_opts.flags & FARF_DEFAULTCLASS) {
- default_class++;
- def = altq;
- }
- }
- if (default_class != 1) {
- warnx("should have one default queue on %s", pa->ifname);
+ if (if_ppa->meta.default_classes != 1) {
+ warnx("should have one default queue on %s", if_ppa->pa.ifname);
return (1);
}
- /* make sure the default queue is a leaf */
- TAILQ_FOREACH(altq, &altqs, entries) {
- if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
- continue;
- if (altq->qname[0] == 0) /* this is for interface */
- continue;
- if (strncmp(altq->parent, def->qname, PF_QNAME_SIZE) == 0) {
- warnx("default queue is not a leaf");
- error++;
- }
- }
- return (error);
+ return (0);
}
static int
@@ -1194,17 +1135,6 @@ is_gsc_under_sc(struct gen_sc *gsc, struct service_curve *sc)
return (1);
}
-static void
-gsc_destroy(struct gen_sc *gsc)
-{
- struct segment *s;
-
- while ((s = LIST_FIRST(gsc)) != NULL) {
- LIST_REMOVE(s, _next);
- free(s);
- }
-}
-
/*
* return a segment entry starting at x.
* if gsc has no entry starting at x, a new entry is created at x.
@@ -1369,8 +1299,7 @@ getifspeed(char *ifname)
struct ifreq ifr;
struct if_data ifrdat;
- if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) < 0)
- err(1, "socket");
+ s = get_query_socket();
bzero(&ifr, sizeof(ifr));
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
sizeof(ifr.ifr_name))
@@ -1378,8 +1307,6 @@ getifspeed(char *ifname)
ifr.ifr_data = (caddr_t)&ifrdat;
if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1)
err(1, "SIOCGIFDATA");
- if (close(s))
- err(1, "close");
return ((u_int32_t)ifrdat.ifi_baudrate);
}
#endif
@@ -1390,8 +1317,7 @@ getifmtu(char *ifname)
int s;
struct ifreq ifr;
- if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) < 0)
- err(1, "socket");
+ s = get_query_socket();
bzero(&ifr, sizeof(ifr));
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
sizeof(ifr.ifr_name))
@@ -1402,8 +1328,6 @@ getifmtu(char *ifname)
#else
err(1, "SIOCGIFMTU");
#endif
- if (close(s))
- err(1, "close");
if (ifr.ifr_mtu > 0)
return (ifr.ifr_mtu);
else {
diff --git a/freebsd/sbin/pfctl/pfctl_optimize.c b/freebsd/sbin/pfctl/pfctl_optimize.c
index cbf94e80..02a1018c 100644
--- a/freebsd/sbin/pfctl/pfctl_optimize.c
+++ b/freebsd/sbin/pfctl/pfctl_optimize.c
@@ -1549,14 +1549,24 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por)
int
interface_group(const char *ifname)
{
+ int s;
+ struct ifgroupreq ifgr;
+
if (ifname == NULL || !ifname[0])
return (0);
- /* Real interfaces must end in a number, interface groups do not */
- if (isdigit(ifname[strlen(ifname) - 1]))
- return (0);
- else
- return (1);
+ s = get_query_socket();
+
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ);
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
+ if (errno == ENOENT)
+ return (0);
+ else
+ err(1, "SIOCGIFGMEMB");
+ }
+
+ return (1);
}
diff --git a/freebsd/sbin/pfctl/pfctl_parser.c b/freebsd/sbin/pfctl/pfctl_parser.c
index 25e2a59b..f339d972 100644
--- a/freebsd/sbin/pfctl/pfctl_parser.c
+++ b/freebsd/sbin/pfctl/pfctl_parser.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <net/pfvar.h>
#include <arpa/inet.h>
+#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -86,7 +87,6 @@ void print_fromto(struct pf_rule_addr *, pf_osfp_t,
struct pf_rule_addr *, u_int8_t, u_int8_t, int, int);
int ifa_skip_if(const char *filter, struct node_host *p);
-struct node_host *ifa_grouplookup(const char *, int);
struct node_host *host_if(const char *, int);
struct node_host *host_v4(const char *, int);
struct node_host *host_v6(const char *, int);
@@ -223,6 +223,19 @@ const struct pf_timeout pf_timeouts[] = {
{ NULL, 0 }
};
+static struct hsearch_data isgroup_map;
+
+static __attribute__((constructor)) void
+pfctl_parser_init(void)
+{
+ /*
+ * As hdestroy() will never be called on these tables, it will be
+ * safe to use references into the stored data as keys.
+ */
+ if (hcreate_r(0, &isgroup_map) == 0)
+ err(1, "Failed to create interface group query response map");
+}
+
const struct icmptypeent *
geticmptypebynumber(u_int8_t type, sa_family_t af)
{
@@ -1167,6 +1180,71 @@ check_netmask(struct node_host *h, sa_family_t af)
static struct node_host *iftab;
+/*
+ * Retrieve the list of groups this interface is a member of and make sure
+ * each group is in the group map.
+ */
+static void
+ifa_add_groups_to_map(char *ifa_name)
+{
+ int s, len;
+ struct ifgroupreq ifgr;
+ struct ifg_req *ifg;
+
+ s = get_query_socket();
+
+ /* Get size of group list for this interface */
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, ifa_name, IFNAMSIZ);
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCGIFGROUP");
+
+ /* Retrieve group list for this interface */
+ len = ifgr.ifgr_len;
+ ifgr.ifgr_groups =
+ (struct ifg_req *)calloc(len / sizeof(struct ifg_req),
+ sizeof(struct ifg_req));
+ if (ifgr.ifgr_groups == NULL)
+ err(1, "calloc");
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCGIFGROUP");
+
+ ifg = ifgr.ifgr_groups;
+ for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
+ len -= sizeof(struct ifg_req);
+ if (strcmp(ifg->ifgrq_group, "all")) {
+ ENTRY item;
+ ENTRY *ret_item;
+ int *answer;
+
+ item.key = ifg->ifgrq_group;
+ if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) {
+ struct ifgroupreq ifgr2;
+
+ /* Don't know the answer yet */
+ if ((answer = malloc(sizeof(int))) == NULL)
+ err(1, "malloc");
+
+ bzero(&ifgr2, sizeof(ifgr2));
+ strlcpy(ifgr2.ifgr_name, ifg->ifgrq_group,
+ sizeof(ifgr2.ifgr_name));
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr2) == 0)
+ *answer = ifgr2.ifgr_len;
+ else
+ *answer = 0;
+
+ item.key = strdup(ifg->ifgrq_group);
+ item.data = answer;
+ if (hsearch_r(item, ENTER, &ret_item,
+ &isgroup_map) == 0)
+ err(1, "interface group query response"
+ " map insert");
+ }
+ }
+ }
+ free(ifgr.ifgr_groups);
+}
+
void
ifa_load(void)
{
@@ -1234,6 +1312,8 @@ ifa_load(void)
sizeof(struct in6_addr));
n->ifindex = ((struct sockaddr_in6 *)
ifa->ifa_addr)->sin6_scope_id;
+ } else if (n->af == AF_LINK) {
+ ifa_add_groups_to_map(ifa->ifa_name);
}
if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
err(1, "ifa_load: strdup");
@@ -1251,7 +1331,7 @@ ifa_load(void)
freeifaddrs(ifap);
}
-int
+static int
get_socket_domain(void)
{
int sdom;
@@ -1271,31 +1351,54 @@ get_socket_domain(void)
return (sdom);
}
+int
+get_query_socket(void)
+{
+ static int s = -1;
+
+ if (s == -1) {
+ if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
+ err(1, "socket");
+ }
+
+ return (s);
+}
+
+/*
+ * Returns the response len if the name is a group, otherwise returns 0.
+ */
+static int
+is_a_group(char *name)
+{
+ ENTRY item;
+ ENTRY *ret_item;
+
+ item.key = name;
+ if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0)
+ return (0);
+
+ return (*(int *)ret_item->data);
+}
+
struct node_host *
-ifa_exists(const char *ifa_name)
+ifa_exists(char *ifa_name)
{
struct node_host *n;
- struct ifgroupreq ifgr;
int s;
if (iftab == NULL)
ifa_load();
- /* check wether this is a group */
- if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
- err(1, "socket");
- bzero(&ifgr, sizeof(ifgr));
- strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
+ /* check whether this is a group */
+ s = get_query_socket();
+ if (is_a_group(ifa_name)) {
/* fake a node_host */
if ((n = calloc(1, sizeof(*n))) == NULL)
err(1, "calloc");
if ((n->ifname = strdup(ifa_name)) == NULL)
err(1, "strdup");
- close(s);
return (n);
}
- close(s);
for (n = iftab; n; n = n->next) {
if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
@@ -1306,23 +1409,20 @@ ifa_exists(const char *ifa_name)
}
struct node_host *
-ifa_grouplookup(const char *ifa_name, int flags)
+ifa_grouplookup(char *ifa_name, int flags)
{
struct ifg_req *ifg;
struct ifgroupreq ifgr;
int s, len;
struct node_host *n, *h = NULL;
- if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
- err(1, "socket");
+ s = get_query_socket();
+ len = is_a_group(ifa_name);
+ if (len == 0)
+ return (NULL);
bzero(&ifgr, sizeof(ifgr));
strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
- close(s);
- return (NULL);
- }
-
- len = ifgr.ifgr_len;
+ ifgr.ifgr_len = len;
if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
err(1, "calloc");
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
@@ -1341,13 +1441,12 @@ ifa_grouplookup(const char *ifa_name, int flags)
}
}
free(ifgr.ifgr_groups);
- close(s);
return (h);
}
struct node_host *
-ifa_lookup(const char *ifa_name, int flags)
+ifa_lookup(char *ifa_name, int flags)
{
struct node_host *p = NULL, *h = NULL, *n = NULL;
int got4 = 0, got6 = 0;
diff --git a/freebsd/sbin/pfctl/pfctl_parser.h b/freebsd/sbin/pfctl/pfctl_parser.h
index 05ebdf29..aa6d98d7 100644
--- a/freebsd/sbin/pfctl/pfctl_parser.h
+++ b/freebsd/sbin/pfctl/pfctl_parser.h
@@ -177,6 +177,24 @@ struct node_queue_opt {
} data;
};
+#define QPRI_BITSET_SIZE 256
+BITSET_DEFINE(qpri_bitset, QPRI_BITSET_SIZE);
+LIST_HEAD(gen_sc, segment);
+
+struct pfctl_altq {
+ struct pf_altq pa;
+ struct {
+ STAILQ_ENTRY(pfctl_altq) link;
+ u_int64_t bwsum;
+ struct qpri_bitset qpris;
+ int children;
+ int root_classes;
+ int default_classes;
+ struct gen_sc lssc;
+ struct gen_sc rtsc;
+ } meta;
+};
+
#ifdef __FreeBSD__
/*
* XXX
@@ -313,10 +331,10 @@ void set_ipmask(struct node_host *, u_int8_t);
int check_netmask(struct node_host *, sa_family_t);
int unmask(struct pf_addr *, sa_family_t);
void ifa_load(void);
-int get_socket_domain(void);
-struct node_host *ifa_exists(const char *);
-struct node_host *ifa_grouplookup(const char *ifa_name, int flags);
-struct node_host *ifa_lookup(const char *, int);
+int get_query_socket(void);
+struct node_host *ifa_exists(char *);
+struct node_host *ifa_grouplookup(char *ifa_name, int flags);
+struct node_host *ifa_lookup(char *, int);
struct node_host *host(const char *);
int append_addr(struct pfr_buffer *, char *, int);
diff --git a/freebsd/sbin/pfctl/rtems-bsd-pfctl-pfctl_altq-data.h b/freebsd/sbin/pfctl/rtems-bsd-pfctl-pfctl_altq-data.h
index fb03f2b6..64f95aaf 100644
--- a/freebsd/sbin/pfctl/rtems-bsd-pfctl-pfctl_altq-data.h
+++ b/freebsd/sbin/pfctl/rtems-bsd-pfctl-pfctl_altq-data.h
@@ -4,6 +4,3 @@
/* pfctl_altq.c */
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char r2sbuf[][16]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int idx);
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct altqs altqs);
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct gen_sc lssc);
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct gen_sc rtsc);
diff --git a/freebsd/sbin/ping/ping.c b/freebsd/sbin/ping/ping.c
index 5df1e875..e31941b8 100644
--- a/freebsd/sbin/ping/ping.c
+++ b/freebsd/sbin/ping/ping.c
@@ -104,16 +104,20 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <math.h>
#include <netdb.h>
+#include <stddef.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
+#include <time.h>
#include <unistd.h>
#ifdef __rtems__
#include "rtems-bsd-ping-ping-data.h"
#endif /* __rtems__ */
+#include "utils.h"
+
#define INADDR_LEN ((int)sizeof(in_addr_t))
#define TIMEVAL_LEN ((int)sizeof(struct tv32))
#define MASK_LEN (ICMP_MASKLEN - ICMP_MINLEN)
@@ -135,7 +139,7 @@ __FBSDID("$FreeBSD$");
struct tv32 {
int32_t tv32_sec;
- int32_t tv32_usec;
+ int32_t tv32_nsec;
};
/* various options */
@@ -235,7 +239,6 @@ static char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
#endif /* __rtems__ */
static void fill(char *, char *);
-static u_short in_cksum(u_short *, int);
#ifndef __rtems__
static cap_channel_t *capdns_setup(void);
#endif /* __rtems__ */
@@ -244,15 +247,14 @@ static void finish(void) __dead2;
static void pinger(void);
static char *pr_addr(struct in_addr);
static char *pr_ntime(n_time);
-static void pr_icmph(struct icmp *);
+static void pr_icmph(struct icmp *, struct ip *, const u_char *const);
static void pr_iph(struct ip *);
-static void pr_pack(char *, int, struct sockaddr_in *, struct timeval *);
-static void pr_retip(struct ip *);
+static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *);
+static void pr_retip(struct ip *, const u_char *);
#ifndef __rtems__
static void status(int);
static void stopit(int);
#endif /* __rtems__ */
-static void tvsub(struct timeval *, const struct timeval *);
static void usage(void) __dead2;
#ifdef __rtems__
@@ -286,9 +288,8 @@ main(int argc, char *const *argv)
{
struct sockaddr_in from, sock_in;
struct in_addr ifaddr;
- struct timeval last, intvl;
+ struct timespec last, intvl;
struct iovec iov;
- struct ip *ip;
struct msghdr msg;
#ifndef __rtems__
struct sigaction si_sa;
@@ -310,7 +311,7 @@ main(int argc, char *const *argv)
long ltmp;
int almost_done, ch, df, hold, i, icmp_len, mib[4], preload;
int ssend_errno, srecv_errno, tos, ttl;
- char ctrl[CMSG_SPACE(sizeof(struct timeval))];
+ char ctrl[CMSG_SPACE(sizeof(struct timespec))];
#ifndef __rtems__
char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
#endif /* __rtems__ */
@@ -335,6 +336,8 @@ main(int argc, char *const *argv)
#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
#endif /* __rtems__ */
+ options |= F_NUMERIC;
+
/*
* Do the stuff that we need root priv's for *first*, and
* then drop our setuid bit. Save error reporting for
@@ -371,7 +374,7 @@ main(int argc, char *const *argv)
outpack = outpackhdr + sizeof(struct ip);
while ((ch = getopt(argc, argv,
- "Aac:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:"
+ "Aac:DdfG:g:Hh:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:"
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"P:"
@@ -437,6 +440,9 @@ main(int argc, char *const *argv)
options |= F_SWEEP;
sweepmin = ltmp;
break;
+ case 'H':
+ options &= ~F_NUMERIC;
+ break;
case 'h': /* Packet size increment for ping sweep */
ltmp = strtol(optarg, &ep, 0);
if (*ep || ep == optarg || ltmp < 1)
@@ -685,8 +691,8 @@ main(int argc, char *const *argv)
hostname = hnamebuf;
}
-#ifndef __rtems__
/* From now on we will use only reverse DNS lookups. */
+#ifdef WITH_CASPER
if (capdns != NULL) {
const char *types[1];
@@ -694,7 +700,7 @@ main(int argc, char *const *argv)
if (cap_dns_type_limit(capdns, types, 1) < 0)
err(1, "unable to limit access to system.dns service");
}
-#endif /* __rtems__ */
+#endif
if (connect(ssend, (struct sockaddr *)&whereto, sizeof(whereto)) != 0)
err(1, "connect");
@@ -759,7 +765,9 @@ main(int argc, char *const *argv)
#endif /*IPSEC*/
if (options & F_HDRINCL) {
- ip = (struct ip*)outpackhdr;
+ struct ip ip;
+
+ memcpy(&ip, outpackhdr, sizeof(ip));
if (!(options & (F_TTL | F_MTTL))) {
mib[0] = CTL_NET;
mib[1] = PF_INET;
@@ -770,15 +778,16 @@ main(int argc, char *const *argv)
err(1, "sysctl(net.inet.ip.ttl)");
}
setsockopt(ssend, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
- ip->ip_v = IPVERSION;
- ip->ip_hl = sizeof(struct ip) >> 2;
- ip->ip_tos = tos;
- ip->ip_id = 0;
- ip->ip_off = htons(df ? IP_DF : 0);
- ip->ip_ttl = ttl;
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
- ip->ip_dst = to->sin_addr;
+ ip.ip_v = IPVERSION;
+ ip.ip_hl = sizeof(struct ip) >> 2;
+ ip.ip_tos = tos;
+ ip.ip_id = 0;
+ ip.ip_off = htons(df ? IP_DF : 0);
+ ip.ip_ttl = ttl;
+ ip.ip_p = IPPROTO_ICMP;
+ ip.ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
+ ip.ip_dst = to->sin_addr;
+ memcpy(outpackhdr, &ip, sizeof(ip));
}
#ifndef __rtems__
@@ -789,7 +798,7 @@ main(int argc, char *const *argv)
*/
caph_cache_catpages();
if (caph_enter_casper() < 0)
- err(1, "cap_enter");
+ err(1, "caph_enter_casper");
cap_rights_init(&rights, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
if (caph_rights_limit(srecv, &rights) < 0)
@@ -841,9 +850,15 @@ main(int argc, char *const *argv)
}
}
#ifdef SO_TIMESTAMP
- { int on = 1;
- if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
- err(EX_OSERR, "setsockopt SO_TIMESTAMP");
+ {
+ int on = 1;
+ int ts_clock = SO_TS_MONOTONIC;
+ if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on,
+ sizeof(on)) < 0)
+ err(EX_OSERR, "setsockopt SO_TIMESTAMP");
+ if (setsockopt(srecv, SOL_SOCKET, SO_TS_CLOCK, &ts_clock,
+ sizeof(ts_clock)) < 0)
+ err(EX_OSERR, "setsockopt SO_TS_CLOCK");
}
#endif
if (sweepmax) {
@@ -946,6 +961,7 @@ main(int argc, char *const *argv)
msg.msg_iovlen = 1;
#ifdef SO_TIMESTAMP
msg.msg_control = (caddr_t)ctrl;
+ msg.msg_controllen = sizeof(ctrl);
#endif
iov.iov_base = packet;
iov.iov_len = IP_MAXPACKET;
@@ -958,19 +974,19 @@ main(int argc, char *const *argv)
while (preload--) /* fire off them quickies */
pinger();
}
- (void)gettimeofday(&last, NULL);
+ (void)clock_gettime(CLOCK_MONOTONIC, &last);
if (options & F_FLOOD) {
intvl.tv_sec = 0;
- intvl.tv_usec = 10000;
+ intvl.tv_nsec = 10000000;
} else {
intvl.tv_sec = interval / 1000;
- intvl.tv_usec = interval % 1000 * 1000;
+ intvl.tv_nsec = interval % 1000 * 1000000;
}
almost_done = 0;
while (!finish_up) {
- struct timeval now, timeout;
+ struct timespec now, timeout;
#ifndef __rtems__
fd_set rfds;
#else /* __rtems__ */
@@ -978,7 +994,8 @@ main(int argc, char *const *argv)
sizeof(fd_set) * 8)];
#define rfds (*(fd_set *)(&big_enough_rfds[0]))
#endif /* __rtems__ */
- int cc, n;
+ int n;
+ ssize_t cc;
check_status();
#ifndef __rtems__
@@ -989,28 +1006,18 @@ main(int argc, char *const *argv)
memset(big_enough_rfds, 0, sizeof(big_enough_rfds));
#endif /* __rtems__ */
FD_SET(srecv, &rfds);
- (void)gettimeofday(&now, NULL);
- timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
- timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
- while (timeout.tv_usec < 0) {
- timeout.tv_usec += 1000000;
- timeout.tv_sec--;
- }
- while (timeout.tv_usec >= 1000000) {
- timeout.tv_usec -= 1000000;
- timeout.tv_sec++;
- }
+ (void)clock_gettime(CLOCK_MONOTONIC, &now);
+ timespecadd(&last, &intvl, &timeout);
+ timespecsub(&timeout, &now, &timeout);
if (timeout.tv_sec < 0)
- timerclear(&timeout);
- n = select(srecv + 1, &rfds, NULL, NULL, &timeout);
+ timespecclear(&timeout);
+ n = pselect(srecv + 1, &rfds, NULL, NULL, &timeout, NULL);
if (n < 0)
continue; /* Must be EINTR. */
if (n == 1) {
- struct timeval *tv = NULL;
+ struct timespec *tv = NULL;
#ifdef SO_TIMESTAMP
- struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl;
-
- msg.msg_controllen = sizeof(ctrl);
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
#endif
msg.msg_namelen = sizeof(from);
if ((cc = recvmsg(srecv, &msg, 0)) < 0) {
@@ -1020,7 +1027,8 @@ main(int argc, char *const *argv)
continue;
}
#ifdef SO_TIMESTAMP
- if (cmsg->cmsg_level == SOL_SOCKET &&
+ if (cmsg != NULL &&
+ cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_TIMESTAMP &&
cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) {
/* Copy to avoid alignment problems: */
@@ -1029,7 +1037,7 @@ main(int argc, char *const *argv)
}
#endif
if (tv == NULL) {
- (void)gettimeofday(&now, NULL);
+ (void)clock_gettime(CLOCK_MONOTONIC, &now);
tv = &now;
}
pr_pack((char *)packet, cc, &from, tv);
@@ -1053,17 +1061,17 @@ main(int argc, char *const *argv)
if (almost_done)
break;
almost_done = 1;
- intvl.tv_usec = 0;
+ intvl.tv_nsec = 0;
if (nreceived) {
intvl.tv_sec = 2 * tmax / 1000;
if (!intvl.tv_sec)
intvl.tv_sec = 1;
} else {
intvl.tv_sec = waittime / 1000;
- intvl.tv_usec = waittime % 1000 * 1000;
+ intvl.tv_nsec = waittime % 1000 * 1000000;
}
}
- (void)gettimeofday(&last, NULL);
+ (void)clock_gettime(CLOCK_MONOTONIC, &last);
if (ntransmitted - nreceived - 1 > nmissedmax) {
nmissedmax = ntransmitted - nreceived - 1;
if (options & F_MISSED)
@@ -1102,53 +1110,69 @@ stopit(int sig __unused)
* Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
* will be added on by the kernel. The ID field is our UNIX process ID,
* and the sequence number is an ascending integer. The first TIMEVAL_LEN
- * bytes of the data portion are used to hold a UNIX "timeval" struct in
+ * bytes of the data portion are used to hold a UNIX "timespec" struct in
* host byte-order, to compute the round-trip time.
*/
static void
pinger(void)
{
- struct timeval now;
+ struct timespec now;
struct tv32 tv32;
- struct ip *ip;
- struct icmp *icp;
+ struct icmp icp;
int cc, i;
u_char *packet;
packet = outpack;
- icp = (struct icmp *)outpack;
- icp->icmp_type = icmp_type;
- icp->icmp_code = 0;
- icp->icmp_cksum = 0;
- icp->icmp_seq = htons(ntransmitted);
- icp->icmp_id = ident; /* ID */
+ memcpy(&icp, outpack, ICMP_MINLEN + phdr_len);
+ icp.icmp_type = icmp_type;
+ icp.icmp_code = 0;
+ icp.icmp_cksum = 0;
+ icp.icmp_seq = htons(ntransmitted);
+ icp.icmp_id = ident; /* ID */
CLR(ntransmitted % MAX_DUP_CHK);
if ((options & F_TIME) || timing) {
- (void)gettimeofday(&now, NULL);
-
- tv32.tv32_sec = htonl(now.tv_sec);
- tv32.tv32_usec = htonl(now.tv_usec);
+ (void)clock_gettime(CLOCK_MONOTONIC, &now);
+ /*
+ * Truncate seconds down to 32 bits in order
+ * to fit the timestamp within 8 bytes of the
+ * packet. We're only concerned with
+ * durations, not absolute times.
+ */
+ tv32.tv32_sec = (uint32_t)htonl(now.tv_sec);
+ tv32.tv32_nsec = (uint32_t)htonl(now.tv_nsec);
if (options & F_TIME)
- icp->icmp_otime = htonl((now.tv_sec % (24*60*60))
- * 1000 + now.tv_usec / 1000);
+ icp.icmp_otime = htonl((now.tv_sec % (24*60*60))
+ * 1000 + now.tv_nsec / 1000000);
if (timing)
bcopy((void *)&tv32,
(void *)&outpack[ICMP_MINLEN + phdr_len],
sizeof(tv32));
}
+ memcpy(outpack, &icp, ICMP_MINLEN + phdr_len);
+
cc = ICMP_MINLEN + phdr_len + datalen;
/* compute ICMP checksum here */
- icp->icmp_cksum = in_cksum((u_short *)icp, cc);
+ icp.icmp_cksum = in_cksum(outpack, cc);
+ /* Update icmp_cksum in the raw packet data buffer. */
+ memcpy(outpack + offsetof(struct icmp, icmp_cksum), &icp.icmp_cksum,
+ sizeof(icp.icmp_cksum));
if (options & F_HDRINCL) {
+ struct ip ip;
+
cc += sizeof(struct ip);
- ip = (struct ip *)outpackhdr;
- ip->ip_len = htons(cc);
- ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
+ ip.ip_len = htons(cc);
+ /* Update ip_len in the raw packet data buffer. */
+ memcpy(outpackhdr + offsetof(struct ip, ip_len), &ip.ip_len,
+ sizeof(ip.ip_len));
+ ip.ip_sum = in_cksum(outpackhdr, cc);
+ /* Update ip_sum in the raw packet data buffer. */
+ memcpy(outpackhdr + offsetof(struct ip, ip_sum), &ip.ip_sum,
+ sizeof(ip.ip_sum));
packet = outpackhdr;
}
i = send(ssend, (char *)packet, cc, 0);
@@ -1178,56 +1202,71 @@ pinger(void)
* program to be run without having intermingled output (or statistics!).
*/
static void
-pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
+pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
{
struct in_addr ina;
- u_char *cp, *dp;
- struct icmp *icp;
- struct ip *ip;
- const void *tp;
+ u_char *cp, *dp, l;
+ struct icmp icp;
+ struct ip ip;
+ const u_char *icmp_data_raw;
double triptime;
- int dupflag, hlen, i, j, recv_len, seq;
+ int dupflag, hlen, i, j, recv_len;
+ uint16_t seq;
static int old_rrlen;
static char old_rr[MAX_IPOPTLEN];
+ struct ip oip;
+ u_char oip_header_len;
+ struct icmp oicmp;
+ const u_char *oicmp_raw;
+
+ /*
+ * Get size of IP header of the received packet. The
+ * information is contained in the lower four bits of the
+ * first byte.
+ */
+ memcpy(&l, buf, sizeof(l));
+ hlen = (l & 0x0f) << 2;
+ memcpy(&ip, buf, hlen);
/* Check the IP header */
- ip = (struct ip *)buf;
- hlen = ip->ip_hl << 2;
recv_len = cc;
if (cc < hlen + ICMP_MINLEN) {
if (options & F_VERBOSE)
- warn("packet too short (%d bytes) from %s", cc,
+ warn("packet too short (%zd bytes) from %s", cc,
inet_ntoa(from->sin_addr));
return;
}
+#ifndef icmp_data
+ icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_ip);
+#else
+ icmp_data_raw = buf + hlen + offsetof(struct icmp, icmp_data);
+#endif
+
/* Now the ICMP part */
cc -= hlen;
- icp = (struct icmp *)(buf + hlen);
- if (icp->icmp_type == icmp_type_rsp) {
- if (icp->icmp_id != ident)
+ memcpy(&icp, buf + hlen, MIN((ssize_t)sizeof(icp), cc));
+ if (icp.icmp_type == icmp_type_rsp) {
+ if (icp.icmp_id != ident)
return; /* 'Twas not our ECHO */
++nreceived;
triptime = 0.0;
if (timing) {
- struct timeval tv1;
+ struct timespec tv1;
struct tv32 tv32;
-#ifndef icmp_data
- tp = &icp->icmp_ip;
-#else
- tp = icp->icmp_data;
-#endif
- tp = (const char *)tp + phdr_len;
+ const u_char *tp;
+
+ tp = icmp_data_raw + phdr_len;
if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
sizeof(tv1)) {
/* Copy to avoid alignment problems: */
memcpy(&tv32, tp, sizeof(tv32));
tv1.tv_sec = ntohl(tv32.tv32_sec);
- tv1.tv_usec = ntohl(tv32.tv32_usec);
- tvsub(tv, &tv1);
+ tv1.tv_nsec = ntohl(tv32.tv32_nsec);
+ timespecsub(tv, &tv1, tv);
triptime = ((double)tv->tv_sec) * 1000.0 +
- ((double)tv->tv_usec) / 1000.0;
+ ((double)tv->tv_nsec) / 1000000.0;
tsum += triptime;
tsumsq += triptime * triptime;
if (triptime < tmin)
@@ -1238,7 +1277,7 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
timing = 0;
}
- seq = ntohs(icp->icmp_seq);
+ seq = ntohs(icp.icmp_seq);
if (TST(seq % MAX_DUP_CHK)) {
++nrepeats;
@@ -1260,10 +1299,9 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
if (options & F_FLOOD)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
- (void)printf("%d bytes from %s: icmp_seq=%u", cc,
- inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
- seq);
- (void)printf(" ttl=%d", ip->ip_ttl);
+ (void)printf("%zd bytes from %s: icmp_seq=%u", cc,
+ pr_addr(from->sin_addr), seq);
+ (void)printf(" ttl=%d", ip.ip_ttl);
if (timing)
(void)printf(" time=%.3f ms", triptime);
if (dupflag)
@@ -1273,12 +1311,12 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
if (options & F_MASK) {
/* Just prentend this cast isn't ugly */
(void)printf(" mask=%s",
- inet_ntoa(*(struct in_addr *)&(icp->icmp_mask)));
+ inet_ntoa(*(struct in_addr *)&(icp.icmp_mask)));
}
if (options & F_TIME) {
- (void)printf(" tso=%s", pr_ntime(icp->icmp_otime));
- (void)printf(" tsr=%s", pr_ntime(icp->icmp_rtime));
- (void)printf(" tst=%s", pr_ntime(icp->icmp_ttime));
+ (void)printf(" tso=%s", pr_ntime(icp.icmp_otime));
+ (void)printf(" tsr=%s", pr_ntime(icp.icmp_rtime));
+ (void)printf(" tst=%s", pr_ntime(icp.icmp_ttime));
}
if (recv_len != send_len) {
(void)printf(
@@ -1286,7 +1324,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
recv_len, send_len);
}
/* check the data */
- cp = (u_char*)&icp->icmp_data[phdr_len];
+ cp = (u_char*)(buf + hlen + offsetof(struct icmp,
+ icmp_data) + phdr_len);
dp = &outpack[ICMP_MINLEN + phdr_len];
cc -= ICMP_MINLEN + phdr_len;
i = 0;
@@ -1301,7 +1340,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
i, *dp, *cp);
(void)printf("\ncp:");
- cp = (u_char*)&icp->icmp_data[0];
+ cp = (u_char*)(buf + hlen +
+ offsetof(struct icmp, icmp_data));
for (i = 0; i < datalen; ++i, ++cp) {
if ((i % 16) == 8)
(void)printf("\n\t");
@@ -1329,22 +1369,22 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
* as root to avoid leaking information not normally
* available to those not running as root.
*/
-#ifndef icmp_data
- struct ip *oip = &icp->icmp_ip;
-#else
- struct ip *oip = (struct ip *)icp->icmp_data;
-#endif
- struct icmp *oicmp = (struct icmp *)(oip + 1);
+ memcpy(&oip_header_len, icmp_data_raw, sizeof(oip_header_len));
+ oip_header_len = (oip_header_len & 0x0f) << 2;
+ memcpy(&oip, icmp_data_raw, oip_header_len);
+ oicmp_raw = icmp_data_raw + oip_header_len;
+ memcpy(&oicmp, oicmp_raw, offsetof(struct icmp, icmp_id) +
+ sizeof(oicmp.icmp_id));
if (((options & F_VERBOSE) && uid == 0) ||
(!(options & F_QUIET2) &&
- (oip->ip_dst.s_addr == whereto.sin_addr.s_addr) &&
- (oip->ip_p == IPPROTO_ICMP) &&
- (oicmp->icmp_type == ICMP_ECHO) &&
- (oicmp->icmp_id == ident))) {
- (void)printf("%d bytes from %s: ", cc,
+ (oip.ip_dst.s_addr == whereto.sin_addr.s_addr) &&
+ (oip.ip_p == IPPROTO_ICMP) &&
+ (oicmp.icmp_type == ICMP_ECHO) &&
+ (oicmp.icmp_id == ident))) {
+ (void)printf("%zd bytes from %s: ", cc,
pr_addr(from->sin_addr));
- pr_icmph(icp);
+ pr_icmph(&icp, &oip, oicmp_raw);
} else
return;
}
@@ -1438,65 +1478,6 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
}
}
-/*
- * in_cksum --
- * Checksum routine for Internet Protocol family headers (C Version)
- */
-u_short
-in_cksum(u_short *addr, int len)
-{
- int nleft, sum;
- u_short *w;
- union {
- u_short us;
- u_char uc[2];
- } last;
- u_short answer;
-
- nleft = len;
- sum = 0;
- w = addr;
-
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum), we add
- * sequential 16 bit words to it, and at the end, fold back all the
- * carry bits from the top 16 bits into the lower 16 bits.
- */
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (nleft == 1) {
- last.uc[0] = *(u_char *)w;
- last.uc[1] = 0;
- sum += last.us;
- }
-
- /* add back carry outs from top 16 bits to low 16 bits */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return(answer);
-}
-
-/*
- * tvsub --
- * Subtract 2 timeval structs: out = out - in. Out is assumed to
- * be >= in.
- */
-static void
-tvsub(struct timeval *out, const struct timeval *in)
-{
-
- if ((out->tv_usec -= in->tv_usec) < 0) {
- --out->tv_sec;
- out->tv_usec += 1000000;
- }
- out->tv_sec -= in->tv_sec;
-}
-
#ifndef __rtems__
/*
* status --
@@ -1593,7 +1574,7 @@ static char *ttab[] = {
* Print a descriptive string about an ICMP header.
*/
static void
-pr_icmph(struct icmp *icp)
+pr_icmph(struct icmp *icp, struct ip *oip, const u_char *const oicmp_raw)
{
switch(icp->icmp_type) {
@@ -1631,19 +1612,11 @@ pr_icmph(struct icmp *icp)
break;
}
/* Print returned IP header information */
-#ifndef icmp_data
- pr_retip(&icp->icmp_ip);
-#else
- pr_retip((struct ip *)icp->icmp_data);
-#endif
+ pr_retip(oip, oicmp_raw);
break;
case ICMP_SOURCEQUENCH:
(void)printf("Source Quench\n");
-#ifndef icmp_data
- pr_retip(&icp->icmp_ip);
-#else
- pr_retip((struct ip *)icp->icmp_data);
-#endif
+ pr_retip(oip, oicmp_raw);
break;
case ICMP_REDIRECT:
switch(icp->icmp_code) {
@@ -1664,11 +1637,7 @@ pr_icmph(struct icmp *icp)
break;
}
(void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr));
-#ifndef icmp_data
- pr_retip(&icp->icmp_ip);
-#else
- pr_retip((struct ip *)icp->icmp_data);
-#endif
+ pr_retip(oip, oicmp_raw);
break;
case ICMP_ECHO:
(void)printf("Echo Request\n");
@@ -1687,20 +1656,12 @@ pr_icmph(struct icmp *icp)
icp->icmp_code);
break;
}
-#ifndef icmp_data
- pr_retip(&icp->icmp_ip);
-#else
- pr_retip((struct ip *)icp->icmp_data);
-#endif
+ pr_retip(oip, oicmp_raw);
break;
case ICMP_PARAMPROB:
(void)printf("Parameter problem: pointer = 0x%02x\n",
icp->icmp_hun.ih_pptr);
-#ifndef icmp_data
- pr_retip(&icp->icmp_ip);
-#else
- pr_retip((struct ip *)icp->icmp_data);
-#endif
+ pr_retip(oip, oicmp_raw);
break;
case ICMP_TSTAMP:
(void)printf("Timestamp\n");
@@ -1798,14 +1759,9 @@ pr_addr(struct in_addr ina)
* Dump some info on a returned (via ICMP) IP packet.
*/
static void
-pr_retip(struct ip *ip)
+pr_retip(struct ip *ip, const u_char *cp)
{
- u_char *cp;
- int hlen;
-
pr_iph(ip);
- hlen = ip->ip_hl << 2;
- cp = (u_char *)ip + hlen;
if (ip->ip_p == 6)
(void)printf("TCP: from port %u, to port %u (decimal)\n",
@@ -1818,7 +1774,7 @@ pr_retip(struct ip *ip)
static char *
pr_ntime(n_time timestamp)
{
- static char buf[10];
+ static char buf[11];
int hour, min, sec;
sec = ntohl(timestamp) / 1000;
@@ -1867,9 +1823,10 @@ static cap_channel_t *
capdns_setup(void)
{
cap_channel_t *capcas, *capdnsloc;
+#ifdef WITH_CASPER
const char *types[2];
int families[1];
-
+#endif
capcas = cap_init();
if (capcas == NULL)
err(1, "unable to create casper process");
@@ -1878,6 +1835,7 @@ capdns_setup(void)
cap_close(capcas);
if (capdnsloc == NULL)
err(1, "unable to open system.dns service");
+#ifdef WITH_CASPER
types[0] = "NAME2ADDR";
types[1] = "ADDR2NAME";
if (cap_dns_type_limit(capdnsloc, types, 2) < 0)
@@ -1885,7 +1843,7 @@ capdns_setup(void)
families[0] = AF_INET;
if (cap_dns_family_limit(capdnsloc, families, 1) < 0)
err(1, "unable to limit access to system.dns service");
-
+#endif
return (capdnsloc);
}
#endif /* __rtems__ */
@@ -1900,11 +1858,11 @@ usage(void)
{
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]",
+"usage: ping [-AaDdfHnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]",
" [-h sweepincrsize] [-i wait] [-l preload] [-M mask | time] [-m ttl]",
" " SECOPT " [-p pattern] [-S src_addr] [-s packetsize] [-t timeout]",
" [-W waittime] [-z tos] host",
-" ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]",
+" ping [-AaDdfHLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]",
" [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]",
" [-s packetsize] [-T ttl] [-t timeout] [-W waittime]",
" [-z tos] mcast-group");
diff --git a/freebsd/sbin/ping/utils.c b/freebsd/sbin/ping/utils.c
new file mode 100644
index 00000000..3e0fe2b1
--- /dev/null
+++ b/freebsd/sbin/ping/utils.c
@@ -0,0 +1,100 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Muuss.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+#include "utils.h"
+
+/*
+ * in_cksum --
+ * Checksum routine for Internet Protocol family headers (C Version)
+ */
+u_short
+in_cksum(u_char *addr, int len)
+{
+ int nleft, sum;
+ u_char *w;
+ union {
+ u_short us;
+ u_char uc[2];
+ } last;
+ u_short answer;
+
+ nleft = len;
+ sum = 0;
+ w = addr;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+ * sequential 16 bit words to it, and at the end, fold back all the
+ * carry bits from the top 16 bits into the lower 16 bits.
+ */
+ while (nleft > 1) {
+ u_short data;
+
+ memcpy(&data, w, sizeof(data));
+ sum += data;
+ w += sizeof(data);
+ nleft -= sizeof(data);
+ }
+
+ /* mop up an odd byte, if necessary */
+ if (nleft == 1) {
+ last.uc[0] = *w;
+ last.uc[1] = 0;
+ sum += last.us;
+ }
+
+ /* add back carry outs from top 16 bits to low 16 bits */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return(answer);
+}
diff --git a/freebsd/sbin/ping/utils.h b/freebsd/sbin/ping/utils.h
new file mode 100644
index 00000000..cb56e587
--- /dev/null
+++ b/freebsd/sbin/ping/utils.h
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (C) 2019 Jan Sucan <jansucan@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef UTILS_H
+#define UTILS_H 1
+
+#include <sys/types.h>
+
+u_short in_cksum(u_char *, int);
+
+#endif
diff --git a/freebsd/sbin/ping6/ping6.c b/freebsd/sbin/ping6/ping6.c
index c95572b0..a56aae1d 100644
--- a/freebsd/sbin/ping6/ping6.c
+++ b/freebsd/sbin/ping6/ping6.c
@@ -72,6 +72,7 @@
*/
#if defined(__rtems__) && defined(INET6)
+#if 0
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
@@ -79,10 +80,9 @@ static const char copyright[] =
#endif /* not lint */
#ifndef lint
-#if 0
static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
-#endif
#endif /* not lint */
+#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -117,9 +117,9 @@ __FBSDID("$FreeBSD$");
#include <machine/rtems-bsd-commands.h>
#endif /* __rtems__ */
#include <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/uio.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <net/if.h>
#include <net/route.h>
@@ -131,6 +131,10 @@ __FBSDID("$FreeBSD$");
#include <arpa/nameser.h>
#include <netdb.h>
+#include <capsicum_helpers.h>
+#include <casper/cap_dns.h>
+#include <libcasper.h>
+
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -141,6 +145,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
+#include <time.h>
#include <unistd.h>
#ifdef IPSEC
@@ -155,7 +160,7 @@ __FBSDID("$FreeBSD$");
struct tv32 {
u_int32_t tv32_sec;
- u_int32_t tv32_usec;
+ u_int32_t tv32_nsec;
};
#define MAXPACKETLEN 131072
@@ -209,7 +214,7 @@ struct tv32 {
#define F_DONTFRAG 0x1000000
#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
#define F_WAITTIME 0x2000000
-u_int options;
+static u_int options;
#define IN6LEN sizeof(struct in6_addr)
#define SA6LEN sizeof(struct sockaddr_in6)
@@ -230,7 +235,8 @@ static struct sockaddr_in6 dst; /* who to ping6 */
static struct sockaddr_in6 src; /* src addr of this packet */
static socklen_t srclen;
static size_t datalen = DEFDATALEN;
-static int s; /* socket file descriptor */
+static int ssend; /* send socket file descriptor */
+static int srecv; /* receive socket file descriptor */
static u_char outpack[MAXPACKETLEN];
static char BSPACE = '\b'; /* characters written for flood */
static char BBELL = '\a'; /* characters written for AUDIBLE */
@@ -240,6 +246,7 @@ static int ident; /* process id to identify our packets */
static u_int8_t nonce[8]; /* nonce field for node information */
static int hoplimit = -1; /* hoplimit */
static u_char *packet = NULL;
+static cap_channel_t *capdns;
/* counters */
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
@@ -274,6 +281,7 @@ static volatile sig_atomic_t seeninfo;
#ifndef __rtems__
int main(int, char *[]);
#endif /* __rtems__ */
+static cap_channel_t *capdns_setup(void);
static void fill(char *, char *);
static int get_hoplim(struct msghdr *);
static int get_pathmtu(struct msghdr *);
@@ -289,7 +297,7 @@ static void pr_suptypes(struct icmp6_nodeinfo *, size_t);
static void pr_nodeaddr(struct icmp6_nodeinfo *, int);
static int myechoreply(const struct icmp6_hdr *);
static int mynireply(const struct icmp6_nodeinfo *);
-static char *dnsdecode(const u_char **, const u_char *, const u_char *,
+static const char *dnsdecode(const u_char *, const u_char *, const u_char *,
char *, size_t);
static void pr_pack(u_char *, int, struct msghdr *);
static void pr_exthdrs(struct msghdr *);
@@ -298,8 +306,11 @@ static void pr_rthdr(void *, size_t);
static int pr_bitrange(u_int32_t, int, int);
static void pr_retip(struct ip6_hdr *, u_char *);
static void summary(void);
-static void tvsub(struct timeval *, struct timeval *);
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
static int setpolicy(int, char *);
+#endif
+#endif
static char *nigroup(char *, int);
static void usage(void);
@@ -332,7 +343,7 @@ rtems_bsd_command_ping6(int argc, char *argv[])
int
main(int argc, char *argv[])
{
- struct timeval last, intvl;
+ struct timespec last, intvl;
struct sockaddr_in6 from, *sin6;
struct addrinfo hints, *res;
struct sigaction si_sa;
@@ -345,19 +356,18 @@ main(int argc, char *argv[])
struct cmsghdr *scmsgp = NULL;
/* For control (ancillary) data received from recvmsg() */
#ifndef __rtems__
- struct cmsghdr cm[CONTROLLEN];
+ u_char cm[CONTROLLEN];
#else /* __rtems__ */
- static struct cmsghdr cm[CONTROLLEN];
+ static u_char cm[CONTROLLEN];
#endif /* __rtems__ */
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
u_long lsockbufsize;
int sockbufsize = 0;
#endif
int usepktinfo = 0;
- struct in6_pktinfo *pktinfo = NULL;
-#ifdef USE_RFC2292BIS
+ struct in6_pktinfo pktinfo;
+ char *cmsg_pktinfo = NULL;
struct ip6_rthdr *rthdr = NULL;
-#endif
#ifdef IPSEC_POLICY_IPSEC
char *policy_in = NULL;
char *policy_out = NULL;
@@ -368,6 +378,9 @@ main(int argc, char *argv[])
#ifdef IPV6_USE_MIN_MTU
int mflag = 0;
#endif
+ cap_rights_t rights_srecv;
+ cap_rights_t rights_ssend;
+ cap_rights_t rights_stdin;
#ifdef __rtems__
struct getopt_data getopt_data;
memset(&getopt_data, 0, sizeof(getopt_data));
@@ -381,23 +394,28 @@ main(int argc, char *argv[])
/* just to be sure */
memset(&smsghdr, 0, sizeof(smsghdr));
memset(&smsgiov, 0, sizeof(smsgiov));
+ memset(&pktinfo, 0, sizeof(pktinfo));
+
+ intvl.tv_sec = interval / 1000;
+ intvl.tv_nsec = interval % 1000 * 1000000;
alarmtimeout = preload = 0;
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
+ capdns = capdns_setup();
#ifndef IPSEC
#define ADDOPTS
#else
#ifdef IPSEC_POLICY_IPSEC
#define ADDOPTS "P:"
#else
-#define ADDOPTS "AE"
+#define ADDOPTS "ZE"
#endif /*IPSEC_POLICY_IPSEC*/
#endif
while ((ch = getopt(argc, argv,
- "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwWx:X:" ADDOPTS)) != -1) {
+ "k:b:c:DdfHe:m:I:i:l:unNop:qaAS:s:OvyYW:t:" ADDOPTS)) != -1) {
#undef ADDOPTS
switch (ch) {
- case 'a':
+ case 'k':
{
char *cp;
@@ -474,13 +492,13 @@ main(int argc, char *argv[])
options |= F_FLOOD;
setbuf(stdout, (char *)NULL);
break;
- case 'g':
+ case 'e':
gateway = optarg;
break;
case 'H':
options |= F_HOSTNAME;
break;
- case 'h': /* hoplimit */
+ case 'm': /* hoplimit */
hoplimit = strtol(optarg, &e, 10);
if (*optarg == '\0' || *e != '\0')
errx(1, "illegal hoplimit %s", optarg);
@@ -503,15 +521,15 @@ main(int argc, char *argv[])
errx(1, "%s: only root may use interval < 1s",
strerror(EPERM));
}
- intvl.tv_sec = (long)t;
- intvl.tv_usec =
- (long)((t - intvl.tv_sec) * 1000000);
+ intvl.tv_sec = (time_t)t;
+ intvl.tv_nsec =
+ (long)((t - intvl.tv_sec) * 1000000000);
if (intvl.tv_sec < 0)
errx(1, "illegal timing interval %s", optarg);
/* less than 1/hz does not make sense */
- if (intvl.tv_sec == 0 && intvl.tv_usec < 1) {
+ if (intvl.tv_sec == 0 && intvl.tv_nsec < 1000) {
warnx("too small interval, raised to .000001");
- intvl.tv_usec = 1;
+ intvl.tv_nsec = 1000;
}
options |= F_INTERVAL;
break;
@@ -524,7 +542,7 @@ main(int argc, char *argv[])
if (preload < 0 || *optarg == '\0' || *e != '\0')
errx(1, "illegal preload value -- %s", optarg);
break;
- case 'm':
+ case 'u':
#ifdef IPV6_USE_MIN_MTU
mflag++;
break;
@@ -549,10 +567,10 @@ main(int argc, char *argv[])
case 'q':
options |= F_QUIET;
break;
- case 'r':
+ case 'a':
options |= F_AUDIBLE;
break;
- case 'R':
+ case 'A':
options |= F_MISSED;
break;
case 'S':
@@ -562,7 +580,7 @@ main(int argc, char *argv[])
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(optarg, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res);
if (error) {
errx(1, "invalid source address: %s",
gai_strerror(error));
@@ -586,22 +604,22 @@ main(int argc, char *argv[])
MAXDATALEN);
}
break;
- case 't':
+ case 'O':
options &= ~F_NOUSERDATA;
options |= F_SUPTYPES;
break;
case 'v':
options |= F_VERBOSE;
break;
- case 'w':
+ case 'y':
options &= ~F_NOUSERDATA;
options |= F_FQDN;
break;
- case 'W':
+ case 'Y':
options &= ~F_NOUSERDATA;
options |= F_FQDNOLD;
break;
- case 'x':
+ case 'W':
t = strtod(optarg, &e);
if (*e || e == optarg || t > (double)INT_MAX)
err(EX_USAGE, "invalid timing interval: `%s'",
@@ -609,7 +627,7 @@ main(int argc, char *argv[])
options |= F_WAITTIME;
waittime = (int)t;
break;
- case 'X':
+ case 't':
alarmtimeout = strtoul(optarg, &e, 0);
if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
errx(EX_USAGE, "invalid timeout: `%s'",
@@ -633,7 +651,7 @@ main(int argc, char *argv[])
errx(1, "invalid security policy");
break;
#else
- case 'A':
+ case 'Z':
options |= F_AUTHHDR;
break;
case 'E':
@@ -678,14 +696,14 @@ main(int argc, char *argv[])
} else
target = argv[argc - 1];
- /* getaddrinfo */
+ /* cap_getaddrinfo */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(target, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, target, NULL, &hints, &res);
if (error)
errx(1, "%s", gai_strerror(error));
if (res->ai_canonname)
@@ -694,13 +712,16 @@ main(int argc, char *argv[])
hostname = target;
if (!res->ai_addr)
- errx(1, "getaddrinfo failed");
+ errx(1, "cap_getaddrinfo failed");
(void)memcpy(&dst, res->ai_addr, res->ai_addrlen);
- if ((s = socket(res->ai_family, res->ai_socktype,
+ if ((ssend = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol)) < 0)
+ err(1, "socket ssend");
+ if ((srecv = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) < 0)
- err(1, "socket");
+ err(1, "socket srecv");
freeaddrinfo(res);
/* set the source address if specified. */
@@ -715,7 +736,7 @@ main(int argc, char *argv[])
if (dst.sin6_scope_id == 0)
dst.sin6_scope_id = src.sin6_scope_id;
}
- if (bind(s, (struct sockaddr *)&src, srclen) != 0)
+ if (bind(ssend, (struct sockaddr *)&src, srclen) != 0)
err(1, "bind");
}
/* set the gateway (next hop) if specified */
@@ -725,15 +746,15 @@ main(int argc, char *argv[])
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(gateway, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, gateway, NULL, &hints, &res);
if (error) {
- errx(1, "getaddrinfo for the gateway %s: %s",
+ errx(1, "cap_getaddrinfo for the gateway %s: %s",
gateway, gai_strerror(error));
}
if (res->ai_next && (options & F_VERBOSE))
warnx("gateway resolves to multiple addresses");
- if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_NEXTHOP,
res->ai_addr, res->ai_addrlen)) {
err(1, "setsockopt(IPV6_NEXTHOP)");
}
@@ -749,25 +770,25 @@ main(int argc, char *argv[])
int opton = 1;
#ifdef IPV6_RECVHOPOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVHOPOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_HOPOPTS)");
#endif
#ifdef IPV6_RECVDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVDSTOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_DSTOPTS)");
#endif
#ifdef IPV6_RECVRTHDRDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
#endif
@@ -810,31 +831,34 @@ main(int argc, char *argv[])
arc4random_buf(nonce, sizeof(nonce));
optval = 1;
if (options & F_DONTFRAG)
- if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_DONTFRAG,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_DONTFRAG");
hold = 1;
- if (options & F_SO_DEBUG)
- (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ if (options & F_SO_DEBUG) {
+ (void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold,
sizeof(hold));
+ (void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ sizeof(hold));
+ }
optval = IPV6_DEFHLIM;
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
- if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_MULTICAST_HOPS");
#ifdef IPV6_USE_MIN_MTU
if (mflag != 1) {
optval = mflag > 1 ? 0 : 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_USE_MIN_MTU)");
}
#ifdef IPV6_RECVPATHMTU
else {
optval = 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPATHMTU,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_RECVPATHMTU)");
}
@@ -844,27 +868,36 @@ main(int argc, char *argv[])
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
if (options & F_POLICY) {
- if (setpolicy(s, policy_in) < 0)
+ if (setpolicy(srecv, policy_in) < 0)
errx(1, "%s", ipsec_strerror());
- if (setpolicy(s, policy_out) < 0)
+ if (setpolicy(ssend, policy_out) < 0)
errx(1, "%s", ipsec_strerror());
}
#else
if (options & F_AUTHHDR) {
optval = IPSEC_LEVEL_REQUIRE;
#ifdef IPV6_AUTH_TRANS_LEVEL
- if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
#else /* old def */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_AUTH_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_AUTH_LEVEL)");
#endif
}
if (options & F_ENCRYPT) {
optval = IPSEC_LEVEL_REQUIRE;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
}
@@ -884,7 +917,7 @@ main(int argc, char *argv[])
} else {
ICMP6_FILTER_SETPASSALL(&filt);
}
- if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
+ if (setsockopt(srecv, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
sizeof(filt)) < 0)
err(1, "setsockopt(ICMP6_FILTER)");
}
@@ -895,11 +928,11 @@ main(int argc, char *argv[])
int opton = 1;
#ifdef IPV6_RECVRTHDR
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVRTHDR)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RTHDR, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RTHDR)");
#endif
@@ -908,7 +941,7 @@ main(int argc, char *argv[])
/*
optval = 1;
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
- if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_MULTICAST_LOOP");
*/
@@ -926,11 +959,10 @@ main(int argc, char *argv[])
errx(1, "can't allocate enough memory");
smsghdr.msg_control = (caddr_t)scmsg;
smsghdr.msg_controllen = ip6optlen;
- scmsgp = (struct cmsghdr *)scmsg;
+ scmsgp = CMSG_FIRSTHDR(&smsghdr);
}
if (usepktinfo) {
- pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp));
- memset(pktinfo, 0, sizeof(*pktinfo));
+ cmsg_pktinfo = CMSG_DATA(scmsgp);
scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
scmsgp->cmsg_level = IPPROTO_IPV6;
scmsgp->cmsg_type = IPV6_PKTINFO;
@@ -941,7 +973,7 @@ main(int argc, char *argv[])
if (ifname) {
#ifndef USE_SIN6_SCOPE_ID
/* pktinfo must have already been allocated */
- if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0)
+ if ((pktinfo.ipi6_ifindex = if_nametoindex(ifname)) == 0)
errx(1, "%s: invalid interface name", ifname);
#else
if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0)
@@ -952,18 +984,15 @@ main(int argc, char *argv[])
scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
scmsgp->cmsg_level = IPPROTO_IPV6;
scmsgp->cmsg_type = IPV6_HOPLIMIT;
- *(int *)(CMSG_DATA(scmsgp)) = hoplimit;
+ memcpy(CMSG_DATA(scmsgp), &hoplimit, sizeof(hoplimit));
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
}
if (argc > 1) { /* some intermediate addrs are specified */
int hops;
-#ifdef USE_RFC2292BIS
int rthdrlen;
-#endif
-#ifdef USE_RFC2292BIS
rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1);
scmsgp->cmsg_len = CMSG_LEN(rthdrlen);
scmsgp->cmsg_level = IPPROTO_IPV6;
@@ -973,42 +1002,36 @@ main(int argc, char *argv[])
IPV6_RTHDR_TYPE_0, argc - 1);
if (rthdr == NULL)
errx(1, "can't initialize rthdr");
-#else /* old advanced API */
- if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp,
- IPV6_RTHDR_TYPE_0)) == NULL)
- errx(1, "can't initialize rthdr");
-#endif /* USE_RFC2292BIS */
for (hops = 0; hops < argc - 1; hops++) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
- if ((error = getaddrinfo(argv[hops], NULL, &hints,
+ if ((error = cap_getaddrinfo(capdns, argv[hops], NULL, &hints,
&res)))
errx(1, "%s", gai_strerror(error));
if (res->ai_addr->sa_family != AF_INET6)
errx(1,
"bad addr family of an intermediate addr");
sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr;
-#ifdef USE_RFC2292BIS
if (inet6_rth_add(rthdr, &sin6->sin6_addr))
errx(1, "can't add an intermediate node");
-#else /* old advanced API */
- if (inet6_rthdr_add(scmsg, &sin6->sin6_addr,
- IPV6_RTHDR_LOOSE))
- errx(1, "can't add an intermediate node");
-#endif /* USE_RFC2292BIS */
freeaddrinfo(res);
}
-#ifndef USE_RFC2292BIS
- if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE))
- errx(1, "can't set the last flag");
-#endif
-
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
}
+ /* From now on we will use only reverse DNS lookups. */
+#ifdef WITH_CASPER
+ if (capdns != NULL) {
+ const char *types[1];
+
+ types[0] = "ADDR2NAME";
+ if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
+ err(1, "unable to limit access to system.dns service");
+ }
+#endif
if (!(options & F_SRCADDR)) {
/*
* get the source address. XXX since we revoked the root
@@ -1025,10 +1048,9 @@ main(int argc, char *argv[])
src.sin6_port = ntohs(DUMMY_PORT);
src.sin6_scope_id = dst.sin6_scope_id;
-#ifdef USE_RFC2292BIS
- if (pktinfo &&
+ if (usepktinfo &&
setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO,
- (void *)pktinfo, sizeof(*pktinfo)))
+ (void *)&pktinfo, sizeof(pktinfo)))
err(1, "UDP setsockopt(IPV6_PKTINFO)");
if (hoplimit != -1 &&
@@ -1045,12 +1067,6 @@ main(int argc, char *argv[])
setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR,
(void *)rthdr, (rthdr->ip6r_len + 1) << 3))
err(1, "UDP setsockopt(IPV6_RTHDR)");
-#else /* old advanced API */
- if (smsghdr.msg_control &&
- setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTOPTIONS,
- (void *)smsghdr.msg_control, smsghdr.msg_controllen))
- err(1, "UDP setsockopt(IPV6_PKTOPTIONS)");
-#endif
if (connect(dummy, (struct sockaddr *)&src, len) < 0)
err(1, "UDP connect");
@@ -1061,14 +1077,40 @@ main(int argc, char *argv[])
close(dummy);
}
+ /* Save pktinfo in the ancillary data. */
+ if (usepktinfo)
+ memcpy(cmsg_pktinfo, &pktinfo, sizeof(pktinfo));
+
+ if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0)
+ err(1, "connect() ssend");
+
+ caph_cache_catpages();
+ if (caph_enter_casper() < 0)
+ err(1, "caph_enter_casper");
+
+ cap_rights_init(&rights_stdin);
+ if (caph_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
+ err(1, "caph_rights_limit stdin");
+ if (caph_limit_stdout() < 0)
+ err(1, "caph_limit_stdout");
+ if (caph_limit_stderr() < 0)
+ err(1, "caph_limit_stderr");
+
+ cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
+ if (caph_rights_limit(srecv, &rights_srecv) < 0)
+ err(1, "caph_rights_limit srecv");
+ cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT);
+ if (caph_rights_limit(ssend, &rights_ssend) < 0)
+ err(1, "caph_rights_limit ssend");
+
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
if (sockbufsize) {
if (datalen > (size_t)sockbufsize)
warnx("you need -b to increase socket buffer size");
- if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
+ if (setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
err(1, "setsockopt(SO_SNDBUF)");
- if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
+ if (setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
err(1, "setsockopt(SO_RCVBUF)");
}
@@ -1082,7 +1124,7 @@ main(int argc, char *argv[])
* to get some stuff for /etc/ethers.
*/
hold = 48 * 1024;
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
+ setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
sizeof(hold));
}
#endif
@@ -1090,25 +1132,32 @@ main(int argc, char *argv[])
optval = 1;
#ifndef USE_SIN6_SCOPE_ID
#ifdef IPV6_RECVPKTINFO
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */
#endif
#endif /* USE_SIN6_SCOPE_ID */
#ifdef IPV6_RECVHOPLIMIT
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */
#endif
+ cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT);
+ if (caph_rights_limit(srecv, &rights_srecv) < 0)
+ err(1, "caph_rights_limit srecv setsockopt");
+ cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT);
+ if (caph_rights_limit(ssend, &rights_ssend) < 0)
+ err(1, "caph_rights_limit ssend setsockopt");
+
printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
(unsigned long)(pingerlen() - 8));
printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
@@ -1122,7 +1171,7 @@ main(int argc, char *argv[])
while (preload--)
pinger();
}
- gettimeofday(&last, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &last);
sigemptyset(&si_sa.sa_mask);
si_sa.sa_flags = 0;
@@ -1141,15 +1190,12 @@ main(int argc, char *argv[])
}
if (options & F_FLOOD) {
intvl.tv_sec = 0;
- intvl.tv_usec = 10000;
- } else if ((options & F_INTERVAL) == 0) {
- intvl.tv_sec = interval / 1000;
- intvl.tv_usec = interval % 1000 * 1000;
+ intvl.tv_nsec = 10000000;
}
almost_done = 0;
while (seenint == 0) {
- struct timeval now, timeout;
+ struct timespec now, timeout;
struct msghdr m;
struct iovec iov[2];
fd_set rfds;
@@ -1166,22 +1212,14 @@ main(int argc, char *argv[])
}
#endif
FD_ZERO(&rfds);
- FD_SET(s, &rfds);
- gettimeofday(&now, NULL);
- timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
- timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
- while (timeout.tv_usec < 0) {
- timeout.tv_usec += 1000000;
- timeout.tv_sec--;
- }
- while (timeout.tv_usec > 1000000) {
- timeout.tv_usec -= 1000000;
- timeout.tv_sec++;
- }
+ FD_SET(srecv, &rfds);
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timespecadd(&last, &intvl, &timeout);
+ timespecsub(&timeout, &now, &timeout);
if (timeout.tv_sec < 0)
- timeout.tv_sec = timeout.tv_usec = 0;
+ timespecclear(&timeout);
- n = select(s + 1, &rfds, NULL, NULL, &timeout);
+ n = pselect(srecv + 1, &rfds, NULL, NULL, &timeout, NULL);
if (n < 0)
continue; /* EINTR */
if (n == 1) {
@@ -1196,7 +1234,7 @@ main(int argc, char *argv[])
m.msg_control = (void *)cm;
m.msg_controllen = CONTROLLEN;
- cc = recvmsg(s, &m, 0);
+ cc = recvmsg(srecv, &m, 0);
if (cc < 0) {
if (errno != EINTR) {
warn("recvmsg");
@@ -1242,17 +1280,18 @@ main(int argc, char *argv[])
* if we've received any packets or (waittime)
* milliseconds if we haven't.
*/
- intvl.tv_usec = 0;
+ intvl.tv_nsec = 0;
if (nreceived) {
intvl.tv_sec = 2 * tmax / 1000;
if (intvl.tv_sec == 0)
intvl.tv_sec = 1;
} else {
intvl.tv_sec = waittime / 1000;
- intvl.tv_usec = waittime % 1000 * 1000;
+ intvl.tv_nsec =
+ waittime % 1000 * 1000000;
}
}
- gettimeofday(&last, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &last);
if (ntransmitted - nreceived - 1 > nmissedmax) {
nmissedmax = ntransmitted - nreceived - 1;
if (options & F_MISSED)
@@ -1295,7 +1334,7 @@ onsignal(int sig)
* Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
* will be added on by the kernel. The ID field is our UNIX process ID,
* and the sequence number is an ascending integer. The first 8 bytes
- * of the data portion are used to hold a UNIX "timeval" struct in VAX
+ * of the data portion are used to hold a UNIX "timespec" struct in VAX
* byte-order, to compute the round-trip time.
*/
static size_t
@@ -1324,7 +1363,7 @@ pinger(void)
struct iovec iov[2];
int i, cc;
struct icmp6_nodeinfo *nip;
- int seq;
+ uint16_t seq;
if (npackets && ntransmitted >= npackets)
return(-1); /* no more transmission */
@@ -1337,6 +1376,8 @@ pinger(void)
CLR(seq % mx_dup_ck);
if (options & F_FQDN) {
+ uint16_t s;
+
icp->icmp6_type = ICMP6_NI_QUERY;
icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
nip->ni_qtype = htons(NI_QTYPE_FQDN);
@@ -1344,13 +1385,15 @@ pinger(void)
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ s = htons(seq);
+ memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
sizeof(dst.sin6_addr));
cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
datalen = 0;
} else if (options & F_FQDNOLD) {
+ uint16_t s;
/* packet format in 03 draft - no Subject data on queries */
icp->icmp6_type = ICMP6_NI_QUERY;
icp->icmp6_code = 0; /* code field is always 0 */
@@ -1359,11 +1402,14 @@ pinger(void)
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ s = htons(seq);
+ memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
cc = ICMP6_NIQLEN;
datalen = 0;
} else if (options & F_NODEADDR) {
+ uint16_t s;
+
icp->icmp6_type = ICMP6_NI_QUERY;
icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
nip->ni_qtype = htons(NI_QTYPE_NODEADDR);
@@ -1371,13 +1417,16 @@ pinger(void)
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ s = htons(seq);
+ memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
sizeof(dst.sin6_addr));
cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
datalen = 0;
} else if (options & F_SUPTYPES) {
+ uint16_t s;
+
icp->icmp6_type = ICMP6_NI_QUERY;
icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/
nip->ni_qtype = htons(NI_QTYPE_SUPTYPES);
@@ -1386,21 +1435,29 @@ pinger(void)
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ s = htons(seq);
+ memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
+
cc = ICMP6_NIQLEN;
datalen = 0;
} else {
icp->icmp6_type = ICMP6_ECHO_REQUEST;
icp->icmp6_code = 0;
icp->icmp6_id = htons(ident);
- icp->icmp6_seq = ntohs(seq);
+ icp->icmp6_seq = htons(seq);
if (timing) {
- struct timeval tv;
- struct tv32 *tv32;
- (void)gettimeofday(&tv, NULL);
- tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN];
- tv32->tv32_sec = htonl(tv.tv_sec);
- tv32->tv32_usec = htonl(tv.tv_usec);
+ struct timespec tv;
+ struct tv32 tv32;
+ (void)clock_gettime(CLOCK_MONOTONIC, &tv);
+ /*
+ * Truncate seconds down to 32 bits in order
+ * to fit the timestamp within 8 bytes of the
+ * packet. We're only concerned with
+ * durations, not absolute times.
+ */
+ tv32.tv32_sec = (uint32_t)htonl(tv.tv_sec);
+ tv32.tv32_nsec = (uint32_t)htonl(tv.tv_nsec);
+ memcpy(&outpack[ICMP6ECHOLEN], &tv32, sizeof(tv32));
}
cc = ICMP6ECHOLEN + datalen;
}
@@ -1410,15 +1467,13 @@ pinger(void)
errx(1, "internal error; length mismatch");
#endif
- smsghdr.msg_name = (caddr_t)&dst;
- smsghdr.msg_namelen = sizeof(dst);
memset(&iov, 0, sizeof(iov));
iov[0].iov_base = (caddr_t)outpack;
iov[0].iov_len = cc;
smsghdr.msg_iov = iov;
smsghdr.msg_iovlen = 1;
- i = sendmsg(s, &smsghdr, 0);
+ i = sendmsg(ssend, &smsghdr, 0);
if (i < 0 || i != cc) {
if (i < 0)
@@ -1452,10 +1507,26 @@ mynireply(const struct icmp6_nodeinfo *nip)
return 0;
}
-static char *
-dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
+/*
+ * Decode a name from a DNS message.
+ *
+ * Format of the message is described in RFC 1035 subsection 4.1.4.
+ *
+ * Arguments:
+ * sp - Pointer to a DNS pointer octet or to the first octet of a label
+ * in the message.
+ * ep - Pointer to the end of the message (one step past the last octet).
+ * base - Pointer to the beginning of the message.
+ * buf - Buffer into which the decoded name will be saved.
+ * bufsiz - Size of the buffer 'buf'.
+ *
+ * Return value:
+ * Pointer to an octet immediately following the ending zero octet
+ * of the decoded label, or NULL if an error occured.
+ */
+static const char *
+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;
@@ -1463,14 +1534,14 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
const u_char *comp;
int l;
- cp = *sp;
+ cp = sp;
*buf = '\0';
if (cp >= ep)
return NULL;
while (cp < ep) {
i = *cp;
- if (i == 0 || cp != *sp) {
+ if (i == 0 || cp != sp) {
if (strlcat((char *)buf, ".", bufsiz) >= bufsiz)
return NULL; /*result overrun*/
}
@@ -1484,7 +1555,7 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
return NULL;
comp = base + (i & 0x3f);
- if (dnsdecode(&comp, cp, base, cresult,
+ if (dnsdecode(comp, cp, base, cresult,
sizeof(cresult)) == NULL)
return NULL;
if (strlcat(buf, cresult, bufsiz) >= bufsiz)
@@ -1508,8 +1579,7 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
if (i != 0)
return NULL; /*not terminated*/
cp++;
- *sp = cp;
- return buf;
+ return cp;
}
/*
@@ -1529,10 +1599,11 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
int hoplim;
struct sockaddr *from;
int fromlen;
- u_char *cp = NULL, *dp, *end = buf + cc;
+ const u_char *cp = NULL;
+ u_char *dp, *end = buf + cc;
struct in6_pktinfo *pktinfo = NULL;
- struct timeval tv, tp;
- struct tv32 *tpp;
+ struct timespec tv, tp;
+ struct tv32 tpp;
double triptime = 0;
int dupflag;
size_t off;
@@ -1540,7 +1611,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
u_int16_t seq;
char dnsname[MAXDNAME + 1];
- (void)gettimeofday(&tv, NULL);
+ (void)clock_gettime(CLOCK_MONOTONIC, &tv);
if (!mhdr || !mhdr->msg_name ||
mhdr->msg_namelen != sizeof(struct sockaddr_in6) ||
@@ -1577,12 +1648,12 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
seq = ntohs(icp->icmp6_seq);
++nreceived;
if (timing) {
- tpp = (struct tv32 *)(icp + 1);
- tp.tv_sec = ntohl(tpp->tv32_sec);
- tp.tv_usec = ntohl(tpp->tv32_usec);
- tvsub(&tv, &tp);
+ memcpy(&tpp, icp + 1, sizeof(tpp));
+ tp.tv_sec = ntohl(tpp.tv32_sec);
+ tp.tv_nsec = ntohl(tpp.tv32_nsec);
+ timespecsub(&tv, &tp, &tv);
triptime = ((double)tv.tv_sec) * 1000.0 +
- ((double)tv.tv_usec) / 1000.0;
+ ((double)tv.tv_nsec) / 1000000.0;
tsum += triptime;
tsumsq += triptime * triptime;
if (triptime < tmin)
@@ -1643,7 +1714,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
}
}
} else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) {
- seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce);
+ memcpy(&seq, ni->icmp6_ni_nonce, sizeof(seq));
+ seq = ntohs(seq);
++nreceived;
if (TST(seq % mx_dup_ck)) {
++nrepeats;
@@ -1701,9 +1773,10 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
} else {
i = 0;
while (cp < end) {
- if (dnsdecode((const u_char **)&cp, end,
+ cp = dnsdecode((const u_char *)cp, end,
(const u_char *)(ni + 1), dnsname,
- sizeof(dnsname)) == NULL) {
+ sizeof(dnsname));
+ if (cp == NULL) {
printf("???");
break;
}
@@ -1721,6 +1794,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
}
}
if (options & F_VERBOSE) {
+ u_long t;
int32_t ttl;
int comma = 0;
@@ -1743,7 +1817,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
putchar(')');
goto fqdnend;
}
- ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]);
+ memcpy(&t, &buf[off+ICMP6ECHOLEN+8], sizeof(t));
+ ttl = (int32_t)ntohl(t);
if (comma)
printf(",");
if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) {
@@ -1821,7 +1896,7 @@ pr_exthdrs(struct msghdr *mhdr)
bufsize = CONTROLLEN - ((caddr_t)CMSG_DATA(cm) - (caddr_t)bufp);
if (bufsize <= 0)
- continue;
+ continue;
switch (cm->cmsg_type) {
case IPV6_HOPOPTS:
printf(" HbH Options: ");
@@ -1842,7 +1917,6 @@ pr_exthdrs(struct msghdr *mhdr)
}
}
-#ifdef USE_RFC2292BIS
static void
pr_ip6opt(void *extbuf, size_t bufsize)
{
@@ -1904,17 +1978,7 @@ pr_ip6opt(void *extbuf, size_t bufsize)
}
return;
}
-#else /* !USE_RFC2292BIS */
-/* ARGSUSED */
-static void
-pr_ip6opt(void *extbuf, size_t bufsize __unused)
-{
- putchar('\n');
- return;
-}
-#endif /* USE_RFC2292BIS */
-#ifdef USE_RFC2292BIS
static void
pr_rthdr(void *extbuf, size_t bufsize)
{
@@ -1970,16 +2034,6 @@ pr_rthdr(void *extbuf, size_t bufsize)
}
-#else /* !USE_RFC2292BIS */
-/* ARGSUSED */
-static void
-pr_rthdr(void *extbuf, size_t bufsize __unused)
-{
- putchar('\n');
- return;
-}
-#endif /* USE_RFC2292BIS */
-
static int
pr_bitrange(u_int32_t v, int soff, int ii)
{
@@ -2127,11 +2181,13 @@ pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen)
if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0)
withttl = 1;
while (nilen > 0) {
- u_int32_t ttl;
+ u_int32_t ttl = 0;
if (withttl) {
- /* XXX: alignment? */
- ttl = (u_int32_t)ntohl(*(u_int32_t *)cp);
+ uint32_t t;
+
+ memcpy(&t, cp, sizeof(t));
+ ttl = (u_int32_t)ntohl(t);
cp += sizeof(u_int32_t);
nilen -= sizeof(u_int32_t);
}
@@ -2170,8 +2226,12 @@ get_hoplim(struct msghdr *mhdr)
if (cm->cmsg_level == IPPROTO_IPV6 &&
cm->cmsg_type == IPV6_HOPLIMIT &&
- cm->cmsg_len == CMSG_LEN(sizeof(int)))
- return(*(int *)CMSG_DATA(cm));
+ cm->cmsg_len == CMSG_LEN(sizeof(int))) {
+ int r;
+
+ memcpy(&r, CMSG_DATA(cm), sizeof(r));
+ return(r);
+ }
}
return(-1);
@@ -2180,6 +2240,7 @@ get_hoplim(struct msghdr *mhdr)
static struct in6_pktinfo *
get_rcvpktinfo(struct msghdr *mhdr)
{
+ static struct in6_pktinfo pi;
struct cmsghdr *cm;
for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
@@ -2189,8 +2250,10 @@ get_rcvpktinfo(struct msghdr *mhdr)
if (cm->cmsg_level == IPPROTO_IPV6 &&
cm->cmsg_type == IPV6_PKTINFO &&
- cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo)))
- return((struct in6_pktinfo *)CMSG_DATA(cm));
+ cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
+ memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
+ return(&pi);
+ }
}
return(NULL);
@@ -2201,7 +2264,7 @@ get_pathmtu(struct msghdr *mhdr)
{
#ifdef IPV6_RECVPATHMTU
struct cmsghdr *cm;
- struct ip6_mtuinfo *mtuctl = NULL;
+ struct ip6_mtuinfo mtuctl;
for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
@@ -2211,7 +2274,7 @@ get_pathmtu(struct msghdr *mhdr)
if (cm->cmsg_level == IPPROTO_IPV6 &&
cm->cmsg_type == IPV6_PATHMTU &&
cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) {
- mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm);
+ memcpy(&mtuctl, CMSG_DATA(cm), sizeof(mtuctl));
/*
* If the notified destination is different from
@@ -2221,17 +2284,17 @@ get_pathmtu(struct msghdr *mhdr)
* have used the default scope zone ID for sending,
* in which case the scope ID value is 0.
*/
- if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr,
+ if (!IN6_ARE_ADDR_EQUAL(&mtuctl.ip6m_addr.sin6_addr,
&dst.sin6_addr) ||
- (mtuctl->ip6m_addr.sin6_scope_id &&
+ (mtuctl.ip6m_addr.sin6_scope_id &&
dst.sin6_scope_id &&
- mtuctl->ip6m_addr.sin6_scope_id !=
+ mtuctl.ip6m_addr.sin6_scope_id !=
dst.sin6_scope_id)) {
if ((options & F_VERBOSE) != 0) {
printf("path MTU for %s is notified. "
"(ignored)\n",
- pr_addr((struct sockaddr *)&mtuctl->ip6m_addr,
- sizeof(mtuctl->ip6m_addr)));
+ pr_addr((struct sockaddr *)&mtuctl.ip6m_addr,
+ sizeof(mtuctl.ip6m_addr)));
}
return(0);
}
@@ -2240,11 +2303,11 @@ get_pathmtu(struct msghdr *mhdr)
* Ignore an invalid MTU. XXX: can we just believe
* the kernel check?
*/
- if (mtuctl->ip6m_mtu < IPV6_MMTU)
+ if (mtuctl.ip6m_mtu < IPV6_MMTU)
return(0);
/* notification for our destination. return the MTU. */
- return((int)mtuctl->ip6m_mtu);
+ return((int)mtuctl.ip6m_mtu);
}
}
#endif
@@ -2252,21 +2315,6 @@ get_pathmtu(struct msghdr *mhdr)
}
/*
- * tvsub --
- * Subtract 2 timeval structs: out = out - in. Out is assumed to
- * be >= in.
- */
-static void
-tvsub(struct timeval *out, struct timeval *in)
-{
- if ((out->tv_usec -= in->tv_usec) < 0) {
- --out->tv_sec;
- out->tv_usec += 1000000;
- }
- out->tv_sec -= in->tv_sec;
-}
-
-/*
* onint --
* SIGINT handler.
*/
@@ -2504,8 +2552,9 @@ pr_icmph(struct icmp6_hdr *icp, u_char *end)
}
printf(", subject=%s", niqcode[ni->ni_code]);
cp = (const u_char *)(ni + 1);
- if (dnsdecode(&cp, end, NULL, dnsname,
- sizeof(dnsname)) != NULL)
+ cp = dnsdecode(cp, end, NULL, dnsname,
+ sizeof(dnsname));
+ if (cp != NULL)
printf("(%s)", dnsname);
else
printf("(invalid)");
@@ -2603,7 +2652,8 @@ pr_addr(struct sockaddr *addr, int addrlen)
if ((options & F_HOSTNAME) == 0)
flag |= NI_NUMERICHOST;
- if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0)
+ if (cap_getnameinfo(capdns, addr, addrlen, buf, sizeof(buf), NULL, 0,
+ flag) == 0)
return (buf);
else
return "?";
@@ -2629,6 +2679,10 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
nh = ip6->ip6_nxt;
cp += hlen;
while (end - cp >= 8) {
+#ifdef IPSEC
+ struct ah ah;
+#endif
+
switch (nh) {
case IPPROTO_HOPOPTS:
printf("HBH ");
@@ -2653,8 +2707,9 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
#ifdef IPSEC
case IPPROTO_AH:
printf("AH ");
- hlen = (((struct ah *)cp)->ah_len+2) << 2;
- nh = ((struct ah *)cp)->ah_nxt;
+ memcpy(&ah, cp, sizeof(ah));
+ hlen = (ah.ah_len+2) << 2;
+ nh = ah.ah_nxt;
break;
#endif
case IPPROTO_ICMPV6:
@@ -2741,7 +2796,7 @@ setpolicy(int so __unused, char *policy)
buf = ipsec_set_policy(policy, strlen(policy));
if (buf == NULL)
errx(1, "%s", ipsec_strerror());
- if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
ipsec_get_policylen(buf)) < 0)
warnx("Unable to set IPsec policy");
free(buf);
@@ -2795,7 +2850,7 @@ nigroup(char *name, int nig_oldmcprefix)
}
if (valid != 1)
return NULL; /*XXX*/
-
+
if (nig_oldmcprefix) {
/* draft-ietf-ipngwg-icmp-name-lookup */
bcopy(digest, &in6.s6_addr[12], 4);
@@ -2815,27 +2870,55 @@ usage(void)
{
(void)fprintf(stderr,
#if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
- "A"
+ "Z"
#endif
"usage: ping6 [-"
- "Dd"
+ "aADd"
#if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
"E"
#endif
- "fH"
+ "fHnNoOq"
#ifdef IPV6_USE_MIN_MTU
- "m"
+ "u"
#endif
- "nNoqrRtvwW] "
- "[-a addrtype] [-b bufsiz] [-c count] [-g gateway]\n"
- " [-h hoplimit] [-I interface] [-i wait] [-l preload]"
+ "vyY] "
+ "[-b bufsiz] [-c count] [-e gateway]\n"
+ " [-I interface] [-i wait] [-k addrtype] [-l preload] "
+ "[-m hoplimit]\n"
+ " [-p pattern]"
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
" [-P policy]"
#endif
- "\n"
- " [-p pattern] [-S sourceaddr] [-s packetsize] "
- "[-x waittime]\n"
- " [-X timeout] [hops ...] host\n");
+ " [-S sourceaddr] [-s packetsize]\n"
+ " [-t timeout] [-W waittime] [hops ...] host\n");
exit(1);
}
+
+static cap_channel_t *
+capdns_setup(void)
+{
+ cap_channel_t *capcas, *capdnsloc;
+#ifdef WITH_CASPER
+ const char *types[2];
+ int families[1];
+#endif
+ capcas = cap_init();
+ if (capcas == NULL)
+ err(1, "unable to create casper process");
+ capdnsloc = cap_service_open(capcas, "system.dns");
+ /* Casper capability no longer needed. */
+ cap_close(capcas);
+ if (capdnsloc == NULL)
+ err(1, "unable to open system.dns service");
+#ifdef WITH_CASPER
+ types[0] = "NAME2ADDR";
+ types[1] = "ADDR2NAME";
+ if (cap_dns_type_limit(capdnsloc, types, nitems(types)) < 0)
+ err(1, "unable to limit access to system.dns service");
+ families[0] = AF_INET6;
+ if (cap_dns_family_limit(capdnsloc, families, nitems(families)) < 0)
+ err(1, "unable to limit access to system.dns service");
+#endif
+ return (capdnsloc);
+}
#endif /* defined(__rtems__) && defined(INET6) */
diff --git a/freebsd/sbin/ping6/rtems-bsd-ping6-data.h b/freebsd/sbin/ping6/rtems-bsd-ping6-data.h
index 40e781b8..e140c085 100644
--- a/freebsd/sbin/ping6/rtems-bsd-ping6-data.h
+++ b/freebsd/sbin/ping6/rtems-bsd-ping6-data.h
@@ -1,4 +1,3 @@
/* generated by userspace-header-gen.py */
#include <rtems/linkersets.h>
/* ping6.c */
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, extern u_int options);
diff --git a/freebsd/sbin/ping6/rtems-bsd-ping6-namespace.h b/freebsd/sbin/ping6/rtems-bsd-ping6-namespace.h
index 8b875692..54f15fad 100644
--- a/freebsd/sbin/ping6/rtems-bsd-ping6-namespace.h
+++ b/freebsd/sbin/ping6/rtems-bsd-ping6-namespace.h
@@ -1,3 +1,2 @@
/* generated by userspace-header-gen.py */
/* ping6.c */
-#define options _bsd_ping6_options
diff --git a/freebsd/sbin/ping6/rtems-bsd-ping6-ping6-data.h b/freebsd/sbin/ping6/rtems-bsd-ping6-ping6-data.h
index 9793bc1c..335fe731 100644
--- a/freebsd/sbin/ping6/rtems-bsd-ping6-ping6-data.h
+++ b/freebsd/sbin/ping6/rtems-bsd-ping6-ping6-data.h
@@ -18,7 +18,6 @@ RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int hoplimit);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int ident);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int interval);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int mx_dup_ck);
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int s);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int timing);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static int waittime);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_ping6, static long int nmissedmax);
diff --git a/freebsd/sbin/sysctl/sysctl.c b/freebsd/sbin/sysctl/sysctl.c
index f298da0c..30ebe5fd 100644
--- a/freebsd/sbin/sysctl/sysctl.c
+++ b/freebsd/sbin/sysctl/sysctl.c
@@ -61,6 +61,7 @@ static const char rcsid[] =
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <dev/evdev/input.h>
#ifdef __amd64__
#include <sys/efi.h>
@@ -729,6 +730,22 @@ S_vmtotal(size_t l2, void *p)
return (0);
}
+static int
+S_input_id(size_t l2, void *p)
+{
+ struct input_id *id = p;
+
+ if (l2 != sizeof(*id)) {
+ warnx("S_input_id %zu != %zu", l2, sizeof(*id));
+ return (1);
+ }
+
+ printf("{ bustype = 0x%04x, vendor = 0x%04x, "
+ "product = 0x%04x, version = 0x%04x }",
+ id->bustype, id->vendor, id->product, id->version);
+ return (0);
+}
+
#ifdef __amd64__
static int
S_efi_map(size_t l2, void *p)
@@ -1036,6 +1053,8 @@ show_var(int *oid, int nlen)
func = S_loadavg;
else if (strcmp(fmt, "S,vmtotal") == 0)
func = S_vmtotal;
+ else if (strcmp(fmt, "S,input_id") == 0)
+ func = S_input_id;
#ifdef __amd64__
else if (strcmp(fmt, "S,efi_map_header") == 0)
func = S_efi_map;