From: Apple Date: Mon, 6 May 2013 23:39:48 +0000 (+0000) Subject: network_cmds-433.tar.gz X-Git-Tag: os-x-109^0 X-Git-Url: https://git.saurik.com/apple/network_cmds.git/commitdiff_plain/9dc66a05cc4adb91b19bae0373afae7fac34ede8?ds=inline network_cmds-433.tar.gz --- diff --git a/dnctl/dnctl.c b/dnctl/dnctl.c index d913f90..90248d3 100644 --- a/dnctl/dnctl.c +++ b/dnctl/dnctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2011 Apple Inc. All rights reserved. + * Copyright (c) 2002-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -70,6 +70,11 @@ #include #include +/* + * Limit delay to avoid computation overflow + */ +#define MAX_DELAY (INT_MAX / 1000) + int do_quiet, /* Be quiet in add and flush */ @@ -584,6 +589,7 @@ delete(int ac, char *av[]) * arguments. */ #define NEED1(msg) {if (!ac) errx(EX_USAGE, msg);} +#define NEED2(msg, arg) {if (!ac) errx(EX_USAGE, msg, arg);} static void config_pipe(int ac, char **av) @@ -820,7 +826,7 @@ end_mask: case TOK_DELAY: if (do_pipe != 1) errx(EX_DATAERR, "delay only valid for pipes"); - NEED1("delay needs argument 0..10000ms\n"); + NEED2("delay needs argument 0..%d\n", MAX_DELAY); p.delay = (int)strtoul(av[0], NULL, 0); ac--; av++; break; @@ -848,8 +854,8 @@ end_mask: if (do_pipe == 1) { if (p.pipe_nr == 0) errx(EX_DATAERR, "pipe_nr must be > 0"); - if (p.delay > 10000) - errx(EX_DATAERR, "delay must be < 10000"); + if (p.delay > MAX_DELAY) + errx(EX_DATAERR, "delay must be < %d ms", MAX_DELAY); } else { /* do_pipe == 2, queue */ if (p.fs.parent_nr == 0) errx(EX_DATAERR, "pipe must be > 0"); diff --git a/ifconfig.tproj/af_inet6.c b/ifconfig.tproj/af_inet6.c index 0f32774..14e2a60 100644 --- a/ifconfig.tproj/af_inet6.c +++ b/ifconfig.tproj/af_inet6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -66,6 +66,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -84,6 +85,10 @@ static const char rcsid[] = #include "ifconfig.h" +#define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ + "\004IFDISABLED\005DONT_SET_IFROUTE\006PROXY_PREFIXES" \ + "\007IGNORE_NA\010INSECURE" + static struct in6_ifreq in6_ridreq; static struct in6_aliasreq in6_addreq = { { 0 }, @@ -110,6 +115,29 @@ setifprefixlen(const char *addr, int dummy __unused, int s, explicit_prefix = 1; } +static void +setnd6flags(const char *dummyaddr __unused, int d, int s, + const struct afswtch *afp) +{ + struct in6_ndireq nd; + int error; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + error = ioctl(s, SIOCGIFINFO_IN6, &nd); + if (error) { + warn("ioctl(SIOCGIFINFO_IN6)"); + return; + } + if (d < 0) + nd.ndi.flags &= ~(-d); + else + nd.ndi.flags |= d; + error = ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd); + if (error) + warn("ioctl(SIOCSIFINFO_FLAGS)"); +} + static void setip6flags(const char *dummyaddr __unused, int flag, int dummysoc __unused, const struct afswtch *afp) @@ -317,6 +345,8 @@ in6_status(int s __unused, const struct ifaddrs *ifa) printf("autoconf "); if ((flags6 & IN6_IFF_TEMPORARY) != 0) printf("temporary "); + if ((flags6 & IN6_IFF_SECURED) != 0) + printf("secured "); if (scopeid) printf("scopeid 0x%x ", scopeid); @@ -503,6 +533,34 @@ in6_status_tunnel(int s) printf("\ttunnel inet6 %s --> %s\n", src, dst); } +static void +nd6_status(int s) +{ + struct in6_ndireq nd; + int s6; + int error; + + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); + if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + if (errno != EPROTONOSUPPORT) + warn("socket(AF_INET6, SOCK_DGRAM)"); + return; + } + error = ioctl(s6, SIOCGIFINFO_IN6, &nd); + if (error) { + if (errno != EPFNOSUPPORT && errno != EINVAL) + warn("ioctl(SIOCGIFINFO_IN6)"); + close(s6); + return; + } + close(s6); + if (nd.ndi.flags == 0) + return; + printb("\tnd6 options", (unsigned int)nd.ndi.flags, ND6BITS); + putchar('\n'); +} + static void in6_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres) { @@ -547,9 +605,21 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags), DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags), DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags), + DEF_CMD("nud", ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags), + DEF_CMD("ifdisabled", ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags), + DEF_CMD("ignore_na", ND6_IFF_IGNORE_NA, setnd6flags), + DEF_CMD("-ignore_na", -ND6_IFF_IGNORE_NA, setnd6flags), + DEF_CMD("proxy_prefixes", ND6_IFF_PROXY_PREFIXES, setnd6flags), + DEF_CMD("-proxy_prefixes", -ND6_IFF_PROXY_PREFIXES, setnd6flags), + DEF_CMD("insecure", ND6_IFF_INSECURE, setnd6flags), + DEF_CMD("-insecure", -ND6_IFF_INSECURE, setnd6flags), DEF_CMD_ARG("pltime", setip6pltime), DEF_CMD_ARG("vltime", setip6vltime), DEF_CMD("eui64", 0, setip6eui64), + DEF_CMD("secured", IN6_IFF_SECURED, setip6flags), + DEF_CMD("-secured", -IN6_IFF_SECURED, setip6flags), }; static struct afswtch af_inet6 = { @@ -558,6 +628,7 @@ static struct afswtch af_inet6 = { .af_status = in6_status, .af_getaddr = in6_getaddr, .af_getprefix = in6_getprefix, + .af_other_status = nd6_status, .af_postproc = in6_postproc, .af_status_tunnel = in6_status_tunnel, .af_settunnel = in6_set_tunnel, diff --git a/ifconfig.tproj/ifbridge.c b/ifconfig.tproj/ifbridge.c index 53c98af..7a3c1b7 100644 --- a/ifconfig.tproj/ifbridge.c +++ b/ifconfig.tproj/ifbridge.c @@ -1,3 +1,31 @@ +/* + * Copyright (c) 2009-2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + /*- * Copyright 2001 Wasabi Systems, Inc. * All rights reserved. @@ -33,11 +61,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/sbin/ifconfig/ifbridge.c,v 1.11.2.1.2.1 2008/11/25 02:59:29 kensmith Exp $"; -#endif /* not lint */ - #include #include #include @@ -79,7 +102,6 @@ static const char *stpstates[] = { "blocking", "discarding" }; -#ifdef notdef static const char *stpproto[] = { "stp", "-", @@ -92,7 +114,6 @@ static const char *stproles[] = { "alternate", "backup" }; -#endif static int get_val(const char *cp, u_long *valp) @@ -181,15 +202,12 @@ bridge_interfaces(int s, const char *prefix) printf("\n"); printf("%s", pad); -#ifdef notdef printf("ifmaxaddr %u", req->ifbr_addrmax); -#endif printf(" port %u priority %u", req->ifbr_portno, req->ifbr_priority); printf(" path cost %u", req->ifbr_path_cost); if (req->ifbr_ifsflags & IFBIF_STP) { -#ifdef notdef if (req->ifbr_proto < sizeof(stpproto) / sizeof(stpproto[0])) printf(" proto %s", stpproto[req->ifbr_proto]); @@ -204,7 +222,6 @@ bridge_interfaces(int s, const char *prefix) else printf("", req->ifbr_role); -#endif if (req->ifbr_state < sizeof(stpstates) / sizeof(stpstates[0])) printf(" state %s", stpstates[req->ifbr_state]); @@ -244,13 +261,8 @@ bridge_addresses(int s, const char *prefix) ifba = ifbac.ifbac_req + i; memcpy(ea.octet, ifba->ifba_dst, sizeof(ea.octet)); -#ifdef notdef printf("%s%s Vlan%d %s %lu ", prefix, ether_ntoa(&ea), ifba->ifba_vlan, ifba->ifba_ifsname, ifba->ifba_expire); -#else - printf("%s%s %s %lu ", prefix, ether_ntoa(&ea), - ifba->ifba_ifsname, ifba->ifba_expire); -#endif printb("flags", ifba->ifba_flags, IFBAFBITS); printf("\n"); } @@ -258,58 +270,17 @@ bridge_addresses(int s, const char *prefix) free(inbuf); } -void -show_config(int sock, const char *prefix) -{ - struct ifbrparam param; - u_int32_t ipfflags; - u_int16_t pri; - u_int8_t ht, fd, ma; - - if (do_cmd(sock, BRDGGPRI, ¶m, sizeof(param), 0) < 0) - err(1, "unable to get bridge priority"); - pri = param.ifbrp_prio; - - if (do_cmd(sock, BRDGGHT, ¶m, sizeof(param), 0) < 0) - err(1, "unable to get hellotime"); - ht = param.ifbrp_hellotime; - - if (do_cmd(sock, BRDGGFD, ¶m, sizeof(param), 0) < 0) - err(1, "unable to get forward delay"); - fd = param.ifbrp_fwddelay; - - if (do_cmd(sock, BRDGGMA, ¶m, sizeof(param), 0) < 0) - err(1, "unable to get max age"); - ma = param.ifbrp_maxage; - - printf("%spriority %u hellotime %u fwddelay %u maxage %u\n", - prefix, pri, ht, fd, ma); - - if (do_cmd(sock, BRDGGFILT, ¶m, sizeof(param), 0) < 0) { - /* err(1, "unable to get ipfilter status"); */ - param.ifbrp_filter = 0; - } - - ipfflags = param.ifbrp_filter; - printf("%sipfilter %s flags 0x%x\n", prefix, - (ipfflags & IFBF_FILT_USEIPF) ? "enabled" : "disabled", - ipfflags); -} - static void bridge_status(int s) { -#ifdef notdef struct ifbropreq ifbp; -#endif struct ifbrparam param; -#ifdef notdef u_int16_t pri; u_int8_t ht, fd, ma, hc, pro; u_int8_t lladdr[ETHER_ADDR_LEN]; u_int16_t bprio; -#endif u_int32_t csize, ctime; + u_int32_t ipfflags; if (do_cmd(s, BRDGGCACHE, ¶m, sizeof(param), 0) < 0) return; @@ -317,7 +288,9 @@ bridge_status(int s) if (do_cmd(s, BRDGGTO, ¶m, sizeof(param), 0) < 0) return; ctime = param.ifbrp_ctime; -#ifdef notdef + if (do_cmd(s, BRDGGFILT, ¶m, sizeof(param), 0) < 0) + return; + ipfflags = param.ifbrp_filter; if (do_cmd(s, BRDGPARAM, &ifbp, sizeof(ifbp), 0) < 0) return; pri = ifbp.ifbop_priority; @@ -327,26 +300,25 @@ bridge_status(int s) hc = ifbp.ifbop_holdcount; ma = ifbp.ifbop_maxage; + printf("\tConfiguration:\n"); PV2ID(ifbp.ifbop_bridgeid, bprio, lladdr); - printf("\tid %s priority %u hellotime %u fwddelay %u\n", + printf("\t\tid %s priority %u hellotime %u fwddelay %u\n", ether_ntoa((struct ether_addr *)lladdr), pri, ht, fd); - printf("\tmaxage %u holdcnt %u proto %s maxaddr %u timeout %u\n", + printf("\t\tmaxage %u holdcnt %u proto %s maxaddr %u timeout %u\n", ma, hc, stpproto[pro], csize, ctime); PV2ID(ifbp.ifbop_designated_root, bprio, lladdr); - printf("\troot id %s priority %d ifcost %u port %u\n", + printf("\t\troot id %s priority %d ifcost %u port %u\n", ether_ntoa((struct ether_addr *)lladdr), bprio, ifbp.ifbop_root_path_cost, ifbp.ifbop_root_port & 0xfff); -#else - printf("\tConfiguration:\n"); - show_config(s, "\t\t"); -#endif + + printf("\t\tipfilter %s flags 0x%x\n", + (ipfflags & IFBF_FILT_USEIPF) ? "enabled" : "disabled", ipfflags); bridge_interfaces(s, "\tmember: "); - if (!all || verbose) { - printf("\tAddress cache (max cache: %u, timeout: %u):\n", - csize, ctime); + if (!all || verbose > 1) { + printf("\tAddress cache:\n"); bridge_addresses(s, "\t\t"); } return; @@ -543,10 +515,8 @@ setbridge_static(const char *val, const char *mac, int s, memcpy(req.ifba_dst, ea->octet, sizeof(req.ifba_dst)); req.ifba_flags = IFBAF_STATIC; -#ifdef notdef req.ifba_vlan = 1; /* XXX allow user to specify */ -#endif - + if (do_cmd(s, BRDGSADDR, &req, sizeof(req), 1) < 0) err(1, "BRDGSADDR %s", val); } @@ -668,6 +638,7 @@ setbridge_protocol(const char *arg, int d, int s, const struct afswtch *afp) if (do_cmd(s, BRDGSPROTO, ¶m, sizeof(param), 1) < 0) err(1, "BRDGSPROTO %s", arg); } + static void setbridge_holdcount(const char *arg, int d, int s, const struct afswtch *afp) { @@ -781,20 +752,24 @@ static struct cmd bridge_cmds[] = { DEF_CMD_ARG("-discover", unsetbridge_discover), DEF_CMD_ARG("learn", setbridge_learn), DEF_CMD_ARG("-learn", unsetbridge_learn), - //DEF_CMD_ARG("sticky", setbridge_sticky), - //DEF_CMD_ARG("-sticky", unsetbridge_sticky), - //DEF_CMD_ARG("span", setbridge_span), - //DEF_CMD_ARG("-span", unsetbridge_span), +#ifdef notdef + DEF_CMD_ARG("sticky", setbridge_sticky), + DEF_CMD_ARG("-sticky", unsetbridge_sticky), + DEF_CMD_ARG("span", setbridge_span), + DEF_CMD_ARG("-span", unsetbridge_span), +#endif DEF_CMD_ARG("stp", setbridge_stp), DEF_CMD_ARG("-stp", unsetbridge_stp), - //DEF_CMD_ARG("edge", setbridge_edge), - //DEF_CMD_ARG("-edge", unsetbridge_edge), - //DEF_CMD_ARG("autoedge", setbridge_autoedge), - //DEF_CMD_ARG("-autoedge", unsetbridge_autoedge), - //DEF_CMD_ARG("ptp", setbridge_ptp), - //DEF_CMD_ARG("-ptp", unsetbridge_ptp), - //DEF_CMD_ARG("autoptp", setbridge_autoptp), - //DEF_CMD_ARG("-autoptp", unsetbridge_autoptp), +#ifdef notdef + DEF_CMD_ARG("edge", setbridge_edge), + DEF_CMD_ARG("-edge", unsetbridge_edge), + DEF_CMD_ARG("autoedge", setbridge_autoedge), + DEF_CMD_ARG("-autoedge", unsetbridge_autoedge), + DEF_CMD_ARG("ptp", setbridge_ptp), + DEF_CMD_ARG("-ptp", unsetbridge_ptp), + DEF_CMD_ARG("autoptp", setbridge_autoptp), + DEF_CMD_ARG("-autoptp", unsetbridge_autoptp), +#endif DEF_CMD("flush", 0, setbridge_flush), DEF_CMD("flushall", 0, setbridge_flushall), DEF_CMD_ARG2("static", setbridge_static), @@ -805,14 +780,20 @@ static struct cmd bridge_cmds[] = { DEF_CMD_ARG("fwddelay", setbridge_fwddelay), DEF_CMD_ARG("maxage", setbridge_maxage), DEF_CMD_ARG("priority", setbridge_priority), - //DEF_CMD_ARG("proto", setbridge_protocol), - //DEF_CMD_ARG("holdcnt", setbridge_holdcount), +#ifdef notdef + DEF_CMD_ARG("proto", setbridge_protocol), + DEF_CMD_ARG("holdcnt", setbridge_holdcount), +#endif DEF_CMD_ARG2("ifpriority", setbridge_ifpriority), DEF_CMD_ARG2("ifpathcost", setbridge_ifpathcost), - //DEF_CMD_ARG2("ifmaxaddr", setbridge_ifmaxaddr), +#ifdef notdef + DEF_CMD_ARG2("ifmaxaddr", setbridge_ifmaxaddr), +#endif DEF_CMD_ARG("timeout", setbridge_timeout), - //DEF_CMD_ARG("private", setbridge_private), - //DEF_CMD_ARG("-private", unsetbridge_private), +#ifdef notdef + DEF_CMD_ARG("private", setbridge_private), + DEF_CMD_ARG("-private", unsetbridge_private), +#endif }; static struct afswtch af_bridge = { .af_name = "af_bridge", diff --git a/ifconfig.tproj/ifclone.c b/ifconfig.tproj/ifclone.c index 3a782ef..16c6643 100644 --- a/ifconfig.tproj/ifclone.c +++ b/ifconfig.tproj/ifclone.c @@ -48,7 +48,6 @@ static const char rcsid[] = static void list_cloners(void) { -#ifdef notdef struct if_clonereq ifcr; char *cp, *buf; int idx; @@ -87,7 +86,6 @@ list_cloners(void) putchar('\n'); free(buf); -#endif } static clone_callback_func *clone_cb = NULL; diff --git a/ifconfig.tproj/ifconfig.8 b/ifconfig.tproj/ifconfig.8 index 5648409..91a2926 100644 --- a/ifconfig.tproj/ifconfig.8 +++ b/ifconfig.tproj/ifconfig.8 @@ -1,3 +1,29 @@ +.\" Copyright (c) 2013 Apple Inc. All rights reserved. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_START@ +.\" +.\" This file contains Original Code and/or Modifications of Original Code +.\" as defined in and that are subject to the Apple Public Source License +.\" Version 2.0 (the 'License'). You may not use this file except in +.\" compliance with the License. The rights granted to you under the License +.\" may not be used to create, or enable the creation or redistribution of, +.\" unlawful or unlicensed copies of an Apple operating system, or to +.\" circumvent, violate, or enable the circumvention or violation of, any +.\" terms of an Apple operating system software license agreement. +.\" +.\" Please obtain a copy of the License at +.\" http://www.opensource.apple.com/apsl/ and read it before using this file. +.\" +.\" The Original Code and all software distributed under the License are +.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +.\" Please see the License for the specific language governing rights and +.\" limitations under the License. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_END@ +.\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -515,6 +541,25 @@ If the interface was reset when previously marked down, the hardware will be re-initialized. .El .Pp +The following parameters are for ICMPv6 Neighbor Discovery Protocol. +Note that the address family keyword +.Dq Li inet6 +is needed for them: +.Bl -tag -width indent +.It Cm nud +Perform network unreachability detection (NUD). +.It Cm -nud +Do not perform network unreachability detection (NUD). +.It Cm ifdisabled +Disable all IPv6 communication on the interface. +.It Cm -ifdisabled +Do not disable all IPv6 communication on the interface. +.It Cm insecure +Disable the processing of Secure Neighbor Discovery (SEND). +.It Cm -insecure +Do not disabled the processing of Secure Neighbor Discovery (SEND). +.El +.Pp The following parameters are specific to link aggregate interfaces: .Bl -tag -width indent .It Cm bonddev Ar iface @@ -689,39 +734,39 @@ This is the default for all interfaces added to a bridge. Clear the .Dq learning attribute on a member interface. -.It Cm sticky Ar interface -Mark an interface as a -.Dq sticky -interface. -Dynamically learned address entries are treated at static once entered into -the cache. -Sticky entries are never aged out of the cache or replaced, even if the -address is seen on a different interface. -.It Cm -sticky Ar interface -Clear the -.Dq sticky -attribute on a member interface. -.It Cm private Ar interface -Mark an interface as a -.Dq private -interface. -A private interface does not forward any traffic to any other port that is also -a private interface. -.It Cm -private Ar interface -Clear the -.Dq private -attribute on a member interface. -.It Cm span Ar interface -Add the interface named by -.Ar interface -as a span port on the bridge. -Span ports transmit a copy of every frame received by the bridge. -This is most useful for snooping a bridged network passively on -another host connected to one of the span ports of the bridge. -.It Cm -span Ar interface -Delete the interface named by -.Ar interface -from the list of span ports of the bridge. +.\".It Cm sticky Ar interface +.\"Mark an interface as a +.\".Dq sticky +.\"interface. +.\"Dynamically learned address entries are treated at static once entered into +.\"the cache. +.\"Sticky entries are never aged out of the cache or replaced, even if the +.\"address is seen on a different interface. +.\".It Cm -sticky Ar interface +.\"Clear the +.\".Dq sticky +.\"attribute on a member interface. +.\".It Cm private Ar interface +.\"Mark an interface as a +.\".Dq private +.\"interface. +.\"A private interface does not forward any traffic to any other port that is also +.\"a private interface. +.\".It Cm -private Ar interface +.\"Clear the +.\".Dq private +.\"attribute on a member interface. +.\".It Cm span Ar interface +.\"Add the interface named by +.\".Ar interface +.\"as a span port on the bridge. +.\"Span ports transmit a copy of every frame received by the bridge. +.\"This is most useful for snooping a bridged network passively on +.\"another host connected to one of the span ports of the bridge. +.\".It Cm -span Ar interface +.\"Delete the interface named by +.\".Ar interface +.\"from the list of span ports of the bridge. .It Cm stp Ar interface Enable Spanning Tree protocol on .Ar interface . @@ -733,43 +778,43 @@ Spanning Tree is used to detect and remove loops in a network topology. Disable Spanning Tree protocol on .Ar interface . This is the default for all interfaces added to a bridge. -.It Cm edge Ar interface -Set -.Ar interface -as an edge port. -An edge port connects directly to end stations cannot create bridging -loops in the network, this allows it to transition straight to forwarding. -.It Cm -edge Ar interface -Disable edge status on -.Ar interface . -.It Cm autoedge Ar interface -Allow -.Ar interface -to automatically detect edge status. -This is the default for all interfaces added to a bridge. -.It Cm -autoedge Ar interface -Disable automatic edge status on -.Ar interface . -.It Cm ptp Ar interface -Set the -.Ar interface -as a point to point link. -This is required for straight transitions to forwarding and -should be enabled on a direct link to another RSTP capable switch. -.It Cm -ptp Ar interface -Disable point to point link status on -.Ar interface . -This should be disabled for a half duplex link and for an interface -connected to a shared network segment, -like a hub or a wireless network. -.It Cm autoptp Ar interface -Automatically detect the point to point status on -.Ar interface -by checking the full duplex link status. -This is the default for interfaces added to the bridge. -.It Cm -autoptp Ar interface -Disable automatic point to point link detection on -.Ar interface . +.\".It Cm edge Ar interface +.\"Set +.\".Ar interface +.\"as an edge port. +.\"An edge port connects directly to end stations cannot create bridging +.\"loops in the network, this allows it to transition straight to forwarding. +.\".It Cm -edge Ar interface +.\"Disable edge status on +.\".Ar interface . +.\".It Cm autoedge Ar interface +.\"Allow +.\".Ar interface +.\"to automatically detect edge status. +.\"This is the default for all interfaces added to a bridge. +.\".It Cm -autoedge Ar interface +.\"Disable automatic edge status on +.\".Ar interface . +.\".It Cm ptp Ar interface +.\"Set the +.\".Ar interface +.\"as a point to point link. +.\"This is required for straight transitions to forwarding and +.\"should be enabled on a direct link to another RSTP capable switch. +.\".It Cm -ptp Ar interface +.\"Disable point to point link status on +.\".Ar interface . +.\"This should be disabled for a half duplex link and for an interface +.\"connected to a shared network segment, +.\"like a hub or a wireless network. +.\".It Cm autoptp Ar interface +.\"Automatically detect the point to point status on +.\".Ar interface +.\"by checking the full duplex link status. +.\"This is the default for interfaces added to the bridge. +.\".It Cm -autoptp Ar interface +.\"Disable automatic point to point link detection on +.\".Ar interface . .It Cm maxage Ar seconds Set the time that a Spanning Tree protocol configuration is valid. The default is 20 seconds. @@ -789,15 +834,15 @@ The minimum is 1 second and the maximum is 2 seconds. Set the bridge priority for Spanning Tree. The default is 32768. The minimum is 0 and the maximum is 61440. -.It Cm proto Ar value -Set the Spanning Tree protocol. -The default is rstp. -The available options are stp and rstp. -.It Cm holdcnt Ar value -Set the transmit hold count for Spanning Tree. -This is the number of packets transmitted before being rate limited. -The default is 6. -The minimum is 1 and the maximum is 10. +.\".It Cm proto Ar value +.\"Set the Spanning Tree protocol. +.\"The default is rstp. +.\"The available options are stp and rstp. +.\".It Cm holdcnt Ar value +.\"Set the transmit hold count for Spanning Tree. +.\"This is the number of packets transmitted before being rate limited. +.\"The default is 6. +.\"The minimum is 1 and the maximum is 10. .It Cm ifpriority Ar interface Ar value Set the Spanning Tree priority of .Ar interface diff --git a/ifconfig.tproj/ifconfig.c b/ifconfig.tproj/ifconfig.c index a6cd36d..ecc5fd4 100644 --- a/ifconfig.tproj/ifconfig.c +++ b/ifconfig.tproj/ifconfig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -137,11 +137,14 @@ static int ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *afp); static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl, struct ifaddrs *ifa); +static char *bytes_to_str(unsigned long long bytes); static char *bps_to_str(unsigned long long rate); +static char *ns_to_str(unsigned long long nsec); static void tunnel_status(int s); static void usage(void); static char *sched2str(unsigned int s); static char *tl2str(unsigned int s); +static char *ift2str(unsigned int t, unsigned int f, unsigned int sf); static struct afswtch *af_getbyname(const char *name); static struct afswtch *af_getbyfamily(int af); @@ -947,19 +950,44 @@ setthrottle(const char *val, int dummy __unused, int s, } } +static void +setlog(const char *val, int dummy __unused, int s, + const struct afswtch *afp) +{ + char *cp; + + errno = 0; + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + + ifr.ifr_log.ifl_level = strtold(val, &cp); + if (val == cp || errno != 0) { + warn("Invalid value '%s'", val); + return; + } + ifr.ifr_log.ifl_flags = (IFRLOGF_DLIL|IFRLOGF_FAMILY|IFRLOGF_DRIVER| + IFRLOGF_FIRMWARE); + + if (ioctl(s, SIOCSIFLOG, &ifr) < 0) + warn("ioctl (set logging parameters)"); +} + #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ "\20MULTICAST" #define IFEFBITS \ -"\020\1AUTOCONFIGURING\7ACCEPT_RTADV\10TXSTART\11RXPOLL\12VLAN\13BOND\14ARPLL" \ -"\15NOWINDOWSCALE\16NOAUTOIPV6LL\20ROUTER4\21ROUTER6" \ -"\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI\35SENDLIST" +"\020\1AUTOCONFIGURING\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \ +"\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\20ROUTER4\21ROUTER6" \ +"\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI\35SENDLIST" \ +"\36DIRECTLINK" #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \ -"\6TSO4\7TSO6\10LRO\11AV" +"\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS" + +#define IFRLOGF_BITS \ +"\020\1DLIL\21FAMILY\31DRIVER\35FIRMWARE" /* * Print the status of the interface. If an address family was @@ -1072,6 +1100,13 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, if (!verbose) goto done; + if (ioctl(s, SIOCGIFTYPE, &ifr) != -1) { + char *c = ift2str(ifr.ifr_type.ift_type, + ifr.ifr_type.ift_family, ifr.ifr_type.ift_subfamily); + if (c != NULL) + printf("\ttype: %s\n", c); + } + if (ioctl(s, SIOCGIFLINKQUALITYMETRIC, &ifr) != -1) { int lqm = ifr.ifr_link_quality_metric; if (verbose > 1) { @@ -1111,6 +1146,11 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, u_int64_t obw_eff = iflpr.iflpr_output_bw.eff_bw; u_int64_t obw_tbr = iflpr.iflpr_output_tbr_rate; u_int32_t obw_pct = iflpr.iflpr_output_tbr_percent; + u_int64_t ilt_max = iflpr.iflpr_input_lt.max_lt; + u_int64_t ilt_eff = iflpr.iflpr_input_lt.eff_lt; + u_int64_t olt_max = iflpr.iflpr_output_lt.max_lt; + u_int64_t olt_eff = iflpr.iflpr_output_lt.eff_lt; + if (eflags & IFEF_TXSTART) { u_int32_t flags = iflpr.iflpr_flags; @@ -1171,6 +1211,33 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, printf("\tuplink rate: %s [tbr]\n", bps_to_str(obw_tbr)); } + + if (ilt_max != 0 || olt_max != 0) { + if (ilt_max == olt_max && ilt_eff == olt_eff && + ilt_max == ilt_eff) { + printf("\tlink latency: %s\n", + ns_to_str(ilt_max)); + } else { + if (olt_max != 0 && olt_eff == olt_max) { + printf("\tuplink latency: %s\n", + ns_to_str(olt_max)); + } else if (olt_max != 0) { + printf("\tuplink latency: " + "%s [eff] / ", ns_to_str(olt_eff)); + printf("%s [max]\n", + ns_to_str(olt_max)); + } + if (ilt_max != 0 && ilt_eff == ilt_max) { + printf("\tdownlink latency: %s\n", + ns_to_str(ilt_max)); + } else if (ilt_max != 0) { + printf("\tdownlink latency: " + "%s [eff] / ", ns_to_str(ilt_eff)); + printf("%s [max]\n", + ns_to_str(ilt_max)); + } + } + } } /* Common OID prefix */ @@ -1184,9 +1251,13 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, err(1, "sysctl IFDATA_SUPPLEMENTAL"); if (ifmsupp.ifmd_data_extended.ifi_alignerrs != 0) { - printf("\tunaligned pkts: %lld\n", + printf("\tunaligned pkts: %llu\n", ifmsupp.ifmd_data_extended.ifi_alignerrs); } + if (ifmsupp.ifmd_data_extended.ifi_dt_bytes != 0) { + printf("\tdata milestone interval: %s\n", + bytes_to_str(ifmsupp.ifmd_data_extended.ifi_dt_bytes)); + } bzero(&ifdr, sizeof (ifdr)); strncpy(ifdr.ifdr_name, name, sizeof (ifdr.ifdr_name)); @@ -1194,11 +1265,52 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, printf("\tdesc: %s\n", ifdr.ifdr_desc); } + if (ioctl(s, SIOCGIFLOG, &ifr) != -1 && ifr.ifr_log.ifl_level) { + printf("\tlogging: level %d ", ifr.ifr_log.ifl_level); + printb("facilities", ifr.ifr_log.ifl_flags, IFRLOGF_BITS); + putchar('\n'); + } + + if (ioctl(s, SIOCGIFDELEGATE, &ifr) != -1 && ifr.ifr_delegated) { + char delegatedif[IFNAMSIZ+1]; + if (if_indextoname(ifr.ifr_delegated, delegatedif) != NULL) + printf("\teffective interface: %s\n", delegatedif); + } + done: close(s); return; } +#define KILOBYTES 1024 +#define MEGABYTES (KILOBYTES * KILOBYTES) +#define GIGABYTES (KILOBYTES * KILOBYTES * KILOBYTES) + +static char * +bytes_to_str(unsigned long long bytes) +{ + static char buf[32]; + const char *u; + long double n = bytes, t; + + if (bytes >= GIGABYTES) { + t = n / GIGABYTES; + u = "GB"; + } else if (n >= MEGABYTES) { + t = n / MEGABYTES; + u = "MB"; + } else if (n >= KILOBYTES) { + t = n / KILOBYTES; + u = "KB"; + } else { + t = n; + u = "bytes"; + } + + snprintf(buf, sizeof (buf), "%-4.2Lf %s", t, u); + return (buf); +} + #define GIGABIT_PER_SEC 1000000000 /* gigabit per second */ #define MEGABIT_PER_SEC 1000000 /* megabit per second */ #define KILOBIT_PER_SEC 1000 /* kilobit per second */ @@ -1228,6 +1340,35 @@ bps_to_str(unsigned long long rate) return (buf); } +#define NSEC_PER_SEC 1000000000 /* nanosecond per second */ +#define USEC_PER_SEC 1000000 /* microsecond per second */ +#define MSEC_PER_SEC 1000 /* millisecond per second */ + +static char * +ns_to_str(unsigned long long nsec) +{ + static char buf[32]; + const char *u; + long double n = nsec, t; + + if (nsec >= NSEC_PER_SEC) { + t = n / NSEC_PER_SEC; + u = "sec "; + } else if (n >= USEC_PER_SEC) { + t = n / USEC_PER_SEC; + u = "msec"; + } else if (n >= MSEC_PER_SEC) { + t = n / MSEC_PER_SEC; + u = "usec"; + } else { + t = n; + u = "nsec"; + } + + snprintf(buf, sizeof (buf), "%-4.2Lf %4s", t, u); + return (buf); +} + static void tunnel_status(int s) { @@ -1434,6 +1575,7 @@ static struct cmd basic_cmds[] = { DEF_CMD_ARG("desc", setifdesc), DEF_CMD_ARG("tbr", settbr), DEF_CMD_ARG("throttle", setthrottle), + DEF_CMD_ARG("log", setlog), }; static __constructor void @@ -1501,3 +1643,75 @@ tl2str(unsigned int s) return (c); } + +static char * +ift2str(unsigned int t, unsigned int f, unsigned int sf) +{ + static char buf[256]; + char *c = NULL; + + switch (t) { + case IFT_ETHER: + switch (sf) { + case IFRTYPE_SUBFAMILY_USB: + c = "USB Ethernet"; + break; + case IFRTYPE_SUBFAMILY_BLUETOOTH: + c = "Bluetooth PAN"; + break; + case IFRTYPE_SUBFAMILY_WIFI: + c = "Wi-Fi"; + break; + case IFRTYPE_SUBFAMILY_THUNDERBOLT: + c = "IP over Thunderbolt"; + break; + case IFRTYPE_SUBFAMILY_ANY: + default: + c = "Ethernet"; + break; + } + break; + + case IFT_IEEE1394: + c = "IP over FireWire"; + break; + + case IFT_PKTAP: + c = "Packet capture"; + break; + + case IFT_CELLULAR: + c = "Cellular"; + break; + + case IFT_BRIDGE: + case IFT_PFLOG: + case IFT_PFSYNC: + case IFT_OTHER: + case IFT_PPP: + case IFT_LOOP: + case IFT_GIF: + case IFT_STF: + case IFT_L2VLAN: + case IFT_IEEE8023ADLAG: + default: + break; + } + + if (verbose > 1) { + if (c == NULL) { + (void) snprintf(buf, sizeof (buf), + "0x%x family: %u subfamily: %u", + ifr.ifr_type.ift_type, ifr.ifr_type.ift_family, + ifr.ifr_type.ift_subfamily); + } else { + (void) snprintf(buf, sizeof (buf), + "%s (0x%x) family: %u subfamily: %u", c, + ifr.ifr_type.ift_type, ifr.ifr_type.ift_family, + ifr.ifr_type.ift_subfamily); + } + c = buf; + } + + return (c); +} diff --git a/ip6fw.tproj/ip6fw.8 b/ip6fw.tproj/ip6fw.8 index 61771a0..9915ea7 100644 --- a/ip6fw.tproj/ip6fw.8 +++ b/ip6fw.tproj/ip6fw.8 @@ -1,576 +1,11 @@ -.\" -.\" $FreeBSD: src/sbin/ip6fw/ip6fw.8,v 1.3.2.12 2003/02/23 20:17:15 trhodes Exp $ -.\" -.\" $KAME$ -.\" -.\" Copyright (C) 1998, 1999, 2000 and 2001 WIDE Project. -.\" 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. -.\" 3. Neither the name of the project 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 PROJECT 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 PROJECT 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. -.\" -.Dd March 13, 2000 +.Dd September 27, 2012 .Dt IP6FW 8 -.Os +.Os Darwin .Sh NAME .Nm ip6fw -.Nd controlling utility for IPv6 firewall (DEPRECATED) -.Sh SYNOPSIS -.Nm -.Op Fl q -.Oo -.Fl p Ar preproc -.Oo Fl D -.Ar macro Ns Op = Ns Ar value -.Oc -.Op Fl U Ar macro -.Oc -.Ar pathname -.Nm -.Op Fl f | Fl q -flush -.Nm -.Op Fl q -zero -.Op Ar number ... -.Nm -delete -.Ar number ... -.Nm -.Op Fl aftN -list -.Op Ar number ... -.Nm -.Op Fl ftN -show -.Op Ar number ... -.Nm -.Op Fl q -add -.Op Ar number -.Ar action -.Op log -.Ar proto -from -.Ar src -to -.Ar dst -.Op via Ar name | ipv6no -.Op Ar options .Sh DESCRIPTION -Note that use of this utility is +This utility is .Cm DEPRECATED. Please use .Xr pfctl 8 instead. -.Pp -To ease configuration, rules can be put into a file which is -processed using -.Nm -as shown in the first synopsis line. -An absolute -.Ar pathname -must be used. -The file -will be read line by line and applied as arguments to the -.Nm -utility. -.Pp -Optionally, a preprocessor can be specified using -.Fl p Ar preproc -where -.Ar pathname -is to be piped through. -Useful preprocessors include -.Xr cpp 1 -and -.Xr m4 1 . -If -.Ar preproc -doesn't start with a slash -.Pq Ql / -as its first character, the usual -.Ev PATH -name search is performed. -Care should be taken with this in environments where not all -file systems are mounted (yet) by the time -.Nm -is being run (e.g. when they are mounted over NFS). -Once -.Fl p -has been specified, optional -.Fl D -and -.Fl U -specifications can follow and will be passed on to the preprocessor. -This allows for flexible configuration files (like conditionalizing -them on the local hostname) and the use of macros to centralize -frequently required arguments like IP addresses. -.Pp -The -.Nm -code works by going through the rule-list for each packet, -until a match is found. -All rules have two associated counters, a packet count and -a byte count. -These counters are updated when a packet matches the rule. -.Pp -The rules are ordered by a -.Dq line-number -from 1 to 65534 that is used -to order and delete rules. -Rules are tried in increasing order, and the -first rule that matches a packet applies. -Multiple rules may share the same number and apply in -the order in which they were added. -.Pp -If a rule is added without a number, it is numbered 100 higher -than the previous rule. -If the highest defined rule number is -greater than 65434, new rules are appended to the last rule. -.Pp -The delete operation deletes the first rule with number -.Ar number , -if any. -.Pp -The list command prints out the current rule set. -.Pp -The show command is equivalent to `ip6fw -a list'. -.Pp -The zero operation zeroes the counters associated with rule number -.Ar number . -.Pp -The flush operation removes all rules. -.Pp -Any command beginning with a -.Sq # , -or being all blank, is ignored. -.Pp -One rule is always present: -.Bd -literal -offset center -65535 deny all from any to any -.Ed -.Pp -This rule is the default policy, i.e., don't allow anything at all. -Your job in setting up rules is to modify this policy to match your -needs. -.Pp -The following options are available: -.Bl -tag -width flag -.It Fl a -While listing, show counter values. See also -.Dq show -command. -.It Fl f -Don't ask for confirmation for commands that can cause problems if misused -(ie; flush). -.Ar Note , -if there is no tty associated with the process, this is implied. -.It Fl q -While adding, zeroing or flushing, be quiet about actions (implies '-f'). -This is useful for adjusting rules by executing multiple ip6fw commands in a -script (e.g. sh /etc/rc.firewall), or by processing a file of many ip6fw rules, -across a remote login session. If a flush is performed in normal -(verbose) mode, it prints a message. Because all rules are flushed, the -message cannot be delivered to the login session, the login session is -closed and the remainder of the ruleset is not processed. Access to the -console is required to recover. -.It Fl t -While listing, show last match timestamp. -.It Fl N -Try to resolve addresses and service names in output. -.El -.Pp -.Ar action : -.Bl -hang -offset flag -width 16n -.It Ar allow -Allow packets that match rule. -The search terminates. -Aliases are -.Ar pass , -.Ar permit , -and -.Ar accept . -.It Ar deny -Discard packets that match this rule. -The search terminates. -.Ar Drop -is an alias for -.Ar deny . -.It Ar reject -(Deprecated.) Discard packets that match this rule, and try to send an ICMPv6 -host unreachable notice. -The search terminates. -.It Ar unreach code -Discard packets that match this rule, and try to send an ICMPv6 -unreachable notice with code -.Ar code , -where -.Ar code -is a number from zero to 255, or one of these aliases: -.Ar noroute , -.Ar admin , -.Ar notneighbor , -.Ar addr , -or -.Ar noport , -The search terminates. -.It Ar reset -TCP packets only. -Discard packets that match this rule, -and try to send a TCP reset (RST) notice. -The search terminates -.Em ( "not working yet" ) . -.It Ar count -Update counters for all packets that match rule. -The search continues with the next rule. -.It Ar skipto number -Skip all subsequent rules numbered less than -.Ar number . -The search continues with the first rule numbered -.Ar number -or higher. -.El -.Pp -If the kernel was compiled with -.Dv IPV6FIREWALL_VERBOSE , -then when a packet matches a rule with the -.Dq log -keyword or a clear/resetlog is performed, a message will be logged to -.Xr syslogd 8 , -or, if that fails, to the console. If the kernel was compiled with the -.Dv IPV6FIREWALL_VERBOSE_LIMIT -option, then logging will cease after the number of packets -specified by the option are received for that particular -chain entry. -When this limit is reached, the limit and rule number will be logged. -Logging may then be re-enabled by clearing -the packet counter for that entry. -.Pp -The -.Xr syslogd 8 -logging and the default log limit are adjustable dynamically through the -.Xr sysctl 8 -interface. -.Pp -.Ar proto : -.Bl -hang -offset flag -width 16n -.It Ar ipv6 -All packets match. -The alias -.Ar all -has the same effect. -.It Ar tcp -Only TCP packets match. -.It Ar udp -Only UDP packets match. -.It Ar ipv6-icmp -Only ICMPv6 packets match. -.It Ar -Only packets for the specified protocol matches (see -.Pa /etc/protocols -for a complete list). -.El -.Pp -.Ar src -and -.Ar dst : -.Bl -hang -offset flag -.It Ar
-.Op Ar ports -.El -.Pp -The -.Em
-may be specified as: -.Bl -hang -offset flag -width 16n -.It Ar ipv6no -An ipv6number of the form -.Li fec0::1:2:3:4 . -.It Ar ipv6no/prefixlen -An ipv6number with a prefix length of the form -.Li fec0::1:2:3:4/112 . -.El -.Pp -The sense of the match can be inverted by preceding an address with the -.Dq not -modifier, causing all other addresses to be matched instead. -This -does not affect the selection of port numbers. -.Pp -With the TCP and UDP protocols, optional -.Em ports -may be specified as: -.Pp -.Bl -hang -offset flag -.It Ns {port|port-port} Ns Op ,port Ns Op ,... -.El -.Pp -Service names (from -.Pa /etc/services ) -may be used instead of numeric port values. -A range may only be specified as the first value, -and the length of the port list is limited to -.Dv IPV6_FW_MAX_PORTS -(as defined in -.Pa /usr/src/sys/netinet6/ip6_fw.h ) -ports. -.Pp -Fragmented packets which have a non-zero offset (i.e. not the first -fragment) will never match a rule which has one or more port -specifications. See the -.Ar frag -option for details on matching fragmented packets. -.Pp -Rules can apply to packets when they are incoming, or outgoing, or both. -The -.Ar in -keyword indicates the rule should only match incoming packets. -The -.Ar out -keyword indicates the rule should only match outgoing packets. -.Pp -To match packets going through a certain interface, specify -the interface using -.Ar via : -.Bl -hang -offset flag -width 16n -.It Ar via ifX -Packet must be going through interface -.Ar ifX . -.It Ar via if* -Packet must be going through interface -.Ar ifX , -where X is any unit number. -.It Ar via any -Packet must be going through -.Em some -interface. -.It Ar via ipv6no -Packet must be going through the interface having IPv6 address -.Ar ipv6no . -.El -.Pp -The -.Ar via -keyword causes the interface to always be checked. -If -.Ar recv -or -.Ar xmit -is used instead of -.Ar via , -then the only receive or transmit interface (respectively) is checked. -By specifying both, it is possible to match packets based on both receive -and transmit interface, e.g.: -.Pp -.Dl "ip6fw add 100 deny ip from any to any out recv ed0 xmit ed1" -.Pp -The -.Ar recv -interface can be tested on either incoming or outgoing packets, while the -.Ar xmit -interface can only be tested on outgoing packets. -So -.Ar out -is required (and -.Ar in -invalid) whenever -.Ar xmit -is used. -Specifying -.Ar via -together with -.Ar xmit -or -.Ar recv -is invalid. -.Pp -A packet may not have a receive or transmit interface: packets originating -from the local host have no receive interface. while packets destined for -the local host have no transmit interface. -.Pp -Additional -.Ar options : -.Bl -hang -offset flag -width 16n -.It frag -Matches if the packet is a fragment and this is not the first fragment -of the datagram. -.Ar frag -may not be used in conjunction with either -.Ar tcpflags -or TCP/UDP port specifications. -.It in -Matches if this packet was on the way in. -.It out -Matches if this packet was on the way out. -.It ipv6options Ar spec -Matches if the IPv6 header contains the comma separated list of -options specified in -.Ar spec . -The supported IPv6 options are: -.Ar hopopt -(hop-by-hop options header), -.Ar route -(routing header), -.Ar frag -(fragment header), -.Ar esp -(encapsulating security payload), -.Ar ah -(authentication header), -.Ar nonxt -(no next header), and -.Ar opts -(destination options header). -The absence of a particular option may be denoted -with a -.Dq \&! -.Em ( "not working yet" ) . -.It established -Matches packets that have the RST or ACK bits set. -TCP packets only. -.It setup -Matches packets that have the SYN bit set but no ACK bit. -TCP packets only. -.It tcpflags Ar spec -Matches if the TCP header contains the comma separated list of -flags specified in -.Ar spec . -The supported TCP flags are: -.Ar fin , -.Ar syn , -.Ar rst , -.Ar psh , -.Ar ack , -and -.Ar urg . -The absence of a particular flag may be denoted -with a -.Dq \&! . -A rule which contains a -.Ar tcpflags -specification can never match a fragmented packet which has -a non-zero offset. See the -.Ar frag -option for details on matching fragmented packets. -.It icmptypes Ar types -Matches if the ICMPv6 type is in the list -.Ar types . -The list may be specified as any combination of ranges -or individual types separated by commas. -.El -.Sh CHECKLIST -Here are some important points to consider when designing your -rules: -.Bl -bullet -offset flag -.It -Remember that you filter both packets going in and out. -Most connections need packets going in both directions. -.It -Remember to test very carefully. -It is a good idea to be near the console when doing this. -.It -Don't forget the loopback interface. -.El -.Sh FINE POINTS -There is one kind of packet that the firewall will always discard, -that is an IPv6 fragment with a fragment offset of one. -This is a valid packet, but it only has one use, to try to circumvent -firewalls. -.Pp -If you are logged in over a network, loading the KLD version of -.Nm -is probably not as straightforward as you would think -.Em ( "not supported" ) . -I recommend this command line: -.Bd -literal -offset center -kldload /modules/ip6fw_mod.o && \e -ip6fw add 32000 allow all from any to any -.Ed -.Pp -Along the same lines, doing an -.Bd -literal -offset center -ip6fw flush -.Ed -.Pp -in similar surroundings is also a bad idea. -.Sh PACKET DIVERSION -not supported. -.Sh EXAMPLES -This command adds an entry which denies all tcp packets from -.Em hacker.evil.org -to the telnet port of -.Em wolf.tambov.su -from being forwarded by the host: -.Pp -.Dl ip6fw add deny tcp from hacker.evil.org to wolf.tambov.su 23 -.Pp -This one disallows any connection from the entire hackers network to -my host: -.Pp -.Dl ip6fw add deny all from fec0::123:45:67:0/112 to my.host.org -.Pp -Here is a good usage of the list command to see accounting records -and timestamp information: -.Pp -.Dl ip6fw -at l -.Pp -or in short form without timestamps: -.Pp -.Dl ip6fw -a l -.Sh SEE ALSO -.Xr ip 4 , -.Xr ipfirewall 4 , -.Xr protocols 5 , -.Xr services 5 , -.Xr reboot 8 , -.Xr sysctl 8 , -.Xr syslogd 8 -.Sh BUGS -.Em WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!! -.Pp -This program can put your computer in rather unusable state. -When -using it for the first time, work on the console of the computer, and -do -.Em NOT -do anything you don't understand. -.Pp -When manipulating/adding chain entries, service and protocol names are -not accepted. -.Sh AUTHORS -.An Ugen J. S. Antsilevich , -.An Poul-Henning Kamp , -.An Alex Nash , -.An Archie Cobbs . -.Pp -.An -nosplit -API based upon code written by -.An Daniel Boulet -for BSDI. -.Sh HISTORY -A -.Nm -utility first appeared in -.Fx 4.0 . diff --git a/ipfw.tproj/ipfw.8 b/ipfw.tproj/ipfw.8 index 4136a3f..71e3aed 100644 --- a/ipfw.tproj/ipfw.8 +++ b/ipfw.tproj/ipfw.8 @@ -1,2118 +1,11 @@ -.\" -.\" $FreeBSD: /repoman/r/ncvs/src/sbin/ipfw/ipfw.8,v 1.63.2.38 2003/07/28 07:15:13 luigi Exp $ -.\" -.Dd August 13, 2002 +.Dd September 27, 2012 .Dt IPFW 8 .Os Darwin .Sh NAME .Nm ipfw -.Nd IP firewall and traffic shaper control program -(DEPRECATED) -.Sh SYNOPSIS -.Nm -.Op Fl cq -.Cm add -.Ar rule -.Nm -.Op Fl acdefnNStT -.Brq Cm list | show -.Op Ar rule | first-last ... -.Nm -.Op Fl f | q -.Cm flush -.Nm -.Op Fl q -.Brq Cm delete | zero | resetlog -.Op Cm set -.Op Ar number ... -.Nm -.Cm enable -.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive -.Nm -.Cm disable -.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive -.Pp -.Nm -.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ... -.Nm -.Cm set move -.Op Cm rule -.Ar number Cm to Ar number -.Nm -.Cm set swap Ar number number -.Nm -.Cm set show -.Pp -.Nm -.Brq Cm pipe | queue -.Ar number -.Cm config -.Ar config-options -.Nm -.Op Fl s Op Ar field -.Brq Cm pipe | queue -.Brq Cm delete | list | show -.Op Ar number ... -.Pp -.Nm -.Op Fl cnNqS -.Oo -.Fl p Ar preproc -.Oo -.Ar preproc-flags -.Oc -.Oc -.Ar pathname .Sh DESCRIPTION -Note that use of this utility is +This utility is .Cm DEPRECATED. Please use .Xr pfctl 8 instead. -.Pp -The -.Nm -utility is the user interface for controlling the -.Xr ipfw 4 -firewall and the -.Xr dummynet 4 -traffic shaper. -.Pp -An -.Nm -configuration, or -.Em ruleset , -is made of a list of -.Em rules -numbered from 1 to 65535. -Packets are passed to -.Nm -from a number of different places in the protocol stack -(depending on the source and destination of the packet, -it is possible that -.Nm -is invoked multiple times on the same packet). -The packet passed to the firewall is compared -against each of the rules in the firewall -.Em ruleset . -When a match is found, the action corresponding to the -matching rule is performed. -.Pp -Depending on the action and certain system settings, packets -can be reinjected into the firewall at some rule after the -matching one for further processing. -.Pp -An -.Nm -ruleset always includes a -.Em default -rule (numbered 65535) which cannot be modified or deleted, -and matches all packets. -The action associated with the -.Em default -rule can be either -.Cm deny -or -.Cm allow -depending on how the kernel is configured. -.Pp -If the ruleset includes one or more rules with the -.Cm keep-state -or -.Cm limit -option, then -.Nm -assumes a -.Em stateful -behaviour, i.e. upon a match it will create dynamic rules matching -the exact parameters (addresses and ports) of the matching packet. -.Pp -These dynamic rules, which have a limited lifetime, are checked -at the first occurrence of a -.Cm check-state , -.Cm keep-state -or -.Cm limit -rule, and are typically used to open the firewall on-demand to -legitimate traffic only. -See the -.Sx STATEFUL FIREWALL -and -.Sx EXAMPLES -Sections below for more information on the stateful behaviour of -.Nm . -.Pp -All rules (including dynamic ones) have a few associated counters: -a packet count, a byte count, a log count and a timestamp -indicating the time of the last match. -Counters can be displayed or reset with -.Nm -commands. -.Pp -Rules can be added with the -.Cm add -command; deleted individually or in groups with the -.Cm delete -command, and globally (except those in set 31) with the -.Cm flush -command; displayed, optionally with the content of the -counters, using the -.Cm show -and -.Cm list -commands. -Finally, counters can be reset with the -.Cm zero -and -.Cm resetlog -commands. -.Pp -Also, each rule belongs to one of 32 different -.Em sets -, and there are -.Nm -commands to atomically manipulate sets, such as enable, -disable, swap sets, move all rules in a set to another -one, delete all rules in a set. These can be useful to -install temporary configurations, or to test them. -See Section -.Sx SETS OF RULES -for more information on -.Em sets . -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl a -While listing, show counter values. -The -.Cm show -command just implies this option. -.It Fl c -When entering or showing rules, print them in compact form, -i.e. without the optional "ip from any to any" string -when this does not carry any additional information. -.It Fl d -While listing, show dynamic rules in addition to static ones. -.It Fl e -While listing, if the -.Fl d -option was specified, also show expired dynamic rules. -.It Fl f -Don't ask for confirmation for commands that can cause problems -if misused, -.No i.e. Cm flush . -If there is no tty associated with the process, this is implied. -.It Fl n -Only check syntax of the command strings, without actually passing -them to the kernel. -.It Fl N -Try to resolve addresses and service names in output. -.It Fl q -While -.Cm add Ns ing , -.Cm zero Ns ing , -.Cm resetlog Ns ging -or -.Cm flush Ns ing , -be quiet about actions -(implies -.Fl f ) . -This is useful for adjusting rules by executing multiple -.Nm -commands in a script -(e.g., -.Ql sh\ /etc/rc.firewall ) , -or by processing a file of many -.Nm -rules across a remote login session. -If a -.Cm flush -is performed in normal (verbose) mode (with the default kernel -configuration), it prints a message. -Because all rules are flushed, the message might not be delivered -to the login session, causing the remote login session to be closed -and the remainder of the ruleset to not be processed. -Access to the console would then be required to recover. -.It Fl S -While listing rules, show the -.Em set -each rule belongs to. -If this flag is not specified, disabled rules will not be -listed. -.It Fl s Op Ar field -While listing pipes, sort according to one of the four -counters (total or current packets or bytes). -.It Fl t -While listing, show last match timestamp (converted with ctime()). -.It Fl T -While listing, show last match timestamp (as seconds from the epoch). -This form can be more convenient for postprocessing by scripts. -.El -.Pp -To ease configuration, rules can be put into a file which is -processed using -.Nm -as shown in the last synopsis line. -An absolute -.Ar pathname -must be used. -The file will be read line by line and applied as arguments to the -.Nm -utility. -.Pp -Optionally, a preprocessor can be specified using -.Fl p Ar preproc -where -.Ar pathname -is to be piped through. -Useful preprocessors include -.Xr cpp 1 -and -.Xr m4 1 . -If -.Ar preproc -doesn't start with a slash -.Pq Ql / -as its first character, the usual -.Ev PATH -name search is performed. -Care should be taken with this in environments where not all -file systems are mounted (yet) by the time -.Nm -is being run (e.g. when they are mounted over NFS). -Once -.Fl p -has been specified, any additional arguments as passed on to the preprocessor -for interpretation. -This allows for flexible configuration files (like conditionalizing -them on the local hostname) and the use of macros to centralize -frequently required arguments like IP addresses. -.Pp -The -.Nm -.Cm pipe -and -.Cm queue -commands are used to configure the traffic shaper, as shown in the -.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION -Section below. -.Pp -If the world and the kernel get out of sync the -.Nm -ABI may break, preventing you from being able to add any rules. This can -adversely effect the booting process. You can use -.Nm -.Cm disable -.Cm firewall -to temporarily disable the firewall to regain access to the network, -allowing you to fix the problem. -.Sh PACKET FLOW -A packet is checked against the active ruleset in multiple places -in the protocol stack, under control of several sysctl variables. -These places and variables are shown below, and it is important to -have this picture in mind in order to design a correct ruleset. -.Bd -literal -offset indent - ^ to upper layers V - | | - +----------->-----------+ - ^ V - [ip_input] [ip_output] net.inet.ip.fw.enable=1 - | | - ^ V -[ether_demux] [ether_output_frame] net.link.ether.ipfw=1 - | | - +-->--[bdg_forward]-->--+ net.link.ether.bridge_ipfw=1 - ^ V - | to devices | -.Ed -.Pp -As can be noted from the above picture, the number of -times the same packet goes through the firewall can -vary between 0 and 4 depending on packet source and -destination, and system configuration. -.Pp -Note that as packets flow through the stack, headers can be -stripped or added to it, and so they may or may not be available -for inspection. -E.g., incoming packets will include the MAC header when -.Nm -is invoked from -.Cm ether_demux() , -but the same packets will have the MAC header stripped off when -.Nm -is invoked from -.Cm ip_input() . -.Pp -Also note that each packet is always checked against the complete ruleset, -irrespective of the place where the check occurs, or the source of the packet. -If a rule contains some match patterns or actions which are not valid -for the place of invocation (e.g. trying to match a MAC header within -.Cm ip_input() -), the match pattern will not match, but a -.Cm not -operator in front of such patterns -.Em will -cause the pattern to -.Em always -match on those packets. -It is thus the responsibility of -the programmer, if necessary, to write a suitable ruleset to -differentiate among the possible places. -.Cm skipto -rules can be useful here, as an example: -.Bd -literal -offset indent -# packets from ether_demux or bdg_forward -ipfw add 10 skipto 1000 all from any to any layer2 in -# packets from ip_input -ipfw add 10 skipto 2000 all from any to any not layer2 in -# packets from ip_output -ipfw add 10 skipto 3000 all from any to any not layer2 out -# packets from ether_output_frame -ipfw add 10 skipto 4000 all from any to any layer2 out -.Ed -.Pp -(yes, at the moment there is no way to differentiate between -ether_demux and bdg_forward). -.Sh SYNTAX -In general, each keyword or argument must be provided as -a separate command line argument, with no leading or trailing -spaces. Keywords are case-sensitive, whereas arguments may -or may not be case-sensitive depending on their nature -(e.g. uid's are, hostnames are not). -.Pp -In -.Nm ipfw2 -you can introduce spaces after commas ',' to make -the line more readable. You can also put the entire -command (including flags) into a single argument. -E.g. the following forms are equivalent: -.Bd -literal -offset indent -ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8 -ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8 -ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8" -.Ed -.Sh RULE FORMAT -The format of -.Nm -rules is the following: -.Bd -ragged -offset indent -.Op Ar rule_number -.Op Cm set Ar set_number -.Op Cm prob Ar match_probability -.br -.Ar " " action -.Op Cm log Op Cm logamount Ar number -.Ar body -.Ed -.Pp -where the body of the rule specifies which information is used -for filtering packets, among the following: -.Pp -.Bl -tag -width "Source and dest. addresses and ports" -offset XXX -compact -.It Layer-2 header fields -When available -.It IPv4 Protocol -TCP, UDP, ICMP, etc. -.It Source and dest. addresses and ports -.It Direction -See Section -.Sx PACKET FLOW -.It Transmit and receive interface -By name or address -.It Misc. IP header fields -Version, type of service, datagram length, identification, -fragment flag (non-zero IP offset), -Time To Live -.It IP options -.It Misc. TCP header fields -TCP flags (SYN, FIN, ACK, RST, etc.), -sequence number, acknowledgment number, -window -.It TCP options -.It ICMP types -for ICMP packets -.It User/group ID -When the packet can be associated with a local socket. -.El -.Pp -Note that some of the above information, e.g. source MAC or IP addresses and -TCP/UDP ports, could easily be spoofed, so filtering on those fields -alone might not guarantee the desired results. -.Bl -tag -width indent -.It Ar rule_number -Each rule is associated with a -.Ar rule_number -in the range 1..65535, with the latter reserved for the -.Em default -rule. -Rules are checked sequentially by rule number. -Multiple rules can have the same number, in which case they are -checked (and listed) according to the order in which they have -been added. -If a rule is entered without specifying a number, the kernel will -assign one in such a way that the rule becomes the last one -before the -.Em default -rule. -Automatic rule numbers are assigned by incrementing the last -non-default rule number by the value of the sysctl variable -.Ar net.inet.ip.fw.autoinc_step -which defaults to 100. -If this is not possible (e.g. because we would go beyond the -maximum allowed rule number), the number of the last -non-default value is used instead. -.It Cm set Ar set_number -Each rule is associated with a -.Ar set_number -in the range 0..31. -Sets can be individually disabled and enabled, so this parameter -is of fundamental importance for atomic ruleset manipulation. -It can be also used to simplify deletion of groups of rules. -If a rule is entered without specifying a set number, -set 0 will be used. -.br -Set 31 is special in that it cannot be disabled, -and rules in set 31 are not deleted by the -.Nm ipfw flush -command (but you can delete them with the -.Nm ipfw delete set 31 -command). -Set 31 is also used for the -.Em default -rule. -.It Cm prob Ar match_probability -A match is only declared with the specified probability -(floating point number between 0 and 1). -This can be useful for a number of applications such as -random packet drop or -(in conjunction with -.Xr dummynet 4 ) -to simulate the effect of multiple paths leading to out-of-order -packet delivery. -.Pp -Note: this condition is checked before any other condition, including -ones such as keep-state or check-state which might have side effects. -.It Cm log Op Cm logamount Ar number -When a packet matches a rule with the -.Cm log -keyword, a message will be -logged to -.Xr syslogd 8 -with a -.Dv LOG_SECURITY -facility. -The logging only occurs if the sysctl variable -.Em net.inet.ip.fw.verbose -is set to 1 -(which is the default when the kernel is compiled with -.Dv IPFIREWALL_VERBOSE -) and the number of packets logged so far for that -particular rule does not exceed the -.Cm logamount -parameter. -If no -.Cm logamount -is specified, the limit is taken from the sysctl variable -.Em net.inet.ip.fw.verbose_limit . -In both cases, a value of 0 removes the logging limit. -.Pp -Once the limit is reached, logging can be re-enabled by -clearing the logging counter or the packet counter for that entry, see the -.Cm resetlog -command. -.Pp -Note: logging is done after all other packet matching conditions -have been successfully verified, and before performing the final -action (accept, deny, etc.) on the packet. -.El -.Ss RULE ACTIONS -A rule can be associated with one of the following actions, which -will be executed when the packet matches the body of the rule. -.Bl -tag -width indent -.It Cm allow | accept | pass | permit -Allow packets that match rule. -The search terminates. -.It Cm check-state -Checks the packet against the dynamic ruleset. -If a match is found, execute the action associated with -the rule which generated this dynamic rule, otherwise -move to the next rule. -.br -.Cm Check-state -rules do not have a body. -If no -.Cm check-state -rule is found, the dynamic ruleset is checked at the first -.Cm keep-state -or -.Cm limit -rule. -.It Cm count -Update counters for all packets that match rule. -The search continues with the next rule. -.It Cm deny | drop -Discard packets that match this rule. -The search terminates. -.It Cm divert Ar port -Divert packets that match this rule to the -.Xr divert 4 -socket bound to port -.Ar port . -The search terminates. -.It Cm fwd | forward Ar ipaddr Ns Op , Ns Ar port -Change the next-hop on matching packets to -.Ar ipaddr , -which can be an IP address in dotted quad format or a host name. -The search terminates if this rule matches. -.Pp -If -.Ar ipaddr -is a local address, then matching packets will be forwarded to -.Ar port -(or the port number in the packet if one is not specified in the rule) -on the local machine. -.br -If -.Ar ipaddr -is not a local address, then the port number -(if specified) is ignored, and the packet will be -forwarded to the remote address, using the route as found in -the local routing table for that IP. -.br -A -.Ar fwd -rule will not match layer-2 packets (those received -on ether_input, ether_output, or bridged). -.br -The -.Cm fwd -action does not change the contents of the packet at all. -In particular, the destination address remains unmodified, so -packets forwarded to another system will usually be rejected by that system -unless there is a matching rule on that system to capture them. -For packets forwarded locally, -the local address of the socket will be -set to the original destination address of the packet. -This makes the -.Xr netstat 1 -entry look rather weird but is intended for -use with transparent proxy servers. -.It Cm pipe Ar pipe_nr -Pass packet to a -.Xr dummynet 4 -.Dq pipe -(for bandwidth limitation, delay, etc.). -See the -.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION -Section for further information. -The search terminates; however, on exit from the pipe and if -the -.Xr sysctl 8 -variable -.Em net.inet.ip.fw.one_pass -is not set, the packet is passed again to the firewall code -starting from the next rule. -.It Cm queue Ar queue_nr -Pass packet to a -.Xr dummynet 4 -.Dq queue -(for bandwidth limitation using WF2Q+). -.It Cm reject -(Deprecated). -Synonym for -.Cm unreach host . -.It Cm reset -Discard packets that match this rule, and if the -packet is a TCP packet, try to send a TCP reset (RST) notice. -The search terminates. -.It Cm skipto Ar number -Skip all subsequent rules numbered less than -.Ar number . -The search continues with the first rule numbered -.Ar number -or higher. -.It Cm tee Ar port -Send a copy of packets matching this rule to the -.Xr divert 4 -socket bound to port -.Ar port . -The search terminates and the original packet is accepted -(but see Section -.Sx BUGS -below). -.It Cm unreach Ar code -Discard packets that match this rule, and try to send an ICMP -unreachable notice with code -.Ar code , -where -.Ar code -is a number from 0 to 255, or one of these aliases: -.Cm net , host , protocol , port , -.Cm needfrag , srcfail , net-unknown , host-unknown , -.Cm isolated , net-prohib , host-prohib , tosnet , -.Cm toshost , filter-prohib , host-precedence -or -.Cm precedence-cutoff . -The search terminates. -.El -.Ss RULE BODY -The body of a rule contains zero or more patterns (such as -specific source and destination addresses or ports, -protocol options, incoming or outgoing interfaces, etc.) -that the packet must match in order to be recognised. -In general, the patterns are connected by (implicit) -.Cm and -operators -- i.e. all must match in order for the -rule to match. -Individual patterns can be prefixed by the -.Cm not -operator to reverse the result of the match, as in -.Pp -.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any" -.Pp -Additionally, sets of alternative match patterns ( -.Em or-blocks -) can be constructed by putting the patterns in -lists enclosed between parentheses ( ) or braces { }, and -using the -.Cm or -operator as follows: -.Pp -.Dl "ipfw add 100 allow ip from { x or not y or z } to any" -.Pp -Only one level of parentheses is allowed. -Beware that most shells have special meanings for parentheses -or braces, so it is advisable to put a backslash \\ in front of them -to prevent such interpretations. -.Pp -The body of a rule must in general include a source and destination -address specifier. -The keyword -.Ar any -can be used in various places to specify that the content of -a required field is irrelevant. -.Pp -The rule body has the following format: -.Bd -ragged -offset indent -.Op Ar proto Cm from Ar src Cm to Ar dst -.Op Ar options -.Ed -.Pp -The first part (proto from src to dst) is for backward -compatibility with -.Nm ipfw1 . -In -.Nm ipfw2 -any match pattern (including MAC headers, IPv4 protocols, -addresses and ports) can be specified in the -.Ar options -section. -.Pp -Rule fields have the following meaning: -.Bl -tag -width indent -.It Ar proto : protocol | Cm { Ar protocol Cm or ... } -.It Ar protocol : Oo Cm not Oc Ar protocol-name | protocol-number -An IPv4 protocol specified by number or name -(for a complete list see -.Pa /etc/protocols ) . -The -.Cm ip -or -.Cm all -keywords mean any protocol will match. -.Pp -The -.Cm { Ar protocol Cm or ... } -format (an -.Em or-block ) -is provided for convenience only but its use is deprecated. -.It Ar src No and Ar dst : Bro Cm addr | Cm { Ar addr Cm or ... } Brc Op Oo Cm not Oc Ar ports -An address (or a list, see below) -optionally followed by -.Ar ports -specifiers. -.Pp -The second format ( -.Em or-block -with multiple addresses) is provided for convenience only and -its use is discouraged. -.It Ar addr : Oo Cm not Oc Brq Cm any | me | Ar addr-list | Ar addr-set -.It Cm any -matches any IP address. -.It Cm me -matches any IP address configured on an interface in the system. -The address list is evaluated at the time the packet is -analysed. -.It Ar addr-list : ip-addr Ns Op Ns , Ns Ar addr-list -.It Ar ip-addr : -A host or subnet address specified in one of the following ways: -.Bl -tag -width indent -.It Ar numeric-ip | hostname -Matches a single IPv4 address, specified as dotted-quad or a hostname. -Hostnames are resolved at the time the rule is added to the firewall list. -.It Ar addr Ns / Ns Ar masklen -Matches all addresses with base -.Ar addr -(specified as a dotted quad or a hostname) -and mask width of -.Cm masklen -bits. -As an example, 1.2.3.4/25 will match -all IP numbers from 1.2.3.0 to 1.2.3.127 . -.It Ar addr Ns : Ns Ar mask -Matches all addresses with base -.Ar addr -(specified as a dotted quad or a hostname) -and the mask of -.Ar mask , -specified as a dotted quad. -As an example, 1.2.3.4/255.0.255.0 will match -1.*.3.*. -We suggest to use this form only for non-contiguous -masks, and resort to the -.Ar addr Ns / Ns Ar masklen -format for contiguous masks, which is more compact and less -error-prone. -.El -.It Ar addr-set : addr Ns Oo Ns / Ns Ar masklen Oc Ns Cm { Ns Ar list Ns Cm } -.It Ar list : Bro Ar num | num-num Brc Ns Op Ns , Ns Ar list -Matches all addresses with base address -.Ar addr -(specified as a dotted quad or a hostname) -and whose last byte is in the list between braces { } . -Note that there must be no spaces between braces and -numbers (spaces after commas are allowed). -Elements of the list can be specified as single entries -or ranges. -The -.Ar masklen -field is used to limit the size of the set of addresses, -and can have any value between 24 and 32. If not specified, -it will be assumed as 24. -.br -This format is particularly useful to handle sparse address sets -within a single rule. Because the matching occurs using a -bitmask, it takes constant time and dramatically reduces -the complexity of rulesets. -.br -As an example, an address specified as 1.2.3.4/24{128,35-55,89} -will match the following IP addresses: -.br -1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 . -.It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Ns Op , Ns Ar ports -For protocols which support port numbers (such as TCP and UDP), optional -.Cm ports -may be specified as one or more ports or port ranges, separated -by commas but no spaces, and an optional -.Cm not -operator. -The -.Ql \&- -notation specifies a range of ports (including boundaries). -.Pp -Service names (from -.Pa /etc/services ) -may be used instead of numeric port values. -The length of the port list is limited to 30 ports or ranges, -though one can specify larger ranges by using an -.Em or-block -in the -.Cm options -section of the rule. -.Pp -A backslash -.Pq Ql \e -can be used to escape the dash -.Pq Ql - -character in a service name (from a shell, the backslash must be -typed twice to avoid the shell itself interpreting it as an escape -character). -.Pp -.Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any" -.Pp -Fragmented packets which have a non-zero offset (i.e. not the first -fragment) will never match a rule which has one or more port -specifications. -See the -.Cm frag -option for details on matching fragmented packets. -.El -.Ss RULE OPTIONS (MATCH PATTERNS) -Additional match patterns can be used within -rules. Zero or more of these so-called -.Em options -can be present in a rule, optionally prefixed by the -.Cm not -operand, and possibly grouped into -.Em or-blocks . -.Pp -The following match patterns can be used (listed in alphabetical order): -.Bl -tag -width indent -.It Cm // this is a comment. -Inserts the specified text as a comment in the rule. -Everything following // is considered as a comment and stored in the rule. -You can have comment-only rules, which are listed as having a -.Cm count -action followed by the comment. -.It Cm bridged -Matches only bridged packets. -.It Cm dst-ip Ar ip-address -Matches IP packets whose destination IP is one of the address(es) -specified as argument. -.It Cm dst-port Ar ports -Matches IP packets whose destination port is one of the port(s) -specified as argument. -.It Cm established -Matches TCP packets that have the RST or ACK bits set. -.It Cm frag -Matches packets that are fragments and not the first -fragment of an IP datagram. Note that these packets will not have -the next protocol header (e.g. TCP, UDP) so options that look into -these headers cannot match. -.It Cm gid Ar group -Matches all TCP or UDP packets sent by or received for a -.Ar group . -A -.Ar group -may be specified by name or number. -.It Cm icmptypes Ar types -Matches ICMP packets whose ICMP type is in the list -.Ar types . -The list may be specified as any combination of -individual types (numeric) separated by commas. -.Em Ranges are not allowed. -The supported ICMP types are: -.Pp -echo reply -.Pq Cm 0 , -destination unreachable -.Pq Cm 3 , -source quench -.Pq Cm 4 , -redirect -.Pq Cm 5 , -echo request -.Pq Cm 8 , -router advertisement -.Pq Cm 9 , -router solicitation -.Pq Cm 10 , -time-to-live exceeded -.Pq Cm 11 , -IP header bad -.Pq Cm 12 , -timestamp request -.Pq Cm 13 , -timestamp reply -.Pq Cm 14 , -information request -.Pq Cm 15 , -information reply -.Pq Cm 16 , -address mask request -.Pq Cm 17 -and address mask reply -.Pq Cm 18 . -.It Cm in | out -Matches incoming or outgoing packets, respectively. -.Cm in -and -.Cm out -are mutually exclusive (in fact, -.Cm out -is implemented as -.Cm not in Ns No ). -.It Cm ipid Ar id-list -Matches IP packets whose -.Cm ip_id -field has value included in -.Ar id-list , -which is either a single value or a list of values or ranges -specified in the same way as -.Ar ports . -.It Cm iplen Ar len-list -Matches IP packets whose total length, including header and data, is -in the set -.Ar len-list , -which is either a single value or a list of values or ranges -specified in the same way as -.Ar ports . -.It Cm ipoptions Ar spec -Matches packets whose IP header contains the comma separated list of -options specified in -.Ar spec . -The supported IP options are: -.Pp -.Cm ssrr -(strict source route), -.Cm lsrr -(loose source route), -.Cm rr -(record packet route) and -.Cm ts -(timestamp). -The absence of a particular option may be denoted -with a -.Ql \&! . -.It Cm ipprecedence Ar precedence -Matches IP packets whose precedence field is equal to -.Ar precedence . -.It Cm ipsec -Matches packets that have IPSEC history associated with them -(i.e. the packet comes encapsulated in IPSEC, the kernel -has IPSEC support and IPSEC_FILTERGIF option, and can correctly -decapsulate it). -.Pp -Note that specifying -.Cm ipsec -is different from specifying -.Cm proto Ar ipsec -as the latter will only look at the specific IP protocol field, -irrespective of IPSEC kernel support and the validity of the IPSEC data. -.It Cm iptos Ar spec -Matches IP packets whose -.Cm tos -field contains the comma separated list of -service types specified in -.Ar spec . -The supported IP types of service are: -.Pp -.Cm lowdelay -.Pq Dv IPTOS_LOWDELAY , -.Cm throughput -.Pq Dv IPTOS_THROUGHPUT , -.Cm reliability -.Pq Dv IPTOS_RELIABILITY , -.Cm mincost -.Pq Dv IPTOS_MINCOST , -.Cm congestion -.Pq Dv IPTOS_CE . -The absence of a particular type may be denoted -with a -.Ql \&! . -.It Cm ipttl Ar ttl-list -Matches IP packets whose time to live is included in -.Ar ttl-list , -which is either a single value or a list of values or ranges -specified in the same way as -.Ar ports . -.It Cm ipversion Ar ver -Matches IP packets whose IP version field is -.Ar ver . -.It Cm keep-state -Upon a match, the firewall will create a dynamic rule, whose -default behaviour is to match bidirectional traffic between -source and destination IP/port using the same protocol. -The rule has a limited lifetime (controlled by a set of -.Xr sysctl 8 -variables), and the lifetime is refreshed every time a matching -packet is found. -.It Cm layer2 -Matches only layer2 packets, i.e. those passed to -.Nm -from ether_demux() and ether_output_frame(). -.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N -The firewall will only allow -.Ar N -connections with the same -set of parameters as specified in the rule. -One or more -of source and destination addresses and ports can be -specified. -.It Cm { MAC | mac } Ar dst-mac src-mac -Match packets with a given -.Ar dst-mac -and -.Ar src-mac -addresses, specified as the -.Cm any -keyword (matching any MAC address), or six groups of hex digits -separated by colons, -and optionally followed by a mask indicating how many bits are -significant, as in -.Pp -.Dl "MAC 10:20:30:40:50:60/33 any" -.Pp -Note that the order of MAC addresses (destination first, -source second) is -the same as on the wire, but the opposite of the one used for -IP addresses. -.It Cm mac-type Ar mac-type -Matches packets whose Ethernet Type field -corresponds to one of those specified as argument. -.Ar mac-type -is specified in the same way as -.Cm port numbers -(i.e. one or more comma-separated single values or ranges). -You can use symbolic names for known values such as -.Em vlan , ipv4, ipv6 . -Values can be entered as decimal or hexadecimal (if prefixed by 0x), -and they are always printed as hexadecimal (unless the -.Cm -N -option is used, in which case symbolic resolution will be attempted). -.It Cm proto Ar protocol -Matches packets with the corresponding IPv4 protocol. -.It Cm recv | xmit | via Brq Ar ifX | Ar if Ns Cm * | Ar ipno | Ar any -Matches packets received, transmitted or going through, -respectively, the interface specified by exact name -.Ns No ( Ar ifX Ns No ), -by device name -.Ns No ( Ar if Ns Ar * Ns No ), -by IP address, or through some interface. -.Pp -The -.Cm via -keyword causes the interface to always be checked. -If -.Cm recv -or -.Cm xmit -is used instead of -.Cm via , -then only the receive or transmit interface (respectively) -is checked. -By specifying both, it is possible to match packets based on -both receive and transmit interface, e.g.: -.Pp -.Dl "ipfw add deny ip from any to any out recv ed0 xmit ed1" -.Pp -The -.Cm recv -interface can be tested on either incoming or outgoing packets, -while the -.Cm xmit -interface can only be tested on outgoing packets. -So -.Cm out -is required (and -.Cm in -is invalid) whenever -.Cm xmit -is used. -.Pp -A packet may not have a receive or transmit interface: packets -originating from the local host have no receive interface, -while packets destined for the local host have no transmit -interface. -.It Cm setup -Matches TCP packets that have the SYN bit set but no ACK bit. -This is the short form of -.Dq Li tcpflags\ syn,!ack . -.It Cm src-ip Ar ip-address -Matches IP packets whose source IP is one of the address(es) -specified as argument. -.It Cm src-port Ar ports -Matches IP packets whose source port is one of the port(s) -specified as argument. -.It Cm tcpack Ar ack -TCP packets only. -Match if the TCP header acknowledgment number field is set to -.Ar ack . -.It Cm tcpflags Ar spec -TCP packets only. -Match if the TCP header contains the comma separated list of -flags specified in -.Ar spec . -The supported TCP flags are: -.Pp -.Cm fin , -.Cm syn , -.Cm rst , -.Cm psh , -.Cm ack -and -.Cm urg . -The absence of a particular flag may be denoted -with a -.Ql \&! . -A rule which contains a -.Cm tcpflags -specification can never match a fragmented packet which has -a non-zero offset. -See the -.Cm frag -option for details on matching fragmented packets. -.It Cm tcpseq Ar seq -TCP packets only. -Match if the TCP header sequence number field is set to -.Ar seq . -.It Cm tcpwin Ar win -TCP packets only. -Match if the TCP header window field is set to -.Ar win . -.It Cm tcpoptions Ar spec -TCP packets only. -Match if the TCP header contains the comma separated list of -options specified in -.Ar spec . -The supported TCP options are: -.Pp -.Cm mss -(maximum segment size), -.Cm window -(tcp window advertisement), -.Cm sack -(selective ack), -.Cm ts -(rfc1323 timestamp) and -.Cm cc -(rfc1644 t/tcp connection count). -The absence of a particular option may be denoted -with a -.Ql \&! . -.It Cm uid Ar user -Match all TCP or UDP packets sent by or received for a -.Ar user . -A -.Ar user -may be matched by name or identification number. -.It Cm verrevpath -For incoming packets, -a routing table lookup is done on the packet's source address. -If the interface on which the packet entered the system matches the -outgoing interface for the route, -the packet matches. -If the interfaces do not match up, -the packet does not match. -All outgoing packets or packets with no incoming interface match. -.Pp -The name and functionality of the option is intentionally similar to -the Cisco IOS command: -.Pp -.Dl ip verify unicast reverse-path -.Pp -This option can be used to make anti-spoofing rules. -.El -.Sh SETS OF RULES -Each rule belongs to one of 32 different -.Em sets -, numbered 0 to 31. -Set 31 is reserved for the default rule. -.Pp -By default, rules are put in set 0, unless you use the -.Cm set N -attribute when entering a new rule. -Sets can be individually and atomically enabled or disabled, -so this mechanism permits an easy way to store multiple configurations -of the firewall and quickly (and atomically) switch between them. -The command to enable/disable sets is -.Bd -ragged -offset indent -.Nm -.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ... -.Ed -.Pp -where multiple -.Cm enable -or -.Cm disable -sections can be specified. -Command execution is atomic on all the sets specified in the command. -By default, all sets are enabled. -.Pp -When you disable a set, its rules behave as if they do not exist -in the firewall configuration, with only one exception: -.Bd -ragged -offset indent -dynamic rules created from a rule before it had been disabled -will still be active until they expire. In order to delete -dynamic rules you have to explicitly delete the parent rule -which generated them. -.Ed -.Pp -The set number of rules can be changed with the command -.Bd -ragged -offset indent -.Nm -.Cm set move -.Brq Cm rule Ar rule-number | old-set -.Cm to Ar new-set -.Ed -.Pp -Also, you can atomically swap two rulesets with the command -.Bd -ragged -offset indent -.Nm -.Cm set swap Ar first-set second-set -.Ed -.Pp -See the -.Sx EXAMPLES -Section on some possible uses of sets of rules. -.Sh STATEFUL FIREWALL -Stateful operation is a way for the firewall to dynamically -create rules for specific flows when packets that -match a given pattern are detected. Support for stateful -operation comes through the -.Cm check-state , keep-state -and -.Cm limit -options of -.Nm rules. -.Pp -Dynamic rules are created when a packet matches a -.Cm keep-state -or -.Cm limit -rule, causing the creation of a -.Em dynamic -rule which will match all and only packets with -a given -.Em protocol -between a -.Em src-ip/src-port dst-ip/dst-port -pair of addresses ( -.Em src -and -.Em dst -are used here only to denote the initial match addresses, but they -are completely equivalent afterwards). -Dynamic rules will be checked at the first -.Cm check-state, keep-state -or -.Cm limit -occurrence, and the action performed upon a match will be the same -as in the parent rule. -.Pp -Note that no additional attributes other than protocol and IP addresses -and ports are checked on dynamic rules. -.Pp -The typical use of dynamic rules is to keep a closed firewall configuration, -but let the first TCP SYN packet from the inside network install a -dynamic rule for the flow so that packets belonging to that session -will be allowed through the firewall: -.Pp -.Dl "ipfw add check-state" -.Dl "ipfw add allow tcp from my-subnet to any setup keep-state" -.Dl "ipfw add deny tcp from any to any" -.Pp -A similar approach can be used for UDP, where an UDP packet coming -from the inside will install a dynamic rule to let the response through -the firewall: -.Pp -.Dl "ipfw add check-state" -.Dl "ipfw add allow udp from my-subnet to any keep-state" -.Dl "ipfw add deny udp from any to any" -.Pp -Dynamic rules expire after some time, which depends on the status -of the flow and the setting of some -.Cm sysctl -variables. -See Section -.Sx SYSCTL VARIABLES -for more details. -For TCP sessions, dynamic rules can be instructed to periodically -send keepalive packets to refresh the state of the rule when it is -about to expire. -.Pp -See Section -.Sx EXAMPLES -for more examples on how to use dynamic rules. -.Sh TRAFFIC SHAPER (DUMMYNET) CONFIGURATION -.Nm -is also the user interface for the -.Xr dummynet 4 -traffic shaper. -.Pp -.Nm dummynet -operates by first using the firewall to classify packets and divide them into -.Em flows , -using any match pattern that can be used in -.Nm -rules. -Depending on local policies, a flow can contain packets for a single -TCP connection, or from/to a given host, or entire subnet, or a -protocol type, etc. -.Pp -Packets belonging to the same flow are then passed to either of two -different objects, which implement the traffic regulation: -.Bl -hang -offset XXXX -.It Em pipe -A pipe emulates a link with given bandwidth, propagation delay, -queue size and packet loss rate. -Packets are queued in front of the pipe as they come out from the classifier, -and then transferred to the pipe according to the pipe's parameters. -.Pp -.It Em queue -A queue -is an abstraction used to implement the WF2Q+ -(Worst-case Fair Weighted Fair Queueing) policy, which is -an efficient variant of the WFQ policy. -.br -The queue associates a -.Em weight -and a reference pipe to each flow, and then all backlogged (i.e., -with packets queued) flows linked to the same pipe share the pipe's -bandwidth proportionally to their weights. -Note that weights are not priorities; a flow with a lower weight -is still guaranteed to get its fraction of the bandwidth even if a -flow with a higher weight is permanently backlogged. -.Pp -.El -In practice, -.Em pipes -can be used to set hard limits to the bandwidth that a flow can use, whereas -.Em queues -can be used to determine how different flow share the available bandwidth. -.Pp -The -.Em pipe -and -.Em queue -configuration commands are the following: -.Bd -ragged -offset indent -.Cm pipe Ar number Cm config Ar pipe-configuration -.Pp -.Cm queue Ar number Cm config Ar queue-configuration -.Ed -.Pp -The following parameters can be configured for a pipe: -.Pp -.Bl -tag -width indent -compact -.It Cm bw Ar bandwidth | device -Bandwidth, measured in -.Sm off -.Op Cm K | M -.Brq Cm bit/s | Byte/s . -.Sm on -.Pp -A value of 0 (default) means unlimited bandwidth. -The unit must immediately follow the number, as in -.Pp -.Dl "ipfw pipe 1 config bw 300Kbit/s" -.Pp -If a device name is specified instead of a numeric value, as in -.Pp -.Dl "ipfw pipe 1 config bw tun0" -.Pp -then the transmit clock is supplied by the specified device. -At the moment only the -.Xr tun 4 -device supports this -functionality, for use in conjunction with -.Xr ppp 8 . -.Pp -.It Cm delay Ar ms-delay -Propagation delay, measured in milliseconds. -The value is rounded to the next multiple of the clock tick -(typically 10ms, but it is a good practice to run kernels -with -.Dq "options HZ=1000" -to reduce -the granularity to 1ms or less). -Default value is 0, meaning no delay. -.El -.Pp -The following parameters can be configured for a queue: -.Pp -.Bl -tag -width indent -compact -.It Cm pipe Ar pipe_nr -Connects a queue to the specified pipe. -Multiple queues (with the same or different weights) can be connected to -the same pipe, which specifies the aggregate rate for the set of queues. -.Pp -.It Cm weight Ar weight -Specifies the weight to be used for flows matching this queue. -The weight must be in the range 1..100, and defaults to 1. -.El -.Pp -Finally, the following parameters can be configured for both -pipes and queues: -.Pp -.Bl -tag -width XXXX -compact -.Pp -.It Cm buckets Ar hash-table-size -Specifies the size of the hash table used for storing the -various queues. -Default value is 64 controlled by the -.Xr sysctl 8 -variable -.Em net.inet.ip.dummynet.hash_size , -allowed range is 16 to 65536. -.Pp -.It Cm mask Ar mask-specifier -Packets sent to a given pipe or queue by an -.Nm -rule can be further classified into multiple flows, each of which is then -sent to a different -.Em dynamic -pipe or queue. -A flow identifier is constructed by masking the IP addresses, -ports and protocol types as specified with the -.Cm mask -options in the configuration of the pipe or queue. -For each different flow identifier, a new pipe or queue is created -with the same parameters as the original object, and matching packets -are sent to it. -.Pp -Thus, when -.Em dynamic pipes -are used, each flow will get the same bandwidth as defined by the pipe, -whereas when -.Em dynamic queues -are used, each flow will share the parent's pipe bandwidth evenly -with other flows generated by the same queue (note that other queues -with different weights might be connected to the same pipe). -.br -Available mask specifiers are a combination of one or more of the following: -.Pp -.Cm dst-ip Ar mask , -.Cm src-ip Ar mask , -.Cm dst-port Ar mask , -.Cm src-port Ar mask , -.Cm proto Ar mask -or -.Cm all , -.Pp -where the latter means all bits in all fields are significant. -.Pp -.It Cm noerror -When a packet is dropped by a dummynet queue or pipe, the error -is normally reported to the caller routine in the kernel, in the -same way as it happens when a device queue fills up. Setting this -option reports the packet as successfully delivered, which can be -needed for some experimental setups where you want to simulate -loss or congestion at a remote router. -.Pp -.It Cm plr Ar packet-loss-rate -Packet loss rate. -Argument -.Ar packet-loss-rate -is a floating-point number between 0 and 1, with 0 meaning no -loss, 1 meaning 100% loss. -The loss rate is internally represented on 31 bits. -.Pp -.It Cm queue Brq Ar slots | size Ns Cm Kbytes -Queue size, in -.Ar slots -or -.Cm KBytes . -Default value is 50 slots, which -is the typical queue size for Ethernet devices. -Note that for slow speed links you should keep the queue -size short or your traffic might be affected by a significant -queueing delay. -E.g., 50 max-sized ethernet packets (1500 bytes) mean 600Kbit -or 20s of queue on a 30Kbit/s pipe. -Even worse effect can result if you get packets from an -interface with a much larger MTU, e.g. the loopback interface -with its 16KB packets. -.Pp -.It Cm red | gred Ar w_q Ns / Ns Ar min_th Ns / Ns Ar max_th Ns / Ns Ar max_p -Make use of the RED (Random Early Detection) queue management algorithm. -.Ar w_q -and -.Ar max_p -are floating -point numbers between 0 and 1 (0 not included), while -.Ar min_th -and -.Ar max_th -are integer numbers specifying thresholds for queue management -(thresholds are computed in bytes if the queue has been defined -in bytes, in slots otherwise). -The -.Xr dummynet 4 -also supports the gentle RED variant (gred). -Three -.Xr sysctl 8 -variables can be used to control the RED behaviour: -.Bl -tag -width indent -.It Em net.inet.ip.dummynet.red_lookup_depth -specifies the accuracy in computing the average queue -when the link is idle (defaults to 256, must be greater than zero) -.It Em net.inet.ip.dummynet.red_avg_pkt_size -specifies the expected average packet size (defaults to 512, must be -greater than zero) -.It Em net.inet.ip.dummynet.red_max_pkt_size -specifies the expected maximum packet size, only used when queue -thresholds are in bytes (defaults to 1500, must be greater than zero). -.El -.El -.Sh CHECKLIST -Here are some important points to consider when designing your -rules: -.Bl -bullet -.It -Remember that you filter both packets going -.Cm in -and -.Cm out . -Most connections need packets going in both directions. -.It -Remember to test very carefully. -It is a good idea to be near the console when doing this. -If you cannot be near the console, -use an auto-recovery script such as the one in -.Pa /usr/share/examples/ipfw/change_rules.sh . -.It -Don't forget the loopback interface. -.El -.Sh FINE POINTS -.Bl -bullet -.It -There are circumstances where fragmented datagrams are unconditionally -dropped. -TCP packets are dropped if they do not contain at least 20 bytes of -TCP header, UDP packets are dropped if they do not contain a full 8 -byte UDP header, and ICMP packets are dropped if they do not contain -4 bytes of ICMP header, enough to specify the ICMP type, code, and -checksum. -These packets are simply logged as -.Dq pullup failed -since there may not be enough good data in the packet to produce a -meaningful log entry. -.It -Another type of packet is unconditionally dropped, a TCP packet with a -fragment offset of one. -This is a valid packet, but it only has one use, to try -to circumvent firewalls. -When logging is enabled, these packets are -reported as being dropped by rule -1. -.It -The -.Nm -filter list may not be modified if the system security level -is set to 3 or higher. -.El -.Sh PACKET DIVERSION -A -.Xr divert 4 -socket bound to the specified port will receive all packets -diverted to that port. -If no socket is bound to the destination port, or if the kernel -wasn't compiled with divert socket support, the packets are -dropped. -.Sh SYSCTL VARIABLES -A set of -.Xr sysctl 8 -variables controls the behaviour of the firewall and -associated modules ( -.Nm dummynet, bridge -). -These are shown below together with their default value -(but always check with the -.Xr sysctl 8 -command what value is actually in use) and meaning: -.Bl -tag -width indent -.It Em net.inet.ip.dummynet.expire : No 1 -Lazily delete dynamic pipes/queue once they have no pending traffic. -You can disable this by setting the variable to 0, in which case -the pipes/queues will only be deleted when the threshold is reached. -.It Em net.inet.ip.dummynet.hash_size : No 64 -Default size of the hash table used for dynamic pipes/queues. -This value is used when no -.Cm buckets -option is specified when configuring a pipe/queue. -.It Em net.inet.ip.dummynet.max_chain_len : No 16 -Target value for the maximum number of pipes/queues in a hash bucket. -The product -.Cm max_chain_len*hash_size -is used to determine the threshold over which empty pipes/queues -will be expired even when -.Cm net.inet.ip.dummynet.expire=0 . -.It Em net.inet.ip.dummynet.red_lookup_depth : No 256 -.It Em net.inet.ip.dummynet.red_avg_pkt_size : No 512 -.It Em net.inet.ip.dummynet.red_max_pkt_size : No 1500 -Parameters used in the computations of the drop probability -for the RED algorithm. -.It Em net.inet.ip.fw.autoinc_step : No 100 -Delta between rule numbers when auto-generating them. -The value must be in the range 1..1000. -This variable is only present in -.Nm ipfw2 , -the delta is hardwired to 100 in -.Nm ipfw1 . -.It Em net.inet.ip.fw.curr_dyn_buckets : Em net.inet.ip.fw.dyn_buckets -The current number of buckets in the hash table for dynamic rules -(readonly). -.It Em net.inet.ip.fw.debug : No 1 -Controls debugging messages produced by -.Nm . -.It Em net.inet.ip.fw.dyn_buckets : No 256 -The number of buckets in the hash table for dynamic rules. -Must be a power of 2, up to 65536. -It only takes effect when all dynamic rules have expired, so you -are advised to use a -.Cm flush -command to make sure that the hash table is resized. -.It Em net.inet.ip.fw.dyn_count : No 3 -Current number of dynamic rules -(read-only). -.It Em net.inet.ip.fw.dyn_keepalive : No 1 -Enables generation of keepalive packets for -.Cm keep-state -rules on TCP sessions. A keepalive is generated to both -sides of the connection every 5 seconds for the last 20 -seconds of the lifetime of the rule. -.It Em net.inet.ip.fw.dyn_max : No 8192 -Maximum number of dynamic rules. -When you hit this limit, no more dynamic rules can be -installed until old ones expire. -.It Em net.inet.ip.fw.dyn_ack_lifetime : No 300 -.It Em net.inet.ip.fw.dyn_syn_lifetime : No 20 -.It Em net.inet.ip.fw.dyn_fin_lifetime : No 1 -.It Em net.inet.ip.fw.dyn_rst_lifetime : No 1 -.It Em net.inet.ip.fw.dyn_udp_lifetime : No 5 -.It Em net.inet.ip.fw.dyn_short_lifetime : No 30 -These variables control the lifetime, in seconds, of dynamic -rules. -Upon the initial SYN exchange the lifetime is kept short, -then increased after both SYN have been seen, then decreased -again during the final FIN exchange or when a RST is received. -Both -.Em dyn_fin_lifetime -and -.Em dyn_rst_lifetime -must be strictly lower than 5 seconds, the period of -repetition of keepalives. The firewall enforces that. -.It Em net.inet.ip.fw.enable : No 1 -Enables the firewall. -Setting this variable to 0 lets you run your machine without -firewall even if compiled in. -.It Em net.inet.ip.fw.one_pass : No 1 -When set, the packet exiting from the -.Xr dummynet 4 -pipe is not passed though the firewall again. -Otherwise, after a pipe action, the packet is -reinjected into the firewall at the next rule. -.It Em net.inet.ip.fw.verbose : No 1 -Enables verbose messages. -.It Em net.inet.ip.fw.verbose_limit : No 0 -Limits the number of messages produced by a verbose firewall. -.It Em net.link.ether.ipfw : No 0 -Controls whether layer-2 packets are passed to -.Nm . -Default is no. -.It Em net.link.ether.bridge_ipfw : No 0 -Controls whether bridged packets are passed to -.Nm . -Default is no. -.El -.Pp -.Sh IPFW2 ENHANCEMENTS -This Section lists the features that have been introduced in -.Nm ipfw2 -which were not present in -.Nm ipfw1 . -We list them in order of the potential impact that they can -have in writing your rulesets. -You might want to consider using these features in order to -write your rulesets in a more efficient way. -.Bl -tag -width indent -.It Syntax and flags -.Nm ipfw1 -does not support the -n flag (only test syntax), -nor it allows spaces after commas or supports all -rule fields in a single argument. -.It Handling of non-IPv4 packets -.Nm ipfw1 -will silently accept all non-IPv4 packets (which -.Nm ipfw1 -will only see when -.Em net.link.ether.bridge_ipfw=1 Ns -). -.Nm ipfw2 -will filter all packets (including non-IPv4 ones) according to the ruleset. -To achieve the same behaviour as -.Nm ipfw1 -you can use the following as the very first rule in your ruleset: -.Pp -.Dl "ipfw add 1 allow layer2 not mac-type ip" -.Pp -The -.Cm layer2 -option might seem redundant, but it is necessary -- packets -passed to the firewall from layer3 will not have a MAC header, -so the -.Cm mac-type ip -pattern will always fail on them, and the -.Cm not -operator will make this rule into a pass-all. -.It Addresses -.Nm ipfw1 -does not supports address sets or lists of addresses. -.Pp -.It Port specifications -.Nm ipfw1 -only allows one port range when specifying TCP and UDP ports, and -is limited to 10 entries instead of the 15 allowed by -.Nm ipfw2 . -Also, in -.Nm ipfw1 -you can only specify ports when the rule is requesting -.Cm tcp -or -.Cm udp -packets. With -.Nm ipfw2 -you can put port specifications in rules matching all packets, -and the match will be attempted only on those packets carrying -protocols which include port identifiers. -.Pp -Finally, -.Nm ipfw1 -allowed the first port entry to be specified as -.Ar port:mask -where -.Ar mask -can be an arbitrary 16-bit mask. -This syntax is of questionable usefulness and it is not -supported anymore in -.Nm ipfw2 . -.It Or-blocks -.Nm ipfw1 -does not support Or-blocks. -.It keepalives -.Nm ipfw1 -does not generate keepalives for stateful sessions. -As a consequence, it might cause idle sessions to drop because -the lifetime of the dynamic rules expires. -.It Sets of rules -.Nm ipfw1 -does not implement sets of rules. -.It MAC header filtering and Layer-2 firewalling. -.Nm ipfw1 -does not implement filtering on MAC header fields, nor is it -invoked on packets from -.Cm ether_demux() -and -.Cm ether_output_frame(). -The sysctl variable -.Em net.link.ether.ipfw -has no effect there. -.It Options -In -.Nm ipfw1 , -the following options only accept a single value as an argument: -.Pp -.Cm ipid, iplen, ipttl -.Pp -The following options are not implemented by -.Nm ipfw1 : -.Pp -.Cm dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port. -.Pp -Additionally, the RELENG_4 version of -.Nm ipfw1 -does not implement the following options: -.Pp -.Cm ipid, iplen, ipprecedence, iptos, ipttl, -.Cm ipversion, tcpack, tcpseq, tcpwin . -.It Dummynet options -The following option for -.Nm dummynet -pipes/queues is not supported: -.Cm noerror . -.El -.Sh EXAMPLES -There are far too many possible uses of -.Nm -so this Section will only give a small set of examples. -.Pp -.Ss BASIC PACKET FILTERING -This command adds an entry which denies all tcp packets from -.Em cracker.evil.org -to the telnet port of -.Em wolf.tambov.su -from being forwarded by the host: -.Pp -.Dl "ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet" -.Pp -This one disallows any connection from the entire cracker's -network to my host: -.Pp -.Dl "ipfw add deny ip from 123.45.67.0/24 to my.host.org" -.Pp -A first and efficient way to limit access (not using dynamic rules) -is the use of the following rules: -.Pp -.Dl "ipfw add allow tcp from any to any established" -.Dl "ipfw add allow tcp from net1 portlist1 to net2 portlist2 setup" -.Dl "ipfw add allow tcp from net3 portlist3 to net3 portlist3 setup" -.Dl "..." -.Dl "ipfw add deny tcp from any to any" -.Pp -The first rule will be a quick match for normal TCP packets, -but it will not match the initial SYN packet, which will be -matched by the -.Cm setup -rules only for selected source/destination pairs. -All other SYN packets will be rejected by the final -.Cm deny -rule. -.Pp -If you administer one or more subnets, you can take advantage of the -.Nm ipfw2 -syntax to specify address sets and or-blocks and write extremely -compact rulesets which selectively enable services to blocks -of clients, as below: -.Pp -.Dl "goodguys=\*q{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }\*q" -.Dl "badguys=\*q10.1.2.0/24{8,38,60}\*q" -.Dl "" -.Dl "ipfw add allow ip from ${goodguys} to any" -.Dl "ipfw add deny ip from ${badguys} to any" -.Dl "... normal policies ..." -.Pp -The -.Nm ipfw1 -syntax would require a separate rule for each IP in the above -example. -.Pp -The -.Cm verrevpath -option could be used to do automated anti-spoofing by adding the -following to the top of a ruleset: -.Pp -.Dl "ipfw add deny ip from any to any not verrevpath in" -.Pp -This rule drops all incoming packets that appear to be coming to the -sytem on the wrong interface. For example, a packet with a source -address belonging to a host on a protected internal network would be -dropped if it tried to enter the system from an external interface. -.Ss DYNAMIC RULES -In order to protect a site from flood attacks involving fake -TCP packets, it is safer to use dynamic rules: -.Pp -.Dl "ipfw add check-state" -.Dl "ipfw add deny tcp from any to any established" -.Dl "ipfw add allow tcp from my-net to any setup keep-state" -.Pp -This will let the firewall install dynamic rules only for -those connection which start with a regular SYN packet coming -from the inside of our network. -Dynamic rules are checked when encountering the first -.Cm check-state -or -.Cm keep-state -rule. -A -.Cm check-state -rule should usually be placed near the beginning of the -ruleset to minimize the amount of work scanning the ruleset. -Your mileage may vary. -.Pp -To limit the number of connections a user can open -you can use the following type of rules: -.Pp -.Dl "ipfw add allow tcp from my-net/24 to any setup limit src-addr 10" -.Dl "ipfw add allow tcp from any to me setup limit src-addr 4" -.Pp -The former (assuming it runs on a gateway) will allow each host -on a /24 network to open at most 10 TCP connections. -The latter can be placed on a server to make sure that a single -client does not use more than 4 simultaneous connections. -.Pp -.Em BEWARE : -stateful rules can be subject to denial-of-service attacks -by a SYN-flood which opens a huge number of dynamic rules. -The effects of such attacks can be partially limited by -acting on a set of -.Xr sysctl 8 -variables which control the operation of the firewall. -.Pp -Here is a good usage of the -.Cm list -command to see accounting records and timestamp information: -.Pp -.Dl ipfw -at list -.Pp -or in short form without timestamps: -.Pp -.Dl ipfw -a list -.Pp -which is equivalent to: -.Pp -.Dl ipfw show -.Pp -Next rule diverts all incoming packets from 192.168.2.0/24 -to divert port 5000: -.Pp -.Dl ipfw divert 5000 ip from 192.168.2.0/24 to any in -.Pp -.Ss TRAFFIC SHAPING -The following rules show some of the applications of -.Nm -and -.Xr dummynet 4 -for simulations and the like. -.Pp -This rule drops random incoming packets with a probability -of 5%: -.Pp -.Dl "ipfw add prob 0.05 deny ip from any to any in" -.Pp -A similar effect can be achieved making use of dummynet pipes: -.Pp -.Dl "ipfw add pipe 10 ip from any to any" -.Dl "ipfw pipe 10 config plr 0.05" -.Pp -We can use pipes to artificially limit bandwidth, e.g. on a -machine acting as a router, if we want to limit traffic from -local clients on 192.168.2.0/24 we do: -.Pp -.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out" -.Dl "ipfw pipe 1 config bw 300Kbit/s queue 50KBytes" -.Pp -note that we use the -.Cm out -modifier so that the rule is not used twice. -Remember in fact that -.Nm -rules are checked both on incoming and outgoing packets. -.Pp -Should we want to simulate a bidirectional link with bandwidth -limitations, the correct way is the following: -.Pp -.Dl "ipfw add pipe 1 ip from any to any out" -.Dl "ipfw add pipe 2 ip from any to any in" -.Dl "ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes" -.Dl "ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes" -.Pp -The above can be very useful, e.g. if you want to see how -your fancy Web page will look for a residential user who -is connected only through a slow link. -You should not use only one pipe for both directions, unless -you want to simulate a half-duplex medium (e.g. AppleTalk, -Ethernet, IRDA). -It is not necessary that both pipes have the same configuration, -so we can also simulate asymmetric links. -.Pp -Should we want to verify network performance with the RED queue -management algorithm: -.Pp -.Dl "ipfw add pipe 1 ip from any to any" -.Dl "ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1" -.Pp -Another typical application of the traffic shaper is to -introduce some delay in the communication. -This can significantly affect applications which do a lot of Remote -Procedure Calls, and where the round-trip-time of the -connection often becomes a limiting factor much more than -bandwidth: -.Pp -.Dl "ipfw add pipe 1 ip from any to any out" -.Dl "ipfw add pipe 2 ip from any to any in" -.Dl "ipfw pipe 1 config delay 250ms bw 1Mbit/s" -.Dl "ipfw pipe 2 config delay 250ms bw 1Mbit/s" -.Pp -Per-flow queueing can be useful for a variety of purposes. -A very simple one is counting traffic: -.Pp -.Dl "ipfw add pipe 1 tcp from any to any" -.Dl "ipfw add pipe 1 udp from any to any" -.Dl "ipfw add pipe 1 ip from any to any" -.Dl "ipfw pipe 1 config mask all" -.Pp -The above set of rules will create queues (and collect -statistics) for all traffic. -Because the pipes have no limitations, the only effect is -collecting statistics. -Note that we need 3 rules, not just the last one, because -when -.Nm -tries to match IP packets it will not consider ports, so we -would not see connections on separate ports as different -ones. -.Pp -A more sophisticated example is limiting the outbound traffic -on a net with per-host limits, rather than per-network limits: -.Pp -.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out" -.Dl "ipfw add pipe 2 ip from any to 192.168.2.0/24 in" -.Dl "ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes" -.Dl "ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes" -.Ss SETS OF RULES -To add a set of rules atomically, e.g. set 18: -.Pp -.Dl "ipfw set disable 18" -.Dl "ipfw add NN set 18 ... # repeat as needed" -.Dl "ipfw set enable 18" -.Pp -To delete a set of rules atomically the command is simply: -.Pp -.Dl "ipfw delete set 18" -.Pp -To test a ruleset and disable it and regain control if something goes wrong: -.Pp -.Dl "ipfw set disable 18" -.Dl "ipfw add NN set 18 ... # repeat as needed" -.Dl "ipfw set enable 18; echo done; sleep 30 && ipfw set disable 18" -.Pp -Here if everything goes well, you press control-C before the "sleep" -terminates, and your ruleset will be left active. Otherwise, e.g. if -you cannot access your box, the ruleset will be disabled after -the sleep terminates thus restoring the previous situation. -.Sh SEE ALSO -.Xr cpp 1 , -.Xr m4 1 , -.Xr divert 4 , -.Xr dummynet 4 , -.Xr ip 4 , -.Xr ipfirewall 4 , -.Xr protocols 5 , -.Xr services 5 , -.Xr reboot 8 , -.Xr sysctl 8 , -.Xr syslogd 8 -.Sh BUGS -The syntax has grown over the years and sometimes it might be confusing. -Unfortunately, backward compatibility prevents cleaning up mistakes -made in the definition of the syntax. -.Pp -.Em !!! WARNING !!! -.Pp -Misconfiguring the firewall can put your computer in an unusable state, -possibly shutting down network services and requiring console access to -regain control of it. -.Pp -Incoming packet fragments diverted by -.Cm divert -or -.Cm tee -are reassembled before delivery to the socket. -The action used on those packet is the one from the -rule which matches the first fragment of the packet. -.Pp -Packets that match a -.Cm tee -rule should not be immediately accepted, but should continue -going through the rule list. -This may be fixed in a later version. -.Pp -Packets diverted to userland, and then reinserted by a userland process -may lose various packet attributes. -The packet source interface name -will be preserved if it is shorter than 8 bytes and the userland process -saves and reuses the sockaddr_in -(as does -.Xr natd 8 ) ; -otherwise, it may be lost. -If a packet is reinserted in this manner, later rules may be incorrectly -applied, making the order of -.Cm divert -rules in the rule sequence very important. -.Sh AUTHORS -.An Ugen J. S. Antsilevich , -.An Poul-Henning Kamp , -.An Alex Nash , -.An Archie Cobbs , -.An Luigi Rizzo . -.Pp -.An -nosplit -API based upon code written by -.An Daniel Boulet -for BSDI. -.Pp -Work on -.Xr dummynet 4 -traffic shaper supported by Akamba Corp. -.Sh HISTORY -The -.Nm -utility first appeared in -.Fx 2.0 . -.Xr dummynet 4 -was introduced in -.Fx 2.2.8 . -Stateful extensions were introduced in -.Fx 4.0 . -.Nm ipfw2 -was introduced in Summer 2002. diff --git a/kdumpd.tproj/kdumpd.c b/kdumpd.tproj/kdumpd.c index 4ad72c9..5f06353 100644 --- a/kdumpd.tproj/kdumpd.c +++ b/kdumpd.tproj/kdumpd.c @@ -261,7 +261,7 @@ main(argc, argv) tempaddr = inet_ntoa(from.sin_addr); snprintf(tempchroot, sizeof(tempchroot), "%s/%s", chroot_dir, tempaddr); statret = stat(tempchroot, &sb); - if ((sb.st_mode & S_IFDIR) && + if (((sb.st_mode & S_IFMT ) == S_IFDIR) && (statret == 0 || (statret == -1 && ipchroot == 1))) chroot_dir = tempchroot; } diff --git a/natd.tproj/natd.8 b/natd.tproj/natd.8 index 3d88a12..6e3a284 100644 --- a/natd.tproj/natd.8 +++ b/natd.tproj/natd.8 @@ -1,576 +1,11 @@ -.\" manual page [] for natd 1.4 -.\" $Id: natd.8,v 1.6 2004/10/21 21:48:41 vazquez Exp $ -.Dd June 27, 2000 +.Dd September 27, 2012 +.Dt Darwin 8 .Os Darwin -.Dt NATD 8 .Sh NAME .Nm natd -.Nd Network Address Translation daemon -.Sh SYNOPSIS -.Nm -.Bk -words -.Op Fl unregistered_only | u -.Op Fl log | l -.Op Fl proxy_only -.Op Fl reverse -.Op Fl deny_incoming | d -.Op Fl use_sockets | s -.Op Fl same_ports | m -.Op Fl verbose | v -.Op Fl dynamic -.Op Fl in_port | i Ar port -.Op Fl out_port | o Ar port -.Op Fl port | p Ar port -.Op Fl alias_address | a Ar address -.Op Fl target_address | t Ar address -.Op Fl interface | n Ar interface -.Op Fl proxy_rule Ar proxyspec -.Op Fl redirect_port Ar linkspec -.Op Fl redirect_proto Ar linkspec -.Op Fl redirect_address Ar linkspec -.Op Fl config | f Ar configfile -.Op Fl log_denied -.Op Fl log_facility Ar facility_name -.Op Fl punch_fw Ar firewall_range -.Op Fl clamp_mss -.Op Fl enable_natportmap -.Op Fl natportmap_interface Ar interface -.Ek .Sh DESCRIPTION -This program provides a Network Address Translation facility for use -with -.Xr divert 4 -sockets under -.Fx . -.Pp -The -.Nm -normally runs in the background as a daemon. -It is passed raw IP packets as they travel into and out of the machine, -and will possibly change these before re-injecting them back into the -IP packet stream. -.Pp -It changes all packets destined for another host so that their source -IP number is that of the current machine. -For each packet changed in this manner, an internal table entry is -created to record this fact. -The source port number is also changed to indicate the table entry -applying to the packet. -Packets that are received with a target IP of the current host are -checked against this internal table. -If an entry is found, it is used to determine the correct target IP -number and port to place in the packet. -.Pp -The following command line options are available: -.Bl -tag -width Fl -.It Fl log | l -Log various aliasing statistics and information to the file -.Pa /var/log/alias.log . -This file is truncated each time -.Nm -is started. -.It Fl deny_incoming | d -Do not pass incoming packets that have no -entry in the internal translation table. -.Pp -If this option is not used, then such a packet will be altered -using the rules in -.Fl target_address -below, and the entry will be made in the internal translation table. -.It Fl log_denied -Log denied incoming packets via -.Xr syslog 3 -.Po -see also -.Fl log_facility -.Pc . -.It Fl log_facility Ar facility_name -Use specified log facility when logging information via -.Xr syslog 3 . -Argument -.Ar facility_name -is one of the keywords specified in -.Xr syslog.conf 5 . -.It Fl use_sockets | s -Allocate a -.Xr socket 2 -in order to establish an FTP data or IRC DCC send connection. -This option uses more system resources, but guarantees successful -connections when port numbers conflict. -.It Fl same_ports | m -Try to keep the same port number when altering outgoing packets. -With this option, protocols such as RPC will have a better chance -of working. -If it is not possible to maintain the port number, it will be silently -changed as per normal. -.It Fl verbose | v -Do not call -.Xr daemon 3 -on startup. Instead, stay attached to the controlling terminal and -display all packet alterations to the standard output. This option -should only be used for debugging purposes. -.It Fl unregistered_only | u -Only alter outgoing packets with an -.Em unregistered -source address. -According to RFC 1918, unregistered source addresses are 10.0.0.0/8, -172.16.0.0/12 and 192.168.0.0/16. -.It Fl redirect_port Ar proto Xo -.Ar targetIP Ns : Ns Xo -.Ar targetPORT Ns Op - Ns Ar targetPORT Xc -.Op Ar aliasIP Ns : Ns Xo -.Ar aliasPORT Ns Op - Ns Ar aliasPORT Xc -.Oo Ar remoteIP Ns Oo : Ns -.Ar remotePORT Ns Op - Ns Ar remotePORT -.Oc Oc -.Xc -Redirect incoming connections arriving to given port(s) to another host -and port(s). -Argument -.Ar proto -is either -.Ar tcp -or -.Ar udp , -.Ar targetIP -is the desired target IP number, -.Ar targetPORT -is the desired target port number or range, -.Ar aliasPORT -is the requested port number or range, and -.Ar aliasIP -is the aliasing address. -Arguments -.Ar remoteIP -and -.Ar remotePORT -can be used to specify the connection more accurately if necessary. -The -.Ar targetPORT -range and -.Ar aliasPORT -range need not be the same numerically, but must have the same size. -If -.Ar remotePORT -is not specified, it is assumed to be all ports. -If -.Ar remotePORT -is specified, it must match the size of -.Ar targetPORT , -or be 0 (all ports). -For example, the argument -.Pp -.Dl Ar tcp inside1:telnet 6666 -.Pp -means that incoming TCP packets destined for port 6666 on this machine -will be sent to the telnet port on the inside1 machine. -.Pp -.Dl Ar tcp inside2:2300-2399 3300-3399 -.Pp -will redirect incoming connections on ports 3300-3399 to host -inside2, ports 2300-2399. -The mapping is 1:1 meaning port 3300 maps to 2300, 3301 maps to 2301, etc. -.It Fl redirect_proto Ar proto localIP Oo -.Ar publicIP Op Ar remoteIP -.Oc -Redirect incoming IP packets of protocol -.Ar proto -.Po see Xr protocols 5 -.Pc -destined for -.Ar publicIP -address to a -.Ar localIP -address and vice versa. -.Pp -If -.Ar publicIP -is not specified, then the default aliasing address is used. -If -.Ar remoteIP -is specified, then only packets coming from/to -.Ar remoteIP -will match the rule. -.It Fl redirect_address Ar localIP publicIP -Redirect traffic for public IP address to a machine on the local -network. -This function is known as -.Em static NAT . -Normally static NAT is useful if your ISP has allocated a small block -of IP addresses to you, but it can even be used in the case of single -address: -.Pp -.Dl Ar redirect_address 10.0.0.8 0.0.0.0 -.Pp -The above command would redirect all incoming traffic -to machine 10.0.0.8. -.Pp -If several address aliases specify the same public address -as follows -.Bd -literal -offset indent -.Ar redirect_address 192.168.0.2 public_addr -.Ar redirect_address 192.168.0.3 public_addr -.Ar redirect_address 192.168.0.4 public_addr -.Ed -.Pp -the incoming traffic will be directed to the last -translated local address (192.168.0.4), but outgoing -traffic from the first two addresses will still be aliased -to appear from the specified -.Ar public_addr . -.It Fl redirect_port Ar proto Xo -.Ar targetIP Ns : Ns Xo -.Ar targetPORT Ns Oo , Ns -.Ar targetIP Ns : Ns Xo -.Ar targetPORT Ns Oo , Ns -.Ar ...\& -.Oc Oc -.Xc -.Xc -.Op Ar aliasIP Ns : Ns Xo -.Ar aliasPORT -.Xc -.Oo Ar remoteIP Ns -.Op : Ns Ar remotePORT -.Oc -.Xc -.It Fl redirect_address Xo -.Ar localIP Ns Oo , Ns -.Ar localIP Ns Oo , Ns -.Ar ...\& -.Oc Oc -.Ar publicIP -.Xc -These forms of -.Fl redirect_port -and -.Fl redirect_address -are used to transparently offload network load on a single server and -distribute the load across a pool of servers. -This function is known as -.Em LSNAT -(RFC 2391). -For example, the argument -.Pp -.Dl Ar tcp www1:http,www2:http,www3:http www:http -.Pp -means that incoming HTTP requests for host www will be transparently -redirected to one of the www1, www2 or www3, where a host is selected -simply on a round-robin basis, without regard to load on the net. -.It Fl dynamic -If the -.Fl n -or -.Fl interface -option is used, -.Nm -will monitor the routing socket for alterations to the -.Ar interface -passed. -If the interface's IP number is changed, -.Nm -will dynamically alter its concept of the alias address. -.It Fl in_port | i Ar port -Read from and write to -.Xr divert 4 -port -.Ar port , -treating all packets as -.Dq incoming . -.It Fl out_port | o Ar port -Read from and write to -.Xr divert 4 -port -.Ar port , -treating all packets as -.Dq outgoing . -.It Fl port | p Ar port -Read from and write to -.Xr divert 4 -port -.Ar port , -distinguishing packets as -.Dq incoming -or -.Dq outgoing -using the rules specified in -.Xr divert 4 . -If -.Ar port -is not numeric, it is searched for in the -.Xr services 5 -database. -If this option is not specified, the divert port named -.Ar natd -will be used as a default. -.It Fl alias_address | a Ar address -Use -.Ar address -as the aliasing address. -If this option is not specified, the -.Fl interface -option must be used. -The specified address is usually the address assigned to the -.Dq public -network interface. -.Pp -All data passing -.Em out -will be rewritten with a source address equal to -.Ar address . -All data coming -.Em in -will be checked to see if it matches any already-aliased outgoing -connection. -If it does, the packet is altered accordingly. -If not, all -.Fl redirect_port , -.Fl redirect_proto -and -.Fl redirect_address -assignments are checked and actioned. -If no other action can be made and if -.Fl deny_incoming -is not specified, the packet is delivered to the local machine -using the rules specified in -.Fl target_address -option below. -.It Fl t | target_address Ar address -Set the target address. -When an incoming packet not associated with any pre-existing link -arrives at the host machine, it will be sent to the specified -.Ar address . -.Pp -The target address may be set to -.Ar 255.255.255.255 , -in which case all new incoming packets go to the alias address set by -.Fl alias_address -or -.Fl interface . -.Pp -If this option is not used, or called with the argument -.Ar 0.0.0.0 , -then all new incoming packets go to the address specified in -the packet. -This allows external machines to talk directly to internal machines if -they can route packets to the machine in question. -.It Fl interface | n Ar interface -Use -.Ar interface -to determine the aliasing address. -If there is a possibility that the IP number associated with -.Ar interface -may change, the -.Fl dynamic -option should also be used. -If this option is not specified, the -.Fl alias_address -option must be used. -.Pp -The specified -.Ar interface -is usually the -.Dq public -(or -.Dq external ) -network interface. -.It Fl config | f Ar file -Read configuration from -.Ar file . -A -.Ar file -should contain a list of options, one per line, in the same form -as the long form of the above command line options. -For example, the line -.Pp -.Dl alias_address 158.152.17.1 -.Pp -would specify an alias address of 158.152.17.1. -Options that do not take an argument are specified with an argument of -.Ar yes -or -.Ar no -in the configuration file. For example, the line - log yes -is synonymous with -.Fl log . -.Pp -Trailing spaces and empty lines are ignored. -A -.Ql \&# -sign will mark the rest of the line as a comment. -.It Fl reverse -This option makes -.Nm -reverse the way it handles -.Dq incoming -and -.Dq outgoing -packets, allowing it to operate on the -.Dq internal -network interface rather than the -.Dq external -one. -.Pp -This can be useful in some transparent proxying situations -when outgoing traffic is redirected to the local machine -and -.Nm -is running on the internal interface (it usually runs on the -external interface). -.It Fl proxy_only -Force -.Nm -to perform transparent proxying only. -Normal address translation is not performed. -.It Fl proxy_rule Xo -.Op Ar type encode_ip_hdr | encode_tcp_stream -.Ar port xxxx -.Ar server a.b.c.d:yyyy -.Xc -Enable transparent proxying. -Outgoing TCP packets with the given port going through this -host to any other host are redirected to the given server and port. -Optionally, the original target address can be encoded into the packet. -Use -.Ar encode_ip_hdr -to put this information into the IP option field or -.Ar encode_tcp_stream -to inject the data into the beginning of the TCP stream. -.It Fl punch_fw Xo -.Ar basenumber Ns : Ns Ar count -.Xc -This option directs -.Nm -to -.Dq punch holes -in an -.Xr ipfirewall 4 -based firewall for FTP/IRC DCC connections. -This is done dynamically by installing temporary firewall rules which -allow a particular connection (and only that connection) to go through -the firewall. -The rules are removed once the corresponding connection terminates. -.Pp -A maximum of -.Ar count -rules starting from the rule number -.Ar basenumber -will be used for punching firewall holes. -The range will be cleared for all rules on startup. -.It Fl clamp_mss Xo -.Xc -This option enables MSS clamping. The MSS value is derived from the -MTU of the interface specified in the -.Fl interface -option. -.It Fl enable_natportmap Xo -.Xc -This option enables port forwarding using the NATPMP protocol. -.It Fl natportmap_interface Ar interface Xo -.Xc -This option instructs natd to listen for NATPMP requests. This option should appear for each -interface on which natd will listen for NATPMP requests. -.El -.Sh RUNNING NATD -The following steps are necessary before attempting to run -.Nm : -.Bl -enum -.It -Ensure that your machine is acting as a gateway. -This can be done by using the command -.Pp -.Dl sysctl -w net.inet.ip.forwarding=1 -.Pp -.It -If you use the -.Fl interface -option, make sure that your interface is already configured. -If, for example, you wish to specify -.Ql tun0 -as your -.Ar interface , -and you are using -.Xr ppp 8 -on that interface, you must make sure that you start -.Nm ppp -prior to starting -.Nm . -.El -.Pp -Running -.Nm -is fairly straight forward. -The line -.Pp -.Dl natd -interface en0 -.Pp -should suffice in most cases (substituting the correct interface name). -.Pp -Once -.Nm -is running, you must ensure that traffic is diverted to -.Nm : -.Bl -enum -.It -If you are not interested in having a firewall, the -following lines will do: -.Bd -literal -offset indent -/sbin/ipfw -f flush -/sbin/ipfw add divert natd all from any to any via en0 -/sbin/ipfw add pass all from any to any -.Ed -.Pp -The second line depends on your interface (change -.Ql en0 -as appropriate). -.Pp -You should be aware of the fact that, with these firewall settings, -everyone on your local network can fake his source-address using your -host as gateway. -If there are other hosts on your local network, you are strongly -encouraged to create firewall rules that only allow traffic to and -from trusted hosts. -.Pp -If you specify real firewall rules, it is best to specify line 2 at -the start of the rules so that -.Nm -sees all packets before they are dropped by the firewall. -.Pp -After translation by -.Nm , -packets re-enter the firewall at the rule number following the rule number -that caused the diversion (not the next rule if there are several at the -same number). -.It -Enable your firewall by using the command -.Pp -.Dl sysctl -w net.inet.ip.fw.enable=1 -.Pp -.El -.Sh SEE ALSO -.Xr divert 4 , -.Xr protocols 5 , -.Xr rc.conf 5 , -.Xr services 5 , -.Xr syslog.conf 5 , -.Xr ipfw 8 , -.Xr ppp 8 -.Sh AUTHORS -This program is the result of the efforts of many people at different -times: -.Pp -.An Archie Cobbs Aq archie@whistle.com -(divert sockets) -.An Charles Mott Aq cmott@scientech.com -(packet aliasing) -.An Eivind Eklund Aq perhaps@yes.no -(IRC support & misc additions) -.An Ari Suutari Aq suutari@iki.fi -(natd) -.An Dru Nelson Aq dnelson@redwoodsoft.com -(early PPTP support) -.An Brian Somers Aq brian@awfulhak.org -(glue) -.An Ruslan Ermilov Aq ru@FreeBSD.org -(natd, packet aliasing, glue) +This utility is +.Cm DEPRECATED. +Please use +.Xr pfctl 8 +instead. diff --git a/ndp.tproj/ndp.8 b/ndp.tproj/ndp.8 index bf480d4..a96e169 100644 --- a/ndp.tproj/ndp.8 +++ b/ndp.tproj/ndp.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2012 Apple Inc. All rights reserved. +.\" Copyright (c) 2012-2013 Apple Inc. All rights reserved. .\" .\" @APPLE_OSREFERENCE_LICENSE_HEADER_START@ .\" @@ -24,9 +24,6 @@ .\" .\" @APPLE_OSREFERENCE_LICENSE_HEADER_END@ .\" -.\" $FreeBSD: src/usr.sbin/ndp/ndp.8,v 1.1.2.6 2001/08/16 15:56:09 ru Exp $ -.\" $KAME: ndp.8,v 1.15 2001/02/08 07:17:03 itojun Exp $ -.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -161,6 +158,25 @@ which means the flag should be cleared. turn on or off NUD (Neighbor Unreachability Detection) on the interface. NUD is usually turned on by default. +.It Xo +.Ic disabled +.Xc +IPv6 can be disabled separately from other network protocols. This flag can be +turned on automatically when Duplicate Address Detection (DAD) indicates that +another device on the network is using the same link-local address. +.It Xo +.Ic proxy_prefixes +.Xc +the interface is enabled to proxy neighbor discovery for global scope prefixes +matching those on link at other interfaces. +.It Xo +.Ic ignore_na +.Xc +ignore neighbor advertisements received on this interface. +.It Xo +.Ic insecure +do not use cryptographically generated addresses (CGA) on this interface. +.Xc .El .It Fl l Show link-layer reachability information. @@ -196,6 +212,8 @@ Show extended link-layer reachability information in addition to that shown by the .Fl l flag. +.It Fl w +Show the cryptographically generated address (CGA) parameters for the node. .El .\" .Sh RETURN VALUES diff --git a/ndp.tproj/ndp.c b/ndp.tproj/ndp.c index 7677017..2afce5d 100644 --- a/ndp.tproj/ndp.c +++ b/ndp.tproj/ndp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -25,10 +25,6 @@ * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ - -/* $FreeBSD: src/usr.sbin/ndp/ndp.c,v 1.2.2.5 2001/08/13 02:58:26 sumikawa Exp $ */ -/* $KAME: ndp.c,v 1.65 2001/05/08 04:36:34 itojun Exp $ */ - /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. @@ -139,57 +135,50 @@ #include #include #include -//#include "gmt2local.h" - -#ifndef NI_WITHSCOPEID -#define NI_WITHSCOPEID 0 -#endif /* packing rule for routing socket */ -#define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t)) -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof (uint32_t) - 1))) : \ + sizeof (uint32_t)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) static int pid; static int cflag; static int nflag; static int tflag; -static int32_t thiszone =0 ; /* time difference with gmt */ +static int32_t thiszone = 0; /* time difference with gmt */ static int s = -1; static int repeat = 0; -char ntop_buf[INET6_ADDRSTRLEN]; /* inet_ntop() */ -char host_buf[NI_MAXHOST]; /* getnameinfo() */ -char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ - -int main __P((int, char **)); -int file __P((char *)); -void getsocket __P((void)); -int set __P((int, char **)); -void get __P((char *)); -int delete __P((char *)); -void dump __P((struct in6_addr *)); -void dump_ext __P((struct in6_addr *, int)); -static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *addr, - int ifindex, int)); -static char *ether_str __P((struct sockaddr_dl *)); -int ndp_ether_aton __P((char *, u_char *)); -void usage __P((void)); -int rtmsg __P((int)); -void ifinfo __P((int, char **)); -void rtrlist __P((void)); -void plist __P((void)); -void pfx_flush __P((void)); -void rtrlist __P((void)); -void rtr_flush __P((void)); -void harmonize_rtr __P((void)); -#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ -static void getdefif __P((void)); -static void setdefif __P((char *)); -#endif -static char *sec2str __P((time_t t)); -static char *ether_str __P((struct sockaddr_dl *sdl)); -static void ts_print __P((const struct timeval *)); +static char host_buf[NI_MAXHOST]; /* getnameinfo() */ +static char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ + +static int file(char *); +static void getsocket(void); +static int set(int, char **); +static void get(char *); +static int delete(char *); +static void dump(struct in6_addr *); +static void dump_ext(struct in6_addr *, int); +static struct in6_nbrinfo *getnbrinfo(struct in6_addr *, int, int); +static char *ether_str(struct sockaddr_dl *); +static int ndp_ether_aton(char *, u_char *); +static void usage(void); +static int rtmsg(int); +static void ifinfo(int, char **); +static void rtrlist(void); +static void plist(void); +static void pfx_flush(void); +static void rtrlist(void); +static void rtr_flush(void); +static void harmonize_rtr(void); +static void getdefif(void); +static void setdefif(char *); +static char *sec2str(time_t); +static char *ether_str(struct sockaddr_dl *); +static void ts_print(const struct timeval *); +static void read_cga_parameters(void); +static void write_cga_parameters(const char[]); static char *rtpref_str[] = { "medium", /* 00 */ @@ -199,19 +188,15 @@ static char *rtpref_str[] = { }; int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { int ch; - int aflag = 0, dflag = 0, sflag = 0, Hflag = 0, - pflag = 0, rflag = 0, Pflag = 0, Rflag = 0, lflag = 0, - xflag = 0; + int aflag = 0, dflag = 0, sflag = 0, Hflag = 0, pflag = 0, rflag = 0, + Pflag = 0, Rflag = 0, lflag = 0, xflag = 0, wflag = 0; pid = getpid(); -// thiszone = gmt2local(0); - while ((ch = getopt(argc, argv, "acndfIilprstA:HPRx")) != -1) - switch ((char)ch) { + while ((ch = getopt(argc, argv, "acndfIilprstA:HPRxwW")) != -1) + switch ((char) ch) { case 'a': aflag = 1; break; @@ -222,15 +207,10 @@ main(argc, argv) dflag = 1; break; case 'I': -#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ if (argc > 2) setdefif(argv[2]); getdefif(); /* always call it to print the result */ exit(0); -#else - errx(1, "not supported yet"); - /*NOTREACHED*/ -#endif case 'i' : argc -= optind; argv += optind; @@ -280,6 +260,14 @@ main(argc, argv) xflag = 1; lflag = 1; break; + case 'w': + wflag = 1; + break; + case 'W': + if (argc != 3) + usage(); + write_cga_parameters(argv[2]); + exit(0); default: usage(); } @@ -325,6 +313,10 @@ main(argc, argv) rtr_flush(); exit(0); } + if (wflag) { + read_cga_parameters(); + exit(0); + } if (argc != 1) usage(); @@ -335,9 +327,8 @@ main(argc, argv) /* * Process a file to set standard ndp entries */ -int -file(name) - char *name; +static int +file(char *name) { FILE *fp; int i, retval; @@ -353,7 +344,7 @@ file(name) args[3] = &arg[3][0]; args[4] = &arg[4][0]; retval = 0; - while(fgets(line, 100, fp) != NULL) { + while (fgets(line, 100, fp) != NULL) { i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2], arg[3], arg[4]); if (i < 2) { @@ -368,8 +359,8 @@ file(name) return (retval); } -void -getsocket() +static void +getsocket(void) { if (s < 0) { s = socket(PF_ROUTE, SOCK_RAW, 0); @@ -380,22 +371,20 @@ getsocket() } } -struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 }; -struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m; -struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m; -int expire_time, flags, found_entry; -struct { +struct sockaddr_in6 so_mask = {sizeof (so_mask), AF_INET6 }; +struct sockaddr_in6 blank_sin = {sizeof (blank_sin), AF_INET6 }, sin_m; +struct sockaddr_dl blank_sdl = {sizeof (blank_sdl), AF_LINK }, sdl_m; +int expire_time, flags, found_entry; +struct { struct rt_msghdr m_rtm; char m_space[512]; -} m_rtmsg; +} m_rtmsg; /* * Set an individual neighbor cache entry */ -int -set(argc, argv) - int argc; - char **argv; +static int +set(int argc, char **argv) { register struct sockaddr_in6 *sin = &sin_m; register struct sockaddr_dl *sdl; @@ -411,19 +400,19 @@ set(argc, argv) sdl_m = blank_sdl; sin_m = blank_sin; - bzero(&hints, sizeof(hints)); + bzero(&hints, sizeof (hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { fprintf(stderr, "ndp: %s: %s\n", host, gai_strerror(gai_error)); - return 1; + return (1); } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = - htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); } #endif ea = (u_char *)LLADDR(&sdl_m); @@ -457,7 +446,7 @@ set(argc, argv) * IPv4 arp command retries with sin_other = SIN_PROXY here. */ fprintf(stderr, "set: cannot configure a new entry\n"); - return 1; + return (1); } overwrite: @@ -473,16 +462,15 @@ overwrite: /* * Display an individual neighbor cache entry */ -void -get(host) - char *host; +static void +get(char *host) { struct sockaddr_in6 *sin = &sin_m; struct addrinfo hints, *res; int gai_error; sin_m = blank_sin; - bzero(&hints, sizeof(hints)); + bzero(&hints, sizeof (hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { @@ -494,14 +482,14 @@ get(host) #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = - htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); } #endif dump(&sin->sin6_addr); if (found_entry == 0) { getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, - sizeof(host_buf), NULL ,0, - NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); + sizeof (host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? + NI_NUMERICHOST : 0)); printf("%s (%s) -- no entry\n", host, host_buf); exit(1); } @@ -510,9 +498,8 @@ get(host) /* * Delete a neighbor cache entry */ -int -delete(host) - char *host; +static int +delete(char *host) { struct sockaddr_in6 *sin = &sin_m; register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; @@ -523,19 +510,19 @@ delete(host) getsocket(); sin_m = blank_sin; - bzero(&hints, sizeof(hints)); + bzero(&hints, sizeof (hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { fprintf(stderr, "ndp: %s: %s\n", host, gai_strerror(gai_error)); - return 1; + return (1); } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = - htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); } #endif if (rtmsg(RTM_GET) < 0) { @@ -554,7 +541,7 @@ delete(host) * IPv4 arp command retries with sin_other = SIN_PROXY here. */ fprintf(stderr, "delete: cannot delete non-NDP entry\n"); - return 1; + return (1); } delete: @@ -563,34 +550,34 @@ delete: return (1); } if (rtmsg(RTM_DELETE) == 0) { - struct sockaddr_in6 s6 = *sin; /* XXX: for safety */ + struct sockaddr_in6 s6 = *sin; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&s6.sin6_addr)) { - s6.sin6_scope_id = ntohs(*(u_int16_t *)&s6.sin6_addr.s6_addr[2]); + s6.sin6_scope_id = + ntohs(*(u_int16_t *)&s6.sin6_addr.s6_addr[2]); *(u_int16_t *)&s6.sin6_addr.s6_addr[2] = 0; } #endif getnameinfo((struct sockaddr *)&s6, s6.sin6_len, host_buf, - sizeof(host_buf), NULL, 0, + sizeof (host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); printf("%s (%s) deleted\n", host, host_buf); } - return 0; + return (0); } -#define W_ADDR 31 -#define W_LL 17 -#define W_IF 6 +#define W_ADDR 31 +#define W_LL 17 +#define W_IF 6 /* * Dump the entire neighbor cache */ -void -dump(addr) - struct in6_addr *addr; +static void +dump(struct in6_addr *addr) { int mib[6]; size_t needed; @@ -635,7 +622,8 @@ again:; rtm = (struct rt_msghdr *)next; sin = (struct sockaddr_in6 *)(rtm + 1); - sdl = (struct sockaddr_dl *)((char *)sin + ROUNDUP(sin->sin6_len)); + sdl = (struct sockaddr_dl *)((char *)sin + + ROUNDUP(sin->sin6_len)); /* * Some OSes can produce a route that has the LINK flag but @@ -662,7 +650,7 @@ again:; if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&sin->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin->sin6_addr)) { - /* XXX: should scope id be filled in the kernel? */ + /* should scope id be filled in the kernel? */ if (sin->sin6_scope_id == 0) sin->sin6_scope_id = sdl->sdl_index; #ifdef __KAME__ @@ -671,15 +659,11 @@ again:; #endif } getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, - sizeof(host_buf), NULL, 0, + sizeof (host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); if (cflag == 1) { -#ifdef RTF_WASCLONED if (rtm->rtm_flags & RTF_WASCLONED) delete(host_buf); -#else - delete(host_buf); -#endif continue; } gettimeofday(&time, 0); @@ -706,40 +690,35 @@ again:; nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index, 1); if (nbi) { if (nbi->expire > time.tv_sec) { - printf(" %-9.9s", - sec2str(nbi->expire - time.tv_sec)); + printf(" %-9.9s", sec2str(nbi->expire - + time.tv_sec)); } else if (nbi->expire == 0) printf(" %-9.9s", "permanent"); else printf(" %-9.9s", "expired"); - switch(nbi->state) { - case ND6_LLINFO_NOSTATE: - printf(" N"); - break; -#ifdef ND6_LLINFO_WAITDELETE - case ND6_LLINFO_WAITDELETE: - printf(" W"); - break; -#endif - case ND6_LLINFO_INCOMPLETE: - printf(" I"); - break; - case ND6_LLINFO_REACHABLE: - printf(" R"); - break; - case ND6_LLINFO_STALE: - printf(" S"); - break; - case ND6_LLINFO_DELAY: - printf(" D"); - break; - case ND6_LLINFO_PROBE: - printf(" P"); - break; - default: - printf(" ?"); - break; + switch (nbi->state) { + case ND6_LLINFO_NOSTATE: + printf(" N"); + break; + case ND6_LLINFO_INCOMPLETE: + printf(" I"); + break; + case ND6_LLINFO_REACHABLE: + printf(" R"); + break; + case ND6_LLINFO_STALE: + printf(" S"); + break; + case ND6_LLINFO_DELAY: + printf(" D"); + break; + case ND6_LLINFO_PROBE: + printf(" P"); + break; + default: + printf(" ?"); + break; } isrouter = nbi->isrouter; @@ -754,17 +733,17 @@ again:; * other flags. R: router, P: proxy, W: ?? */ if ((rtm->rtm_addrs & RTA_NETMASK) == 0) { - snprintf(flgbuf, sizeof(flgbuf), "%s%s", + snprintf(flgbuf, sizeof (flgbuf), "%s%s", isrouter ? "R" : "", (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } else { sin = (struct sockaddr_in6 *) (sdl->sdl_len + (char *)sdl); - snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s", + snprintf(flgbuf, sizeof (flgbuf), "%s%s%s%s", isrouter ? "R" : "", !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "P" : "", - (sin->sin6_len != sizeof(struct sockaddr_in6)) + (sin->sin6_len != sizeof (struct sockaddr_in6)) ? "W" : "", (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } @@ -841,7 +820,8 @@ again:; ertm = (struct rt_msghdr_ext *)next; sin = (struct sockaddr_in6 *)(ertm + 1); - sdl = (struct sockaddr_dl *)((char *)sin + ROUNDUP(sin->sin6_len)); + sdl = (struct sockaddr_dl *)((char *)sin + + ROUNDUP(sin->sin6_len)); /* * Some OSes can produce a route that has the LINK flag but @@ -868,7 +848,7 @@ again:; if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&sin->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin->sin6_addr)) { - /* XXX: should scope id be filled in the kernel? */ + /* should scope id be filled in the kernel? */ if (sin->sin6_scope_id == 0) sin->sin6_scope_id = sdl->sdl_index; #ifdef __KAME__ @@ -877,15 +857,11 @@ again:; #endif } getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, - sizeof(host_buf), NULL, 0, + sizeof (host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); if (cflag == 1) { -#ifdef RTF_WASCLONED if (ertm->rtm_flags & RTF_WASCLONED) delete(host_buf); -#else - delete(host_buf); -#endif continue; } gettimeofday(&time, 0); @@ -929,33 +905,28 @@ again:; /* Print neighbor discovery specific informations */ nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index, 1); if (nbi) { - switch(nbi->state) { - case ND6_LLINFO_NOSTATE: - printf(" N"); - break; -#ifdef ND6_LLINFO_WAITDELETE - case ND6_LLINFO_WAITDELETE: - printf(" W"); - break; -#endif - case ND6_LLINFO_INCOMPLETE: - printf(" I"); - break; - case ND6_LLINFO_REACHABLE: - printf(" R"); - break; - case ND6_LLINFO_STALE: - printf(" S"); - break; - case ND6_LLINFO_DELAY: - printf(" D"); - break; - case ND6_LLINFO_PROBE: - printf(" P"); - break; - default: - printf(" ?"); - break; + switch (nbi->state) { + case ND6_LLINFO_NOSTATE: + printf(" N"); + break; + case ND6_LLINFO_INCOMPLETE: + printf(" I"); + break; + case ND6_LLINFO_REACHABLE: + printf(" R"); + break; + case ND6_LLINFO_STALE: + printf(" S"); + break; + case ND6_LLINFO_DELAY: + printf(" D"); + break; + case ND6_LLINFO_PROBE: + printf(" P"); + break; + default: + printf(" ?"); + break; } isrouter = nbi->isrouter; @@ -970,17 +941,17 @@ again:; * other flags. R: router, P: proxy, W: ?? */ if ((ertm->rtm_addrs & RTA_NETMASK) == 0) { - snprintf(flgbuf, sizeof(flgbuf), "%s%s", + snprintf(flgbuf, sizeof (flgbuf), "%s%s", isrouter ? "R" : "", (ertm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } else { sin = (struct sockaddr_in6 *) (sdl->sdl_len + (char *)sdl); - snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s", + snprintf(flgbuf, sizeof (flgbuf), "%s%s%s%s", isrouter ? "R" : "", !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "P" : "", - (sin->sin6_len != sizeof(struct sockaddr_in6)) + (sin->sin6_len != sizeof (struct sockaddr_in6)) ? "W" : "", (ertm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } @@ -1061,58 +1032,55 @@ getnbrinfo(addr, ifindex, warning) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - bzero(&nbi, sizeof(nbi)); + bzero(&nbi, sizeof (nbi)); if_indextoname(ifindex, nbi.ifname); nbi.addr = *addr; if (ioctl(s, SIOCGNBRINFO_IN6, (caddr_t)&nbi) < 0) { if (warning) warn("ioctl(SIOCGNBRINFO_IN6)"); close(s); - return(NULL); + return (NULL); } close(s); - return(&nbi); + return (&nbi); } static char * -ether_str(sdl) - struct sockaddr_dl *sdl; +ether_str(struct sockaddr_dl *sdl) { static char ebuf[32]; u_char *cp; if (sdl->sdl_alen) { cp = (u_char *)LLADDR(sdl); - snprintf(ebuf, sizeof(ebuf), "%x:%x:%x:%x:%x:%x", + snprintf(ebuf, sizeof (ebuf), "%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); } else { - snprintf(ebuf, sizeof(ebuf), "(incomplete)"); + snprintf(ebuf, sizeof (ebuf), "(incomplete)"); } - return(ebuf); + return (ebuf); } -int -ndp_ether_aton(a, n) - char *a; - u_char *n; +static int +ndp_ether_aton(char *a, u_char *n) { int i, o[6]; - i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2], - &o[3], &o[4], &o[5]); + i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2], &o[3], &o[4], + &o[5]); if (i != 6) { fprintf(stderr, "ndp: invalid Ethernet address '%s'\n", a); return (1); } - for (i=0; i<6; i++) + for (i = 0; i < 6; i++) n[i] = o[i]; return (0); } -void -usage() +static void +usage(void) { printf("usage: ndp hostname\n"); printf(" ndp -a[lnt]\n"); @@ -1121,21 +1089,20 @@ usage() printf(" ndp -d[nt] hostname\n"); printf(" ndp -f[nt] filename\n"); printf(" ndp -i interface [flags...]\n"); -#ifdef SIOCSDEFIFACE_IN6 printf(" ndp -I [interface|delete]\n"); -#endif printf(" ndp -p\n"); printf(" ndp -r\n"); printf(" ndp -s hostname ether_addr [temp] [proxy]\n"); printf(" ndp -H\n"); printf(" ndp -P\n"); printf(" ndp -R\n"); + printf(" ndp -w\n"); + printf(" ndp -W cfgfile\n"); exit(1); } -int -rtmsg(cmd) - int cmd; +static int +rtmsg(int cmd) { static int seq; int rlen; @@ -1146,7 +1113,7 @@ rtmsg(cmd) errno = 0; if (cmd == RTM_DELETE) goto doit; - bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); + bzero((char *)&m_rtmsg, sizeof (m_rtmsg)); rtm->rtm_flags = flags; rtm->rtm_version = RTM_VERSION; @@ -1167,13 +1134,14 @@ rtmsg(cmd) case RTM_GET: rtm->rtm_addrs |= RTA_DST; } -#define NEXTADDR(w, s) \ +#define NEXTADDR(w, s) \ if (rtm->rtm_addrs & (w)) { \ - bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);} + bcopy((char *)&s, cp, sizeof (s)); cp += sizeof (s); \ + } NEXTADDR(RTA_DST, sin_m); NEXTADDR(RTA_GATEWAY, sdl_m); - memset(&so_mask.sin6_addr, 0xff, sizeof(so_mask.sin6_addr)); + memset(&so_mask.sin6_addr, 0xff, sizeof (so_mask.sin6_addr)); NEXTADDR(RTA_NETMASK, so_mask); rtm->rtm_msglen = cp - (char *)&m_rtmsg; @@ -1188,7 +1156,7 @@ doit: } } do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); + l = read(s, (char *)&m_rtmsg, sizeof (m_rtmsg)); } while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid)); if (l < 0) (void) fprintf(stderr, "ndp: read from routing socket: %s\n", @@ -1196,30 +1164,26 @@ doit: return (0); } -void -ifinfo(argc, argv) - int argc; - char **argv; +static void +ifinfo(int argc, char **argv) { struct in6_ndireq nd; int i, s; char *ifname = argv[0]; u_int32_t newflags; -#ifdef IPV6CTL_USETEMPADDR u_int8_t nullbuf[8]; -#endif if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("ndp: socket"); exit(1); } - bzero(&nd, sizeof(nd)); - strlcpy(nd.ifname, ifname, sizeof(nd.ifname)); + bzero(&nd, sizeof (nd)); + strlcpy(nd.ifname, ifname, sizeof (nd.ifname)); if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { - perror("ioctl (SIOCGIFINFO_IN6)"); - exit(1); - } -#define ND nd.ndi + perror("ioctl (SIOCGIFINFO_IN6)"); + exit(1); + } +#define ND nd.ndi newflags = ND.flags; for (i = 1; i < argc; i++) { int clear = 0; @@ -1230,7 +1194,7 @@ ifinfo(argc, argv) cp++; } -#define SETFLAG(s, f) \ +#define SETFLAG(s, f) \ do {\ if (strcmp(cp, (s)) == 0) {\ if (clear)\ @@ -1242,6 +1206,8 @@ ifinfo(argc, argv) SETFLAG("nud", ND6_IFF_PERFORMNUD); SETFLAG("proxy_prefixes", ND6_IFF_PROXY_PREFIXES); SETFLAG("ignore_na", ND6_IFF_IGNORE_NA); + SETFLAG("disabled", ND6_IFF_IFDISABLED); + SETFLAG("insecure", ND6_IFF_INSECURE); ND.flags = newflags; if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) { @@ -1253,18 +1219,17 @@ ifinfo(argc, argv) printf("linkmtu=%d", ND.linkmtu); printf(", curhlim=%d", ND.chlim); - printf(", basereachable=%ds%dms", - ND.basereachable / 1000, ND.basereachable % 1000); + printf(", basereachable=%ds%dms", ND.basereachable / 1000, + ND.basereachable % 1000); printf(", reachable=%ds", ND.reachable); printf(", retrans=%ds%dms", ND.retrans / 1000, ND.retrans % 1000); -#ifdef IPV6CTL_USETEMPADDR - memset(nullbuf, 0, sizeof(nullbuf)); - if (memcmp(nullbuf, ND.randomid, sizeof(nullbuf)) != 0) { + memset(nullbuf, 0, sizeof (nullbuf)); + if (memcmp(nullbuf, ND.randomid, sizeof (nullbuf)) != 0) { int j; u_int8_t *rbuf = NULL; for (i = 0; i < 3; i++) { - switch(i) { + switch (i) { case 0: printf("\nRandom seed(0): "); rbuf = ND.randomseed0; @@ -1282,39 +1247,40 @@ ifinfo(argc, argv) printf("%02x", rbuf[j]); } } -#endif if (ND.flags) { printf("\nFlags: "); - if ((ND.flags & ND6_IFF_PERFORMNUD) != 0) - printf("PERFORMNUD "); - if ((ND.flags & ND6_IFF_PROXY_PREFIXES) != 0) - printf("PROXY_PREFIXES "); if ((ND.flags & ND6_IFF_IFDISABLED) != 0) printf("IFDISABLED "); if ((ND.flags & ND6_IFF_IGNORE_NA) != 0) printf("IGNORE_NA "); + if ((ND.flags & ND6_IFF_INSECURE) != 0) + printf("INSECURE "); + if ((ND.flags & ND6_IFF_PERFORMNUD) != 0) + printf("PERFORMNUD "); + if ((ND.flags & ND6_IFF_PROXY_PREFIXES) != 0) + printf("PROXY_PREFIXES "); } putc('\n', stdout); #undef ND - + close(s); } #ifndef ND_RA_FLAG_RTPREF_MASK /* XXX: just for compilation on *BSD release */ -#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ +#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ #endif -void -rtrlist() +static void +rtrlist(void) { -#ifdef ICMPV6CTL_ND6_DRLIST int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_DRLIST }; char *buf; struct in6_defrouter *p, *ep; size_t l; struct timeval time; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) { + if (sysctl(mib, sizeof (mib) / sizeof (mib[0]), NULL, &l, NULL, 0) + < 0) { err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)"); /*NOTREACHED*/ } @@ -1323,7 +1289,7 @@ rtrlist() errx(1, "not enough core"); /*NOTREACHED*/ } - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) { + if (sysctl(mib, sizeof (mib) / sizeof (mib[0]), buf, &l, NULL, 0) < 0) { err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)"); /*NOTREACHED*/ } @@ -1333,21 +1299,21 @@ rtrlist() int rtpref; if (getnameinfo((struct sockaddr *)&p->rtaddr, - p->rtaddr.sin6_len, host_buf, sizeof(host_buf), NULL, 0, + p->rtaddr.sin6_len, host_buf, sizeof (host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)) != 0) - strlcpy(host_buf, "?", sizeof(host_buf)); - - printf("%s if=%s", host_buf, - if_indextoname(p->if_index, ifix_buf)); + strlcpy(host_buf, "?", sizeof (host_buf)); + + printf("%s if=%s", host_buf, if_indextoname(p->if_index, + ifix_buf)); printf(", flags=%s%s%s%s%s", - p->flags & ND_RA_FLAG_MANAGED ? "M" : "", - p->flags & ND_RA_FLAG_OTHER ? "O" : "", - p->stateflags & NDDRF_INSTALLED ? "T" : "", - p->stateflags & NDDRF_IFSCOPE ? "I" : "", - p->stateflags & NDDRF_STATIC ? "S" : ""); + p->stateflags & NDDRF_IFSCOPE ? "I" : "", + p->flags & ND_RA_FLAG_MANAGED ? "M" : "", + p->flags & ND_RA_FLAG_OTHER ? "O" : "", + p->stateflags & NDDRF_STATIC ? "S" : "", + p->stateflags & NDDRF_INSTALLED ? "T" : ""); rtpref = ((p->flags & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff; printf(", pref=%s", rtpref_str[rtpref]); - + gettimeofday(&time, 0); if (p->expire == 0) printf(", expire=Never\n"); @@ -1356,70 +1322,23 @@ rtrlist() sec2str(p->expire - time.tv_sec)); } free(buf); -#else - struct in6_drlist dr; - int s, i; - struct timeval time; - - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("ndp: socket"); - exit(1); - } - bzero(&dr, sizeof(dr)); - strlcpy(dr.ifname, "lo0", sizeof(dr.ifname)); /* dummy */ - if (ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) { - perror("ioctl (SIOCGDRLST_IN6)"); - exit(1); - } -#define DR dr.defrouter[i] - for (i = 0 ; DR.if_index && i < DRLSTSIZ ; i++) { - struct sockaddr_in6 sin6; - - bzero(&sin6, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(sin6); - sin6.sin6_addr = DR.rtaddr; - getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, host_buf, - sizeof(host_buf), NULL, 0, - NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); - - printf("%s if=%s", host_buf, - if_indextoname(DR.if_index, ifix_buf)); - printf(", flags=%s%s", - DR.flags & ND_RA_FLAG_MANAGED ? "M" : "", - DR.flags & ND_RA_FLAG_OTHER ? "O" : ""); - gettimeofday(&time, 0); - if (DR.expire == 0) - printf(", expire=Never\n"); - else - printf(", expire=%s\n", - sec2str(DR.expire - time.tv_sec)); - } -#undef DR - close(s); -#endif } -void -plist() +static void +plist(void) { -#ifdef ICMPV6CTL_ND6_PRLIST int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_PRLIST }; char *buf; struct in6_prefix *p, *ep, *n; struct sockaddr_in6 *advrtr; size_t l; struct timeval time; -#ifdef NI_WITHSCOPEID const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; int ninflags = (nflag ? NI_NUMERICHOST : 0) | NI_WITHSCOPEID; -#else - const int niflags = NI_NUMERICHOST; - int ninflags = nflag ? NI_NUMERICHOST : 0; -#endif char namebuf[NI_MAXHOST]; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) { + if (sysctl(mib, sizeof (mib) / sizeof (mib[0]), NULL, &l, NULL, 0) + < 0) { err(1, "sysctl(ICMPV6CTL_ND6_PRLIST)"); /*NOTREACHED*/ } @@ -1428,7 +1347,8 @@ plist() errx(1, "not enough core"); /*NOTREACHED*/ } - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) { + if (sysctl(mib, sizeof (mib) / sizeof (mib[0]), buf, &l, NULL, 0) + < 0) { err(1, "sysctl(ICMPV6CTL_ND6_PRLIST)"); /*NOTREACHED*/ } @@ -1439,35 +1359,25 @@ plist() n = (struct in6_prefix *)&advrtr[p->advrtrs]; if (getnameinfo((struct sockaddr *)&p->prefix, - p->prefix.sin6_len, namebuf, sizeof(namebuf), + p->prefix.sin6_len, namebuf, sizeof (namebuf), NULL, 0, niflags) != 0) - strlcpy(namebuf, "?", sizeof(namebuf)); + strlcpy(namebuf, "?", sizeof (namebuf)); printf("%s/%d if=%s\n", namebuf, p->prefixlen, - if_indextoname(p->if_index, ifix_buf)); + if_indextoname(p->if_index, ifix_buf)); gettimeofday(&time, 0); /* * meaning of fields, especially flags, is very different * by origin. notify the difference to the users. */ - printf("flags=%s%s%s%s%s%s%s%s", - p->raflags.onlink ? "L" : "", - p->raflags.autonomous ? "A" : "", - (p->flags & NDPRF_ONLINK) != 0 ? "O" : "", - (p->flags & NDPRF_DETACHED) != 0 ? "D" : "", - (p->flags & NDPRF_IFSCOPE) != 0 ? "I" : "", - (p->flags & NDPRF_PRPROXY) != 0 ? "Y" : "", -#ifdef NDPRF_HOME - (p->flags & NDPRF_HOME) != 0 ? "H" : "", -#else - "", -#endif -#ifdef NDPRF_STATIC - (p->flags & NDPRF_STATIC) != 0 ? "S" : "" -#else - "" -#endif - ); + printf("flags=%s%s%s%s%s%s%s", + p->raflags.autonomous ? "A" : "", + (p->flags & NDPRF_DETACHED) != 0 ? "D" : "", + (p->flags & NDPRF_IFSCOPE) != 0 ? "I" : "", + p->raflags.onlink ? "L" : "", + (p->flags & NDPRF_STATIC) != 0 ? "S" : "", + (p->flags & NDPRF_ONLINK) != 0 ? "O" : "", + (p->flags & NDPRF_PRPROXY) != 0 ? "Y" : ""); if (p->vltime == ND6_INFINITE_LIFETIME) printf(" vltime=infinity"); else @@ -1499,15 +1409,15 @@ plist() struct in6_nbrinfo *nbi; if (getnameinfo((struct sockaddr *)sin6, - sin6->sin6_len, namebuf, sizeof(namebuf), + sin6->sin6_len, namebuf, sizeof (namebuf), NULL, 0, ninflags) != 0) - strlcpy(namebuf, "?", sizeof(namebuf)); + strlcpy(namebuf, "?", sizeof (namebuf)); printf(" %s", namebuf); nbi = getnbrinfo(&sin6->sin6_addr, p->if_index, - 0); + 0); if (nbi) { - switch(nbi->state) { + switch (nbi->state) { case ND6_LLINFO_REACHABLE: case ND6_LLINFO_STALE: case ND6_LLINFO_DELAY: @@ -1525,229 +1435,53 @@ plist() printf(" No advertising router\n"); } free(buf); -#else - struct in6_prlist pr; - int s, i; - struct timeval time; - - gettimeofday(&time, 0); - - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("ndp: socket"); - exit(1); - } - bzero(&pr, sizeof(pr)); - strlcpy(pr.ifname, "lo0", sizeof(pr.ifname)); /* dummy */ - if (ioctl(s, SIOCGPRLST_IN6, (caddr_t)&pr) < 0) { - perror("ioctl (SIOCGPRLST_IN6)"); - exit(1); - } -#define PR pr.prefix[i] - for (i = 0; PR.if_index && i < PRLSTSIZ ; i++) { - struct sockaddr_in6 p6; - char namebuf[NI_MAXHOST]; - int niflags; - -#ifdef NDPRF_ONLINK - p6 = PR.prefix; -#else - memset(&p6, 0, sizeof(p6)); - p6.sin6_family = AF_INET6; - p6.sin6_len = sizeof(p6); - p6.sin6_addr = PR.prefix; -#endif - - /* - * copy link index to sin6_scope_id field. - * XXX: KAME specific. - */ - if (IN6_IS_ADDR_LINKLOCAL(&p6.sin6_addr)) { - u_int16_t linkid; - - memcpy(&linkid, &p6.sin6_addr.s6_addr[2], - sizeof(linkid)); - linkid = ntohs(linkid); - p6.sin6_scope_id = linkid; - p6.sin6_addr.s6_addr[2] = 0; - p6.sin6_addr.s6_addr[3] = 0; - } - - niflags = NI_NUMERICHOST; -#ifdef __KAME__ - niflags |= NI_WITHSCOPEID; -#endif - if (getnameinfo((struct sockaddr *)&p6, - sizeof(p6), namebuf, sizeof(namebuf), - NULL, 0, niflags)) { - warnx("getnameinfo failed"); - continue; - } - printf("%s/%d if=%s\n", namebuf, PR.prefixlen, - if_indextoname(PR.if_index, ifix_buf)); - - gettimeofday(&time, 0); - /* - * meaning of fields, especially flags, is very different - * by origin. notify the difference to the users. - */ -#if 0 - printf(" %s", - PR.origin == PR_ORIG_RA ? "" : "advertise: "); -#endif -#ifdef NDPRF_ONLINK - printf("flags=%s%s%s%s%s", - PR.raflags.onlink ? "L" : "", - PR.raflags.autonomous ? "A" : "", - (PR.flags & NDPRF_ONLINK) != 0 ? "O" : "", - (PR.flags & NDPRF_DETACHED) != 0 ? "D" : "", -#ifdef NDPRF_HOME - (PR.flags & NDPRF_HOME) != 0 ? "H" : "" -#else - "" -#endif - ); -#else - printf("flags=%s%s", - PR.raflags.onlink ? "L" : "", - PR.raflags.autonomous ? "A" : ""); -#endif - if (PR.vltime == ND6_INFINITE_LIFETIME) - printf(" vltime=infinity"); - else - printf(" vltime=%ld", (long)PR.vltime); - if (PR.pltime == ND6_INFINITE_LIFETIME) - printf(", pltime=infinity"); - else - printf(", pltime=%ld", (long)PR.pltime); - if (PR.expire == 0) - printf(", expire=Never"); - else if (PR.expire >= time.tv_sec) - printf(", expire=%s", - sec2str(PR.expire - time.tv_sec)); - else - printf(", expired"); -#ifdef NDPRF_ONLINK - printf(", ref=%d", PR.refcnt); -#endif -#if 0 - switch (PR.origin) { - case PR_ORIG_RA: - printf(", origin=RA"); - break; - case PR_ORIG_RR: - printf(", origin=RR"); - break; - case PR_ORIG_STATIC: - printf(", origin=static"); - break; - case PR_ORIG_KERNEL: - printf(", origin=kernel"); - break; - default: - printf(", origin=?"); - break; - } -#endif - printf("\n"); - /* - * "advertising router" list is meaningful only if the prefix - * information is from RA. - */ - if (0 && /* prefix origin is almost obsolted */ - PR.origin != PR_ORIG_RA) - ; - else if (PR.advrtrs) { - int j; - printf(" advertised by\n"); - for (j = 0; j < PR.advrtrs; j++) { - struct sockaddr_in6 sin6; - struct in6_nbrinfo *nbi; - - bzero(&sin6, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(sin6); - sin6.sin6_addr = PR.advrtr[j]; - sin6.sin6_scope_id = PR.if_index; /* XXX */ - getnameinfo((struct sockaddr *)&sin6, - sin6.sin6_len, host_buf, - sizeof(host_buf), NULL, 0, - NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); - printf(" %s", host_buf); - - nbi = getnbrinfo(&sin6.sin6_addr, PR.if_index, - 0); - if (nbi) { - switch(nbi->state) { - case ND6_LLINFO_REACHABLE: - case ND6_LLINFO_STALE: - case ND6_LLINFO_DELAY: - case ND6_LLINFO_PROBE: - printf(" (reachable)\n"); - break; - default: - printf(" (unreachable)\n"); - } - } else - printf(" (no neighbor state)\n"); - } - if (PR.advrtrs > DRLSTSIZ) - printf(" and %d routers\n", - PR.advrtrs - DRLSTSIZ); - } else - printf(" No advertising router\n"); - } -#undef PR - close(s); -#endif } -void -pfx_flush() +static void +pfx_flush(void) { char dummyif[IFNAMSIZ+8]; int s; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ + strlcpy(dummyif, "lo0", sizeof (dummyif)); /* dummy */ if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummyif) < 0) - err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); + err(1, "ioctl(SIOCSPFXFLUSH_IN6)"); } -void -rtr_flush() +static void +rtr_flush(void) { char dummyif[IFNAMSIZ+8]; int s; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ + strlcpy(dummyif, "lo0", sizeof (dummyif)); /* dummy */ if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) - err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); + err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); close(s); } -void -harmonize_rtr() +static void +harmonize_rtr(void) { char dummyif[IFNAMSIZ+8]; int s; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - strlcpy(dummyif, "lo0", sizeof(dummyif)); /* dummy */ + strlcpy(dummyif, "lo0", sizeof (dummyif)); /* dummy */ if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) - err(1, "ioctl (SIOCSNDFLUSH_IN6)"); + err(1, "ioctl (SIOCSNDFLUSH_IN6)"); close(s); } -#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ static void -setdefif(ifname) - char *ifname; +setdefif(char *ifname) { struct in6_ndifreq ndifreq; unsigned int ifindex; @@ -1762,17 +1496,17 @@ setdefif(ifname) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ + strlcpy(ndifreq.ifname, "lo0", sizeof (ndifreq.ifname)); /* dummy */ ndifreq.ifindex = ifindex; if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) - err(1, "ioctl (SIOCSDEFIFACE_IN6)"); + err(1, "ioctl (SIOCSDEFIFACE_IN6)"); close(s); } static void -getdefif() +getdefif(void) { struct in6_ndifreq ndifreq; char ifname[IFNAMSIZ+8]; @@ -1780,11 +1514,11 @@ getdefif() if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) err(1, "socket"); - memset(&ndifreq, 0, sizeof(ndifreq)); - strlcpy(ndifreq.ifname, "lo0", sizeof(ndifreq.ifname)); /* dummy */ + memset(&ndifreq, 0, sizeof (ndifreq)); + strlcpy(ndifreq.ifname, "lo0", sizeof (ndifreq.ifname)); /* dummy */ if (ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) - err(1, "ioctl (SIOCGDEFIFACE_IN6)"); + err(1, "ioctl (SIOCGDEFIFACE_IN6)"); if (ndifreq.ifindex == 0) printf("No default interface.\n"); @@ -1797,11 +1531,9 @@ getdefif() close(s); } -#endif static char * -sec2str(total) - time_t total; +sec2str(time_t total) { static char result[256]; int days, hours, mins, secs; @@ -1815,19 +1547,17 @@ sec2str(total) if (days) { first = 0; - p += snprintf(p, sizeof(result) - (p - result), "%dd", days); + p += snprintf(p, sizeof (result) - (p - result), "%dd", days); } if (!first || hours) { first = 0; - p += snprintf(p, sizeof(result) - (p - result), "%dh", hours); - } - if (!first || mins) { - first = 0; - p += snprintf(p, sizeof(result) - (p - result), "%dm", mins); + p += snprintf(p, sizeof (result) - (p - result), "%dh", hours); } - snprintf(p, sizeof(result) - (p - result), "%ds", secs); + if (!first || mins) + p += snprintf(p, sizeof (result) - (p - result), "%dm", mins); + snprintf(p, sizeof (result) - (p - result), "%ds", secs); - return(result); + return (result); } /* @@ -1835,13 +1565,125 @@ sec2str(total) * from tcpdump/util.c */ static void -ts_print(tvp) - const struct timeval *tvp; +ts_print(const struct timeval *tvp) { int s; /* Default */ s = (tvp->tv_sec + thiszone) % 86400; - (void)printf("%02d:%02d:%02d.%06u ", - s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); + printf("%02d:%02d:%02d.%06u ", s / 3600, (s % 3600) / 60, s % 60, + (u_int32_t)tvp->tv_usec); +} + +#define SYSCTL_CGA_PARAMETERS_BUFFER_SIZE \ + 2 * (sizeof (size_t) + IN6_CGA_KEY_MAXSIZE) + \ + sizeof (struct in6_cga_prepare) + +static void +read_cga_parameters(void) +{ + static char oldb[SYSCTL_CGA_PARAMETERS_BUFFER_SIZE]; + + int error; + struct in6_cga_nodecfg cfg; + struct iovec *iov; + const char *oldp; + const char *finp; + size_t oldn; + unsigned int column; + uint16_t u16; + + oldn = sizeof oldb; + error = sysctlbyname("net.inet6.send.cga_parameters", oldb, &oldn, + NULL, NULL); + if (error != 0) + err(1, "sysctlbyname"); + + if (oldn == 0) { + printf("No CGA parameters.\n"); + exit(0); + } + + oldp = oldb; + finp = &oldb[oldn]; + memset(&cfg, 0, sizeof (cfg)); + + if (oldp + sizeof (cfg.cga_prepare) > finp) + err(1, "format error[1]"); + + memcpy(&cfg.cga_prepare, oldp, sizeof (cfg.cga_prepare)); + oldp += sizeof (cfg.cga_prepare); + + iov = &cfg.cga_pubkey; + + if (oldp + sizeof (u16) > finp) + err(1, "format error[2]"); + + memcpy(&u16, oldp, sizeof (u16)); + oldp += sizeof (u16); + iov->iov_len = u16; + + if (oldp + iov->iov_len > finp) + err(1, "format error[3]"); + + iov->iov_base = (void *)oldp; + oldp += iov->iov_len; + + if (oldp != finp) + err(1, "format error[4]"); + + puts("Public Key:"); + finp = &iov->iov_base[iov->iov_len]; + column = 0; + oldp = iov->iov_base; + while (oldp < finp) { + if (column++ != 0) + putchar(':'); + printf("%02x", (unsigned char) *oldp++); + if (column >= 32) { + column = 0; + puts(""); + } + } + if (column < 32) + puts(""); + puts(""); + puts("Modifier:"); + oldp = (const char*) cfg.cga_prepare.cga_modifier.octets; + finp = &oldp[sizeof (cfg.cga_prepare.cga_modifier.octets)]; + column = 0; + while (oldp < finp) { + if (column++ != 0) + putchar(':'); + printf("%02x", (unsigned char) *oldp++); + } + puts("\n"); + printf("Security Level: %u\n", cfg.cga_prepare.cga_security_level); +} + +static void +write_cga_parameters(const char filename[]) +{ + static char newb[SYSCTL_CGA_PARAMETERS_BUFFER_SIZE]; + + int error; + FILE* fp; + size_t oldn, newn; + + fp = fopen(filename, "r"); + if (fp == NULL) + err(1, "opening '%s' for reading.", filename); + + newn = fread(newb, 1, sizeof (newb), fp); + if (feof(fp) == 0) + err(1, "parameters too large"); + + if (fclose(fp) != 0) + err(1, "closing file."); + + oldn = 0; + error = sysctlbyname("net.inet6.send.cga_parameters", NULL, NULL, newb, + newn); + if (error != 0) + err(1, "sysctlbyname"); } diff --git a/netstat.tproj/if.c b/netstat.tproj/if.c index 70e5705..6428d96 100644 --- a/netstat.tproj/if.c +++ b/netstat.tproj/if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -273,28 +273,30 @@ intpr(void (*pfunc)(char *)) u_int64_t oerrors = 0; u_int64_t ierrors = 0; u_int64_t collisions = 0; + u_int64_t fpackets = 0; + u_int64_t fbytes = 0; uint32_t mtu = 0; - short timer = 0; + int timer = 0; int drops = 0; struct sockaddr *sa = NULL; char name[32]; short network_layer; short link_layer; - int mib[6]; - char *buf = NULL, *lim, *next; + int mib[6]; + char *buf = NULL, *lim, *next; size_t len; struct if_msghdr *ifm; struct sockaddr *rti_info[RTAX_MAX]; unsigned int ifindex = 0; - + if (interval) { sidewaysintpr(); return; } - + if (interface != 0) ifindex = if_nametoindex(interface); - + mib[0] = CTL_NET; // networking subsystem mib[1] = PF_ROUTE; // type of information mib[2] = 0; // protocol (IPPROTO_xxx) @@ -336,32 +338,40 @@ intpr(void (*pfunc)(char *)) printf(" %s", "Time"); if (dflag) printf(" %s", "Drop"); + if (Fflag) { + printf(" %8.8s", "Fpkts"); + if (bflag) + printf(" %10.10s", "Fbytes"); + } putchar('\n'); } - lim = buf + len; - for (next = buf; next < lim; ) { + lim = buf + len; + for (next = buf; next < lim; ) { char *cp; int n, m; struct ifmibdata_supplemental ifmsupp; - u_int64_t ift_itcp = 0; /* input tc packets */ - u_int64_t ift_itcb = 0; /* input tc bytes */ - u_int64_t ift_otcp = 0; /* output tc packets */ - u_int64_t ift_otcb = 0; /* output tc bytes */ + u_int64_t ift_itcp = 0; /* input tc packets */ + u_int64_t ift_itcb = 0; /* input tc bytes */ + u_int64_t ift_otcp = 0; /* output tc packets */ + u_int64_t ift_otcb = 0; /* output tc bytes */ u_int64_t ift_ipvp = 0; /* input priv tc packets */ u_int64_t ift_ipvb = 0; /* input priv tc bytes */ u_int64_t ift_opvp = 0; /* output priv tc packets */ u_int64_t ift_opvb = 0; /* output priv tc bytes */ bzero(&ifmsupp, sizeof(struct ifmibdata_supplemental)); - + network_layer = 0; link_layer = 0; - ifm = (struct if_msghdr *)next; + ifm = (struct if_msghdr *)next; next += ifm->ifm_msglen; - if (ifm->ifm_type == RTM_IFINFO2) { + if (ifm->ifm_type == RTM_IFINFO2) { struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm; - struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1); + struct sockaddr_dl *sdl = + (struct sockaddr_dl *)(if2m + 1); + int mibname[6]; + size_t miblen = sizeof(struct ifmibdata_supplemental); strncpy(name, sdl->sdl_data, sdl->sdl_nlen); name[sdl->sdl_nlen] = 0; @@ -393,55 +403,55 @@ intpr(void (*pfunc)(char *)) drops = if2m->ifm_snd_drops; mtu = if2m->ifm_data.ifi_mtu; - if (prioflag >= 0) { - int name[6]; - size_t miblen = sizeof(struct ifmibdata_supplemental); - - /* Common OID prefix */ - name[0] = CTL_NET; - name[1] = PF_LINK; - name[2] = NETLINK_GENERIC; - name[3] = IFMIB_IFDATA; - name[4] = if2m->ifm_index; - name[5] = IFDATA_SUPPLEMENTAL; - if (sysctl(name, 6, &ifmsupp, &miblen, (void *)0, 0) == -1) - err(1, "sysctl IFDATA_SUPPLEMENTAL"); + /* Common OID prefix */ + mibname[0] = CTL_NET; + mibname[1] = PF_LINK; + mibname[2] = NETLINK_GENERIC; + mibname[3] = IFMIB_IFDATA; + mibname[4] = if2m->ifm_index; + mibname[5] = IFDATA_SUPPLEMENTAL; + if (sysctl(mibname, 6, &ifmsupp, &miblen, NULL, 0) == -1) + err(1, "sysctl IFDATA_SUPPLEMENTAL"); + fpackets = ifmsupp.ifmd_data_extended.ifi_fpackets; + fbytes = ifmsupp.ifmd_data_extended.ifi_fbytes; + + if (prioflag >= 0) { switch (prioflag) { - case SO_TC_BE: - ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibepackets; - ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibebytes; - ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obepackets; - ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obebytes; - break; - case SO_TC_BK: - ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibkpackets; - ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibkbytes; - ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obkpackets; - ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obkbytes; - break; - case SO_TC_VI: - ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivipackets; - ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivibytes; - ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovipackets; - ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovibytes; - break; - case SO_TC_VO: - ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivopackets; - ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivobytes; - ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovopackets; - ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovobytes; - break; - default: - ift_itcp = 0; - ift_itcb = 0; - ift_otcp = 0; - ift_otcb = 0; - ift_ipvp = 0; - ift_ipvb = 0; - ift_opvp = 0; - ift_opvb = 0; - break; + case SO_TC_BE: + ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibepackets; + ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibebytes; + ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obepackets; + ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obebytes; + break; + case SO_TC_BK: + ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibkpackets; + ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibkbytes; + ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obkpackets; + ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obkbytes; + break; + case SO_TC_VI: + ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivipackets; + ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivibytes; + ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovipackets; + ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovibytes; + break; + case SO_TC_VO: + ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivopackets; + ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivobytes; + ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovopackets; + ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovobytes; + break; + default: + ift_itcp = 0; + ift_itcb = 0; + ift_otcp = 0; + ift_otcb = 0; + ift_ipvp = 0; + ift_ipvb = 0; + ift_opvp = 0; + ift_opvb = 0; + break; } ift_ipvp = ifmsupp.ifmd_traffic_class.ifi_ipvpackets; ift_ipvb = ifmsupp.ifmd_traffic_class.ifi_ipvbytes; @@ -449,14 +459,16 @@ intpr(void (*pfunc)(char *)) ift_opvb = ifmsupp.ifmd_traffic_class.ifi_opvbytes; } - get_rti_info(if2m->ifm_addrs, (struct sockaddr*)(if2m + 1), rti_info); + get_rti_info(if2m->ifm_addrs, + (struct sockaddr*)(if2m + 1), rti_info); sa = rti_info[RTAX_IFP]; - } else if (ifm->ifm_type == RTM_NEWADDR) { - struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm; - + } else if (ifm->ifm_type == RTM_NEWADDR) { + struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm; + if (interface != 0 && ifam->ifam_index != ifindex) continue; - get_rti_info(ifam->ifam_addrs, (struct sockaddr*)(ifam + 1), rti_info); + get_rti_info(ifam->ifam_addrs, + (struct sockaddr*)(ifam + 1), rti_info); sa = rti_info[RTAX_IFA]; } else { continue; @@ -474,16 +486,18 @@ intpr(void (*pfunc)(char *)) break; case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct sockaddr_in *sin = + (struct sockaddr_in *)sa; struct sockaddr_in mask; - + mask.sin_addr.s_addr = 0; - memcpy(&mask, - rti_info[RTAX_NETMASK], - ((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_len); - + memcpy(&mask, rti_info[RTAX_NETMASK], + ((struct sockaddr_in *) + rti_info[RTAX_NETMASK])->sin_len); + printf("%-13.13s ", - netname(sin->sin_addr.s_addr & mask.sin_addr.s_addr, + netname(sin->sin_addr.s_addr & + mask.sin_addr.s_addr, ntohl(mask.sin_addr.s_addr))); printf("%-15.15s ", @@ -494,16 +508,15 @@ intpr(void (*pfunc)(char *)) } #ifdef INET6 case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - struct sockaddr *mask = (struct sockaddr *)rti_info[RTAX_NETMASK]; + struct sockaddr_in6 *sin6 = + (struct sockaddr_in6 *)sa; + struct sockaddr *mask = + (struct sockaddr *)rti_info[RTAX_NETMASK]; - printf("%-11.11s ", - netname6(sin6, - mask)); - printf("%-17.17s ", - (char *)inet_ntop(AF_INET6, - &sin6->sin6_addr, - ntop_buf, sizeof(ntop_buf))); + printf("%-11.11s ", netname6(sin6, mask)); + printf("%-17.17s ", (char *)inet_ntop(AF_INET6, + &sin6->sin6_addr, ntop_buf, + sizeof(ntop_buf))); network_layer = 1; break; @@ -511,11 +524,12 @@ intpr(void (*pfunc)(char *)) #endif /*INET6*/ case AF_LINK: { struct sockaddr_dl *sdl = - (struct sockaddr_dl *)sa; + (struct sockaddr_dl *)sa; char linknum[10]; cp = (char *)LLADDR(sdl); n = sdl->sdl_alen; - snprintf(linknum, sizeof(linknum), "", sdl->sdl_index); + snprintf(linknum, sizeof(linknum), + "", sdl->sdl_index); m = printf("%-11.11s ", linknum); goto hexprint; } @@ -537,7 +551,7 @@ intpr(void (*pfunc)(char *)) link_layer = 1; break; } - } + } show_stat("llu", 8, ipackets, link_layer|network_layer); printf(" "); @@ -582,15 +596,24 @@ intpr(void (*pfunc)(char *)) show_stat("llu", 5, collisions, link_layer); if (tflag) { printf(" "); - show_stat("ll", 3, timer, link_layer); + show_stat("d", 3, timer, link_layer); } if (dflag) { printf(" "); - show_stat("ll", 3, drops, link_layer); + show_stat("d", 3, drops, link_layer); + } + if (Fflag) { + printf(" "); + show_stat("llu", 8, fpackets, link_layer|network_layer); + if (bflag) { + printf(" "); + show_stat("llu", 10, fbytes, + link_layer|network_layer); + } } putchar('\n'); - if (aflag) + if (aflag) multipr(sa->sa_family, next, lim); } free(buf); @@ -599,22 +622,24 @@ intpr(void (*pfunc)(char *)) struct iftot { SLIST_ENTRY(iftot) chain; char ift_name[16]; /* interface name */ - u_int64_t ift_ip; /* input packets */ - u_int64_t ift_ie; /* input errors */ - u_int64_t ift_op; /* output packets */ - u_int64_t ift_oe; /* output errors */ - u_int64_t ift_co; /* collisions */ - u_int64_t ift_dr; /* drops */ - u_int64_t ift_ib; /* input bytes */ - u_int64_t ift_ob; /* output bytes */ - u_int64_t ift_itcp; /* input tc packets */ - u_int64_t ift_itcb; /* input tc bytes */ - u_int64_t ift_otcp; /* output tc packets */ - u_int64_t ift_otcb; /* output tc bytes */ - u_int64_t ift_ipvp; /* input priv tc packets */ - u_int64_t ift_ipvb; /* input priv tc bytes */ - u_int64_t ift_opvp; /* output priv tc packets */ - u_int64_t ift_opvb; /* output priv tc bytes */ + u_int64_t ift_ip; /* input packets */ + u_int64_t ift_ie; /* input errors */ + u_int64_t ift_op; /* output packets */ + u_int64_t ift_oe; /* output errors */ + u_int64_t ift_co; /* collisions */ + u_int64_t ift_dr; /* drops */ + u_int64_t ift_ib; /* input bytes */ + u_int64_t ift_ob; /* output bytes */ + u_int64_t ift_itcp; /* input tc packets */ + u_int64_t ift_itcb; /* input tc bytes */ + u_int64_t ift_otcp; /* output tc packets */ + u_int64_t ift_otcb; /* output tc bytes */ + u_int64_t ift_ipvp; /* input priv tc packets */ + u_int64_t ift_ipvb; /* input priv tc bytes */ + u_int64_t ift_opvp; /* output priv tc packets */ + u_int64_t ift_opvb; /* output priv tc bytes */ + u_int64_t ift_fp; /* forwarded packets */ + u_int64_t ift_fb; /* forwarded bytes */ }; u_char signalled; /* set if alarm goes off "early" */ @@ -660,17 +685,19 @@ sidewaysintpr() name[5] = IFDATA_GENERAL; if (sysctl(name, 6, ifmdall, &len, (void *)0, 0) == -1) err(1, "sysctl IFMIB_IFALLDATA"); - + interesting = NULL; interesting_row = 0; for (i = 0; i < ifcount; i++) { struct ifmibdata *ifmd = ifmdall + i; - + if (interface && strcmp(ifmd->ifmd_name, interface) == 0) { - if ((interesting = calloc(ifcount, sizeof(struct iftot))) == NULL) + if ((interesting = calloc(ifcount, + sizeof(struct iftot))) == NULL) err(1, "malloc failed"); interesting_row = if_nametoindex(interface); - snprintf(interesting->ift_name, 16, "(%s)", ifmd->ifmd_name);; + snprintf(interesting->ift_name, 16, "(%s)", + ifmd->ifmd_name);; } } if ((total = calloc(1, sizeof(struct iftot))) == NULL) @@ -689,6 +716,9 @@ sidewaysintpr() (void)setitimer(ITIMER_REAL, &timer_interval, NULL); first = 1; banner: + if (vflag > 0) + printf("%9s", " "); + if (prioflag >= 0) printf("%39s %39s %36s", "input", interesting ? interesting->ift_name : "(Total)", "output"); @@ -696,24 +726,33 @@ banner: printf("%17s %14s %16s", "input", interesting ? interesting->ift_name : "(Total)", "output"); putchar('\n'); - printf("%10s %5s %10s ", - "packets", "errs", "bytes"); + + if (vflag > 0) + printf("%9s", " "); + + printf("%10s %5s %10s ", "packets", "errs", "bytes"); if (prioflag >= 0) - printf(" %10s %10s %10s %10s", "tcpkts", "tcbytes", "pvpkts", "pvbytes"); - printf("%10s %5s %10s %5s", - "packets", "errs", "bytes", "colls"); + printf(" %10s %10s %10s %10s", + "tcpkts", "tcbytes", "pvpkts", "pvbytes"); + printf("%10s %5s %10s %5s", "packets", "errs", "bytes", "colls"); if (dflag) printf(" %5.5s", "drops"); if (prioflag >= 0) - printf(" %10s %10s %10s %10s", "tcpkts", "tcbytes", "pvpkts", "pvbytes"); + printf(" %10s %10s %10s %10s", + "tcpkts", "tcbytes", "pvpkts", "pvbytes"); + if (Fflag) + printf(" %10s %10s", "fpackets", "fbytes"); putchar('\n'); fflush(stdout); line = 0; loop: + if (vflag && !first) + print_time(); + if (interesting != NULL) { struct ifmibdata ifmd; struct ifmibdata_supplemental ifmsupp; - + len = sizeof(struct ifmibdata); name[3] = IFMIB_IFDATA; name[4] = interesting_row; @@ -721,84 +760,111 @@ loop: if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1) err(1, "sysctl IFDATA_GENERAL %d", interesting_row); - if (prioflag >= 0) { - len = sizeof(struct ifmibdata_supplemental); - name[3] = IFMIB_IFDATA; - name[4] = interesting_row; - name[5] = IFDATA_SUPPLEMENTAL; - if (sysctl(name, 6, &ifmsupp, &len, (void *)0, 0) == -1) - err(1, "sysctl IFDATA_SUPPLEMENTAL %d", interesting_row); - } + len = sizeof(struct ifmibdata_supplemental); + name[3] = IFMIB_IFDATA; + name[4] = interesting_row; + name[5] = IFDATA_SUPPLEMENTAL; + if (sysctl(name, 6, &ifmsupp, &len, (void *)0, 0) == -1) + err(1, "sysctl IFDATA_SUPPLEMENTAL %d", + interesting_row); if (!first) { printf("%10llu %5llu %10llu ", - ifmd.ifmd_data.ifi_ipackets - interesting->ift_ip, - ifmd.ifmd_data.ifi_ierrors - interesting->ift_ie, - ifmd.ifmd_data.ifi_ibytes - interesting->ift_ib); + ifmd.ifmd_data.ifi_ipackets - interesting->ift_ip, + ifmd.ifmd_data.ifi_ierrors - interesting->ift_ie, + ifmd.ifmd_data.ifi_ibytes - interesting->ift_ib); switch (prioflag) { - case SO_TC_BE: - printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_ibepackets - interesting->ift_itcp, - ifmsupp.ifmd_traffic_class.ifi_ibebytes - interesting->ift_itcb); - break; - case SO_TC_BK: - printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_ibkpackets - interesting->ift_itcp, - ifmsupp.ifmd_traffic_class.ifi_ibkbytes - interesting->ift_itcb); - break; - case SO_TC_VI: - printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_ivipackets - interesting->ift_itcp, - ifmsupp.ifmd_traffic_class.ifi_ivibytes - interesting->ift_itcb); - break; - case SO_TC_VO: - printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_ivopackets - interesting->ift_itcp, - ifmsupp.ifmd_traffic_class.ifi_ivobytes - interesting->ift_itcb); - break; - default: - break; + case SO_TC_BE: + printf("%10llu %10llu ", + ifmsupp.ifmd_traffic_class.ifi_ibepackets - + interesting->ift_itcp, + ifmsupp.ifmd_traffic_class.ifi_ibebytes - + interesting->ift_itcb); + break; + case SO_TC_BK: + printf("%10llu %10llu ", + ifmsupp.ifmd_traffic_class.ifi_ibkpackets - + interesting->ift_itcp, + ifmsupp.ifmd_traffic_class.ifi_ibkbytes - + interesting->ift_itcb); + break; + case SO_TC_VI: + printf("%10llu %10llu ", + ifmsupp.ifmd_traffic_class.ifi_ivipackets - + interesting->ift_itcp, + ifmsupp.ifmd_traffic_class.ifi_ivibytes - + interesting->ift_itcb); + break; + case SO_TC_VO: + printf("%10llu %10llu ", + ifmsupp.ifmd_traffic_class.ifi_ivopackets - + interesting->ift_itcp, + ifmsupp.ifmd_traffic_class.ifi_ivobytes - + interesting->ift_itcb); + break; + default: + break; } if (prioflag >= 0) { printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_ipvpackets - interesting->ift_ipvp, - ifmsupp.ifmd_traffic_class.ifi_ipvbytes - interesting->ift_ipvb); + ifmsupp.ifmd_traffic_class.ifi_ipvpackets - + interesting->ift_ipvp, + ifmsupp.ifmd_traffic_class.ifi_ipvbytes - + interesting->ift_ipvb); } printf("%10llu %5llu %10llu %5llu", - ifmd.ifmd_data.ifi_opackets - interesting->ift_op, - ifmd.ifmd_data.ifi_oerrors - interesting->ift_oe, - ifmd.ifmd_data.ifi_obytes - interesting->ift_ob, - ifmd.ifmd_data.ifi_collisions - interesting->ift_co); + ifmd.ifmd_data.ifi_opackets - interesting->ift_op, + ifmd.ifmd_data.ifi_oerrors - interesting->ift_oe, + ifmd.ifmd_data.ifi_obytes - interesting->ift_ob, + ifmd.ifmd_data.ifi_collisions - interesting->ift_co); if (dflag) - printf(" %5llu", ifmd.ifmd_snd_drops - interesting->ift_dr); + printf(" %5llu", + ifmd.ifmd_snd_drops - interesting->ift_dr); switch (prioflag) { - case SO_TC_BE: - printf(" %10llu %10llu", - ifmsupp.ifmd_traffic_class.ifi_obepackets - interesting->ift_otcp, - ifmsupp.ifmd_traffic_class.ifi_obebytes - interesting->ift_otcb); - break; - case SO_TC_BK: - printf(" %10llu %10llu", - ifmsupp.ifmd_traffic_class.ifi_obkpackets - interesting->ift_otcp, - ifmsupp.ifmd_traffic_class.ifi_obkbytes - interesting->ift_otcb); - break; - case SO_TC_VI: - printf(" %10llu %10llu", - ifmsupp.ifmd_traffic_class.ifi_ovipackets - interesting->ift_otcp, - ifmsupp.ifmd_traffic_class.ifi_ovibytes - interesting->ift_otcb); - break; - case SO_TC_VO: - printf(" %10llu %10llu", - ifmsupp.ifmd_traffic_class.ifi_ovopackets - interesting->ift_otcp, - ifmsupp.ifmd_traffic_class.ifi_ovobytes - interesting->ift_otcb); - break; - default: - break; + case SO_TC_BE: + printf(" %10llu %10llu", + ifmsupp.ifmd_traffic_class.ifi_obepackets - + interesting->ift_otcp, + ifmsupp.ifmd_traffic_class.ifi_obebytes - + interesting->ift_otcb); + break; + case SO_TC_BK: + printf(" %10llu %10llu", + ifmsupp.ifmd_traffic_class.ifi_obkpackets - + interesting->ift_otcp, + ifmsupp.ifmd_traffic_class.ifi_obkbytes - + interesting->ift_otcb); + break; + case SO_TC_VI: + printf(" %10llu %10llu", + ifmsupp.ifmd_traffic_class.ifi_ovipackets - + interesting->ift_otcp, + ifmsupp.ifmd_traffic_class.ifi_ovibytes - + interesting->ift_otcb); + break; + case SO_TC_VO: + printf(" %10llu %10llu", + ifmsupp.ifmd_traffic_class.ifi_ovopackets - + interesting->ift_otcp, + ifmsupp.ifmd_traffic_class.ifi_ovobytes - + interesting->ift_otcb); + break; + default: + break; } if (prioflag >= 0) { printf("%10llu %10llu ", - ifmsupp.ifmd_traffic_class.ifi_opvpackets - interesting->ift_opvp, - ifmsupp.ifmd_traffic_class.ifi_opvbytes - interesting->ift_opvb); + ifmsupp.ifmd_traffic_class.ifi_opvpackets - + interesting->ift_opvp, + ifmsupp.ifmd_traffic_class.ifi_opvbytes - + interesting->ift_opvb); + } + if (Fflag) { + printf("%10llu %10llu", + ifmsupp.ifmd_data_extended.ifi_fpackets - + interesting->ift_fp, + ifmsupp.ifmd_data_extended.ifi_fbytes - + interesting->ift_fb); } } interesting->ift_ip = ifmd.ifmd_data.ifi_ipackets; @@ -809,45 +875,68 @@ loop: interesting->ift_ob = ifmd.ifmd_data.ifi_obytes; interesting->ift_co = ifmd.ifmd_data.ifi_collisions; interesting->ift_dr = ifmd.ifmd_snd_drops; + /* private counters */ switch (prioflag) { - case SO_TC_BE: - interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibepackets; - interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibebytes; - interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obepackets; - interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obebytes; - break; - case SO_TC_BK: - interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibkpackets; - interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibkbytes; - interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obkpackets; - interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obkbytes; - break; - case SO_TC_VI: - interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivipackets; - interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivibytes; - interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovipackets; - interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovibytes; - break; - case SO_TC_VO: - interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivopackets; - interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivobytes; - interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovopackets; - interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovobytes; - break; - default: - break; + case SO_TC_BE: + interesting->ift_itcp = + ifmsupp.ifmd_traffic_class.ifi_ibepackets; + interesting->ift_itcb = + ifmsupp.ifmd_traffic_class.ifi_ibebytes; + interesting->ift_otcp = + ifmsupp.ifmd_traffic_class.ifi_obepackets; + interesting->ift_otcb = + ifmsupp.ifmd_traffic_class.ifi_obebytes; + break; + case SO_TC_BK: + interesting->ift_itcp = + ifmsupp.ifmd_traffic_class.ifi_ibkpackets; + interesting->ift_itcb = + ifmsupp.ifmd_traffic_class.ifi_ibkbytes; + interesting->ift_otcp = + ifmsupp.ifmd_traffic_class.ifi_obkpackets; + interesting->ift_otcb = + ifmsupp.ifmd_traffic_class.ifi_obkbytes; + break; + case SO_TC_VI: + interesting->ift_itcp = + ifmsupp.ifmd_traffic_class.ifi_ivipackets; + interesting->ift_itcb = + ifmsupp.ifmd_traffic_class.ifi_ivibytes; + interesting->ift_otcp = + ifmsupp.ifmd_traffic_class.ifi_ovipackets; + interesting->ift_otcb = + ifmsupp.ifmd_traffic_class.ifi_ovibytes; + break; + case SO_TC_VO: + interesting->ift_itcp = + ifmsupp.ifmd_traffic_class.ifi_ivopackets; + interesting->ift_itcb = + ifmsupp.ifmd_traffic_class.ifi_ivobytes; + interesting->ift_otcp = + ifmsupp.ifmd_traffic_class.ifi_ovopackets; + interesting->ift_otcb = + ifmsupp.ifmd_traffic_class.ifi_ovobytes; + break; + default: + break; } if (prioflag >= 0) { - interesting->ift_ipvp = ifmsupp.ifmd_traffic_class.ifi_ipvpackets; - interesting->ift_ipvb = ifmsupp.ifmd_traffic_class.ifi_ipvbytes; - interesting->ift_opvp = ifmsupp.ifmd_traffic_class.ifi_opvpackets; - interesting->ift_opvb = ifmsupp.ifmd_traffic_class.ifi_opvbytes; + interesting->ift_ipvp = + ifmsupp.ifmd_traffic_class.ifi_ipvpackets; + interesting->ift_ipvb = + ifmsupp.ifmd_traffic_class.ifi_ipvbytes; + interesting->ift_opvp = + ifmsupp.ifmd_traffic_class.ifi_opvpackets; + interesting->ift_opvb = + ifmsupp.ifmd_traffic_class.ifi_opvbytes; } + interesting->ift_fp = ifmsupp.ifmd_data_extended.ifi_fpackets; + interesting->ift_fb = ifmsupp.ifmd_data_extended.ifi_fbytes; } else { unsigned int latest_ifcount; struct ifmibdata_supplemental *ifmsuppall = NULL; - + len = sizeof(int); name[3] = IFMIB_SYSTEM; name[4] = IFMIB_IFCOUNT; @@ -870,17 +959,17 @@ loop: name[5] = IFDATA_GENERAL; if (sysctl(name, 6, ifmdall, &len, (void *)0, 0) == -1) err(1, "sysctl IFMIB_IFALLDATA"); - if (prioflag >= 0) { - len = ifcount * sizeof(struct ifmibdata_supplemental); - ifmsuppall = malloc(len); - if (ifmsuppall == NULL) - err(1, "malloc ifmsuppall failed"); - name[3] = IFMIB_IFALLDATA; - name[4] = 0; - name[5] = IFDATA_SUPPLEMENTAL; - if (sysctl(name, 6, ifmsuppall, &len, (void *)0, 0) == -1) - err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL"); - } + + len = ifcount * sizeof(struct ifmibdata_supplemental); + ifmsuppall = malloc(len); + if (ifmsuppall == NULL) + err(1, "malloc ifmsuppall failed"); + name[3] = IFMIB_IFALLDATA; + name[4] = 0; + name[5] = IFDATA_SUPPLEMENTAL; + if (sysctl(name, 6, ifmsuppall, &len, (void *)0, 0) == -1) + err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL"); + sum->ift_ip = 0; sum->ift_ie = 0; sum->ift_ib = 0; @@ -897,9 +986,12 @@ loop: sum->ift_ipvb = 0; sum->ift_opvp = 0; sum->ift_opvb = 0; + sum->ift_fp = 0; + sum->ift_fb = 0; for (i = 0; i < ifcount; i++) { struct ifmibdata *ifmd = ifmdall + i; - + struct ifmibdata_supplemental *ifmsupp = ifmsuppall + i; + sum->ift_ip += ifmd->ifmd_data.ifi_ipackets; sum->ift_ie += ifmd->ifmd_data.ifi_ierrors; sum->ift_ib += ifmd->ifmd_data.ifi_ibytes; @@ -910,40 +1002,41 @@ loop: sum->ift_dr += ifmd->ifmd_snd_drops; /* private counters */ if (prioflag >= 0) { - struct ifmibdata_supplemental *ifmsupp = ifmsuppall + i; switch (prioflag) { - case SO_TC_BE: - sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ibepackets; - sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ibebytes; - sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_obepackets; - sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_obebytes; - break; - case SO_TC_BK: - sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ibkpackets; - sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ibkbytes; - sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_obkpackets; - sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_obkbytes; - break; - case SO_TC_VI: - sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivipackets; - sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivibytes; - sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovipackets; - sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovibytes; - break; - case SO_TC_VO: - sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivopackets; - sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivobytes; - sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovopackets; - sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovobytes; - break; - default: - break; + case SO_TC_BE: + sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ibepackets; + sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ibebytes; + sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_obepackets; + sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_obebytes; + break; + case SO_TC_BK: + sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ibkpackets; + sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ibkbytes; + sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_obkpackets; + sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_obkbytes; + break; + case SO_TC_VI: + sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivipackets; + sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivibytes; + sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovipackets; + sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovibytes; + break; + case SO_TC_VO: + sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivopackets; + sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivobytes; + sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovopackets; + sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovobytes; + break; + default: + break; } sum->ift_ipvp += ifmsupp->ifmd_traffic_class.ifi_ipvpackets; sum->ift_ipvb += ifmsupp->ifmd_traffic_class.ifi_ipvbytes; sum->ift_opvp += ifmsupp->ifmd_traffic_class.ifi_opvpackets; sum->ift_opvb += ifmsupp->ifmd_traffic_class.ifi_opvbytes; } + sum->ift_fp += ifmsupp->ifmd_data_extended.ifi_fpackets; + sum->ift_fb += ifmsupp->ifmd_data_extended.ifi_fbytes; } if (!first) { printf("%10llu %5llu %10llu ", @@ -969,6 +1062,10 @@ loop: sum->ift_otcb - total->ift_otcb, sum->ift_opvp - total->ift_opvp, sum->ift_opvb - total->ift_opvb); + if (Fflag) + printf(" %10llu %10llu", + sum->ift_fp - total->ift_fp, + sum->ift_fb - total->ift_fb); } *total = *sum; } diff --git a/netstat.tproj/inet.c b/netstat.tproj/inet.c index dd17d27..fe69a54 100644 --- a/netstat.tproj/inet.c +++ b/netstat.tproj/inet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -72,6 +72,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -103,6 +104,10 @@ static const char rcsid[] = #include #include "netstat.h" +#ifdef __APPLE__ +#include +#endif + #define ROUNDUP64(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint64_t) - 1))) : sizeof(uint64_t)) #define ADVANCE64(x, n) (((char *)x) += ROUNDUP64(n)) @@ -112,6 +117,7 @@ void inetprint (struct in_addr *, int, char *, int); #ifdef INET6 extern void inet6print (struct in6_addr *, int, char *, int); static int udp_done, tcp_done; +extern int mptcp_done; #endif /* INET6 */ #ifdef SRVCACHE @@ -218,7 +224,7 @@ protopr(uint32_t proto, /* for sysctl version we pass proto # */ struct xsockbuf_n *so_snd = NULL; struct xsockstat_n *so_stat = NULL; int which = 0; - + istcp = 0; switch (proto) { case IPPROTO_TCP: @@ -305,7 +311,8 @@ protopr(uint32_t proto, /* for sysctl version we pass proto # */ break; } } else { - printf("got %d twice\n", xgn->xgn_kind); + if (vflag) + printf("got %d twice\n", xgn->xgn_kind); } if ((istcp && which != ALL_XGN_KIND_TCP) || (!istcp && which != ALL_XGN_KIND_INP)) @@ -493,7 +500,7 @@ protopr(uint32_t proto, /* for sysctl version we pass proto # */ u_int64_t rxbytes = 0; u_int64_t txbytes = 0; - for (i = 0; i < SO_TC_MAX; i++) { + for (i = 0; i < SO_TC_STATS_MAX; i++) { rxbytes += so_stat->xst_tc_stats[i].rxbytes; txbytes += so_stat->xst_tc_stats[i].txbytes; } @@ -502,8 +509,8 @@ protopr(uint32_t proto, /* for sysctl version we pass proto # */ } if (prioflag >= 0) { printf(" %10llu %10llu", - prioflag < SO_TC_MAX ? so_stat->xst_tc_stats[prioflag].rxbytes : 0, - prioflag < SO_TC_MAX ? so_stat->xst_tc_stats[prioflag].txbytes : 0); + prioflag < SO_TC_STATS_MAX ? so_stat->xst_tc_stats[prioflag].rxbytes : 0, + prioflag < SO_TC_STATS_MAX ? so_stat->xst_tc_stats[prioflag].txbytes : 0); } putchar('\n'); } @@ -526,11 +533,13 @@ protopr(uint32_t proto, /* for sysctl version we pass proto # */ * Dump TCP statistics structure. */ void -tcp_stats(uint32_t off , char *name, int af ) +tcp_stats(uint32_t off , char *name, int af) { static struct tcpstat ptcpstat; struct tcpstat tcpstat; size_t len = sizeof tcpstat; + static uint32_t r_swcsum, pr_swcsum; + static uint32_t t_swcsum, pt_swcsum; if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) { warn("sysctl: net.inet.tcp.stats"); @@ -544,6 +553,8 @@ tcp_stats(uint32_t off , char *name, int af ) tcp_done = 1; #endif + if (interval && vflag > 0) + print_time(); printf ("%s:\n", name); #define TCPDIFF(f) (tcpstat.f - ptcpstat.f) @@ -571,6 +582,15 @@ tcp_stats(uint32_t off , char *name, int af ) p(tcps_sndwinup, "\t\t%u window update packet%s\n"); p(tcps_sndctrl, "\t\t%u control packet%s\n"); p(tcps_fcholdpacket, "\t\t%u data packet%s sent after flow control\n"); + t_swcsum = tcpstat.tcps_snd_swcsum + tcpstat.tcps_snd6_swcsum; + if ((t_swcsum - pt_swcsum) || sflag <= 1) + printf("\t\t%u checksummed in software\n", (t_swcsum - pt_swcsum)); + p2(tcps_snd_swcsum, tcps_snd_swcsum_bytes, + "\t\t\t%u segment%s (%u byte%s) over IPv4\n"); +#if INET6 + p2(tcps_snd6_swcsum, tcps_snd6_swcsum_bytes, + "\t\t\t%u segment%s (%u byte%s) over IPv6\n"); +#endif /* INET6 */ p(tcps_rcvtotal, "\t%u packet%s received\n"); p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %u byte%s)\n"); p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n"); @@ -591,6 +611,16 @@ tcp_stats(uint32_t off , char *name, int af ) p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n"); p(tcps_badrst, "\t\t%u bad reset%s\n"); p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n"); + r_swcsum = tcpstat.tcps_rcv_swcsum + tcpstat.tcps_rcv6_swcsum; + if ((r_swcsum - pr_swcsum) || sflag <= 1) + printf("\t\t%u checksummed in software\n", + (r_swcsum - pr_swcsum)); + p2(tcps_rcv_swcsum, tcps_rcv_swcsum_bytes, + "\t\t\t%u segment%s (%u byte%s) over IPv4\n"); +#if INET6 + p2(tcps_rcv6_swcsum, tcps_rcv6_swcsum_bytes, + "\t\t\t%u segment%s (%u byte%s) over IPv6\n"); +#endif /* INET6 */ p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n"); p1a(tcps_rcvshort, "\t\t%u discarded because packet too short\n"); p(tcps_connattempt, "\t%u connection request%s\n"); @@ -631,8 +661,22 @@ tcp_stats(uint32_t off , char *name, int af ) p1a(tcps_sack_sboverflow, "\t%u SACK scoreboard overflow\n"); #endif /* TCP_MAX_SACK */ - if (interval > 0) + p(tcps_coalesced_pack, "\t%u LRO coalesced packet%s\n"); + p(tcps_flowtbl_full, "\t\t%u time%s LRO flow table was full\n"); + p(tcps_flowtbl_collision, "\t\t%u collision%s in LRO flow table\n"); + p(tcps_lro_twopack, "\t\t%u time%s LRO coalesced 2 packets\n"); + p(tcps_lro_multpack, "\t\t%u time%s LRO coalesced 3 or 4 packets\n"); + p(tcps_lro_largepack, "\t\t%u time%s LRO coalesced 5 or more packets\n"); + + p(tcps_limited_txt, "\t%u limited transmit%s done\n"); + p(tcps_early_rexmt, "\t%u early retransmit%s done\n"); + p(tcps_sack_ackadv, "\t%u time%s cumulative ack advanced along with SACK\n"); + + if (interval > 0) { bcopy(&tcpstat, &ptcpstat, len); + pr_swcsum = r_swcsum; + pt_swcsum = t_swcsum; + } #undef TCPDIFF #undef p @@ -642,6 +686,76 @@ tcp_stats(uint32_t off , char *name, int af ) #undef p3 } +#if TARGET_OS_EMBEDDED +/* + * Dump MPTCP statistics + */ +void +mptcp_stats(uint32_t off , char *name, int af) +{ + static struct tcpstat ptcpstat; + struct tcpstat tcpstat; + size_t len = sizeof tcpstat; + + if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) { + warn("sysctl: net.inet.tcp.stats"); + return; + } + +#ifdef INET6 + if (mptcp_done != 0 && interval == 0) + return; + else + mptcp_done = 1; +#endif + + if (interval && vflag > 0) + print_time(); + printf ("%s:\n", name); + +#define MPTCPDIFF(f) (tcpstat.f - ptcpstat.f) +#define p(f, m) if (MPTCPDIFF(f) || sflag <= 1) \ + printf(m, MPTCPDIFF(f), plural(MPTCPDIFF(f))) +#define p1a(f, m) if (MPTCPDIFF(f) || sflag <= 1) \ + printf(m, MPTCPDIFF(f)) +#define p2(f1, f2, m) if (MPTCPDIFF(f1) || MPTCPDIFF(f2) || sflag <= 1) \ + printf(m, MPTCPDIFF(f1), plural(MPTCPDIFF(f1)), \ + MPTCPDIFF(f2), plural(MPTCPDIFF(f2))) +#define p2a(f1, f2, m) if (MPTCPDIFF(f1) || MPTCPDIFF(f2) || sflag <= 1) \ + printf(m, MPTCPDIFF(f1), plural(MPTCPDIFF(f1)), MPTCPDIFF(f2)) +#define p3(f, m) if (MPTCPDIFF(f) || sflag <= 1) \ + printf(m, MPTCPDIFF(f), plurales(MPTCPDIFF(f))) + + p(tcps_mp_sndpacks, "\t%u data packet%s sent\n"); + p(tcps_mp_sndbytes, "\t%u data byte%s sent\n"); + p(tcps_mp_rcvtotal, "\t%u data packet%s received\n"); + p(tcps_mp_rcvbytes, "\t%u data byte%s received\n"); + p(tcps_invalid_mpcap, "\t%u packet%s with an invalid MPCAP option\n"); + p(tcps_invalid_joins, "\t%u packet%s with an invalid MPJOIN option\n"); + p(tcps_mpcap_fallback, "\t%u time%s primary subflow fell back to " + "TCP\n"); + p(tcps_join_fallback, "\t%u time%s secondary subflow fell back to " + "TCP\n"); + p(tcps_estab_fallback, "\t%u DSS option drop%s\n"); + p(tcps_invalid_opt, "\t%u other invalid MPTCP option%s\n"); + p(tcps_mp_reducedwin, "\t%u time%s the MPTCP subflow window was reduced\n"); + p(tcps_mp_badcsum, "\t%u bad DSS checksum%s\n"); + p(tcps_mp_oodata, "\t%u time%s received out of order data \n"); + p3(tcps_mp_switches, "\t%u subflow switch%s\n"); + + if (interval > 0) { + bcopy(&tcpstat, &ptcpstat, len); + } + +#undef MPTCPDIFF +#undef p +#undef p1a +#undef p2 +#undef p2a +#undef p3 +} +#endif /* TARGET_OS_EMBEDDED */ + /* * Dump UDP statistics structure. */ @@ -652,6 +766,8 @@ udp_stats(uint32_t off , char *name, int af ) struct udpstat udpstat; size_t len = sizeof udpstat; uint32_t delivered; + static uint32_t r_swcsum, pr_swcsum; + static uint32_t t_swcsum, pt_swcsum; if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) { warn("sysctl: net.inet.udp.stats"); @@ -665,6 +781,8 @@ udp_stats(uint32_t off , char *name, int af ) udp_done = 1; #endif + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define UDPDIFF(f) (udpstat.f - pudpstat.f) @@ -672,15 +790,30 @@ udp_stats(uint32_t off , char *name, int af ) printf(m, UDPDIFF(f), plural(UDPDIFF(f))) #define p1a(f, m) if (UDPDIFF(f) || sflag <= 1) \ printf(m, UDPDIFF(f)) +#define p2(f1, f2, m) if (UDPDIFF(f1) || UDPDIFF(f2) || sflag <= 1) \ + printf(m, UDPDIFF(f1), plural(UDPDIFF(f1)), UDPDIFF(f2), plural(UDPDIFF(f2))) p(udps_ipackets, "\t%u datagram%s received\n"); - p1a(udps_hdrops, "\t%u with incomplete header\n"); - p1a(udps_badlen, "\t%u with bad data length field\n"); - p1a(udps_badsum, "\t%u with bad checksum\n"); - p1a(udps_noport, "\t%u dropped due to no socket\n"); + p1a(udps_hdrops, "\t\t%u with incomplete header\n"); + p1a(udps_badlen, "\t\t%u with bad data length field\n"); + p1a(udps_badsum, "\t\t%u with bad checksum\n"); + p1a(udps_nosum, "\t\t%u with no checksum\n"); + r_swcsum = udpstat.udps_rcv_swcsum + udpstat.udps_rcv6_swcsum; + if ((r_swcsum - pr_swcsum) || sflag <= 1) + printf("\t\t%u checksummed in software\n", (r_swcsum - pr_swcsum)); + p2(udps_rcv_swcsum, udps_rcv_swcsum_bytes, + "\t\t\t%u datagram%s (%u byte%s) over IPv4\n"); +#if INET6 + p2(udps_rcv6_swcsum, udps_rcv6_swcsum_bytes, + "\t\t\t%u datagram%s (%u byte%s) over IPv6\n"); +#endif /* INET6 */ + p1a(udps_noport, "\t\t%u dropped due to no socket\n"); p(udps_noportbcast, - "\t%u broadcast/multicast datagram%s dropped due to no socket\n"); - p1a(udps_fullsock, "\t%u dropped due to full socket buffers\n"); - p1a(udpps_pcbhashmiss, "\t%u not for hashed pcb\n"); + "\t\t%u broadcast/multicast datagram%s undelivered\n"); + /* the next statistic is cumulative in udps_noportbcast */ + p(udps_filtermcast, + "\t\t%u time%s multicast source filter matched\n"); + p1a(udps_fullsock, "\t\t%u dropped due to full socket buffers\n"); + p1a(udpps_pcbhashmiss, "\t\t%u not for hashed pcb\n"); delivered = UDPDIFF(udps_ipackets) - UDPDIFF(udps_hdrops) - UDPDIFF(udps_badlen) - @@ -689,15 +822,28 @@ udp_stats(uint32_t off , char *name, int af ) UDPDIFF(udps_noportbcast) - UDPDIFF(udps_fullsock); if (delivered || sflag <= 1) - printf("\t%u delivered\n", delivered); + printf("\t\t%u delivered\n", delivered); p(udps_opackets, "\t%u datagram%s output\n"); + t_swcsum = udpstat.udps_snd_swcsum + udpstat.udps_snd6_swcsum; + if ((t_swcsum - pt_swcsum) || sflag <= 1) + printf("\t\t%u checksummed in software\n", (t_swcsum - pt_swcsum)); + p2(udps_snd_swcsum, udps_snd_swcsum_bytes, + "\t\t\t%u datagram%s (%u byte%s) over IPv4\n"); +#if INET6 + p2(udps_snd6_swcsum, udps_snd6_swcsum_bytes, + "\t\t\t%u datagram%s (%u byte%s) over IPv6\n"); +#endif /* INET6 */ - if (interval > 0) + if (interval > 0) { bcopy(&udpstat, &pudpstat, len); + pr_swcsum = r_swcsum; + pt_swcsum = t_swcsum; + } #undef UDPDIFF #undef p #undef p1a +#undef p2 } /* @@ -715,6 +861,8 @@ ip_stats(uint32_t off , char *name, int af ) return; } + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define IPDIFF(f) (ipstat.f - pipstat.f) @@ -722,41 +870,51 @@ ip_stats(uint32_t off , char *name, int af ) printf(m, IPDIFF(f), plural(IPDIFF(f))) #define p1a(f, m) if (IPDIFF(f) || sflag <= 1) \ printf(m, IPDIFF(f)) +#define p2(f1, f2, m) if (IPDIFF(f1) || IPDIFF(f2) || sflag <= 1) \ + printf(m, IPDIFF(f1), plural(IPDIFF(f1)), IPDIFF(f2), plural(IPDIFF(f2))) p(ips_total, "\t%u total packet%s received\n"); - p(ips_badsum, "\t%u bad header checksum%s\n"); - p1a(ips_toosmall, "\t%u with size smaller than minimum\n"); - p1a(ips_tooshort, "\t%u with data size < data length\n"); - p1a(ips_toolong, "\t%u with ip length > max ip packet size\n"); - p1a(ips_badhlen, "\t%u with header length < data size\n"); - p1a(ips_badlen, "\t%u with data length < header length\n"); - p1a(ips_badoptions, "\t%u with bad options\n"); - p1a(ips_badvers, "\t%u with incorrect version number\n"); - p(ips_fragments, "\t%u fragment%s received\n"); - p(ips_fragdropped, "\t%u fragment%s dropped (dup or out of space)\n"); - p(ips_fragtimeout, "\t%u fragment%s dropped after timeout\n"); - p(ips_reassembled, "\t%u packet%s reassembled ok\n"); - p(ips_delivered, "\t%u packet%s for this host\n"); - p(ips_noproto, "\t%u packet%s for unknown/unsupported protocol\n"); - p(ips_forward, "\t%u packet%s forwarded"); + p(ips_badsum, "\t\t%u bad header checksum%s\n"); + p2(ips_rcv_swcsum, ips_rcv_swcsum_bytes, + "\t\t%u header%s (%u byte%s) checksummed in software\n"); + p1a(ips_toosmall, "\t\t%u with size smaller than minimum\n"); + p1a(ips_tooshort, "\t\t%u with data size < data length\n"); + p1a(ips_adj, "\t\t%u with data size > data length\n"); + p(ips_adj_hwcsum_clr, + "\t\t\t%u packet%s forced to software checksum\n"); + p1a(ips_toolong, "\t\t%u with ip length > max ip packet size\n"); + p1a(ips_badhlen, "\t\t%u with header length < data size\n"); + p1a(ips_badlen, "\t\t%u with data length < header length\n"); + p1a(ips_badoptions, "\t\t%u with bad options\n"); + p1a(ips_badvers, "\t\t%u with incorrect version number\n"); + p(ips_fragments, "\t\t%u fragment%s received\n"); + p1a(ips_fragdropped, "\t\t\t%u dropped (dup or out of space)\n"); + p1a(ips_fragtimeout, "\t\t\t%u dropped after timeout\n"); + p1a(ips_reassembled, "\t\t\t%u reassembled ok\n"); + p(ips_delivered, "\t\t%u packet%s for this host\n"); + p(ips_noproto, "\t\t%u packet%s for unknown/unsupported protocol\n"); + p(ips_forward, "\t\t%u packet%s forwarded"); p(ips_fastforward, " (%u packet%s fast forwarded)"); if (IPDIFF(ips_forward) || sflag <= 1) putchar('\n'); - p(ips_cantforward, "\t%u packet%s not forwardable\n"); + p(ips_cantforward, "\t\t%u packet%s not forwardable\n"); p(ips_notmember, - "\t%u packet%s received for unknown multicast group\n"); - p(ips_redirectsent, "\t%u redirect%s sent\n"); + "\t\t%u packet%s received for unknown multicast group\n"); + p(ips_redirectsent, "\t\t%u redirect%s sent\n"); p(ips_localout, "\t%u packet%s sent from this host\n"); - p(ips_rawout, "\t%u packet%s sent with fabricated ip header\n"); + p(ips_rawout, "\t\t%u packet%s sent with fabricated ip header\n"); p(ips_odropped, - "\t%u output packet%s dropped due to no bufs, etc.\n"); - p(ips_noroute, "\t%u output packet%s discarded due to no route\n"); - p(ips_fragmented, "\t%u output datagram%s fragmented\n"); - p(ips_ofragments, "\t%u fragment%s created\n"); - p(ips_cantfrag, "\t%u datagram%s that can't be fragmented\n"); - p(ips_nogif, "\t%u tunneling packet%s that can't find gif\n"); - p(ips_badaddr, "\t%u datagram%s with bad address in header\n"); - p(ips_pktdropcntrl, "\t%u packet%s dropped due to no bufs for control data\n"); + "\t\t%u output packet%s dropped due to no bufs, etc.\n"); + p(ips_noroute, "\t\t%u output packet%s discarded due to no route\n"); + p(ips_fragmented, "\t\t%u output datagram%s fragmented\n"); + p(ips_ofragments, "\t\t%u fragment%s created\n"); + p(ips_cantfrag, "\t\t%u datagram%s that can't be fragmented\n"); + p(ips_nogif, "\t\t%u tunneling packet%s that can't find gif\n"); + p(ips_badaddr, "\t\t%u datagram%s with bad address in header\n"); + p(ips_pktdropcntrl, + "\t\t%u packet%s dropped due to no bufs for control data\n"); + p2(ips_snd_swcsum, ips_snd_swcsum_bytes, + "\t\t%u header%s (%u byte%s) checksummed in software\n"); if (interval > 0) bcopy(&ipstat, &pipstat, len); @@ -764,6 +922,55 @@ ip_stats(uint32_t off , char *name, int af ) #undef IPDIFF #undef p #undef p1a +#undef p2 +} + +/* + * Dump ARP statistics structure. + */ +void +arp_stats(uint32_t off, char *name, int af) +{ + static struct arpstat parpstat; + struct arpstat arpstat; + size_t len = sizeof (arpstat); + + if (sysctlbyname("net.link.ether.inet.stats", &arpstat, + &len, 0, 0) < 0) { + warn("sysctl: net.link.ether.inet.stats"); + return; + } + + if (interval && vflag > 0) + print_time(); + printf("%s:\n", name); + +#define ARPDIFF(f) (arpstat.f - parpstat.f) +#define p(f, m) if (ARPDIFF(f) || sflag <= 1) \ + printf(m, ARPDIFF(f), plural(ARPDIFF(f))) +#define p2(f, m) if (ARPDIFF(f) || sflag <= 1) \ + printf(m, ARPDIFF(f), pluralies(ARPDIFF(f))) + + p(txrequests, "\t%u ARP request%s sent\n"); + p2(txreplies, "\t%u ARP repl%s sent\n"); + p(txannounces, "\t%u ARP announcement%s sent\n"); + p(rxrequests, "\t%u ARP request%s received\n"); + p2(rxreplies, "\t%u ARP repl%s received\n"); + p(received, "\t%u total ARP packet%s received\n"); + p(txconflicts, "\t%u ARP conflict probe%s sent\n"); + p(invalidreqs, "\t%u invalid ARP resolve request%s\n"); + p(reqnobufs, "\t%u total packet%s dropped due to lack of memory\n"); + p(dropped, "\t%u total packet%s dropped due to no ARP entry\n"); + p(purged, "\t%u total packet%s dropped during ARP entry removal\n"); + p2(timeouts, "\t%u ARP entr%s timed out\n"); + p(dupips, "\t%u Duplicate IP%s seen\n"); + + if (interval > 0) + bcopy(&arpstat, &parpstat, len); + +#undef ARPDIFF +#undef p +#undef p2 } static char *icmpnames[] = { @@ -810,6 +1017,8 @@ icmp_stats(uint32_t off , char *name, int af ) if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0) return; /* XXX should complain, but not traditional */ + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define ICMPDIFF(f) (icmpstat.f - picmpstat.f) @@ -885,6 +1094,8 @@ igmp_stats(uint32_t off , char *name, int af ) igmpstat.igps_len, IGPS_VERSION3_LEN); } + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define IGMPDIFF(f) ((uintmax_t)(igmpstat.f - pigmpstat.f)) diff --git a/netstat.tproj/inet6.c b/netstat.tproj/inet6.c index 0d8396e..b4f6867 100644 --- a/netstat.tproj/inet6.c +++ b/netstat.tproj/inet6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -383,6 +383,8 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) memset(&ip6stat, 0, len); if (sysctl(mib, 4, &ip6stat, &len, (void *)0, 0) < 0) return; + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define IP6DIFF(f) (ip6stat.f - pip6stat.f) @@ -392,28 +394,42 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) printf(m, (unsigned long long)IP6DIFF(f)) p(ip6s_total, "\t%llu total packet%s received\n"); - p1a(ip6s_toosmall, "\t%llu with size smaller than minimum\n"); - p1a(ip6s_tooshort, "\t%llu with data size < data length\n"); - p1a(ip6s_badoptions, "\t%llu with bad options\n"); - p1a(ip6s_badvers, "\t%llu with incorrect version number\n"); - p(ip6s_fragments, "\t%llu fragment%s received\n"); - p(ip6s_fragdropped, "\t%llu fragment%s dropped (dup or out of space)\n"); - p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n"); - p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n"); - p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n"); - p(ip6s_delivered, "\t%llu packet%s for this host\n"); - p(ip6s_forward, "\t%llu packet%s forwarded\n"); - p(ip6s_cantforward, "\t%llu packet%s not forwardable\n"); - p(ip6s_redirectsent, "\t%llu redirect%s sent\n"); + p1a(ip6s_toosmall, "\t\t%llu with size smaller than minimum\n"); + p1a(ip6s_tooshort, "\t\t%llu with data size < data length\n"); + p1a(ip6s_adj, "\t\t%llu with data size > data length\n"); + p(ip6s_adj_hwcsum_clr, + "\t\t\t%llu packet%s forced to software checksum\n"); + p1a(ip6s_badoptions, "\t\t%llu with bad options\n"); + p1a(ip6s_badvers, "\t\t%llu with incorrect version number\n"); + p(ip6s_fragments, "\t\t%llu fragment%s received\n"); + p1a(ip6s_fragdropped, + "\t\t\t%llu dropped (dup or out of space)\n"); + p1a(ip6s_fragtimeout, "\t\t\t%llu dropped after timeout\n"); + p1a(ip6s_fragoverflow, "\t\t\t%llu exceeded limit\n"); + p1a(ip6s_reassembled, "\t\t\t%llu reassembled ok\n"); + p(ip6s_delivered, "\t\t%llu packet%s for this host\n"); + p(ip6s_forward, "\t\t%llu packet%s forwarded\n"); + p(ip6s_cantforward, "\t\t%llu packet%s not forwardable\n"); + p(ip6s_redirectsent, "\t\t%llu redirect%s sent\n"); + p(ip6s_notmember, "\t\t%llu multicast packet%s which we don't join\n"); + p(ip6s_exthdrtoolong, + "\t\t%llu packet%s whose headers are not continuous\n"); + p(ip6s_nogif, "\t\t%llu tunneling packet%s that can't find gif\n"); + p(ip6s_toomanyhdr, + "\t\t%llu packet%s discarded due to too may headers\n"); + p1a(ip6s_forward_cachehit, "\t\t%llu forward cache hit\n"); + p1a(ip6s_forward_cachemiss, "\t\t%llu forward cache miss\n"); + p(ip6s_pktdropcntrl, + "\t\t%llu packet%s dropped due to no bufs for control data\n"); p(ip6s_localout, "\t%llu packet%s sent from this host\n"); - p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n"); - p(ip6s_odropped, "\t%llu output packet%s dropped due to no bufs, etc.\n"); - p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n"); - p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n"); - p(ip6s_ofragments, "\t%llu fragment%s created\n"); - p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n"); - p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n"); - p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n"); + p(ip6s_rawout, "\t\t%llu packet%s sent with fabricated ip header\n"); + p(ip6s_odropped, + "\t\t%llu output packet%s dropped due to no bufs, etc.\n"); + p(ip6s_noroute, "\t\t%llu output packet%s discarded due to no route\n"); + p(ip6s_fragmented, "\t\t%llu output datagram%s fragmented\n"); + p(ip6s_ofragments, "\t\t%llu fragment%s created\n"); + p(ip6s_cantfrag, "\t\t%llu datagram%s that can't be fragmented\n"); + p(ip6s_badscope, "\t\t%llu packet%s that violated scope rules\n"); for (first = 1, i = 0; i < 256; i++) if (IP6DIFF(ip6s_nxthist[i]) != 0) { if (first) { @@ -441,39 +457,34 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) (unsigned long long)IP6DIFF(ip6s_mext1)); printf("\t\t%llu two or more ext mbuf\n", (unsigned long long)IP6DIFF(ip6s_mext2m)); - p(ip6s_exthdrtoolong, - "\t%llu packet%s whose headers are not continuous\n"); - p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n"); - p(ip6s_toomanyhdr, - "\t%llu packet%s discarded due to too may headers\n"); /* for debugging source address selection */ #define PRINT_SCOPESTAT(s,i) do {\ switch(i) { /* XXX hardcoding in each case */\ case 1:\ - p(s, "\t\t%llu node-local%s\n");\ + p(s, "\t\t\t%llu node-local%s\n");\ break;\ case 2:\ - p(s,"\t\t%llu link-local%s\n");\ + p(s,"\t\t\t%llu link-local%s\n");\ break;\ case 5:\ - p(s,"\t\t%llu site-local%s\n");\ + p(s,"\t\t\t%llu site-local%s\n");\ break;\ case 14:\ - p(s,"\t\t%llu global%s\n");\ + p(s,"\t\t\t%llu global%s\n");\ break;\ default:\ - printf("\t\t%llu addresses scope=%x\n",\ + printf("\t\t\t%llu addresses scope=%x\n",\ (unsigned long long)IP6DIFF(s), i);\ }\ } while (0); p(ip6s_sources_none, - "\t%llu failure%s of source address selection\n"); + "\t\t%llu failure%s of source address selection\n"); for (first = 1, i = 0; i < 16; i++) { if (IP6DIFF(ip6s_sources_sameif[i])) { if (first) { - printf("\tsource addresses on an outgoing I/F\n"); + printf("\t\tsource addresses on an outgoing I/F\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); @@ -482,7 +493,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) for (first = 1, i = 0; i < 16; i++) { if (IP6DIFF(ip6s_sources_otherif[i])) { if (first) { - printf("\tsource addresses on a non-outgoing I/F\n"); + printf("\t\tsource addresses on a non-outgoing I/F\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); @@ -491,7 +502,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) for (first = 1, i = 0; i < 16; i++) { if (IP6DIFF(ip6s_sources_samescope[i])) { if (first) { - printf("\tsource addresses of same scope\n"); + printf("\t\tsource addresses of same scope\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); @@ -500,7 +511,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) for (first = 1, i = 0; i < 16; i++) { if (IP6DIFF(ip6s_sources_otherscope[i])) { if (first) { - printf("\tsource addresses of a different scope\n"); + printf("\t\tsource addresses of a different scope\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); @@ -509,17 +520,13 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) for (first = 1, i = 0; i < 16; i++) { if (IP6DIFF(ip6s_sources_deprecated[i])) { if (first) { - printf("\tdeprecated source addresses\n"); + printf("\t\tdeprecated source addresses\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); } } - p1a(ip6s_forward_cachehit, "\t%llu forward cache hit\n"); - p1a(ip6s_forward_cachemiss, "\t%llu forward cache miss\n"); - p(ip6s_pktdropcntrl, "\t%llu packet%s dropped due to no bufs for control data\n"); - if (interval > 0) bcopy(&ip6stat, &pip6stat, len); @@ -546,6 +553,8 @@ ip6_ifstats(char *ifname) return; } + if (interval && vflag > 0) + print_time(); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); printf("ip6 on %s:\n", ifr.ifr_name); @@ -864,6 +873,8 @@ icmp6_stats(uint32_t off __unused, char *name, int af __unused) memset(&icmp6stat, 0, len); if (sysctl(mib, 4, &icmp6stat, &len, (void *)0, 0) < 0) return; + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define ICMP6DIFF(f) (icmp6stat.f - picmp6stat.f) @@ -951,6 +962,8 @@ icmp6_ifstats(char *ifname) return; } + if (interval && vflag > 0) + print_time(); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); printf("icmp6 on %s:\n", ifr.ifr_name); @@ -1013,6 +1026,8 @@ pim6_stats(void) if (sysctlbyname("net.inet6.ip6.pim6stat", &pim6stat, &len, 0, 0) == -1) return; + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define PIM6DIFF(f) (pim6stat.f - ppim6stat.f) @@ -1056,6 +1071,8 @@ rip6_stats(uint32_t off __unused, char *name, int af __unused) return; } + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define RIP6DIFF(f) (rip6stat.f - prip6stat.f) @@ -1154,7 +1171,7 @@ inet6name(struct in6_addr *in6p) first = 0; if (gethostname(domain, MAXHOSTNAMELEN) == 0 && (cp = index(domain, '.'))) - (void) strlcpy(domain, cp + 1, sizeof(domain)); + (void) memmove(domain, cp + 1, strlen(cp + 1) + 1); else domain[0] = 0; } diff --git a/netstat.tproj/ipsec.c b/netstat.tproj/ipsec.c index 547b70b..62ece4b 100644 --- a/netstat.tproj/ipsec.c +++ b/netstat.tproj/ipsec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Apple Inc. All rights reserved. + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -242,6 +242,9 @@ print_ipsecstats(void) ipsec_hist(ipsecstat.f, pipsecstat.f, \ sizeof(ipsecstat.f)/sizeof(ipsecstat.f[0]), (n), (t)); + if (interval && vflag > 0) + print_time(); + p(in_success, "\t" LLU " inbound packet%s processed successfully\n"); p(in_polvio, "\t" LLU " inbound packet%s violated process security " "policy\n"); @@ -318,6 +321,8 @@ pfkey_stats(uint32_t off __unused, char *name, int af __unused) len = sizeof(struct pfkeystat); if (sysctlbyname("net.key.pfkeystat", &pfkeystat, &len, 0, 0) == -1) return; + if (interval && vflag > 0) + print_time(); printf ("%s:\n", name); #define PFKEYDIFF(f) (pfkeystat.f - ppfkeystat.f) diff --git a/netstat.tproj/main.c b/netstat.tproj/main.c index efc37dd..e097bc6 100644 --- a/netstat.tproj/main.c +++ b/netstat.tproj/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -102,166 +102,68 @@ char const copyright[] = * */ -static struct nlist nl[] = { -#define N_IFNET 0 - { "_ifnet" }, -#define N_IMP 1 - { "_imp_softc" }, -#define N_RTSTAT 2 - { "_rtstat" }, -#define N_UNIXSW 3 - { "_localsw" }, -#define N_IDP 4 - { "_nspcb"}, -#define N_IDPSTAT 5 - { "_idpstat"}, -#define N_SPPSTAT 6 - { "_spp_istat"}, -#define N_NSERR 7 - { "_ns_errstat"}, -#define N_CLNPSTAT 8 - { "_clnp_stat"}, -#define IN_NOTUSED 9 - { "_tp_inpcb" }, -#define ISO_TP 10 - { "_tp_refinfo" }, -#define N_TPSTAT 11 - { "_tp_stat" }, -#define N_ESISSTAT 12 - { "_esis_stat"}, -#define N_NIMP 13 - { "_nimp"}, -#define N_RTREE 14 - { "_rt_tables"}, -#define N_CLTP 15 - { "_cltb"}, -#define N_CLTPSTAT 16 - { "_cltpstat"}, -#define N_NFILE 17 - { "_nfile" }, -#define N_FILE 18 - { "_file" }, -#define N_IPX 22 - { "_ipxpcb"}, -#define N_IPXSTAT 23 - { "_ipxstat"}, -#define N_SPXSTAT 24 - { "_spx_istat"}, -#define N_DDPSTAT 25 - { "_ddpstat"}, -#define N_DDPCB 26 - { "_ddpcb"}, -#define N_NGSOCKS 27 - { "_ngsocklist"}, -#define N_IP6STAT 28 - { "_ip6stat" }, -#define N_ICMP6STAT 29 - { "_icmp6stat" }, -#define N_IPSECSTAT 30 - { "_ipsecstat" }, -#define N_IPSEC6STAT 31 - { "_ipsec6stat" }, -#define N_PIM6STAT 32 - { "_pim6stat" }, -#define N_MRT6PROTO 33 - { "_ip6_mrtproto" }, -#define N_MRT6STAT 34 - { "_mrt6stat" }, -#define N_MF6CTABLE 35 - { "_mf6ctable" }, -#define N_MIF6TABLE 36 - { "_mif6table" }, -#define N_PFKEYSTAT 37 - { "_pfkeystat" }, -#define N_MBSTAT 38 - { "_mbstat" }, -#define N_MBTYPES 39 - { "_mbtypes" }, -#define N_NMBCLUSTERS 40 - { "_nmbclusters" }, -#define N_NMBUFS 41 - { "_nmbufs" }, -#define N_RTTRASH 42 - { "_rttrash" }, - { "" }, -}; - - struct protox { - u_char pr_index; /* index into nlist of cb head */ - u_char pr_sindex; /* index into nlist of stat block */ - u_char pr_wanted; /* 1 if wanted, 0 otherwise */ void (*pr_cblocks)(uint32_t, char *, int); /* control blocks printing routine */ void (*pr_stats)(uint32_t, char *, int); /* statistics printing routine */ void (*pr_istats)(char *); /* per/if statistics printing routine */ char *pr_name; /* well-known name */ - int pr_usesysctl; /* true if we use sysctl, not kvm */ + int pr_protocol; } protox[] = { - { -1, -1, 1, protopr, - tcp_stats, NULL, "tcp", IPPROTO_TCP }, - { -1, -1, 1, protopr, - udp_stats, NULL, "udp", IPPROTO_UDP }, - { -1, -1, 1, protopr, - NULL, NULL, "divert",IPPROTO_DIVERT }, - { -1, -1, 1, protopr, - ip_stats, NULL, "ip", IPPROTO_RAW }, - { -1, -1, 1, protopr, - icmp_stats, NULL, "icmp", IPPROTO_ICMP }, - { -1, -1, 1, protopr, - igmp_stats, NULL, "igmp", IPPROTO_IGMP }, + { protopr, tcp_stats, NULL, "tcp", IPPROTO_TCP }, + { protopr, udp_stats, NULL, "udp", IPPROTO_UDP }, + { protopr, NULL, NULL, "divert", IPPROTO_DIVERT }, + { protopr, ip_stats, NULL, "ip", IPPROTO_RAW }, + { protopr, icmp_stats, NULL, "icmp", IPPROTO_ICMP }, + { protopr, igmp_stats, NULL, "igmp", IPPROTO_IGMP }, #ifdef IPSEC - { -1, -1, 1, 0, - ipsec_stats, NULL, "ipsec", IPPROTO_ESP}, + { NULL, ipsec_stats, NULL, "ipsec", IPPROTO_ESP}, +#endif + { NULL, arp_stats, NULL, "arp", 0 }, +#if TARGET_OS_EMBEDDED + { mptcppr, mptcp_stats, NULL, "mptcp", IPPROTO_TCP }, #endif - { -1, -1, 0, 0, - 0, NULL, 0 } + { NULL, NULL, NULL, NULL, 0 } }; #ifdef INET6 struct protox ip6protox[] = { - { -1, -1, 1, protopr, - tcp_stats, NULL, "tcp", IPPROTO_TCP }, - { -1, -1, 1, protopr, - udp_stats, NULL, "udp", IPPROTO_UDP }, - { -1, N_IP6STAT, 1, protopr, - ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW }, - { -1, N_ICMP6STAT, 1, protopr, - icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 }, + { protopr, tcp_stats, NULL, "tcp", IPPROTO_TCP }, + { protopr, udp_stats, NULL, "udp", IPPROTO_UDP }, + { protopr, ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW }, + { protopr, icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 }, #ifdef IPSEC - { -1, N_IPSEC6STAT, 1, 0, - ipsec_stats, NULL, "ipsec6",IPPROTO_ESP }, + { NULL, ipsec_stats, NULL, "ipsec6", IPPROTO_ESP }, #endif #ifdef notyet - { -1, N_PIM6STAT, 1, 0, - pim6_stats, NULL, "pim6", 0 }, + { NULL, pim6_stats, NULL, "pim6", 0 }, #endif - { -1, -1, 1, 0, - rip6_stats, NULL, "rip6", IPPROTO_RAW }, - { -1, -1, 0, 0, - 0, NULL, 0, 0 } + { NULL, rip6_stats, NULL, "rip6", IPPROTO_RAW }, +#if TARGET_OS_EMBEDDED + { mptcppr, mptcp_stats, NULL, "mptcp", IPPROTO_TCP }, +#endif + { NULL, NULL, NULL, NULL, 0 } }; #endif /*INET6*/ #ifdef IPSEC struct protox pfkeyprotox[] = { - { -1, N_PFKEYSTAT, 1, 0, - pfkey_stats, NULL, "pfkey", PF_KEY_V2 }, - { -1, -1, 0, 0, - 0, NULL, 0, 0 } + { NULL, pfkey_stats, NULL, "pfkey", PF_KEY_V2 }, + { NULL, NULL, NULL, NULL, 0 } }; #endif struct protox *protoprotox[] = { - protox, + protox, #ifdef INET6 - ip6protox, + ip6protox, #endif #ifdef IPSEC - pfkeyprotox, + pfkeyprotox, #endif - NULL }; + NULL +}; static void printproto (struct protox *, char *); static void usage (void); @@ -276,6 +178,7 @@ int aflag; /* show all sockets (including servers) */ int bflag; /* show i/f total bytes in/out */ int cflag; /* show specific classq */ int dflag; /* show i/f dropped packets */ +int Fflag; /* show i/f forwarded packets */ #if defined(__APPLE__) int gflag; /* show group (multicast) routing or stats */ #endif @@ -314,7 +217,7 @@ main(argc, argv) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "Aabc:df:gI:iLlmnP:p:qQrRstuvWw:x")) != -1) + while ((ch = getopt(argc, argv, "Aabc:dFf:gI:iLlmnP:p:qQrRstuvWw:x")) != -1) switch(ch) { case 'A': Aflag = 1; @@ -332,6 +235,9 @@ main(argc, argv) case 'd': dflag = 1; break; + case 'F': + Fflag = 1; + break; case 'f': if (strcmp(optarg, "ipx") == 0) af = AF_IPX; @@ -461,7 +367,7 @@ main(argc, argv) if (sflag) rt_stats(); else - routepr(nl[N_RTREE].n_value); + routepr(); exit(0); } if (qflag || Qflag) { @@ -479,7 +385,7 @@ main(argc, argv) #if defined(__APPLE__) if (gflag) { -#if !TARGET_OS_EMBEDDED +#if !TARGET_OS_EMBEDDED if (sflag) { if (af == AF_INET || af == AF_UNSPEC) mrt_stats(); @@ -543,7 +449,7 @@ printproto(tp, name) if (iflag && !pflag) { if (tp->pr_istats) intpr(tp->pr_istats); - else + else if (vflag) printf("%s: no per-interface stats routine\n", tp->pr_name); return; @@ -551,25 +457,23 @@ printproto(tp, name) else { pr = tp->pr_stats; if (!pr) { - if (pflag) + if (pflag && vflag) printf("%s: no stats routine\n", tp->pr_name); return; } - off = tp->pr_usesysctl ? tp->pr_usesysctl - : nl[tp->pr_sindex].n_value; + off = tp->pr_protocol; } } else { pr = tp->pr_cblocks; if (!pr) { - if (pflag) + if (pflag && vflag) printf("%s: no PCB routine\n", tp->pr_name); return; } - off = tp->pr_usesysctl ? tp->pr_usesysctl - : nl[tp->pr_index].n_value; + off = tp->pr_protocol; } - if (pr != NULL && (off || af != AF_UNSPEC)) { + if (pr != NULL) { if (sflag && iflag && pflag) intervalpr(pr, off, name, af); else @@ -591,6 +495,12 @@ plurales(int n) return (n != 1 ? "es" : ""); } +char * +pluralies(int n) +{ + return (n != 1 ? "ies" : "y"); +} + /* * Find the protox for the given "well-known" name. */ @@ -653,3 +563,19 @@ usage(void) (void) fprintf(stderr, "%s\n", NETSTAT_USAGE); exit(1); } + +int +print_time(void) +{ + time_t now; + struct tm tm; + int num_written = 0; + + (void) time(&now); + (void) localtime_r(&now, &tm); + + num_written += printf("%02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec); + + return (num_written); +} + diff --git a/netstat.tproj/mptcp.c b/netstat.tproj/mptcp.c new file mode 100644 index 0000000..5aca9b6 --- /dev/null +++ b/netstat.tproj/mptcp.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifdef __APPLE__ +#include +#endif + +#if TARGET_OS_EMBEDDED +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "netstat.h" + +/* XXX we can't include tcp_fsm.h because inet.c already includes it. */ +static const char *tcpstates[] = { + "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", + "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", + "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT" +}; + +static const char *mptcpstates[] = { + "CLOSED", "LISTEN", "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", + "CLOSING", "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", "FASTCLOSE_WAIT" +}; + +int mptcp_done = 0; +extern void inetprint (struct in_addr *, int, char *, int); +extern void inet6print (struct in6_addr *, int, char *, int); + +static void +printmptcp(int id, conninfo_mptcp_t *mptcp) +{ + int i; + conninfo_tcp_t *tcpci; + struct sockaddr_storage *src, *dst; + mptcp_flow_t *flow; + int af; + + printf("mptcp/%-2.2d %69s\n", id, + mptcpstates[mptcp->mptcpci_state]); + for (i = 0; i < mptcp->mptcpci_nflows; i++) { + flow = &mptcp->mptcpci_flows[i]; + src = &flow->flow_src; + dst = &flow->flow_dst; + af = src->ss_family; + printf(" tcp%d/%-2.2d ", af == AF_INET ? 4 : 6, + flow->flow_cid); + printf("%-8.8x ", flow->flow_flags); +#define SIN(x) ((struct sockaddr_in *)(x)) +#define SIN6(x) ((struct sockaddr_in6 *)(x)) + switch (af) { + case AF_INET: + inetprint(&SIN(src)->sin_addr, SIN(src)->sin_port, + "tcp", nflag); + inetprint(&SIN(dst)->sin_addr, SIN(dst)->sin_port, + "tcp", nflag); + break; +#ifdef INET6 + case AF_INET6: + inet6print(&SIN6(src)->sin6_addr, SIN6(src)->sin6_port, + "tcp", nflag); + inet6print(&SIN6(dst)->sin6_addr, SIN6(dst)->sin6_port, + "tcp", nflag); + break; + } +#endif +#undef SIN +#undef SIN6 + tcpci = &flow->flow_ci; + printf("%s\n", tcpstates[tcpci->tcpci_tcp_info.tcpi_state]); + } +} + +void +mptcppr(uint32_t off, char *name, int af) +{ +#pragma unused(off, name, af) + const char *mibvar = "net.inet.mptcp.pcblist"; + size_t len = 0; + conninfo_mptcp_t *mptcp; + char *buf, *bufp; + int id = 0; + + if (Lflag || Aflag || mptcp_done) + return; + mptcp_done = 1; + + if (sysctlbyname(mibvar, 0, &len, NULL, 0) < 0) { + if (errno != ENOENT) + warn("sysctl: %s", mibvar); + return; + } + if ((buf = malloc(len)) == NULL) { + warn("malloc"); + return; + } + if (sysctlbyname(mibvar, buf, &len, NULL, 0) < 0) { + warn("sysctl: %s", mibvar); + free(buf); + return; + } + + printf("Active Multipath Internet connections\n"); + printf("%-8.8s %-9.9s %-22.22s %-22.22s %-11.11s\n", + "Proto/ID", "Flags", + "Local Address", "Foreign Address", + "(state)"); + + bufp = buf; + while (bufp < buf + len) { + /* Sanity check */ + if (buf + len - bufp < sizeof(conninfo_mptcp_t)) + break; + mptcp = (conninfo_mptcp_t *)bufp; + printmptcp(id++, mptcp); + bufp += mptcp->mptcpci_len; + } + free(buf); +} +#endif /* TARGET_OS_EMBEDDED */ diff --git a/netstat.tproj/netstat.1 b/netstat.tproj/netstat.1 index 86e711e..e66f46e 100644 --- a/netstat.tproj/netstat.1 +++ b/netstat.tproj/netstat.1 @@ -412,7 +412,6 @@ interfaces. Information for a specific interface may be displayed with the .Fl I option. .Sh SEE ALSO -.Xr fstat 1 , .Xr nfsstat 1 , .Xr ps 1 , .Xr inet 4 , @@ -423,8 +422,6 @@ option. .Xr route 8 , .Xr services 5 , .Xr iostat 8 , -.Xr trpt 8 , -.Xr vmstat 8 .Sh HISTORY The .Nm netstat diff --git a/netstat.tproj/netstat.h b/netstat.tproj/netstat.h index da71069..86aec50 100644 --- a/netstat.tproj/netstat.h +++ b/netstat.tproj/netstat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -71,6 +71,7 @@ extern int aflag; /* show all sockets (including servers) */ extern int bflag; /* show i/f total bytes in/out */ extern int cflag; /* show specific classq */ extern int dflag; /* show i/f dropped packets */ +extern int Fflag; /* show i/f forwarded packets */ #if defined(__APPLE__) && !TARGET_OS_EMBEDDED extern int gflag; /* show group (multicast) routing or stats */ #endif @@ -98,15 +99,19 @@ extern int unit; /* unit number for above */ extern int af; /* address family */ -extern char *plural (int); -extern char *plurales (int); +extern char *plural(int); +extern char *plurales(int); +extern char *pluralies(int); extern void protopr(uint32_t, char *, int); +extern void mptcppr(uint32_t, char *, int); extern void tcp_stats(uint32_t, char *, int); +extern void mptcp_stats(uint32_t, char *, int); extern void udp_stats(uint32_t, char *, int); extern void ip_stats(uint32_t, char *, int); extern void icmp_stats(uint32_t, char *, int); extern void igmp_stats(uint32_t, char *, int); +extern void arp_stats(uint32_t, char *, int); #ifdef IPSEC extern void ipsec_stats(uint32_t, char *, int); #endif @@ -151,7 +156,7 @@ extern void rt_stats(void); extern void upHex(char *); extern char *routename(uint32_t); extern char *netname(uint32_t, uint32_t); -extern void routepr(uint32_t); +extern void routepr(void); extern void unixpr(void); extern void aqstatpr(void); @@ -163,3 +168,5 @@ extern void mrt_stats(void); #endif extern void ifmalist_dump(void); + +extern int print_time(void); diff --git a/netstat.tproj/route.c b/netstat.tproj/route.c index 203cb14..a5b556f 100644 --- a/netstat.tproj/route.c +++ b/netstat.tproj/route.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -128,31 +128,12 @@ typedef union { u_short u_data[128]; } sa_u; -static void ntreestuff __P((void)); static void np_rtentry __P((struct rt_msghdr2 *)); static void p_sockaddr __P((struct sockaddr *, struct sockaddr *, int, int)); static void p_flags __P((int, char *)); static uint32_t forgemask __P((uint32_t)); static void domask __P((char *, uint32_t, uint32_t)); -/* - * Print routing tables. - */ -void -routepr(uint32_t rtree) -{ - printf("Routing tables\n"); - - if (dflag == 0) { - ntreestuff(); - } else { - if (rtree == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; - } - } - } - /* * Print address family header before a section of the routing table. */ @@ -225,14 +206,19 @@ pr_rthdr(int af) "Flags", "Netif", "Expire"); } -static void -ntreestuff(void) +/* + * Print routing tables. + */ +void +routepr(void) { size_t needed; int mib[6]; char *buf, *next, *lim; struct rt_msghdr2 *rtm; + printf("Routing tables\n"); + mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; diff --git a/network_cmds.xcodeproj/project.pbxproj b/network_cmds.xcodeproj/project.pbxproj index a642039..962376f 100644 --- a/network_cmds.xcodeproj/project.pbxproj +++ b/network_cmds.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ @@ -20,6 +20,7 @@ 690D97BC12DE7151004323A7 /* PBXTargetDependency */, 03B2DBD1100BE626005349BC /* PBXTargetDependency */, 034E4475100BDEC6009CA3DC /* PBXTargetDependency */, + 7250E1491616642900A11A76 /* PBXTargetDependency */, 034E447B100BDF0D009CA3DC /* PBXTargetDependency */, 03B2DBD3100BE645005349BC /* PBXTargetDependency */, 18515B85133D1DBF000148A4 /* PBXTargetDependency */, @@ -49,6 +50,7 @@ 724DABEC0EE891DF008900D0 /* PBXTargetDependency */, 724DAC240EE89525008900D0 /* PBXTargetDependency */, 7216D2670EE8978F00AE70E4 /* PBXTargetDependency */, + 7250E1471616642000A11A76 /* PBXTargetDependency */, 7216D2C00EE89ADF00AE70E4 /* PBXTargetDependency */, 7216D2C20EE89ADF00AE70E4 /* PBXTargetDependency */, 7216D2DA0EE89BE900AE70E4 /* PBXTargetDependency */, @@ -74,6 +76,7 @@ 565825B113392242003E5FA5 /* PBXTargetDependency */, 72ABD08C1083D75D008C721C /* PBXTargetDependency */, 72ABD08E1083D75F008C721C /* PBXTargetDependency */, + 7250E14B1616643000A11A76 /* PBXTargetDependency */, 72ABD0901083D762008C721C /* PBXTargetDependency */, 72ABD0921083D764008C721C /* PBXTargetDependency */, 72ABD0941083D767008C721C /* PBXTargetDependency */, @@ -108,6 +111,7 @@ 565825A6133921A3003E5FA5 /* mnc_multicast.c in Sources */ = {isa = PBXBuildFile; fileRef = 565825981339217B003E5FA5 /* mnc_multicast.c */; }; 565825A7133921A3003E5FA5 /* mnc_opts.c in Sources */ = {isa = PBXBuildFile; fileRef = 565825991339217B003E5FA5 /* mnc_opts.c */; }; 565825A9133921CF003E5FA5 /* mnc.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 565825941339217B003E5FA5 /* mnc.1 */; }; + 56B6B66816F79A1C00D8A7A9 /* mptcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 56B6B66716F79A1C00D8A7A9 /* mptcp.c */; }; 690D97A612DE6F96004323A7 /* mtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 690D979412DE6E6B004323A7 /* mtest.c */; }; 690D97AE12DE70AE004323A7 /* mtest.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 690D979512DE6E76004323A7 /* mtest.8 */; }; 7216D24C0EE896F300AE70E4 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261208B0EE86F4800AFED1B /* data.c */; }; @@ -153,6 +157,8 @@ 7216D3AB0EE8A3C400AE70E4 /* spray.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120E00EE86F9D00AFED1B /* spray.c */; }; 7216D3AF0EE8A3D800AE70E4 /* spray.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120DF0EE86F9D00AFED1B /* spray.8 */; }; 724753E7144905E300F6A941 /* dnctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724753E61448E1EF00F6A941 /* dnctl.8 */; }; + 7247B83616165EDC00873B3C /* pktapctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7247B83516165EDC00873B3C /* pktapctl.8 */; }; + 7247B83C16165F0100873B3C /* pktapctl.c in Sources */ = {isa = PBXBuildFile; fileRef = 7247B83B16165F0100873B3C /* pktapctl.c */; }; 724DAB640EE88E63008900D0 /* ipfw2.c in Sources */ = {isa = PBXBuildFile; fileRef = 726121000EE8701100AFED1B /* ipfw2.c */; }; 724DAB680EE88E78008900D0 /* ipfw.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120FF0EE8701100AFED1B /* ipfw.8 */; }; 724DAB860EE88F0D008900D0 /* ip6fw.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120690EE86F2300AFED1B /* ip6fw.c */; }; @@ -445,6 +451,27 @@ remoteGlobalIDString = 724DAC0C0EE8940D008900D0; remoteInfo = ndp; }; + 7250E1461616642000A11A76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7247B83016165EDC00873B3C; + remoteInfo = pktapctl; + }; + 7250E1481616642900A11A76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7247B83016165EDC00873B3C; + remoteInfo = pktapctl; + }; + 7250E14A1616643000A11A76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7247B83016165EDC00873B3C; + remoteInfo = pktapctl; + }; 726121480EE8717B00AFED1B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; @@ -735,6 +762,16 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 7247B82F16165EDC00873B3C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/local/share/man/man8/; + dstSubfolderSpec = 0; + files = ( + 7247B83616165EDC00873B3C /* pktapctl.8 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; 724DAB760EE88E9C008900D0 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -851,6 +888,7 @@ 5658259A1339217B003E5FA5 /* mnc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mnc.h; sourceTree = ""; }; 5658259B1339217B003E5FA5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; 5658259F1339218F003E5FA5 /* mnc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mnc; sourceTree = BUILT_PRODUCTS_DIR; }; + 56B6B66716F79A1C00D8A7A9 /* mptcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mptcp.c; sourceTree = ""; }; 690D978112DE6034004323A7 /* mtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mtest; sourceTree = BUILT_PRODUCTS_DIR; }; 690D979412DE6E6B004323A7 /* mtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mtest.c; sourceTree = ""; }; 690D979512DE6E76004323A7 /* mtest.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mtest.8; sourceTree = ""; }; @@ -865,6 +903,9 @@ 7216D3A70EE8A3BB00AE70E4 /* spray */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = spray; sourceTree = BUILT_PRODUCTS_DIR; }; 723C7068142BAFEA007C87E9 /* dnctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dnctl; sourceTree = BUILT_PRODUCTS_DIR; }; 724753E61448E1EF00F6A941 /* dnctl.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = dnctl.8; sourceTree = ""; }; + 7247B83116165EDC00873B3C /* pktapctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pktapctl; sourceTree = BUILT_PRODUCTS_DIR; }; + 7247B83516165EDC00873B3C /* pktapctl.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pktapctl.8; sourceTree = ""; }; + 7247B83B16165F0100873B3C /* pktapctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pktapctl.c; sourceTree = ""; }; 724DAB5F0EE88E2A008900D0 /* ipfw */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ipfw; sourceTree = BUILT_PRODUCTS_DIR; }; 724DAB820EE88EFA008900D0 /* ip6fw */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ip6fw; sourceTree = BUILT_PRODUCTS_DIR; }; 724DABA20EE88FE3008900D0 /* kdumpd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kdumpd; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1085,6 +1126,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7247B82E16165EDC00873B3C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 724DAB5D0EE88E2A008900D0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1204,6 +1252,15 @@ path = dnctl; sourceTree = ""; }; + 7247B83216165EDC00873B3C /* pktapctl */ = { + isa = PBXGroup; + children = ( + 7247B83B16165F0100873B3C /* pktapctl.c */, + 7247B83516165EDC00873B3C /* pktapctl.8 */, + ); + path = pktapctl; + sourceTree = ""; + }; 7248622F0EE86EB7001D0DE9 = { isa = PBXGroup; children = ( @@ -1222,6 +1279,7 @@ 726120770EE86F3600AFED1B /* natd.tproj */, 726120830EE86F4000AFED1B /* ndp.tproj */, 7261208A0EE86F4800AFED1B /* netstat.tproj */, + 7247B83216165EDC00873B3C /* pktapctl */, 7261209E0EE86F5000AFED1B /* ping.tproj */, 726120A40EE86F5C00AFED1B /* ping6.tproj */, 726120AC0EE86F6700AFED1B /* rarpd.tproj */, @@ -1343,6 +1401,7 @@ 726120910EE86F4800AFED1B /* main.c */, 726120930EE86F4800AFED1B /* mbuf.c */, 726120940EE86F4800AFED1B /* mcast.c */, + 56B6B66716F79A1C00D8A7A9 /* mptcp.c */, 726120950EE86F4800AFED1B /* mroute.c */, 726120960EE86F4800AFED1B /* mroute6.c */, 726120970EE86F4800AFED1B /* netstat.1 */, @@ -1511,6 +1570,7 @@ 690D978112DE6034004323A7 /* mtest */, 5658259F1339218F003E5FA5 /* mnc */, 723C7068142BAFEA007C87E9 /* dnctl */, + 7247B83116165EDC00873B3C /* pktapctl */, ); name = Products; sourceTree = ""; @@ -1747,6 +1807,23 @@ productReference = 723C7068142BAFEA007C87E9 /* dnctl */; productType = "com.apple.product-type.tool"; }; + 7247B83016165EDC00873B3C /* pktapctl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7247B83A16165EDC00873B3C /* Build configuration list for PBXNativeTarget "pktapctl" */; + buildPhases = ( + 7247B82D16165EDC00873B3C /* Sources */, + 7247B82E16165EDC00873B3C /* Frameworks */, + 7247B82F16165EDC00873B3C /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = pktapctl; + productName = pktapctl; + productReference = 7247B83116165EDC00873B3C /* pktapctl */; + productType = "com.apple.product-type.tool"; + }; 724DAB5E0EE88E2A008900D0 /* ipfw */ = { isa = PBXNativeTarget; buildConfigurationList = 724DAB770EE88E9C008900D0 /* Build configuration list for PBXNativeTarget "ipfw" */; @@ -1933,8 +2010,11 @@ /* Begin PBXProject section */ 724862310EE86EB7001D0DE9 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + }; buildConfigurationList = 724862340EE86EB7001D0DE9 /* Build configuration list for PBXProject "network_cmds" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -1965,6 +2045,7 @@ 724DABDA0EE8912D008900D0 /* natd */, 724DAC0C0EE8940D008900D0 /* ndp */, 7216D2450EE896C000AE70E4 /* netstat */, + 7247B83016165EDC00873B3C /* pktapctl */, 7216D27B0EE8980A00AE70E4 /* ping */, 7216D2990EE898BD00AE70E4 /* ping6 */, 7216D2CC0EE89B7900AE70E4 /* rarpd */, @@ -2301,6 +2382,7 @@ 7216D2550EE896F300AE70E4 /* mroute6.c in Sources */, 7216D2560EE896F300AE70E4 /* route.c in Sources */, 7216D2570EE896F300AE70E4 /* tp_astring.c in Sources */, + 56B6B66816F79A1C00D8A7A9 /* mptcp.c in Sources */, 7216D2580EE896F300AE70E4 /* unix.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2382,6 +2464,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7247B82D16165EDC00873B3C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7247B83C16165F0100873B3C /* pktapctl.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 724DAB5C0EE88E2A008900D0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2648,6 +2738,21 @@ target = 724DAC0C0EE8940D008900D0 /* ndp */; targetProxy = 724DAC230EE89525008900D0 /* PBXContainerItemProxy */; }; + 7250E1471616642000A11A76 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7247B83016165EDC00873B3C /* pktapctl */; + targetProxy = 7250E1461616642000A11A76 /* PBXContainerItemProxy */; + }; + 7250E1491616642900A11A76 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7247B83016165EDC00873B3C /* pktapctl */; + targetProxy = 7250E1481616642900A11A76 /* PBXContainerItemProxy */; + }; + 7250E14B1616643000A11A76 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7247B83016165EDC00873B3C /* pktapctl */; + targetProxy = 7250E14A1616643000A11A76 /* PBXContainerItemProxy */; + }; 726121490EE8717B00AFED1B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7261212C0EE8710B00AFED1B /* arp */; @@ -2762,6 +2867,7 @@ "TARGET_OS_EMBEDDED=1", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; PREBINDING = NO; SDKROOT = ""; "STRIPFLAGS[sdk=iphoneos*]" = "-S"; @@ -3059,6 +3165,7 @@ "$(inherited)", HAVE_SOCKADDR_SA_LEN, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -3075,6 +3182,7 @@ INET6, IPSEC, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -3533,6 +3641,39 @@ }; name = "Ignore Me"; }; + 7247B83716165EDC00873B3C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 0555; + INSTALL_OWNER = root; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 7247B83816165EDC00873B3C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 0555; + INSTALL_OWNER = root; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 7247B83916165EDC00873B3C /* Ignore Me */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = 0555; + INSTALL_OWNER = root; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = "Ignore Me"; + }; 724862320EE86EB7001D0DE9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3554,6 +3695,7 @@ "TARGET_OS_EMBEDDED=1", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; PREBINDING = NO; SDKROOT = ""; WARNING_CFLAGS = "-Wall"; @@ -3581,6 +3723,7 @@ "TARGET_OS_EMBEDDED=1", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; PREBINDING = NO; SDKROOT = ""; "STRIPFLAGS[sdk=iphoneos*]" = "-S"; @@ -3903,6 +4046,7 @@ "$(inherited)", HAVE_SOCKADDR_SA_LEN, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -3919,6 +4063,7 @@ "$(inherited)", HAVE_SOCKADDR_SA_LEN, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -3935,6 +4080,7 @@ INET6, IPSEC, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -3951,6 +4097,7 @@ INET6, IPSEC, ); + HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; INSTALL_OWNER = root; @@ -4146,6 +4293,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 7247B83A16165EDC00873B3C /* Build configuration list for PBXNativeTarget "pktapctl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7247B83716165EDC00873B3C /* Debug */, + 7247B83816165EDC00873B3C /* Release */, + 7247B83916165EDC00873B3C /* Ignore Me */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 724862340EE86EB7001D0DE9 /* Build configuration list for PBXProject "network_cmds" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ping.tproj/ping.8 b/ping.tproj/ping.8 index 0760922..9bf8c1b 100644 --- a/ping.tproj/ping.8 +++ b/ping.tproj/ping.8 @@ -1,3 +1,29 @@ +.\" Copyright (c) 1999-2013 Apple Inc. All rights reserved. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_START@ +.\" +.\" This file contains Original Code and/or Modifications of Original Code +.\" as defined in and that are subject to the Apple Public Source License +.\" Version 2.0 (the 'License'). You may not use this file except in +.\" compliance with the License. The rights granted to you under the License +.\" may not be used to create, or enable the creation or redistribution of, +.\" unlawful or unlicensed copies of an Apple operating system, or to +.\" circumvent, violate, or enable the circumvention or violation of, any +.\" terms of an Apple operating system software license agreement. +.\" +.\" Please obtain a copy of the License at +.\" http://www.opensource.apple.com/apsl/ and read it before using this file. +.\" +.\" The Original Code and all software distributed under the License are +.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +.\" Please see the License for the specific language governing rights and +.\" limitations under the License. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_END@ +.\" .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -26,9 +52,8 @@ .\" SUCH DAMAGE. .\" .\" @(#)ping.8 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/sbin/ping/ping.8,v 1.51.8.2 2006/08/10 10:48:21 glebius Exp $ .\" -.Dd April 4, 2006 +.Dd March 29, 2013 .Dt PING 8 .Os .Sh NAME @@ -159,17 +184,18 @@ This can be very hard on a network and should be used with caution. Specify the maximum size of .Tn ICMP payload when sending sweeping pings. -This option is required for ping sweeps. +This option is required for ping sweeps. .It Fl g Ar sweepminsize Specify the size of .Tn ICMP -payload to start with when sending sweeping pings. +payload to start with when sending sweeping pings. The default value is 0. .It Fl h Ar sweepincrsize Specify the number of bytes to increment the size of .Tn ICMP payload after -each sweep when sending sweeping pings. The default value is 1. +each sweep when sending sweeping pings. +The default value is 1. .It Fl I Ar iface Source multicast packets with the given interface address. This flag only applies if the ping destination is a multicast address. @@ -180,7 +206,7 @@ seconds .Em between sending each packet . The default is to wait for one second between each packet. The wait time may be fractional, but only the super-user may specify -values less than 1 second. +values less than 0.1 second. This option is incompatible with the .Fl f option. @@ -337,8 +363,8 @@ When the specified number of packets have been sent or if the program is terminated with a .Dv SIGINT , a brief summary is displayed, showing the number of packets sent and -received, and the minimum, mean, maximum, and the population standard -deviation of the round-trip times. +received, and the minimum, mean, maximum, and standard deviation of +the round-trip times. .Pp If .Nm @@ -509,17 +535,21 @@ packets that they use for packets, for example either 30 or 60. Others may use completely wild values. .El -.Sh RETURN VALUES +.Sh EXIT STATUS The .Nm -utility returns an exit status of zero if at least one response was -heard from the specified -.Ar host ; -a status of two if the transmission was successful but no responses -were received; or another value -(from -.In sysexits.h ) -if an error occurred. +utility exits with one of the following values: +.Bl -tag -width indent +.It 0 +At least one response was heard from the specified +.Ar host . +.It 2 +The transmission was successful but no responses were received. +.It any other value +An error occurred. +These values are defined in +.In sysexits.h . +.El .Sh SEE ALSO .Xr netstat 1 , .Xr ifconfig 8 , diff --git a/ping.tproj/ping.c b/ping.tproj/ping.c index 8290b7a..4480408 100644 --- a/ping.tproj/ping.c +++ b/ping.tproj/ping.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * Copyright (c) 1999-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -69,10 +69,7 @@ static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; #endif /* not lint */ #endif #include -#ifndef __APPLE__ -__FBSDID("$FreeBSD: src/sbin/ping/ping.c,v 1.112 2007/07/01 12:08:06 gnn Exp $"); -#endif - + /* * P I N G . C * @@ -250,13 +247,11 @@ static void pr_pack(char *, int, struct sockaddr_in *, struct timeval *, int); static void pr_retip(struct ip *); static void status(int); static void stopit(int); -static void tvsub(struct timeval *, struct timeval *); +static void tvsub(struct timeval *, const struct timeval *); static void usage(void) __dead2; int -main(argc, argv) - int argc; - char *const *argv; +main(int argc, char *const *argv) { struct sockaddr_in from, sock_in; struct in_addr ifaddr; @@ -266,7 +261,7 @@ main(argc, argv) struct msghdr msg; struct sigaction si_sa; size_t sz; - u_char *datap, packet[IP_MAXPACKET]; + u_char *datap, packet[IP_MAXPACKET] __attribute__((aligned(4))); char *ep, *source, *target, *payload; struct hostent *hp; #ifdef IPSEC_POLICY_IPSEC @@ -300,7 +295,8 @@ main(argc, argv) s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); sockerrno = errno; - setuid(getuid()); + if (setuid(getuid()) != 0) + err(EX_NOPERM, "setuid() failed"); uid = getuid(); alarmtimeout = df = preload = tos = 0; @@ -422,7 +418,7 @@ main(argc, argv) optarg); options |= F_INTERVAL; interval = (int)t; - if (uid && interval < 1000) { + if (uid && interval < 100) { errno = EPERM; err(EX_NOPERM, "-i interval too short"); } @@ -696,6 +692,8 @@ main(argc, argv) err(EX_OSERR, "socket"); } hold = 1; + (void) setsockopt(s, SOL_SOCKET, SO_RECV_ANYIF, (char *)&hold, + sizeof(hold)); if (ifscope != 0) { if (setsockopt(s, IPPROTO_IP, IP_BOUND_IF, (char *)&ifscope, sizeof (ifscope)) != 0) @@ -894,17 +892,21 @@ main(argc, argv) if (sigaction(SIGINT, &si_sa, 0) == -1) { err(EX_OSERR, "sigaction SIGINT"); } - + si_sa.sa_handler = stopit; + if (sigaction(SIGQUIT, &si_sa, 0) == -1) { + err(EX_OSERR, "sigaction SIGQUIT"); + } + si_sa.sa_handler = status; if (sigaction(SIGINFO, &si_sa, 0) == -1) { - err(EX_OSERR, "sigaction"); + err(EX_OSERR, "sigaction SIGINFO"); } - if (alarmtimeout > 0) { + if (alarmtimeout > 0) { si_sa.sa_handler = stopit; if (sigaction(SIGALRM, &si_sa, 0) == -1) err(EX_OSERR, "sigaction SIGALRM"); - } + } bzero(&msg, sizeof(msg)); msg.msg_name = (caddr_t)&from; @@ -977,7 +979,7 @@ main(argc, argv) continue; } for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - #ifdef SO_TIMESTAMP +#ifdef SO_TIMESTAMP if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP && cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) { @@ -985,7 +987,7 @@ main(argc, argv) memcpy(&now, CMSG_DATA(cmsg), sizeof(now)); tv = &now; } - #endif +#endif if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TRAFFIC_CLASS && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { @@ -1050,8 +1052,7 @@ main(argc, argv) * to be called from a signal handler. */ void -stopit(sig) - int sig __unused; +stopit(int sig __unused) { /* @@ -1171,12 +1172,8 @@ pinger(void) * program to be run without having intermingled output (or statistics!). */ static void -pr_pack(buf, cc, from, tv, tc) - char *buf; - int cc; - struct sockaddr_in *from; - struct timeval *tv; - int tc; +pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv, + int tc) { struct in_addr ina; u_char *cp, *dp; @@ -1444,9 +1441,7 @@ pr_pack(buf, cc, from, tv, tc) * Checksum routine for Internet Protocol family headers (C Version) */ u_short -in_cksum(addr, len) - u_short *addr; - int len; +in_cksum(u_short *addr, int len) { int nleft, sum; u_short *w; @@ -1490,8 +1485,7 @@ in_cksum(addr, len) * be >= in. */ static void -tvsub(out, in) - struct timeval *out, *in; +tvsub(struct timeval *out, const struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { @@ -1507,15 +1501,14 @@ tvsub(out, in) */ static void -status(sig) - int sig __unused; +status(int sig __unused) { siginfo_p = 1; } static void -check_status() +check_status(void) { if (siginfo_p) { @@ -1535,7 +1528,7 @@ check_status() * Print out statistics, and give up. */ static void -finish() +finish(void) { (void)signal(SIGINT, SIG_IGN); @@ -1594,8 +1587,7 @@ static char *ttab[] = { * Print a descriptive string about an ICMP header. */ static void -pr_icmph(icp) - struct icmp *icp; +pr_icmph(struct icmp *icp) { switch(icp->icmp_type) { @@ -1742,8 +1734,7 @@ pr_icmph(icp) * Print an IP header with options. */ static void -pr_iph(ip) - struct ip *ip; +pr_iph(struct ip *ip) { u_char *cp; int hlen; @@ -1775,8 +1766,7 @@ pr_iph(ip) * a hostname. */ static char * -pr_addr(ina) - struct in_addr ina; +pr_addr(struct in_addr ina) { struct hostent *hp; static char buf[16 + 3 + MAXHOSTNAMELEN]; @@ -1795,8 +1785,7 @@ pr_addr(ina) * Dump some info on a returned (via ICMP) IP packet. */ static void -pr_retip(ip) - struct ip *ip; +pr_retip(struct ip *ip) { u_char *cp; int hlen; @@ -1814,7 +1803,7 @@ pr_retip(ip) } static char * -pr_ntime (n_time timestamp) +pr_ntime(n_time timestamp) { static char buf[10]; int hour, min, sec; @@ -1830,8 +1819,7 @@ pr_ntime (n_time timestamp) } static void -fill(bp, patp) - char *bp, *patp; +fill(char *bp, char *patp) { char *cp; int pat[16]; @@ -1867,7 +1855,7 @@ fill(bp, patp) #define SECOPT "" #endif static void -usage() +usage(void) { (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", diff --git a/ping6.tproj/ping6.8 b/ping6.tproj/ping6.8 index d6f4cb0..f4c18bb 100644 --- a/ping6.tproj/ping6.8 +++ b/ping6.tproj/ping6.8 @@ -1,4 +1,28 @@ -.\" $KAME: ping6.8,v 1.58 2003/06/20 12:00:22 itojun Exp $ +.\" Copyright (c) 2002-2013 Apple Inc. All rights reserved. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_START@ +.\" +.\" This file contains Original Code and/or Modifications of Original Code +.\" as defined in and that are subject to the Apple Public Source License +.\" Version 2.0 (the 'License'). You may not use this file except in +.\" compliance with the License. The rights granted to you under the License +.\" may not be used to create, or enable the creation or redistribution of, +.\" unlawful or unlicensed copies of an Apple operating system, or to +.\" circumvent, violate, or enable the circumvention or violation of, any +.\" terms of an Apple operating system software license agreement. +.\" +.\" Please obtain a copy of the License at +.\" http://www.opensource.apple.com/apsl/ and read it before using this file. +.\" +.\" The Original Code and all software distributed under the License are +.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +.\" Please see the License for the specific language governing rights and +.\" limitations under the License. +.\" +.\" @APPLE_OSREFERENCE_LICENSE_HEADER_END@ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -27,9 +51,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/sbin/ping6/ping6.8,v 1.24 2007/11/20 01:58:34 dd Exp $ .\" -.Dd November 15, 2007 +.Dd March 29, 2013 .Dt PING6 8 .Os .Sh NAME @@ -40,9 +63,9 @@ packets to network hosts .Sh SYNOPSIS .Nm .\" without ipsec, or new ipsec -.Op Fl CdfHmnNoqtvwW +.Op Fl CDdfHmnNoqtvwW .\" old ipsec -.\" .Op Fl AdEfmnNqRtvwW +.\" .Op Fl ADdEfmnNqRtvwW .Bk -words .Op Fl a Ar addrtype .Ek @@ -153,6 +176,8 @@ Stop after sending .Ar count .Tn ECHO_RESPONSE packets. +.It Fl D +Disable IPv6 fragmentation. .It Fl d Set the .Dv SO_DEBUG @@ -198,6 +223,8 @@ Wait seconds .Em between sending each packet . The default is to wait for one second between each packet. +The wait time may be fractional, but only the super-user may specify +values less than 0.1 second. This option is incompatible with the .Fl f option. @@ -440,8 +467,8 @@ The .Nm utility returns 0 on success (the host is alive), 2 if the transmission was successful but no responses were received, -any other non-zero value if the arguments are incorrect or -another error has occured. +any other non-zero value if the arguments are incorrect or +another error has occurred. .Sh EXAMPLES Normally, .Nm diff --git a/ping6.tproj/ping6.c b/ping6.tproj/ping6.c index 5a1b25d..419552b 100644 --- a/ping6.tproj/ping6.c +++ b/ping6.tproj/ping6.c @@ -1,4 +1,30 @@ -/* $KAME: ping6.c,v 1.169 2003/07/25 06:01:47 itojun Exp $ */ +/* + * Copyright (c) 2002-2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -29,8 +55,6 @@ * SUCH DAMAGE. */ -/* BSDI ping.c,v 2.3 1996/01/21 17:56:50 jch Exp */ - /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -73,14 +97,6 @@ static const char copyright[] = The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ -#ifndef lint -#if 0 -static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - /* * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure round-trip-delays and packet loss across network paths. @@ -138,11 +154,7 @@ static const char rcsid[] = #include #endif -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#include -#else #include "md5.h" -#endif struct tv32 { u_int32_t tv32_sec; @@ -195,6 +207,7 @@ struct tv32 { #define F_ONCE 0x200000 #define F_AUDIBLE 0x400000 #define F_MISSED 0x800000 +#define F_DONTFRAG 0x1000000 #define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES) u_int options; @@ -229,9 +242,17 @@ int ident; /* process id to identify our packets */ u_int8_t nonce[8]; /* nonce field for node information */ int hoplimit = -1; /* hoplimit */ int pathmtu = 0; /* path MTU for the destination. 0 = unspec. */ +u_char *packet = NULL; +struct cmsghdr *cm = NULL; char *boundif; unsigned int ifscope; int nocell; +#ifdef HAVE_POLL_H +struct pollfd fdmaskp[1]; +#else +fd_set *fdmaskp = NULL; +int fdmasks; +#endif /* counters */ long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ @@ -254,7 +275,7 @@ u_short naflags; /* for ancillary data(advanced API) */ struct msghdr smsghdr; struct iovec smsgiov; -char *scmsg = 0; +char *scmsg = NULL; volatile sig_atomic_t seenalrm; volatile sig_atomic_t seenint; @@ -301,9 +322,7 @@ char *nigroup(char *); void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { struct itimerval itimer; struct sockaddr_in6 from; @@ -316,19 +335,12 @@ main(argc, argv) struct timeval timeout, *tv; #endif struct addrinfo hints; -#ifdef HAVE_POLL_H - struct pollfd fdmaskp[1]; -#else - fd_set *fdmaskp; - int fdmasks; -#endif int cc, i; int ch, hold, packlen, preload, optval, ret_ga; - u_char *datap, *packet; + u_char *datap; char *e, *target, *ifname = NULL, *gateway = NULL; int ip6optlen = 0; struct cmsghdr *scmsgp = NULL; - struct cmsghdr *cm; #if defined(SO_SNDBUF) && defined(SO_RCVBUF) u_long lsockbufsize; int sockbufsize = 0; @@ -347,7 +359,8 @@ main(argc, argv) #ifdef IPV6_USE_MIN_MTU int mflag = 0; #endif - int tclass = -2; /* T_CLASS value -1 means default, so -2 means do not bother */ + /* T_CLASS value -1 means default, so -2 means do not bother */ + int tclass = -2; /* just to be sure */ memset(&smsghdr, 0, sizeof(smsghdr)); @@ -365,7 +378,7 @@ main(argc, argv) #endif /*IPSEC_POLICY_IPSEC*/ #endif while ((ch = getopt(argc, argv, - "a:b:B:Cc:dfHg:h:I:i:k:l:mnNop:qrRS:s:tvwWz:" ADDOPTS)) != -1) { + "a:b:B:Cc:DdfHg:h:I:i:k:l:mnNop:qrRS:s:tvwWz:" ADDOPTS)) != -1) { #undef ADDOPTS switch (ch) { case 'a': @@ -400,8 +413,8 @@ main(argc, argv) naflags |= NI_NODEADDR_FLAG_ANYCAST; break; #else - errx(1, -"-a A is not supported on the platform"); + errx(1, "-a A is not supported on " + "the platform"); /*NOTREACHED*/ #endif default: @@ -421,8 +434,8 @@ main(argc, argv) sockbufsize != lsockbufsize) errx(1, "invalid socket buffer size"); #else - errx(1, -"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported"); + errx(1, "-b option ignored: SO_SNDBUF/SO_RCVBUF " + "socket options not supported"); #endif break; case 'B': @@ -437,6 +450,9 @@ main(argc, argv) errx(1, "illegal number of packets -- %s", optarg); break; + case 'D': + options |= F_DONTFRAG; + break; case 'd': options |= F_SO_DEBUG; break; @@ -473,8 +489,8 @@ main(argc, argv) intval = strtod(optarg, &e); if (*optarg == '\0' || *e != '\0') errx(1, "illegal timing interval %s", optarg); - if (intval < 1 && getuid()) { - errx(1, "%s: only root may use interval < 1s", + if (intval < 0.1 && getuid()) { + errx(1, "%s: only root may use interval < 0.1s", strerror(EPERM)); } interval.tv_sec = (long)intval; @@ -552,6 +568,7 @@ main(argc, argv) memcpy(&src, res->ai_addr, res->ai_addrlen); srclen = res->ai_addrlen; freeaddrinfo(res); + res = NULL; options |= F_SRCADDR; break; case 's': /* size of packet to send */ @@ -755,8 +772,10 @@ main(argc, argv) } /* revoke root privilege */ - seteuid(getuid()); - setuid(getuid()); + if (seteuid(getuid()) != 0) + err(1, "seteuid() failed"); + if (setuid(getuid()) != 0) + err(1, "setuid() failed"); if ((options & F_FLOOD) && (options & F_INTERVAL)) errx(1, "-f and -i incompatible options"); @@ -797,12 +816,20 @@ main(argc, argv) for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t)) *((u_int32_t *)&nonce[i]) = arc4random(); #endif - + optval = 1; + if (options & F_DONTFRAG) + if (setsockopt(s, 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, sizeof(hold)); + + hold = 1; + (void) setsockopt(s, SOL_SOCKET, SO_RECV_ANYIF, (char *)&hold, + sizeof(hold)); + optval = IPV6_DEFHLIM; if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, @@ -892,15 +919,17 @@ main(argc, argv) if (tclass != -2) { int on = 1; - - if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on))) + + if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, + sizeof(on))) err(1, "setsockopt(IPV6_RECVTCLASS)"); - - if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof(tclass))) + + if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &tclass, + sizeof(tclass))) err(1, "setsockopt(IPV6_TCLASS)"); } - /* +/* optval = 1; if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, @@ -915,6 +944,11 @@ main(argc, argv) if (hoplimit != -1) ip6optlen += CMSG_SPACE(sizeof(int)); +#ifdef IPV6_USE_MIN_MTU + if (mflag != 1) + ip6optlen += CMSG_SPACE(sizeof(int)); +#endif /* IPV6_USE_MIN_MTU */ + if (tclass != -2) ip6optlen += CMSG_SPACE(sizeof(int)); @@ -967,6 +1001,19 @@ main(argc, argv) scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); } +#ifdef IPV6_USE_MIN_MTU + if (mflag != 1) { + optval = mflag > 1 ? 0 : 1; + + scmsgp->cmsg_len = CMSG_LEN(sizeof(int)); + scmsgp->cmsg_level = IPPROTO_IPV6; + scmsgp->cmsg_type = IPV6_USE_MIN_MTU; + *(int *)(CMSG_DATA(scmsgp)) = optval; + + scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); + } +#endif /* IPV6_USE_MIN_MTU */ + if (argc > 1) { /* some intermediate addrs are specified */ int hops, error; #ifdef USE_RFC2292BIS @@ -1145,7 +1192,8 @@ main(argc, argv) #else /* old adv. API */ if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, sizeof(optval)) < 0) - warn("setsockopt(IPV6_HOPLIMIT, %d, %lu)", optval, sizeof(optval)); /* XXX err? */ + warn("setsockopt(IPV6_HOPLIMIT, %d, %lu)", + optval, sizeof(optval)); /* XXX err? */ #endif printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), @@ -1273,7 +1321,7 @@ main(argc, argv) /* * receive control messages only. Process the - * exceptions (currently the only possiblity is + * exceptions (currently the only possibility is * a path MTU notification.) */ if ((mtu = get_pathmtu(&m)) > 0) { @@ -1299,12 +1347,29 @@ main(argc, argv) } } summary(); + + if (res != NULL) + freeaddrinfo(res); + + if (packet != NULL) + free(packet); + + if (cm != NULL) + free(cm); + + if (scmsg != NULL) + free(scmsg); + +#ifndef HAVE_POLL_H + if (fdmaskp != NULL) + free(fdmaskp); +#endif + exit(nreceived == 0 ? 2 : 0); } void -onsignal(sig) - int sig; +onsignal(int sig) { switch (sig) { @@ -1327,7 +1392,7 @@ onsignal(sig) * This routine transmits another ping6. */ void -retransmit() +retransmit(void) { struct itimerval itimer; @@ -1363,7 +1428,7 @@ retransmit() * byte-order, to compute the round-trip time. */ size_t -pingerlen() +pingerlen(void) { size_t l; @@ -1382,7 +1447,7 @@ pingerlen() } int -pinger() +pinger(void) { struct icmp6_hdr *icp; struct iovec iov[2]; @@ -1497,8 +1562,7 @@ pinger() } int -myechoreply(icp) - const struct icmp6_hdr *icp; +myechoreply(const struct icmp6_hdr *icp) { if (ntohs(icp->icmp6_id) == ident) return 1; @@ -1507,8 +1571,7 @@ myechoreply(icp) } int -mynireply(nip) - const struct icmp6_nodeinfo *nip; +mynireply(const struct icmp6_nodeinfo *nip) { if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), nonce + sizeof(u_int16_t), @@ -1519,12 +1582,9 @@ mynireply(nip) } char * -dnsdecode(sp, ep, base, buf, bufsiz) - const u_char **sp; - const u_char *ep; - const u_char *base; /*base for compressed name*/ - char *buf; - size_t bufsiz; +dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf, + size_t bufsiz) + /*base for compressed name*/ { int i; const u_char *cp; @@ -1589,10 +1649,7 @@ dnsdecode(sp, ep, base, buf, bufsiz) * program to be run without having intermingled output (or statistics!). */ void -pr_pack(buf, cc, mhdr) - u_char *buf; - int cc; - struct msghdr *mhdr; +pr_pack(u_char *buf, int cc, struct msghdr *mhdr) { #define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) struct icmp6_hdr *icp; @@ -1613,7 +1670,7 @@ pr_pack(buf, cc, mhdr) char dnsname[NS_MAXDNAME + 1]; int tclass = 0; int sotc = -1; - + (void)gettimeofday(&tv, NULL); if (!mhdr || !mhdr->msg_name || @@ -1719,7 +1776,9 @@ pr_pack(buf, cc, mhdr) dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; for (i = 8; cp < end; ++i, ++cp, ++dp) { if (*cp != *dp) { - (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); + (void)printf("\nwrong data byte #%d " + "should be 0x%x but was 0x%x", + i, *dp, *cp); break; } } @@ -1825,7 +1884,8 @@ pr_pack(buf, cc, mhdr) putchar(')'); goto fqdnend; } - ttl = (int32_t)ntohl(*(u_int32_t *)&buf[off+ICMP6ECHOLEN+8]); + ttl = (int32_t)ntohl(*(u_int32_t *) + &buf[off+ICMP6ECHOLEN+8]); if (comma) printf(","); if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { @@ -1888,8 +1948,7 @@ pr_pack(buf, cc, mhdr) } void -pr_exthdrs(mhdr) - struct msghdr *mhdr; +pr_exthdrs(struct msghdr *mhdr) { ssize_t bufsize; void *bufp; @@ -1904,7 +1963,7 @@ pr_exthdrs(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: "); @@ -2065,10 +2124,7 @@ pr_rthdr(void *extbuf, size_t bufsize __unused) #endif /* USE_RFC2292BIS */ int -pr_bitrange(v, soff, ii) - u_int32_t v; - int soff; - int ii; +pr_bitrange(u_int32_t v, int soff, int ii) { int off; int i; @@ -2114,9 +2170,8 @@ pr_bitrange(v, soff, ii) } void -pr_suptypes(ni, nilen) - struct icmp6_nodeinfo *ni; /* ni->qtype must be SUPTYPES */ - size_t nilen; +pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen) + /* ni->qtype must be SUPTYPES */ { size_t clen; u_int32_t v; @@ -2181,9 +2236,8 @@ pr_suptypes(ni, nilen) } void -pr_nodeaddr(ni, nilen) - struct icmp6_nodeinfo *ni; /* ni->qtype must be NODEADDR */ - int nilen; +pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen) + /* ni->qtype must be NODEADDR */ { u_char *cp = (u_char *)(ni + 1); char ntop_buf[INET6_ADDRSTRLEN]; @@ -2248,8 +2302,7 @@ pr_nodeaddr(ni, nilen) } int -get_hoplim(mhdr) - struct msghdr *mhdr; +get_hoplim(struct msghdr *mhdr) { struct cmsghdr *cm; @@ -2268,8 +2321,7 @@ get_hoplim(mhdr) } struct in6_pktinfo * -get_rcvpktinfo(mhdr) - struct msghdr *mhdr; +get_rcvpktinfo(struct msghdr *mhdr) { struct cmsghdr *cm; @@ -2288,8 +2340,7 @@ get_rcvpktinfo(mhdr) } int -get_pathmtu(mhdr) - struct msghdr *mhdr; +get_pathmtu(struct msghdr *mhdr) { #ifdef IPV6_RECVPATHMTU struct cmsghdr *cm; @@ -2367,21 +2418,20 @@ int get_so_traffic_class(struct msghdr *mhdr) { struct cmsghdr *cm; - + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { if (cm->cmsg_len == 0) return(-1); - + if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SO_TRAFFIC_CLASS && cm->cmsg_len == CMSG_LEN(sizeof(int))) return(*(int *)CMSG_DATA(cm)); } - + return(-1); -} - +} /* * tvsub -- @@ -2389,8 +2439,7 @@ get_so_traffic_class(struct msghdr *mhdr) * be >= in. */ void -tvsub(out, in) - struct timeval *out, *in; +tvsub(struct timeval *out, struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; @@ -2405,11 +2454,27 @@ tvsub(out, in) */ /* ARGSUSED */ void -onint(notused) - int notused; +onint(int notused __unused) { summary(); + if (res != NULL) + freeaddrinfo(res); + + if (packet != NULL) + free(packet); + + if (cm != NULL) + free(cm); + + if (scmsg != NULL) + free(scmsg); + +#ifndef HAVE_POLL_H + if (fdmaskp != NULL) + free(fdmaskp); +#endif + (void)signal(SIGINT, SIG_DFL); (void)kill(getpid(), SIGINT); @@ -2422,9 +2487,8 @@ onint(notused) * Print out statistics. */ void -summary() +summary(void) { - (void)printf("\n--- %s ping6 statistics ---\n", hostname); (void)printf("%ld packets transmitted, ", ntransmitted); (void)printf("%ld packets received, ", nreceived); @@ -2470,9 +2534,7 @@ static const char *nircode[] = { * Print a descriptive string about an ICMP header. */ void -pr_icmph(icp, end) - struct icmp6_hdr *icp; - u_char *end; +pr_icmph(struct icmp6_hdr *icp, u_char *end) { char ntop_buf[INET6_ADDRSTRLEN]; struct nd_redirect *red; @@ -2702,8 +2764,7 @@ pr_icmph(icp, end) * Print an IP6 header. */ void -pr_iph(ip6) - struct ip6_hdr *ip6; +pr_iph(struct ip6_hdr *ip6) { u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; u_int8_t tc; @@ -2731,9 +2792,7 @@ pr_iph(ip6) * a hostname. */ const char * -pr_addr(addr, addrlen) - struct sockaddr *addr; - int addrlen; +pr_addr(struct sockaddr *addr, int addrlen) { static char buf[NI_MAXHOST]; int flag = 0; @@ -2752,9 +2811,7 @@ pr_addr(addr, addrlen) * Dump some info on a returned (via ICMPv6) IPv6 packet. */ void -pr_retip(ip6, end) - struct ip6_hdr *ip6; - u_char *end; +pr_retip(struct ip6_hdr *ip6, u_char *end) { u_char *cp = (u_char *)ip6, nh; int hlen; @@ -2834,8 +2891,7 @@ pr_retip(ip6, end) } void -fill(bp, patp) - char *bp, *patp; +fill(char *bp, char *patp) { int ii, jj, kk; int pat[16]; @@ -2868,9 +2924,7 @@ fill(bp, patp) #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC int -setpolicy(so, policy) - int so; - char *policy; +setpolicy(int so __unused, char *policy) { char *buf; @@ -2891,8 +2945,7 @@ setpolicy(so, policy) #endif char * -nigroup(name) - char *name; +nigroup(char *name) { char *p; char *q; @@ -2936,14 +2989,14 @@ nigroup(name) } void -usage() +usage(void) { (void)fprintf(stderr, #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC) "A" #endif "usage: ping6 [-" - "d" + "Dd" #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC) "E" #endif diff --git a/pktapctl/pktapctl.8 b/pktapctl/pktapctl.8 new file mode 100644 index 0000000..5f11615 --- /dev/null +++ b/pktapctl/pktapctl.8 @@ -0,0 +1,41 @@ +.Dd 9/28/12 +.Dt pktapctl 8 +.Os Darwin +.Sh NAME +.Nm pktapctl +.Sh SYNOPSIS +.Nm +.Op Fl g +.Op Fl h +.Op Fl i Ar interface +.Op Fl p Ar rule +.Op Fl s Ar rule +.Sh DESCRIPTION +.Nm +let you configure a pktap virtual interface. +.Pp +This is an experimental command whose syntax and functionalities may change in +future releases. +.Pp +The options have the following meaning: +.Bl -tag -width -indent +.It Fl g +Get the list of filter rules for the given +.Ar interface. +.It Fl h +Display a quick help and exit. +.It Fl p +To add a pass interface filter rule. +.It Fl s +To add a skip interface filter rule. +.El +.Pp +Here is the syntax of the interface filter rules: +.Bl -tag -indent +.It type number +An interface type number or 0 for any interface type. +.It name string +To specify interface with name matching the given string. +.El +.Sh SEE ALSO +.Xr tcpdump 1 diff --git a/pktapctl/pktapctl.c b/pktapctl/pktapctl.c new file mode 100644 index 0000000..9bbe0ed --- /dev/null +++ b/pktapctl/pktapctl.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *ifname = NULL; +unsigned int ifindex = 0; +int do_get = 0; +int num_filter_entries = 0; +struct pktap_filter set_filter[PKTAP_MAX_FILTERS]; + +static const char *parameters_format = " %-24s %s\n"; + +static void +usage(const char *s) +{ + printf("# usage: %s -i -g -p -s -h\n", s); + printf(" Get or set filtering rules on a pktap interface\n"); + printf(" Options:\n"); + printf(parameters_format, "-h", "display this help"); + printf(parameters_format, "-i ", "name pktap interface"); + printf(parameters_format, "-g", "get filter rules"); + printf(parameters_format, "-p param", "add a pass rule"); + printf(parameters_format, "-s param", "add a skip rule"); + printf(" Format of parameter:\n"); + printf(parameters_format, "type ", "interfaces of given type"); + printf(parameters_format, "", "use 0 for any interface type"); + printf(parameters_format, "name ", "interface of given name"); +} + +static void +print_filter_entry(struct pktap_filter *filter) +{ + printf("filter_op: %u filter_param %u ", filter->filter_op, filter->filter_param); + if (filter->filter_param == PKTAP_FILTER_PARAM_IF_TYPE) + printf("%u", filter->filter_param_if_type); + else if (filter->filter_param == PKTAP_FILTER_PARAM_IF_NAME) + printf("%s", filter->filter_param_if_name); +} + +int main(int argc, char * const argv[]) +{ + int ch; + struct ifdrv ifdr; + int fd = -1; + int i; + + //printf("sizeof(struct pktap_filter) %lu\n", sizeof(struct pktap_filter)); + //printf("sizeof(pktap_filter) %lu\n", sizeof(set_filter)); + + while ((ch = getopt(argc, argv, "ghi:p:s:")) != -1) { + switch (ch) { + case 'g': + do_get++; + break; + + case 'h': + usage(argv[0]); + exit(0); + /* NOT REACHED */ + + case 'i': + ifname = optarg; + + ifindex = if_nametoindex(ifname); + if (ifindex == 0) + err(1, "if_nametoindex(%s) failed", ifname); + + break; + + case 'p': + case 's': { + /* -p (type|name) */ + struct pktap_filter entry; + + if (num_filter_entries >= PKTAP_MAX_FILTERS) + errx(1, "Too many filter entries, max is %u", PKTAP_MAX_FILTERS); + if (optind + 1 > argc) + errx(1, "-%c needs two arguments optind %d argc %d", ch, optind, argc); + if (ch == 'p') + entry.filter_op = PKTAP_FILTER_OP_PASS; + else + entry.filter_op = PKTAP_FILTER_OP_SKIP; + if (strcmp(optarg, "type") == 0) { + entry.filter_param = PKTAP_FILTER_PARAM_IF_TYPE; + entry.filter_param_if_type = (uint32_t)strtoul(argv[optind], NULL, 0); + } else if (strcmp(optarg, "name") == 0) { + entry.filter_param = PKTAP_FILTER_PARAM_IF_NAME; + snprintf(entry.filter_param_if_name, sizeof(entry.filter_param_if_name), "%s", argv[optind]); + } else + errx(1, "syntax error -p %s", optarg); + printf("Addin entry: "); + print_filter_entry(&entry); + printf("\n"); + set_filter[num_filter_entries] = entry; + + num_filter_entries++; + optind++; + break; + } + + case '?': + default: + err(1, "syntax error"); + exit(0); + /* NOT REACHED */ + } + } + if (ifname == NULL) + errx(1, "missing interface"); + + fd = socket(PF_INET, SOCK_DGRAM, 0); + if (fd == -1) + err(1, "socket(PF_INET, SOCK_DGRAM, 0)"); + + if (num_filter_entries > 0) { + for (i = num_filter_entries; i < PKTAP_MAX_FILTERS; i++) { + struct pktap_filter *filter = set_filter + i; + filter->filter_op = PKTAP_FILTER_OP_NONE; + filter->filter_param = PKTAP_FILTER_PARAM_NONE; + } + + snprintf(ifdr.ifd_name, sizeof(ifdr.ifd_name), "%s", ifname); + ifdr.ifd_cmd = PKTP_CMD_FILTER_SET; + ifdr.ifd_len = sizeof(set_filter); + ifdr.ifd_data = &set_filter[0]; + + if (ioctl(fd, SIOCSDRVSPEC, &ifdr) == -1) + err(1, "ioctl(SIOCSDRVSPEC)"); + + } + + if (do_get) { + struct pktap_filter get_filter[PKTAP_MAX_FILTERS]; + + snprintf(ifdr.ifd_name, sizeof(ifdr.ifd_name), "%s", ifname); + ifdr.ifd_cmd = PKTP_CMD_FILTER_GET; + ifdr.ifd_len = sizeof(get_filter); + ifdr.ifd_data = &get_filter[0]; + + if (ioctl(fd, SIOCGDRVSPEC, &ifdr) == -1) + err(1, "ioctl(SIOCGDRVSPEC)"); + + for (i = 0; i < PKTAP_MAX_FILTERS; i++) { + struct pktap_filter *filter = get_filter + i; + + printf("[%d] ", i); + print_filter_entry(filter); + printf("\n"); + } + } + + return 0; +} + diff --git a/route.tproj/route.c b/route.tproj/route.c index 23cba41..8a60ed8 100644 --- a/route.tproj/route.c +++ b/route.tproj/route.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Apple Inc. All rights reserved. + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -328,7 +328,7 @@ routename(sa) if (gethostname(domain, MAXHOSTNAMELEN) == 0 && (cp = index(domain, '.'))) { domain[MAXHOSTNAMELEN] = '\0'; - (void) strlcpy(domain, cp + 1, sizeof(domain)); + (void) memmove(domain, cp + 1, strlen(cp + 1) + 1); } else domain[0] = 0; } diff --git a/rtadvd.tproj/rtadvd.c b/rtadvd.tproj/rtadvd.c index a4dff6d..ae888c2 100644 --- a/rtadvd.tproj/rtadvd.c +++ b/rtadvd.tproj/rtadvd.c @@ -351,7 +351,9 @@ die() for (i = 0; i < retrans; i++) { for (ra = ralist; ra; ra = ra->next) ra_output(ra); - sleep(MIN_DELAY_BETWEEN_RAS); + + if (retrans != 1) + sleep(MIN_DELAY_BETWEEN_RAS); } pidfile_remove(pfh); exit(0); @@ -1639,7 +1641,8 @@ ra_timer_update(void *data, struct timeval *tm) interval += random() % (rai->maxinterval - rai->mininterval); /* - * For the first few advertisements (up to + * The first advertisement is sent as soon as rtadvd starts up + * and for the next few advertisements (up to * MAX_INITIAL_RTR_ADVERTISEMENTS), if the randomly chosen interval * is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL, the timer * SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead. @@ -1649,7 +1652,7 @@ ra_timer_update(void *data, struct timeval *tm) interval > MAX_INITIAL_RTR_ADVERT_INTERVAL) interval = MAX_INITIAL_RTR_ADVERT_INTERVAL; - tm->tv_sec = interval; + tm->tv_sec = rai->initcounter == 0 ? 0 : interval; tm->tv_usec = 0; syslog(LOG_DEBUG, diff --git a/rtadvd.tproj/rtadvd.h b/rtadvd.tproj/rtadvd.h index fdd8977..d019b19 100644 --- a/rtadvd.tproj/rtadvd.h +++ b/rtadvd.tproj/rtadvd.h @@ -54,7 +54,7 @@ #define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 #define MAX_INITIAL_RTR_ADVERTISEMENTS 3 -#define MAX_FINAL_RTR_ADVERTISEMENTS 3 +#define MAX_FINAL_RTR_ADVERTISEMENTS 1 #define MIN_DELAY_BETWEEN_RAS 3 #define MAX_RA_DELAY_TIME 500000 /* usec */ diff --git a/traceroute.tproj/traceroute.c b/traceroute.tproj/traceroute.c index ec6b958..d556fb4 100644 --- a/traceroute.tproj/traceroute.c +++ b/traceroute.tproj/traceroute.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2009 Apple Inc. All rights reserved. + * Copyright (c) 2004-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -792,6 +792,8 @@ main(int argc, char **argv) Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno)); exit(1); } + (void) setsockopt(s, SOL_SOCKET, SO_RECV_ANYIF, (char *)&on, + sizeof(on)); if (options & SO_DEBUG) (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); diff --git a/traceroute6.tproj/traceroute6.c b/traceroute6.tproj/traceroute6.c index 09c38f2..373b7c5 100644 --- a/traceroute6.tproj/traceroute6.c +++ b/traceroute6.tproj/traceroute6.c @@ -682,6 +682,8 @@ main(argc, argv) rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; rcvmhdr.msg_controllen = rcvcmsglen; + (void) setsockopt(rcvsock, SOL_SOCKET, SO_RECV_ANYIF, (char *)&on, + sizeof(on)); if (options & SO_DEBUG) (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); @@ -1394,7 +1396,7 @@ inetname(sa) first = 0; if (gethostname(domain, sizeof(domain)) == 0 && (cp = strchr(domain, '.'))) - (void) strlcpy(domain, cp + 1, sizeof(domain)); + (void) memmove(domain, cp + 1, strlen(cp + 1) + 1); else domain[0] = 0; }