]> git.saurik.com Git - apple/network_cmds.git/commitdiff
network_cmds-511.tar.gz macos-1012 macos-10121 macos-10122 macos-10123 os-x-1012 v511
authorApple <opensource@apple.com>
Sat, 11 Jun 2016 02:35:45 +0000 (02:35 +0000)
committerApple <opensource@apple.com>
Sat, 11 Jun 2016 02:35:45 +0000 (02:35 +0000)
25 files changed:
frame_delay/frame_delay.8 [new file with mode: 0644]
frame_delay/frame_delay.c [new file with mode: 0644]
ifconfig.tproj/af_inet6.c
ifconfig.tproj/ifconfig.8
ifconfig.tproj/ifconfig.c
ip6fw.tproj/ip6fw.8 [deleted file]
ip6fw.tproj/ip6fw.c [deleted file]
ipfw.tproj/ipfw.8 [deleted file]
ipfw.tproj/ipfw2.c [deleted file]
kdumpd.tproj/kdumpd.c
ndp.tproj/ndp.8
ndp.tproj/ndp.c
netstat.tproj/if.c
netstat.tproj/inet.c
netstat.tproj/inet6.c
netstat.tproj/mptcp.c
netstat.tproj/systm.c
netstat.tproj/unix.c
network_cmds.xcodeproj/project.pbxproj
ping.tproj/ping.8
ping.tproj/ping.c
ping6.tproj/ping6.8
ping6.tproj/ping6.c
pktmnglr/packet_mangler.c
route.tproj/route.c

diff --git a/frame_delay/frame_delay.8 b/frame_delay/frame_delay.8
new file mode 100644 (file)
index 0000000..0f454d5
--- /dev/null
@@ -0,0 +1,45 @@
+.Dd October 12, 2015
+.Dt FRAME_DELAY 8
+.Os Darwin
+.Sh NAME
+.Nm frame_delay
+.Nd Utility to measure TCP/UDP frame delay
+
+.Sh DESCRIPTION
+.Pp
+The
+.Nm
+utility is designed to measure the effect of latency on
+delivery of evenly spaced TCP/UDP frames. This can be latency induced
+due to buffering or protocol stack or network drivers.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl m
+Server/Client mode. Should be "server" or "client".
+.It Fl t
+TCP/UDP frame. Should be either "tcp" or "udp".
+.It Fl i
+(Client Only) Server ip address.
+.It Fl p
+Port number.
+.It Fl n
+Number of frames.
+.It Fl f
+Frame size.
+.It Fl d
+(Client only) Delay traffic class. Pick one from {BK_SYS, BK, BE, RD, QAM, AV, RV, VI, VO, CTL}.
+.El
+
+.Sh EXAMPLES
+.Pp
+Setup TCP server:
+.Dl "frame_delay -m server -t tcp -p 10010 -n 10 -f 1000"
+.Pp
+Setup corresponding TCP client:
+.Dl "frame_delay -m client -t tcp -i 127.0.0.1 -p 10010 -n 10 -f 1000 -d 2000  -k RD"
+
+.Sh AUTHORS
+.An Padma Bhooma ,
+.An Kang Sun ,
+.An Vincent Lubet .
\ No newline at end of file
diff --git a/frame_delay/frame_delay.c b/frame_delay/frame_delay.c
new file mode 100644 (file)
index 0000000..37a58b7
--- /dev/null
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2009-2015 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@
+ */
+
+/*
+ * Usage for frame_delay
+ *
+ * Server
+ *     ./frame_delay -m server -t <tcp/udp> -p <port> -n <num_frames> -f <frame_size>
+ *
+ * Client
+ *     ./frame_delay -m client -t <tcp/udp> -i <srv_ipv4_add> -p <srv_port> -n <num_frames> -f <frame_size> -d <delay_ms>  -k <traffic_class>
+ */
+
+/*
+ * TODO list :
+ *                             1. UDP fragmentation and reassembly
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+
+/* Server Static variable */
+static int so, srv_so;
+static int srv_port = 0;
+static struct sockaddr_in laddr, dst_addr;
+/* Client Static variable */
+static struct sockaddr_in srv_addr;
+static uint32_t tc = 0;
+/* Usage */
+void ErrorUsage(void);
+/* str2svc */
+uint32_t str2svc(const char *str);
+/* Show Stastics */
+void ShowStastics(int64_t *DiffsBuf, int num_frames);
+/* Returns difference between two timevals in microseconds */
+int64_t time_diff(struct timeval *b, struct timeval *a);
+/* tcp server */
+void tcpServer(int frame_size, int num_frames, char *buf, int64_t *DiffsBuf);
+/* udp server */
+void udpServer(int frame_size, int num_frames, char *buf, int64_t *DiffsBuf);
+/* tcp server */
+void tcpClient(int num_frames, int frame_size,
+                          const char *buf, struct timespec sleep_time);
+/* udp server */
+void udpClient(int num_frames, int frame_size,
+                          const char *buf, struct timespec sleep_time);
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+       int num_frames = 0, frame_size = 0, delay_ms = 0, rc = 0;
+       char *buf = NULL, ch, *type = NULL, *mode = NULL, *ip_addr = NULL;
+       int64_t *DiffsBuf;
+       struct timespec sleep_time;
+
+       while ((ch = getopt(argc, argv, "m:p:f:n:t:d:i:k:")) != -1) {
+               switch (ch) {
+                       case 'm': {
+                               mode = optarg;
+                               break;
+                       }
+                       case 'p': {
+                               srv_port = atoi(optarg);
+                               break;
+                       }
+                       case 'f' : {
+                               frame_size = atoi(optarg);
+                               break;
+                       }
+                       case 'n' : {
+                               num_frames = atoi(optarg);
+                               break;
+                       }
+                       case 'i': {
+                               ip_addr = optarg;
+                               bzero(&srv_addr, sizeof(srv_addr));
+                               rc = inet_aton(optarg, &srv_addr.sin_addr);
+                               if (rc == 0) {
+                                       perror("inet_ntoa failed");
+                                       exit(1);
+                               }
+                       }
+                       case 'd': {
+                               delay_ms = atoi(optarg);
+                               break;
+                       }
+                       case 't' : {
+                               type = optarg;
+                               break;
+                       }
+                       case 'k': {
+                               tc = str2svc(optarg);
+                               break;
+                       }
+                       default: {
+                               printf("Invalid option: %c\n", ch);
+                               ErrorUsage();
+                       }
+               }
+       }
+       /* General check for both server and client */
+       if (srv_port <= 0 || frame_size <= 0 || num_frames <= 0 || !mode || !type) {
+               ErrorUsage();
+       }
+       if ( strcmp(type, "tcp") != 0 && strcmp(type, "udp") != 0 ) {
+               ErrorUsage();
+       }
+       /* Allocate memory for buf */
+       buf = calloc(1, frame_size);
+       if (buf == NULL) {
+               printf("malloc failed\n");
+               exit(1);
+       }
+       if ( strcmp(mode, "server") == 0 ) {
+               /* Server */
+               printf("<LOG>   :   Start %s server on port %d with expected frame size of %d\n",
+                          type, srv_port, frame_size);
+               DiffsBuf = (int64_t *)calloc(num_frames, sizeof(int64_t));
+               if (DiffsBuf == NULL) {
+                       printf("malloc failed\n");
+                       exit(1);
+               }
+               if( strcmp(type, "tcp") == 0) {
+                       /* tcpServer */
+                       tcpServer(frame_size, num_frames, buf, DiffsBuf);
+               } else {
+                       /* updServer */
+                       udpServer(frame_size, num_frames, buf, DiffsBuf);
+               }
+       }
+       else if ( strcmp(mode, "client") == 0 ){
+               if ( !ip_addr || (tc > 0 && (tc < SO_TC_BK_SYS || tc > SO_TC_CTL)) ){
+                       ErrorUsage();
+                }
+               /* Client */
+               printf("<LOG>   :   Start sending %d %s frames to %s:%d with a frame size of %d\n",
+                          num_frames, type, ip_addr, srv_port, frame_size);
+               /* Resolving sleep time bug : delay_ms should just be calculated once */
+               bzero(&sleep_time, sizeof(sleep_time));
+               while (delay_ms >= 1000) {
+                       sleep_time.tv_sec++;
+                       delay_ms -= 1000;
+               }
+               sleep_time.tv_nsec = delay_ms * 1000 * 1000;
+               if( strcmp(type, "tcp") == 0) {
+                       /* Call TCP client */
+                       tcpClient(num_frames, frame_size, buf, sleep_time);
+               } else {
+                       /* Call UDP client */
+                       udpClient(num_frames, frame_size, buf, sleep_time);
+               }
+       } else {
+               ErrorUsage();
+       }
+}
+
+/* Error usage */
+void
+ErrorUsage(void) {
+       printf("Correct Usage");
+       printf("Server : frame_delay -m server -t <tcp/udp> -p <port> -n <num_frames> -f <frame_size>\n");
+       printf("Client : frame_delay -m client -t <tcp/udp> -i <srv_ipv4_add> -p <srv_port> -n <num_frames> -f <frame_size> -d <delay_ms>  -k <traffic_class>\n");
+       exit(1);
+}
+
+/* str2svc */
+uint32_t
+str2svc(const char *str)
+{
+       uint32_t svc;
+       char *endptr;
+
+       if (str == NULL || *str == '\0')
+               svc = UINT32_MAX;
+       else if (strcasecmp(str, "BK_SYS") == 0)
+               return SO_TC_BK_SYS;
+       else if (strcasecmp(str, "BK") == 0)
+               return SO_TC_BK;
+       else if (strcasecmp(str, "BE") == 0)
+               return SO_TC_BE;
+       else if (strcasecmp(str, "RD") == 0)
+               return SO_TC_RD;
+       else if (strcasecmp(str, "OAM") == 0)
+               return SO_TC_OAM;
+       else if (strcasecmp(str, "AV") == 0)
+               return SO_TC_AV;
+       else if (strcasecmp(str, "RV") == 0)
+               return SO_TC_RV;
+       else if (strcasecmp(str, "VI") == 0)
+               return SO_TC_VI;
+       else if (strcasecmp(str, "VO") == 0)
+               return SO_TC_VO;
+       else if (strcasecmp(str, "CTL") == 0)
+               return SO_TC_CTL;
+       else {
+               svc = (uint32_t)strtoul(str, &endptr, 0);
+               if (*endptr != '\0')
+                       svc = UINT32_MAX;
+       }
+       return (svc);
+}
+
+/* Show Stastics */
+void
+ShowStastics(int64_t *DiffsBuf, int num_frames) {
+       int i = 0;
+       int64_t sum = 0, mean = 0;
+
+       /* Mean */
+       while(i < num_frames)
+               sum += DiffsBuf[i++];
+       mean = sum / num_frames;
+       printf("<LOG>   :   Mean: %.2f usecs\n", sum / (double)num_frames);
+       /* Popular Standard Deviation */
+       i = 0;
+       sum = 0;
+       while(i < num_frames) {
+               sum += (DiffsBuf[i]-mean)*(DiffsBuf[i]-mean);
+               i++;
+       }
+       printf("<LOG>   :   Popular Standard Deviation: %.2f usecs\n",
+                  sqrt(sum/(double)num_frames));
+}
+
+/* Returns difference between two timevals in microseconds */
+int64_t
+time_diff(struct timeval *b, struct timeval *a)
+{
+       int64_t usecs;
+       usecs = (a->tv_sec - b->tv_sec) * 1000 * 1000;
+       usecs += (int64_t)(a->tv_usec - b->tv_usec);
+       return(usecs);
+}
+
+/* Server */
+
+/* tcp server */
+void
+tcpServer(int frame_size, int num_frames, char *buf, int64_t *DiffsBuf) {
+       int rc = 0, i = 0, ignore_count = 0;
+       uint32_t dst_len = 0;
+       struct timeval before, after;
+       ssize_t bytes;
+       int64_t usecs;
+       /* New change from Padama */
+       uint64_t prev_frame_ts = 0, prev_recv = 0, frame_ts = 0, cur_recv = 0;
+       uint64_t min_variation = 0, max_variation = 0, avg_variation = 0;
+
+       printf("<LOG>   :   TCP Server\n");
+       so = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       if (so == -1) {
+               perror("failed to create socket");
+               exit(1);
+       }
+       bzero(&laddr, sizeof(laddr));
+       laddr.sin_family = AF_INET;
+       laddr.sin_port = htons(srv_port);
+       rc = bind(so, (const struct sockaddr *)&laddr, sizeof(laddr));
+       if (rc != 0) {
+               perror("failed to bind");
+               exit(1);
+       }
+       rc = listen(so, 10);
+       if (rc != 0) {
+               perror("failed to listen");
+               exit(1);
+       }
+       srv_so = accept(so, (struct sockaddr *)&dst_addr, &dst_len);
+       if (srv_so == -1) {
+               perror("failed to accept");
+               exit(1);
+       }
+       while (1) {
+               if ( i == num_frames ) {
+                       printf("<LOG>   :   Completed\n");
+                       break;
+               }
+               printf("<LOG>   :   Waiting for receiving\n");
+               bzero(&before, sizeof(before));
+               bzero(&after, sizeof(after));
+               rc = gettimeofday(&before, NULL);
+               if (rc == -1) {
+                       perror("gettimeofday failed");
+                       exit(1);
+               }
+               bytes = recv(srv_so, buf, frame_size, MSG_WAITALL);
+               if (bytes == -1) {
+                       perror("recv failed");
+                       exit(1);
+               }
+               else if (bytes > 0 && bytes != frame_size) {
+                       printf("Client exited\n");
+                       printf("Didn't recv the complete frame, bytes %ld\n",
+                                  bytes);
+                       exit(1);
+               }
+               else if (bytes == 0) {
+                       break;
+               }
+               rc = gettimeofday(&after, NULL);
+               if (rc == -1) {
+                       perror("gettimeofday failed");
+                       exit(1);
+               }
+               cur_recv = after.tv_sec * 1000 * 1000 + after.tv_usec;
+               memcpy((void *)&frame_ts, buf, sizeof(frame_ts));
+               if (prev_frame_ts > 0) {
+                       int64_t d_variation = 0;
+                       d_variation = (int64_t)((cur_recv - prev_recv) -
+                                                                       (frame_ts - prev_frame_ts));
+                       /* printf("Frame %u ts %llu d_variation %lld usecs\n",
+                        i, frame_ts, d_variation);*/
+                       if (d_variation > 0) {
+                               if (min_variation == 0)
+                                       min_variation = d_variation;
+                               else
+                                       min_variation = ((min_variation <= d_variation) ?
+                                                                        min_variation : d_variation);
+                               max_variation = ((max_variation >= d_variation) ?
+                                                                max_variation : d_variation);
+                               avg_variation += d_variation;
+                       } else {
+                               ignore_count++;
+                       }
+               }
+               prev_recv = cur_recv;
+               prev_frame_ts = frame_ts;
+               ++i;
+               /* Compute the time differenc */
+               usecs = time_diff(&before, &after);
+               DiffsBuf[i] = usecs;
+               printf("<LOG>   :   Frame %d received after %lld usecs\n", i, usecs);
+       }
+       if (i != ignore_count)
+               avg_variation = avg_variation / (i - ignore_count);
+       else
+               avg_variation = 0;
+
+       printf("<LOG>   :   Received frames: %u\n", i);
+       printf("<LOG>   :   Ignored frames: %u\n", ignore_count);
+       printf("<LOG>   :   Minimum delay variation: %llu usecs\n", min_variation);
+       printf("<LOG>   :   Maximum delay variation: %llu usecs\n", max_variation);
+       printf("<LOG>   :   Average delay variation: %llu usecs\n", avg_variation);
+       ShowStastics(DiffsBuf, num_frames);
+}
+
+/* udp server */
+void
+udpServer(int frame_size, int num_frames, char *buf, int64_t *DiffsBuf) {
+       int rc = 0, i = 0, ignore_count = 0;
+       uint32_t dst_len = 0;
+       ssize_t bytes;
+       struct timeval before, after;
+       int64_t usecs;
+       /* New change from Padama */
+       uint64_t prev_frame_ts = 0, prev_recv = 0, frame_ts = 0, cur_recv = 0;
+       uint64_t min_variation = 0, max_variation = 0, avg_variation = 0;
+
+       printf("<LOG>   :   UDP Server\n");
+       so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (so == -1) {
+               perror("failed to create socket");
+               exit(1);
+       }
+       bzero(&laddr,sizeof(laddr));
+       laddr.sin_family = AF_INET;
+       laddr.sin_addr.s_addr=htonl(INADDR_ANY);
+       laddr.sin_port=htons(srv_port);
+       rc = bind(so, (struct sockaddr *)&laddr,sizeof(laddr));
+       if (rc != 0) {
+               perror("failed to bind");
+               exit(1);
+       }
+       while (1) {
+               if ( i == num_frames ) {
+                       printf("<LOG>   :   Completed\n");
+                       break;
+               }
+               printf("<LOG>   :   Waiting for receiving\n");
+               bzero(&before, sizeof(before));
+               bzero(&after, sizeof(after));
+               rc = gettimeofday(&before, NULL);
+               if (rc == -1) {
+                       perror("gettimeofday failed");
+                       exit(1);
+               }
+               bytes = recvfrom(so, buf, frame_size, 0, (struct sockaddr *)&dst_addr, &dst_len);
+               if (bytes == -1) {
+                       perror("recv failed");
+                       exit(1);
+               }
+               else if (bytes > 0 && bytes != frame_size) {
+                       printf("Client exited\n");
+                       printf("Didn't recv the complete frame, bytes %ld\n",
+                                  bytes);
+                       exit(1);
+               }
+               else if (bytes == 0) {
+                       break;
+               }
+               rc = gettimeofday(&after, NULL);
+               if (rc == -1) {
+                       perror("gettimeofday failed");
+                       exit(1);
+               }
+               cur_recv = after.tv_sec * 1000 * 1000 + after.tv_usec;
+               memcpy((void *)&frame_ts, buf, sizeof(frame_ts));
+               if (prev_frame_ts > 0) {
+                       int64_t d_variation = 0;
+
+                       d_variation = (int64_t)((cur_recv - prev_recv) -
+                                                                       (frame_ts - prev_frame_ts));
+                       /* printf("Frame %u ts %llu d_variation %lld usecs\n",
+                        i, frame_ts, d_variation);*/
+                       if (d_variation > 0) {
+                               if (min_variation == 0)
+                                       min_variation = d_variation;
+                               else
+                                       min_variation = ((min_variation <= d_variation) ?
+                                                                        min_variation : d_variation);
+                               max_variation = ((max_variation >= d_variation) ?
+                                                                max_variation : d_variation);
+                               avg_variation += d_variation;
+                       } else {
+                               ignore_count++;
+                       }
+               }
+               prev_recv = cur_recv;
+               prev_frame_ts = frame_ts;
+               ++i;
+               /* Compute the time differenc */
+               usecs = time_diff(&before, &after);
+               DiffsBuf[i] = usecs;
+               printf("<LOG>   :   Frame %d received after %lld usecs\n", i, usecs);
+       }
+       if (i != ignore_count)
+               avg_variation = avg_variation / (i - ignore_count);
+       else
+               avg_variation = 0;
+       printf("<LOG>   :   Received frames: %u\n", i);
+       printf("<LOG>   :   Ignored frames: %u\n", ignore_count);
+       printf("<LOG>   :   Minimum delay variation: %llu usecs\n", min_variation);
+       printf("<LOG>   :   Maximum delay variation: %llu usecs\n", max_variation);
+       printf("<LOG>   :   Average delay variation: %llu usecs\n", avg_variation);
+       ShowStastics(DiffsBuf, num_frames);
+}
+
+/* Client */
+void
+tcpClient(int num_frames, int frame_size,
+                          const char *buf, struct timespec sleep_time){
+       int rc = 0, i = 0;
+       ssize_t bytes;
+
+       printf("<LOG>   :   TCP Client\n");
+       so = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+       if (so <= 0) {
+               perror("creating socket failed");
+               exit(1);
+       }
+       srv_addr.sin_port = htons(srv_port);
+       srv_addr.sin_len = sizeof(srv_addr);
+       srv_addr.sin_family = AF_INET;
+       rc = connect(so, (const struct sockaddr *)&srv_addr,
+                                sizeof(srv_addr));
+       if (rc != 0) {
+               perror("connect failed");
+               exit(1);
+       }
+       if (tc > 0) {
+               rc = setsockopt(so, SOL_SOCKET, SO_TRAFFIC_CLASS, &tc,
+                                               sizeof(tc));
+               if (rc == -1) {
+                       perror("failed to set traffic class");
+                       exit(1);
+               }
+       }
+       for (i = 0; i < num_frames; ++i) {
+               struct timeval fts;
+               uint64_t frame_ts;
+               /* Add a timestamp to the frame */
+               rc = gettimeofday(&fts, NULL);
+               if (rc == -1) {
+                       perror("faile to get time of day");
+                       exit(1);
+               }
+               frame_ts = fts.tv_sec * 1000 * 1000 + fts.tv_usec;
+               memcpy((void *)buf, (const void *)&frame_ts, sizeof(frame_ts));
+               bytes = send(so, buf, frame_size, 0);
+               if (bytes == -1) {
+                       perror("send failed \n");
+                       exit(1);
+               }
+               if (bytes != frame_size) {
+                       printf("failed to send all bytes, sent %ld\n", bytes);
+                       exit (1);
+               }
+               rc = nanosleep(&sleep_time, NULL);
+               if (rc == -1) {
+                       perror("sleep failed");
+                       exit(1);
+               }
+               printf("<LOG>   :   Sent %u frames as a whole\n", (i + 1));
+       }
+}
+
+void
+udpClient(int num_frames, int frame_size,
+                          const char *buf, struct timespec sleep_time){
+       int rc = 0, i = 0;
+       ssize_t bytes;
+
+       printf("<LOG>   :   UDP Client\n");
+       so = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (so <= 0) {
+               perror("creating socket failed");
+               exit(1);
+       }
+       srv_addr.sin_port = htons(srv_port);
+       srv_addr.sin_len = sizeof(srv_addr);
+       srv_addr.sin_family = AF_INET;
+       if (tc > 0) {
+               rc = setsockopt(so, SOL_SOCKET, SO_TRAFFIC_CLASS, &tc,
+                                               sizeof(tc));
+               if (rc == -1) {
+                       perror("failed to set traffic class");
+                       exit(1);
+               }
+       }
+       for (i = 0; i < num_frames; ++i) {
+               struct timeval fts;
+               uint64_t frame_ts;
+               /* Add a timestamp to the frame */
+               rc = gettimeofday(&fts, NULL);
+               if (rc == -1) {
+                       perror("faile to get time of day");
+                       exit(1);
+               }
+               frame_ts = fts.tv_sec * 1000 * 1000 + fts.tv_usec;
+               memcpy((void *)buf, (const void *)&frame_ts, sizeof(frame_ts));
+               bytes = sendto(so, buf, frame_size, 0, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
+               if (bytes == -1) {
+                       perror("send failed \n");
+                       exit(1);
+               }
+               if (bytes != frame_size) {
+                       printf("failed to send all bytes, sent %ld\n", bytes);
+                       exit (1);
+               }
+               rc = nanosleep(&sleep_time, NULL);
+               if (rc == -1) {
+                       perror("sleep failed");
+                       exit(1);
+               }
+               printf("<LOG>   :   Sent %u frames as a whole\n", (i + 1));
+       }
+}
+
+
index 4a9c8fa28ee013e4602ea22de29366e7ea929bb0..d2a5b1be14338926af99fe28edb1c04ac0afb459 100644 (file)
@@ -83,7 +83,7 @@
 
 #define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \
        "\004IFDISABLED\005DONT_SET_IFROUTE\006PROXY_PREFIXES" \
 
 #define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \
        "\004IFDISABLED\005DONT_SET_IFROUTE\006PROXY_PREFIXES" \
-       "\007IGNORE_NA\010INSECURE"
+       "\007IGNORE_NA\010INSECURE\011REPLICATED\012DAD"
 
 static struct in6_ifreq in6_ridreq;
 static struct in6_aliasreq in6_addreq = 
 
 static struct in6_ifreq in6_ridreq;
 static struct in6_aliasreq in6_addreq = 
@@ -607,8 +607,8 @@ static struct cmd inet6_cmds[] = {
        DEF_CMD("-nud",         -ND6_IFF_PERFORMNUD,    setnd6flags),
        DEF_CMD("ifdisabled",   ND6_IFF_IFDISABLED,     setnd6flags),
        DEF_CMD("-ifdisabled",  -ND6_IFF_IFDISABLED,    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("replicated",   ND6_IFF_REPLICATED,     setnd6flags),
+       DEF_CMD("-replicated",  -ND6_IFF_REPLICATED,    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("proxy_prefixes", ND6_IFF_PROXY_PREFIXES,       setnd6flags),
        DEF_CMD("-proxy_prefixes", -ND6_IFF_PROXY_PREFIXES,     setnd6flags),
        DEF_CMD("insecure",     ND6_IFF_INSECURE,       setnd6flags),
@@ -618,6 +618,8 @@ static struct cmd inet6_cmds[] = {
        DEF_CMD("eui64",        0,                      setip6eui64),
        DEF_CMD("secured",      IN6_IFF_SECURED,        setip6flags),
        DEF_CMD("-secured",     -IN6_IFF_SECURED,       setip6flags),
        DEF_CMD("eui64",        0,                      setip6eui64),
        DEF_CMD("secured",      IN6_IFF_SECURED,        setip6flags),
        DEF_CMD("-secured",     -IN6_IFF_SECURED,       setip6flags),
+       DEF_CMD("dad",          ND6_IFF_DAD,            setnd6flags),
+       DEF_CMD("-dad",         -ND6_IFF_DAD,           setnd6flags),
 };
 
 static struct afswtch af_inet6 = {
 };
 
 static struct afswtch af_inet6 = {
index 6a7ea05bb0b51d8ad882f656c13238e40c2e9420..9b06f04fe70d5337d0f2c088e8b9ff3484f64209 100644 (file)
@@ -558,6 +558,16 @@ Do not disable all IPv6 communication on the interface.
 Disable the processing of Secure Neighbor Discovery (SEND).
 .It Cm -insecure
 Do not disabled the processing of Secure Neighbor Discovery (SEND).
 Disable the processing of Secure Neighbor Discovery (SEND).
 .It Cm -insecure
 Do not disabled the processing of Secure Neighbor Discovery (SEND).
+.It Cm dad
+Perform duplicate address detection (DAD).
+.It Cm -dad
+Do not perform duplicate address detection (DAD).
+.It Cm replicated
+Modify duplicate address detection (DAD) protocol to expect that interface
+configuration is replicated at a network sleep proxy. Ignores certain NA
+messages and disables optimistic DAD.
+.It Cm -replicated
+Do not use modified duplicated address detection (DAD) protocol.
 .El
 .Pp
 The following parameters are specific to link aggregate interfaces:
 .El
 .Pp
 The following parameters are specific to link aggregate interfaces:
index 1a708da087ed54f47bd612e910b3d98d417a8b3a..d20a2f7b84831dae01ec6a9ec68ffd6a35007cba 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -98,6 +98,7 @@ __unused static const char copyright[] =
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sysexits.h>
 
 #include "ifconfig.h"
 
 
 #include "ifconfig.h"
 
@@ -762,7 +763,6 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp)
                Perror(vname);
 }
 
                Perror(vname);
 }
 
-#ifdef SIOCGIFCAP
 void
 setifcap(const char *vname, int value, int s, const struct afswtch *afp)
 {
 void
 setifcap(const char *vname, int value, int s, const struct afswtch *afp)
 {
@@ -783,7 +783,6 @@ setifcap(const char *vname, int value, int s, const struct afswtch *afp)
        if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0)
                Perror(vname);
 }
        if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0)
                Perror(vname);
 }
-#endif
 
 static void
 setifmetric(const char *val, int dummy __unused, int s, 
 
 static void
 setifmetric(const char *val, int dummy __unused, int s, 
@@ -940,6 +939,33 @@ setthrottle(const char *val, int dummy __unused, int s,
        }
 }
 
        }
 }
 
+static void
+setdisableoutput(const char *val, int dummy __unused, int s,
+    const struct afswtch *afp)
+{
+       struct ifreq ifr;
+       char *cp;
+       errno = 0;
+       bzero(&ifr, sizeof (ifr));
+       strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+
+       ifr.ifr_ifru.ifru_disable_output = strtold(val, &cp);
+       if (val == cp || errno != 0) {
+               warn("Invalid value '%s'", val);
+               return;
+       }
+
+       if (ioctl(s, SIOCSIFDISABLEOUTPUT, &ifr) < 0 && errno != ENXIO) {
+               warn("ioctl set disable output");
+       } else if (errno == ENXIO) {
+               printf("output thread can not be disabled on %s\n", name);
+       } else {
+               printf("output %s on %s\n",
+                   ((ifr.ifr_ifru.ifru_disable_output == 0) ? "enabled" : "disabled"),
+                   name);
+       }
+}
+
 static void
 setlog(const char *val, int dummy __unused, int s,
     const struct afswtch *afp)
 static void
 setlog(const char *val, int dummy __unused, int s,
     const struct afswtch *afp)
@@ -981,6 +1007,19 @@ setexpensive(const char *vname, int value, int s, const struct afswtch *afp)
                Perror(vname);
 }
 
                Perror(vname);
 }
 
+void
+settimestamp(const char *vname, int value, int s, const struct afswtch *afp)
+{
+       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       
+       if (value == 0) {
+               if (ioctl(s, SIOCSIFTIMESTAMPDISABLE, (caddr_t)&ifr) < 0)
+                       Perror(vname);
+       } else {
+               if (ioctl(s, SIOCSIFTIMESTAMPENABLE, (caddr_t)&ifr) < 0)
+                       Perror(vname);
+       }
+}
 
 void
 setecnmode(const char *val, int dummy __unused, int s,
 
 void
 setecnmode(const char *val, int dummy __unused, int s,
@@ -1008,6 +1047,137 @@ setecnmode(const char *val, int dummy __unused, int s,
                Perror("ioctl(SIOCSECNMODE)");
 }
 
                Perror("ioctl(SIOCSECNMODE)");
 }
 
+#if defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED)
+
+void
+setqosmarking(const char *cmd, const char *arg, int s, const struct afswtch *afp)
+{
+       u_long ioc;
+
+#if (DEBUG | DEVELOPMENT)
+       printf("%s(%s, %s)\n", __func__, cmd, arg);
+#endif /* (DEBUG | DEVELOPMENT) */
+       
+       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       
+       if (strcmp(cmd, "mode") == 0) {
+               ioc = SIOCSQOSMARKINGMODE;
+               
+               if (strcmp(arg, "fastlane") == 0)
+                       ifr.ifr_qosmarking_mode = IFRTYPE_QOSMARKING_FASTLANE;
+               else if (strcasecmp(arg, "none") == 0 || strcasecmp(arg, "off") == 0)
+                       ifr.ifr_qosmarking_mode = IFRTYPE_QOSMARKING_MODE_NONE;
+               else
+                       err(EX_USAGE, "bad value for qosmarking mode: %s", arg);
+       } else if (strcmp(cmd, "enabled") == 0) {
+               ioc = SIOCSQOSMARKINGENABLED;
+               if (strcmp(arg, "1") == 0 || strcasecmp(arg, "on") == 0||
+                   strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0)
+                       ifr.ifr_qosmarking_enabled = 1;
+               else if (strcmp(arg, "0") == 0 || strcasecmp(arg, "off") == 0||
+                        strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0)
+                       ifr.ifr_qosmarking_enabled = 0;
+               else
+                       err(EX_USAGE, "bad value for qosmarking enabled: %s", arg);
+       } else {
+               err(EX_USAGE, "qosmarking takes mode or enabled");
+       }
+       
+       if (ioctl(s, ioc, (caddr_t)&ifr) < 0)
+               err(EX_OSERR, "ioctl(%s, %s)", cmd, arg);
+}
+
+void
+setfastlane(const char *cmd, const char *arg, int s, const struct afswtch *afp)
+{
+       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       
+       warnx("### fastlane is obsolete, use qosmarking ###");
+       
+       if (strcmp(cmd, "capable") == 0) {
+               if (strcmp(arg, "1") == 0 || strcasecmp(arg, "on") == 0||
+                   strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0)
+                       setqosmarking("mode", "fastlane", s, afp);
+               else if (strcmp(arg, "0") == 0 || strcasecmp(arg, "off") == 0||
+                        strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0)
+                       setqosmarking("mode", "off", s, afp);
+               else
+                       err(EX_USAGE, "bad value for fastlane %s", cmd);
+       } else if (strcmp(cmd, "enable") == 0) {
+               if (strcmp(arg, "1") == 0 || strcasecmp(arg, "on") == 0||
+                   strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0)
+                       setqosmarking("enabled", "1", s, afp);
+               else if (strcmp(arg, "0") == 0 || strcasecmp(arg, "off") == 0||
+                        strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0)
+                       setqosmarking("enabled", "0", s, afp);
+               else
+                       err(EX_USAGE, "bad value for fastlane %s", cmd);
+       } else {
+               err(EX_USAGE, "fastlane takes capable or enable");
+       }
+}
+
+#else /* defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED) */
+
+void
+setfastlane(const char *cmd, const char *arg, int s, const struct afswtch *afp)
+{
+       int value;
+       u_long ioc;
+       
+       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       
+       if (strcmp(cmd, "capable") == 0)
+               ioc = SIOCSFASTLANECAPABLE;
+       else if (strcmp(cmd, "enable") == 0)
+               ioc = SIOCSFASTLEENABLED;
+       else
+               err(EX_USAGE, "fastlane takes capable or enabled");
+       
+       if (strcmp(arg, "1") == 0 || strcasecmp(arg, "on") == 0||
+           strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0)
+               value = 1;
+       else if (strcmp(arg, "0") == 0 || strcasecmp(arg, "off") == 0||
+                strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0)
+               value = 0;
+       else
+               err(EX_USAGE, "bad value for fastlane %s", cmd);
+       
+       if (ioc == SIOCSFASTLANECAPABLE)
+               ifr.ifr_fastlane_capable = value;
+       else
+               ifr.ifr_fastlane_enabled = value;
+       
+       if (ioctl(s, ioc, (caddr_t)&ifr) < 0)
+               err(EX_OSERR, "ioctl(%s, %s)", cmd, arg);
+}
+
+
+void
+setqosmarking(const char *cmd, const char *arg, int s, const struct afswtch *afp)
+{
+       if (strcmp(cmd, "mode") == 0) {
+               if (strcmp(arg, "fastlane") == 0)
+                       setfastlane("capable", "on", s, afp);
+               else if (strcmp(arg, "none") == 0)
+                       setfastlane("capable", "off", s, afp);
+               else
+                       err(EX_USAGE, "bad value for qosmarking mode: %s", arg);
+       } else if (strcmp(cmd, "enabled") == 0) {
+               if (strcmp(arg, "1") == 0 || strcasecmp(arg, "on") == 0||
+                   strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0)
+                       setfastlane("enable", "on", s, afp);
+               else if (strcmp(arg, "0") == 0 || strcasecmp(arg, "off") == 0||
+                        strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0)
+                       setfastlane("enable", "off", s, afp);
+               else
+                       err(EX_USAGE, "bad value for qosmarking enabled: %s", arg);
+       } else {
+               err(EX_USAGE, "qosmarking takes mode or enabled");
+       }
+}
+
+#endif /* defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED) */
 
 #define        IFFBITS \
 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
 
 #define        IFFBITS \
 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
@@ -1015,14 +1185,15 @@ setecnmode(const char *val, int dummy __unused, int s,
 "\20MULTICAST"
 
 #define        IFEFBITS \
 "\20MULTICAST"
 
 #define        IFEFBITS \
-"\020\1AUTOCONFIGURING\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \
+"\020\1AUTOCONFIGURING\5FASTLN_CAP\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \
 "\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \
 "\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \
 "\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \
 "\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \
-"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\35SENDLIST\36DIRECTLINK\40UPDOWNCHANGE"
+"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\34CA\35SENDLIST\36DIRECTLINK" \
+"\37FASTLN_ON\40UPDOWNCHANGE"
 
 #define        IFCAPBITS \
 "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \
 
 #define        IFCAPBITS \
 "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \
-"\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS"
+"\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS\14HW_TIMESTAMP\15SW_TIMESTAMP"
 
 #define        IFRLOGF_BITS \
 "\020\1DLIL\21FAMILY\31DRIVER\35FIRMWARE"
 
 #define        IFRLOGF_BITS \
 "\020\1DLIL\21FAMILY\31DRIVER\35FIRMWARE"
@@ -1044,7 +1215,8 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
        struct ifmibdata_supplemental ifmsupp;
        size_t miblen = sizeof(struct ifmibdata_supplemental);
        u_int64_t eflags = 0;
        struct ifmibdata_supplemental ifmsupp;
        size_t miblen = sizeof(struct ifmibdata_supplemental);
        u_int64_t eflags = 0;
-
+       int curcap = 0;
+       
        if (afp == NULL) {
                allfamilies = 1;
                afp = af_getbyname("inet");
        if (afp == NULL) {
                allfamilies = 1;
                afp = af_getbyname("inet");
@@ -1067,11 +1239,11 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                printf(" mtu %d", ifr.ifr_mtu);
        if (showrtref && ioctl(s, SIOCGIFGETRTREFCNT, &ifr) != -1)
                printf(" rtref %d", ifr.ifr_route_refcnt);
                printf(" mtu %d", ifr.ifr_mtu);
        if (showrtref && ioctl(s, SIOCGIFGETRTREFCNT, &ifr) != -1)
                printf(" rtref %d", ifr.ifr_route_refcnt);
-    if (verbose) {
-        unsigned int ifindex = if_nametoindex(ifa->ifa_name);
-        if (ifindex != 0)
-            printf(" index %u", ifindex);
-    }
+       if (verbose) {
+               unsigned int ifindex = if_nametoindex(ifa->ifa_name);
+               if (ifindex != 0)
+                       printf(" index %u", ifindex);
+       }
        putchar('\n');
 
        if (verbose && ioctl(s, SIOCGIFEFLAGS, (caddr_t)&ifr) != -1 &&
        putchar('\n');
 
        if (verbose && ioctl(s, SIOCGIFEFLAGS, (caddr_t)&ifr) != -1 &&
@@ -1080,9 +1252,9 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                putchar('\n');
        }
 
                putchar('\n');
        }
 
-#ifdef SIOCGIFCAP      
        if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
                if (ifr.ifr_curcap != 0) {
        if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
                if (ifr.ifr_curcap != 0) {
+                       curcap = ifr.ifr_curcap;
                        printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
                        putchar('\n');
                }
                        printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
                        putchar('\n');
                }
@@ -1091,7 +1263,6 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                        putchar('\n');
                }
        }
                        putchar('\n');
                }
        }
-#endif
        
        tunnel_status(s);
 
        
        tunnel_status(s);
 
@@ -1402,7 +1573,7 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                        printf("\teffective interface: %s\n", delegatedif);
        }
 
                        printf("\teffective interface: %s\n", delegatedif);
        }
 
-       if(ioctl(s, SIOCGSTARTDELAY, &ifr) != -1) {
+       if (ioctl(s, SIOCGSTARTDELAY, &ifr) != -1) {
                if (ifr.ifr_start_delay_qlen > 0 &&
                    ifr.ifr_start_delay_timeout > 0) {
                        printf("\ttxstart qlen: %u packets "
                if (ifr.ifr_start_delay_qlen > 0 &&
                    ifr.ifr_start_delay_timeout > 0) {
                        printf("\ttxstart qlen: %u packets "
@@ -1411,7 +1582,32 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                            ifr.ifr_start_delay_timeout/1000);
                }
        }
                            ifr.ifr_start_delay_timeout/1000);
                }
        }
-
+#if defined(IFCAP_HW_TIMESTAMP) && defined(IFCAP_SW_TIMESTAMP)
+       if ((curcap & (IFCAP_HW_TIMESTAMP | IFCAP_SW_TIMESTAMP)) &&
+           ioctl(s, SIOCGIFTIMESTAMPENABLED, &ifr) != -1) {
+               printf("\ttimestamp: %s\n",
+                      (ifr.ifr_intval != 0) ? "enabled" : "disabled");
+       }
+#endif
+#if defined(SIOCGQOSMARKINGENABLED) && defined(SIOCGQOSMARKINGMODE)
+       if (ioctl(s, SIOCGQOSMARKINGENABLED, &ifr) != -1) {
+               printf("\tqosmarking enabled: %s mode: ",
+                      ifr.ifr_qosmarking_enabled ? "yes" : "no");
+               if (ioctl(s, SIOCGQOSMARKINGMODE, &ifr) != -1) {
+                       switch (ifr.ifr_qosmarking_mode) {
+                               case IFRTYPE_QOSMARKING_FASTLANE:
+                                       printf("fastlane\n");
+                                       break;
+                               case IFRTYPE_QOSMARKING_MODE_NONE:
+                                       printf("none\n");
+                                       break;
+                               default:
+                                       printf("unknown (%u)\n", ifr.ifr_qosmarking_mode);
+                                       break;
+                       }
+               }
+       }
+#endif /* defined(SIOCGQOSMARKINGENABLED) && defined(SIOCGQOSMARKINGMODE) */
 done:
        close(s);
        return;
 done:
        close(s);
        return;
@@ -1715,7 +1911,12 @@ static struct cmd basic_cmds[] = {
        DEF_CMD("-cl2k",        0,              setcl2k),
        DEF_CMD("expensive",    1,              setexpensive),
        DEF_CMD("-expensive",   0,              setexpensive),
        DEF_CMD("-cl2k",        0,              setcl2k),
        DEF_CMD("expensive",    1,              setexpensive),
        DEF_CMD("-expensive",   0,              setexpensive),
+       DEF_CMD("timestamp",    1,              settimestamp),
+       DEF_CMD("-timestamp",   0,              settimestamp),
        DEF_CMD_ARG("ecn",                      setecnmode),
        DEF_CMD_ARG("ecn",                      setecnmode),
+       DEF_CMD_ARG2("fastlane",                setfastlane),
+       DEF_CMD_ARG2("qosmarking",              setqosmarking),
+       DEF_CMD_ARG("disable_output",           setdisableoutput),
 };
 
 static __constructor void
 };
 
 static __constructor void
diff --git a/ip6fw.tproj/ip6fw.8 b/ip6fw.tproj/ip6fw.8
deleted file mode 100644 (file)
index 9915ea7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-.Dd September 27, 2012
-.Dt IP6FW 8
-.Os Darwin
-.Sh NAME
-.Nm ip6fw
-.Sh DESCRIPTION
-This utility is
-.Cm DEPRECATED.
-Please use
-.Xr pfctl 8
-instead.
diff --git a/ip6fw.tproj/ip6fw.c b/ip6fw.tproj/ip6fw.c
deleted file mode 100644 (file)
index baaa620..0000000
+++ /dev/null
@@ -1,1446 +0,0 @@
-/*
- * Copyright (c) 2009 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) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Idea and grammar partially left from:
- * Copyright (c) 1993 Daniel Boulet
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- *
- * NEW command line interface for IP firewall facility
- *
- * $Id: ip6fw.c,v 1.3 2006/02/07 06:22:17 lindak Exp $
- * $FreeBSD: src/sbin/ip6fw/ip6fw.c,v 1.1.2.6 2001/08/01 06:52:18 obrien Exp $
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <sysexits.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet6/ip6_fw.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-
-int            lineno = -1;
-
-int            s;                              /* main RAW socket         */
-int            do_resolv=0;                    /* Would try to resolv all */
-int            do_acct=0;                      /* Show packet/byte count  */
-int            do_time=0;                      /* Show time stamps        */
-int            do_quiet=0;                     /* Be quiet in add and flush  */
-int            do_force=0;                     /* Don't ask for confirmation */
-
-struct icmpcode {
-       int     code;
-       char    *str;
-};
-
-static struct icmpcode icmp6codes[] = {
-      { ICMP6_DST_UNREACH_NOROUTE,     "noroute" },
-      { ICMP6_DST_UNREACH_ADMIN,       "admin" },
-      { ICMP6_DST_UNREACH_NOTNEIGHBOR, "notneighbor" },
-      { ICMP6_DST_UNREACH_ADDR,                "addr" },
-      { ICMP6_DST_UNREACH_NOPORT,      "noport" },
-      { 0, NULL }
-};
-
-static char ntop_buf[INET6_ADDRSTRLEN];
-
-static void show_usage(const char *fmt, ...);
-
-static int
-mask_bits(u_char *m_ad, int m_len)
-{
-       int h_num = 0,i;
-
-       for (i = 0; i < m_len; i++, m_ad++) {
-               if (*m_ad != 0xff)
-                       break;
-               h_num += 8;
-       }
-       if (i < m_len) {
-               switch (*m_ad) {
-#define        MASKLEN(m, l)   case m: h_num += l; break
-               MASKLEN(0xfe, 7);
-               MASKLEN(0xfc, 6);
-               MASKLEN(0xf8, 5);
-               MASKLEN(0xf0, 4);
-               MASKLEN(0xe0, 3);
-               MASKLEN(0xc0, 2);
-               MASKLEN(0x80, 1);
-#undef MASKLEN
-               }
-       }
-       return h_num;
-}
-
-static int pl2m[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
-
-struct in6_addr *plen2mask(int n)
-{
-       static struct in6_addr ia;
-       u_char  *p;
-       int     i;
-
-       memset(&ia, 0, sizeof(struct in6_addr));
-       p = (u_char *)&ia;
-       for (i = 0; i < 16; i++, p++, n -= 8) {
-               if (n >= 8) {
-                       *p = 0xff;
-                       continue;
-               }
-               *p = pl2m[n];
-               break;
-       }
-       return &ia;
-}
-
-void
-print_port(prot, port, comma)
-       u_char  prot;
-       u_short port;
-       const char *comma;
-{
-       struct servent *se;
-       struct protoent *pe;
-       const char *protocol;
-       int printed = 0;
-
-       if (do_resolv) {
-               pe = getprotobynumber(prot);
-               if (pe)
-                       protocol = pe->p_name;
-               else
-                       protocol = NULL;
-
-               se = getservbyport(htons(port), protocol);
-               if (se) {
-                       printf("%s%s", comma, se->s_name);
-                       printed = 1;
-               }
-       }
-       if (!printed)
-               printf("%s%d",comma,port);
-}
-
-static void
-print_iface(char *key, union ip6_fw_if *un, int byname)
-{
-       char ifnb[IP6FW_IFNLEN+1];
-
-       if (byname) {
-               strncpy(ifnb, un->fu_via_if.name, IP6FW_IFNLEN);
-               ifnb[IP6FW_IFNLEN]='\0';
-               if (un->fu_via_if.unit == -1)
-                       printf(" %s %s*", key, ifnb);
-               else
-                       printf(" %s %s%d", key, ifnb, un->fu_via_if.unit);
-       } else if (!IN6_IS_ADDR_UNSPECIFIED(&un->fu_via_ip6)) {
-               printf(" %s %s", key, inet_ntop(AF_INET6,&un->fu_via_ip6,ntop_buf,sizeof(ntop_buf)));
-       } else
-               printf(" %s any", key);
-}
-
-static void
-print_reject_code(int code)
-{
-       struct icmpcode *ic;
-
-       for (ic = icmp6codes; ic->str; ic++)
-               if (ic->code == code) {
-                       printf("%s", ic->str);
-                       return;
-               }
-       printf("%u", code);
-}
-
-static void
-show_ip6fw(struct ip6_fw *chain)
-{
-       char *comma;
-       struct hostent *he;
-       struct protoent *pe;
-       int i, mb;
-       int nsp = IPV6_FW_GETNSRCP(chain);
-       int ndp = IPV6_FW_GETNDSTP(chain);
-
-       if (do_resolv)
-               setservent(1/*stayopen*/);
-
-       printf("%05u ", chain->fw_number);
-
-       if (do_acct)
-               printf("%10u %10u ",chain->fw_pcnt,chain->fw_bcnt);
-
-       if (do_time)
-       {
-               if (chain->timestamp)
-               {
-                       char timestr[30];
-
-                       strlcpy(timestr, ctime((time_t *)&chain->timestamp), sizeof(timestr));
-                       *strchr(timestr, '\n') = '\0';
-                       printf("%s ", timestr);
-               }
-               else
-                       printf("                         ");
-       }
-
-       switch (chain->fw_flg & IPV6_FW_F_COMMAND)
-       {
-               case IPV6_FW_F_ACCEPT:
-                       printf("allow");
-                       break;
-               case IPV6_FW_F_DENY:
-                       printf("deny");
-                       break;
-               case IPV6_FW_F_COUNT:
-                       printf("count");
-                       break;
-               case IPV6_FW_F_DIVERT:
-                       printf("divert %u", chain->fw_divert_port);
-                       break;
-               case IPV6_FW_F_TEE:
-                       printf("tee %u", chain->fw_divert_port);
-                       break;
-               case IPV6_FW_F_SKIPTO:
-                       printf("skipto %u", chain->fw_skipto_rule);
-                       break;
-               case IPV6_FW_F_REJECT:
-                       if (chain->fw_reject_code == IPV6_FW_REJECT_RST)
-                               printf("reset");
-                       else {
-                               printf("unreach ");
-                               print_reject_code(chain->fw_reject_code);
-                       }
-                       break;
-               default:
-                       errx(EX_OSERR, "impossible");
-       }
-
-       if (chain->fw_flg & IPV6_FW_F_PRN)
-               printf(" log");
-
-       pe = getprotobynumber(chain->fw_prot);
-       if (pe)
-               printf(" %s", pe->p_name);
-       else
-               printf(" %u", chain->fw_prot);
-
-       printf(" from %s", chain->fw_flg & IPV6_FW_F_INVSRC ? "not " : "");
-
-       mb=mask_bits((u_char *)&chain->fw_smsk,sizeof(chain->fw_smsk));
-       if (mb==128 && do_resolv) {
-               he=gethostbyaddr((char *)&(chain->fw_src),sizeof(chain->fw_src),AF_INET6);
-               if (he==NULL) {
-                       printf("%s", inet_ntop(AF_INET6,&chain->fw_src,ntop_buf,sizeof(ntop_buf)));
-               } else
-                       printf("%s",he->h_name);
-       } else {
-               if (mb!=128) {
-                       if (mb == 0) {
-                               printf("any");
-                       } else {
-                               printf("%s", inet_ntop(AF_INET6,&chain->fw_src,ntop_buf,sizeof(ntop_buf)));
-                               printf("/%d",mb);
-                       }
-               } else
-                       printf("%s", inet_ntop(AF_INET6,&chain->fw_src,ntop_buf,sizeof(ntop_buf)));
-       }
-
-       if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
-               comma = " ";
-               for (i = 0; i < nsp; i++) {
-                       print_port(chain->fw_prot, chain->fw_pts[i], comma);
-                       if (i==0 && (chain->fw_flg & IPV6_FW_F_SRNG))
-                               comma = "-";
-                       else
-                               comma = ",";
-               }
-       }
-
-       printf(" to %s", chain->fw_flg & IPV6_FW_F_INVDST ? "not " : "");
-
-       mb=mask_bits((u_char *)&chain->fw_dmsk,sizeof(chain->fw_dmsk));
-       if (mb==128 && do_resolv) {
-               he=gethostbyaddr((char *)&(chain->fw_dst),sizeof(chain->fw_dst),AF_INET);
-               if (he==NULL) {
-                       printf("%s", inet_ntop(AF_INET6,&chain->fw_dst,ntop_buf,sizeof(ntop_buf)));
-               } else
-                       printf("%s",he->h_name);
-       } else {
-               if (mb!=128) {
-                       if (mb == 0) {
-                               printf("any");
-                       } else {
-                               printf("%s", inet_ntop(AF_INET6,&chain->fw_dst,ntop_buf,sizeof(ntop_buf)));
-                               printf("/%d",mb);
-                       }
-               } else
-                       printf("%s", inet_ntop(AF_INET6,&chain->fw_dst,ntop_buf,sizeof(ntop_buf)));
-       }
-
-       if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
-               comma = " ";
-               for (i = 0; i < ndp; i++) {
-                       print_port(chain->fw_prot, chain->fw_pts[nsp+i], comma);
-                       if (i==0 && (chain->fw_flg & IPV6_FW_F_DRNG))
-                               comma = "-";
-                       else
-                               comma = ",";
-               }
-       }
-
-       /* Direction */
-       if ((chain->fw_flg & IPV6_FW_F_IN) && !(chain->fw_flg & IPV6_FW_F_OUT))
-               printf(" in");
-       if (!(chain->fw_flg & IPV6_FW_F_IN) && (chain->fw_flg & IPV6_FW_F_OUT))
-               printf(" out");
-
-       /* Handle hack for "via" backwards compatibility */
-       if ((chain->fw_flg & IF6_FW_F_VIAHACK) == IF6_FW_F_VIAHACK) {
-               print_iface("via",
-                   &chain->fw_in_if, chain->fw_flg & IPV6_FW_F_IIFNAME);
-       } else {
-               /* Receive interface specified */
-               if (chain->fw_flg & IPV6_FW_F_IIFACE)
-                       print_iface("recv", &chain->fw_in_if,
-                           chain->fw_flg & IPV6_FW_F_IIFNAME);
-               /* Transmit interface specified */
-               if (chain->fw_flg & IPV6_FW_F_OIFACE)
-                       print_iface("xmit", &chain->fw_out_if,
-                           chain->fw_flg & IPV6_FW_F_OIFNAME);
-       }
-
-       if (chain->fw_flg & IPV6_FW_F_FRAG)
-               printf(" frag");
-
-       if (chain->fw_ip6opt || chain->fw_ip6nopt) {
-               int     _opt_printed = 0;
-#define        PRINTOPT(x)     {if (_opt_printed) printf(",");\
-                       printf(x); _opt_printed = 1;}
-
-               printf(" ip6opt ");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_HOPOPT) PRINTOPT("hopopt");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_HOPOPT) PRINTOPT("!hopopt");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_ROUTE)  PRINTOPT("route");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_ROUTE)  PRINTOPT("!route");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_FRAG)  PRINTOPT("frag");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_FRAG)  PRINTOPT("!frag");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_ESP)    PRINTOPT("esp");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_ESP)    PRINTOPT("!esp");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_AH)     PRINTOPT("ah");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_AH)     PRINTOPT("!ah");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_NONXT)  PRINTOPT("nonxt");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_NONXT)  PRINTOPT("!nonxt");
-               if (chain->fw_ip6opt  & IPV6_FW_IP6OPT_OPTS)   PRINTOPT("opts");
-               if (chain->fw_ip6nopt & IPV6_FW_IP6OPT_OPTS)   PRINTOPT("!opts");
-       }
-
-       if (chain->fw_ipflg & IPV6_FW_IF_TCPEST)
-               printf(" established");
-       else if (chain->fw_tcpf == IPV6_FW_TCPF_SYN &&
-           chain->fw_tcpnf == IPV6_FW_TCPF_ACK)
-               printf(" setup");
-       else if (chain->fw_tcpf || chain->fw_tcpnf) {
-               int     _flg_printed = 0;
-#define        PRINTFLG(x)     {if (_flg_printed) printf(",");\
-                       printf(x); _flg_printed = 1;}
-
-               printf(" tcpflg ");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_FIN)  PRINTFLG("fin");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_FIN)  PRINTFLG("!fin");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_SYN)  PRINTFLG("syn");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_SYN)  PRINTFLG("!syn");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_RST)  PRINTFLG("rst");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_RST)  PRINTFLG("!rst");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_PSH)  PRINTFLG("psh");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_PSH)  PRINTFLG("!psh");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_ACK)  PRINTFLG("ack");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_ACK)  PRINTFLG("!ack");
-               if (chain->fw_tcpf  & IPV6_FW_TCPF_URG)  PRINTFLG("urg");
-               if (chain->fw_tcpnf & IPV6_FW_TCPF_URG)  PRINTFLG("!urg");
-       }
-       if (chain->fw_flg & IPV6_FW_F_ICMPBIT) {
-               int type_index;
-               int first = 1;
-
-               printf(" icmptype");
-
-               for (type_index = 0; type_index < IPV6_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8; ++type_index)
-                       if (chain->fw_icmp6types[type_index / (sizeof(unsigned) * 8)] &
-                               (1U << (type_index % (sizeof(unsigned) * 8)))) {
-                               printf("%c%d", first == 1 ? ' ' : ',', type_index);
-                               first = 0;
-                       }
-       }
-       printf("\n");
-       if (do_resolv)
-               endservent();
-}
-
-void
-list(ac, av)
-       int     ac;
-       char    **av;
-{
-       struct ip6_fw *r, *rules;
-       int l,i;
-       unsigned long rulenum;
-       int nalloc, maxbytes;
-       socklen_t bytes;
-
-       /* extract rules from kernel, resizing array as necessary */
-       rules = NULL;
-       nalloc = sizeof *rules;
-       bytes = nalloc;
-       maxbytes = 65536 * sizeof *rules;
-       while (bytes >= nalloc) {
-               nalloc = nalloc * 2 + 200;
-               bytes = nalloc;
-               if ((rules = realloc(rules, bytes)) == NULL)
-                       err(EX_OSERR, "realloc");
-               memset(rules, 0, sizeof *rules);
-               rules->version = IPV6_FW_CURRENT_API_VERSION;
-               i = getsockopt(s, IPPROTO_IPV6, IPV6_FW_GET, rules, &bytes);
-               if ((i < 0 && errno != EINVAL) || nalloc > maxbytes)
-                       err(EX_OSERR, "getsockopt(IPV6_FW_GET)");
-       }
-       if (!ac) {
-               /* display all rules */
-               for (r = rules, l = bytes; l >= sizeof rules[0];
-                        r++, l-=sizeof rules[0])
-                       show_ip6fw(r);
-       }
-       else {
-               /* display specific rules requested on command line */
-               int exitval = 0;
-
-               while (ac--) {
-                       char *endptr;
-                       int seen;
-
-                       /* convert command line rule # */
-                       rulenum = strtoul(*av++, &endptr, 10);
-                       if (*endptr) {
-                               exitval = 1;
-                               warn("invalid rule number: %s", av[-1]);
-                               continue;
-                       }
-                       seen = 0;
-                       for (r = rules, l = bytes;
-                                l >= sizeof rules[0] && r->fw_number <= rulenum;
-                                r++, l-=sizeof rules[0])
-                               if (rulenum == r->fw_number) {
-                                       show_ip6fw(r);
-                                       seen = 1;
-                               }
-                       if (!seen) {
-                               exitval = 1;
-                               warnx("rule %lu does not exist", rulenum);
-                       }
-               }
-               if (exitval != 0)
-                       exit(exitval);
-       }
-}
-
-static void
-show_usage(const char *fmt, ...)
-{
-       if (fmt) {
-               char buf[100];
-               va_list args;
-
-               va_start(args, fmt);
-               vsnprintf(buf, sizeof(buf), fmt, args);
-               va_end(args);
-               warnx("error: %s", buf);
-       }
-       fprintf(stderr, "usage: ip6fw [options]\n"
-"    flush\n"
-"    add [number] rule\n"
-"    delete number ...\n"
-"    list [number ...]\n"
-"    show [number ...]\n"
-"    zero [number ...]\n"
-"  rule:  action proto src dst extras...\n"
-"    action:\n"
-"      {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
-"       reset|count|skipto num} [log]\n"
-"    proto: {ipv6|tcp|udp|ipv6-icmp|<number>}\n"
-"    src: from [not] {any|ipv6[/prefixlen]} [{port|port-port},[port],...]\n"
-"    dst: to [not] {any|ipv6[/prefixlen]} [{port|port-port},[port],...]\n"
-"  extras:\n"
-"    fragment     (may not be used with ports or tcpflags)\n"
-"    in\n"
-"    out\n"
-"    {xmit|recv|via} {iface|ipv6|any}\n"
-"    {established|setup}\n"
-"    tcpflags [!]{syn|fin|rst|ack|psh|urg},...\n"
-"    ipv6options [!]{hopopt|route|frag|esp|ah|nonxt|opts},...\n"
-"    icmptypes {type[,type]}...\n");
-
-       exit(1);
-}
-
-static int
-lookup_host (host, addr, family)
-       char *host;
-       u_char *addr;
-{
-       struct hostent *he = gethostbyname2(host, family);
-
-       if (!he)
-               return(-1);
-
-       memcpy(addr, he->h_addr_list[0], he->h_length);
-
-       return(0);
-}
-
-void
-fill_ip6(ipno, mask, acp, avp)
-       struct in6_addr *ipno, *mask;
-       int *acp;
-       char ***avp;
-{
-       int ac = *acp;
-       char **av = *avp;
-       char *p = 0, md = 0;
-       int i;
-
-       if (ac && !strncmp(*av,"any",strlen(*av))) {
-               *ipno = *mask = in6addr_any; av++; ac--;
-       } else {
-               p = strchr(*av, '/');
-               if (p) {
-                       md = *p;
-                       *p++ = '\0';
-               }
-
-               if (lookup_host(*av, (u_char *)ipno, AF_INET6) != 0)
-                       show_usage("hostname ``%s'' unknown", *av);
-               switch (md) {
-                       case '/':
-                               if (atoi(p) == 0) {
-                                       *mask = in6addr_any;
-                               } else if (atoi(p) > 128) {
-                                       show_usage("bad width ``%s''", p);
-                               } else {
-                                       *mask = *(plen2mask(atoi(p)));
-                               }
-                               break;
-                       default:
-                               *mask = *(plen2mask(128));
-                               break;
-               }
-               for (i = 0; i < sizeof(*ipno); i++)
-                       ipno->s6_addr[i] &= mask->s6_addr[i];
-               av++;
-               ac--;
-       }
-       *acp = ac;
-       *avp = av;
-}
-
-static void
-fill_reject_code6(u_short *codep, char *str)
-{
-       struct icmpcode *ic;
-       u_long val;
-       char *s;
-
-       val = strtoul(str, &s, 0);
-       if (s != str && *s == '\0' && val < 0x100) {
-               *codep = val;
-               return;
-       }
-       for (ic = icmp6codes; ic->str; ic++)
-               if (!strcasecmp(str, ic->str)) {
-                       *codep = ic->code;
-                       return;
-               }
-       show_usage("unknown ICMP6 unreachable code ``%s''", str);
-}
-
-static void
-add_port(cnt, ptr, off, port)
-       u_short *cnt, *ptr, off, port;
-{
-       if (off + *cnt >= IPV6_FW_MAX_PORTS)
-               errx(1, "too many ports (max is %d)", IPV6_FW_MAX_PORTS);
-       ptr[off+*cnt] = port;
-       (*cnt)++;
-}
-
-static int
-lookup_port(const char *arg, int test, int nodash)
-{
-       int             val;
-       char            *earg, buf[32];
-       struct servent  *s;
-
-       snprintf(buf, sizeof(buf), "%s", arg);
-       buf[strcspn(arg, nodash ? "-," : ",")] = 0;
-       val = (int) strtoul(buf, &earg, 0);
-       if (!*buf || *earg) {
-               setservent(1);
-               if ((s = getservbyname(buf, NULL))) {
-                       val = htons(s->s_port);
-               } else {
-                       if (!test) {
-                               errx(1, "unknown port ``%s''", arg);
-                       }
-                       val = -1;
-               }
-       } else {
-               if (val < 0 || val > 0xffff) {
-                       if (!test) {
-                               errx(1, "port ``%s'' out of range", arg);
-                       }
-                       val = -1;
-               }
-       }
-       return(val);
-}
-
-int
-fill_port(cnt, ptr, off, arg)
-       u_short *cnt, *ptr, off;
-       char *arg;
-{
-       char *s;
-       int initial_range = 0;
-
-       s = arg + strcspn(arg, "-,");   /* first port name can't have a dash */
-       if (*s == '-') {
-               *s++ = '\0';
-               if (strchr(arg, ','))
-                       errx(1, "port range must be first in list");
-               add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0x0000);
-               arg = s;
-               s = strchr(arg,',');
-               if (s)
-                       *s++ = '\0';
-               add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0xffff);
-               arg = s;
-               initial_range = 1;
-       }
-       while (arg != NULL) {
-               s = strchr(arg,',');
-               if (s)
-                       *s++ = '\0';
-               add_port(cnt, ptr, off, lookup_port(arg, 0, 0));
-               arg = s;
-       }
-       return initial_range;
-}
-
-void
-fill_tcpflag(set, reset, vp)
-       u_char *set, *reset;
-       char **vp;
-{
-       char *p = *vp,*q;
-       u_char *d;
-
-       while (p && *p) {
-               struct tpcflags {
-                       char * name;
-                       u_char value;
-               } flags[] = {
-                       { "syn", IPV6_FW_TCPF_SYN },
-                       { "fin", IPV6_FW_TCPF_FIN },
-                       { "ack", IPV6_FW_TCPF_ACK },
-                       { "psh", IPV6_FW_TCPF_PSH },
-                       { "rst", IPV6_FW_TCPF_RST },
-                       { "urg", IPV6_FW_TCPF_URG }
-               };
-               int i;
-
-               if (*p == '!') {
-                       p++;
-                       d = reset;
-               } else {
-                       d = set;
-               }
-               q = strchr(p, ',');
-               if (q)
-                       *q++ = '\0';
-               for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
-                       if (!strncmp(p, flags[i].name, strlen(p))) {
-                               *d |= flags[i].value;
-                               break;
-                       }
-               if (i == sizeof(flags) / sizeof(flags[0]))
-                       show_usage("invalid tcp flag ``%s''", p);
-               p = q;
-       }
-}
-
-static void
-fill_ip6opt(u_char *set, u_char *reset, char **vp)
-{
-       char *p = *vp,*q;
-       u_char *d;
-
-       while (p && *p) {
-               if (*p == '!') {
-                       p++;
-                       d = reset;
-               } else {
-                       d = set;
-               }
-               q = strchr(p, ',');
-               if (q)
-                       *q++ = '\0';
-               if (!strncmp(p,"hopopt",strlen(p))) *d |= IPV6_FW_IP6OPT_HOPOPT;
-               if (!strncmp(p,"route",strlen(p)))  *d |= IPV6_FW_IP6OPT_ROUTE;
-               if (!strncmp(p,"frag",strlen(p)))   *d |= IPV6_FW_IP6OPT_FRAG;
-               if (!strncmp(p,"esp",strlen(p)))    *d |= IPV6_FW_IP6OPT_ESP;
-               if (!strncmp(p,"ah",strlen(p)))     *d |= IPV6_FW_IP6OPT_AH;
-               if (!strncmp(p,"nonxt",strlen(p)))  *d |= IPV6_FW_IP6OPT_NONXT;
-               if (!strncmp(p,"opts",strlen(p)))   *d |= IPV6_FW_IP6OPT_OPTS;
-               p = q;
-       }
-}
-
-void
-fill_icmptypes(types, vp, fw_flg)
-       unsigned *types;
-       char **vp;
-       u_short *fw_flg;
-{
-       char *c = *vp;
-
-       while (*c)
-       {
-               unsigned long icmptype;
-
-               if ( *c == ',' )
-                       ++c;
-
-               icmptype = strtoul(c, &c, 0);
-
-               if ( *c != ',' && *c != '\0' )
-                       show_usage("invalid ICMP6 type");
-
-               if (icmptype >= IPV6_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8)
-                       show_usage("ICMP6 type out of range");
-
-               types[icmptype / (sizeof(unsigned) * 8)] |=
-                       1U << (icmptype % (sizeof(unsigned) * 8));
-               *fw_flg |= IPV6_FW_F_ICMPBIT;
-       }
-}
-
-void
-delete(ac,av)
-       int ac;
-       char **av;
-{
-       struct ip6_fw rule;
-       int i;
-       int exitval = 0;
-
-       memset(&rule, 0, sizeof rule);
-       rule.version = IPV6_FW_CURRENT_API_VERSION;
-
-       av++; ac--;
-
-       /* Rule number */
-       while (ac && isdigit(**av)) {
-               rule.fw_number = atoi(*av); av++; ac--;
-               i = setsockopt(s, IPPROTO_IPV6, IPV6_FW_DEL, &rule, sizeof rule);
-               if (i) {
-                       exitval = 1;
-                       warn("rule %u: setsockopt(%s)", rule.fw_number, "IPV6_FW_DEL");
-               }
-       }
-       if (exitval != 0)
-               exit(exitval);
-}
-
-static void
-verify_interface(union ip6_fw_if *ifu)
-{
-       struct ifreq ifr;
-
-       /*
-        *      If a unit was specified, check for that exact interface.
-        *      If a wildcard was specified, check for unit 0.
-        */
-       snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d",
-                        ifu->fu_via_if.name,
-                        ifu->fu_via_if.unit == -1 ? 0 : ifu->fu_via_if.unit);
-
-       if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
-               warnx("warning: interface ``%s'' does not exist", ifr.ifr_name);
-}
-
-static void
-fill_iface(char *which, union ip6_fw_if *ifu, int *byname, int ac, char *arg)
-{
-       if (!ac)
-           show_usage("missing argument for ``%s''", which);
-
-       /* Parse the interface or address */
-       if (!strcmp(arg, "any")) {
-               ifu->fu_via_ip6 = in6addr_any;
-               *byname = 0;
-       } else if (!isdigit(*arg)) {
-               char *q;
-
-               *byname = 1;
-               strncpy(ifu->fu_via_if.name, arg, sizeof(ifu->fu_via_if.name));
-               ifu->fu_via_if.name[sizeof(ifu->fu_via_if.name) - 1] = '\0';
-               for (q = ifu->fu_via_if.name;
-                   *q && !isdigit(*q) && *q != '*'; q++)
-                       continue;
-               ifu->fu_via_if.unit = (*q == '*') ? -1 : atoi(q);
-               *q = '\0';
-               verify_interface(ifu);
-       } else if (inet_pton(AF_INET6, arg, &ifu->fu_via_ip6) != 1) {
-               show_usage("bad ip6 address ``%s''", arg);
-       } else
-               *byname = 0;
-}
-
-static void
-add(ac,av)
-       int ac;
-       char **av;
-{
-       struct ip6_fw rule;
-       int i;
-       u_char proto;
-       struct protoent *pe;
-       int saw_xmrc = 0, saw_via = 0;
-
-       memset(&rule, 0, sizeof rule);
-       rule.version = IPV6_FW_CURRENT_API_VERSION;
-
-       av++; ac--;
-
-       /* Rule number */
-       if (ac && isdigit(**av)) {
-               rule.fw_number = atoi(*av); av++; ac--;
-       }
-
-       /* Action */
-       if (ac == 0)
-               show_usage("missing action");
-       if (!strncmp(*av,"accept",strlen(*av))
-                   || !strncmp(*av,"pass",strlen(*av))
-                   || !strncmp(*av,"allow",strlen(*av))
-                   || !strncmp(*av,"permit",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_ACCEPT; av++; ac--;
-       } else if (!strncmp(*av,"count",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_COUNT; av++; ac--;
-       }
-#if 0
-       else if (!strncmp(*av,"divert",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_DIVERT; av++; ac--;
-               if (!ac)
-                       show_usage("missing divert port");
-               rule.fw_divert_port = strtoul(*av, NULL, 0); av++; ac--;
-               if (rule.fw_divert_port == 0) {
-                       struct servent *s;
-                       setservent(1);
-                       s = getservbyname(av[-1], "divert");
-                       if (s != NULL)
-                               rule.fw_divert_port = ntohs(s->s_port);
-                       else
-                               show_usage("illegal divert port");
-               }
-       } else if (!strncmp(*av,"tee",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_TEE; av++; ac--;
-               if (!ac)
-                       show_usage("missing divert port");
-               rule.fw_divert_port = strtoul(*av, NULL, 0); av++; ac--;
-               if (rule.fw_divert_port == 0) {
-                       struct servent *s;
-                       setservent(1);
-                       s = getservbyname(av[-1], "divert");
-                       if (s != NULL)
-                               rule.fw_divert_port = ntohs(s->s_port);
-                       else
-                               show_usage("illegal divert port");
-               }
-       }
-#endif
-       else if (!strncmp(*av,"skipto",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_SKIPTO; av++; ac--;
-               if (!ac)
-                       show_usage("missing skipto rule number");
-               rule.fw_skipto_rule = strtoul(*av, NULL, 0); av++; ac--;
-       } else if ((!strncmp(*av,"deny",strlen(*av))
-                   || !strncmp(*av,"drop",strlen(*av)))) {
-               rule.fw_flg |= IPV6_FW_F_DENY; av++; ac--;
-       } else if (!strncmp(*av,"reject",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_REJECT; av++; ac--;
-               rule.fw_reject_code = ICMP6_DST_UNREACH_NOROUTE;
-       } else if (!strncmp(*av,"reset",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_REJECT; av++; ac--;
-               rule.fw_reject_code = IPV6_FW_REJECT_RST;       /* check TCP later */
-       } else if (!strncmp(*av,"unreach",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_REJECT; av++; ac--;
-               fill_reject_code6(&rule.fw_reject_code, *av); av++; ac--;
-       } else {
-               show_usage("invalid action ``%s''", *av);
-       }
-
-       /* [log] */
-       if (ac && !strncmp(*av,"log",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_PRN; av++; ac--;
-       }
-
-       /* protocol */
-       if (ac == 0)
-               show_usage("missing protocol");
-       if ((proto = atoi(*av)) > 0) {
-               rule.fw_prot = proto; av++; ac--;
-       } else if (!strncmp(*av,"all",strlen(*av))) {
-               rule.fw_prot = IPPROTO_IPV6; av++; ac--;
-       } else if ((pe = getprotobyname(*av)) != NULL) {
-               rule.fw_prot = pe->p_proto; av++; ac--;
-       } else {
-               show_usage("invalid protocol ``%s''", *av);
-       }
-
-       if (rule.fw_prot != IPPROTO_TCP
-           && (rule.fw_flg & IPV6_FW_F_COMMAND) == IPV6_FW_F_REJECT
-           && rule.fw_reject_code == IPV6_FW_REJECT_RST)
-               show_usage("``reset'' is only valid for tcp packets");
-
-       /* from */
-       if (ac && !strncmp(*av,"from",strlen(*av))) { av++; ac--; }
-       else
-               show_usage("missing ``from''");
-
-       if (ac && !strncmp(*av,"not",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_INVSRC;
-               av++; ac--;
-       }
-       if (!ac)
-               show_usage("missing arguments");
-
-       fill_ip6(&rule.fw_src, &rule.fw_smsk, &ac, &av);
-
-       if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
-               u_short nports = 0;
-
-               if (fill_port(&nports, rule.fw_pts, 0, *av))
-                       rule.fw_flg |= IPV6_FW_F_SRNG;
-               IPV6_FW_SETNSRCP(&rule, nports);
-               av++; ac--;
-       }
-
-       /* to */
-       if (ac && !strncmp(*av,"to",strlen(*av))) { av++; ac--; }
-       else
-               show_usage("missing ``to''");
-
-       if (ac && !strncmp(*av,"not",strlen(*av))) {
-               rule.fw_flg |= IPV6_FW_F_INVDST;
-               av++; ac--;
-       }
-       if (!ac)
-               show_usage("missing arguments");
-
-       fill_ip6(&rule.fw_dst, &rule.fw_dmsk, &ac, &av);
-
-       if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
-               u_short nports = 0;
-
-               if (fill_port(&nports,
-                   rule.fw_pts, IPV6_FW_GETNSRCP(&rule), *av))
-                       rule.fw_flg |= IPV6_FW_F_DRNG;
-               IPV6_FW_SETNDSTP(&rule, nports);
-               av++; ac--;
-       }
-
-       if ((rule.fw_prot != IPPROTO_TCP) && (rule.fw_prot != IPPROTO_UDP)
-           && (IPV6_FW_GETNSRCP(&rule) || IPV6_FW_GETNDSTP(&rule))) {
-               show_usage("only TCP and UDP protocols are valid"
-                   " with port specifications");
-       }
-
-       while (ac) {
-               if (!strncmp(*av,"in",strlen(*av))) {
-                       rule.fw_flg |= IPV6_FW_F_IN;
-                       av++; ac--; continue;
-               }
-               if (!strncmp(*av,"out",strlen(*av))) {
-                       rule.fw_flg |= IPV6_FW_F_OUT;
-                       av++; ac--; continue;
-               }
-               if (ac && !strncmp(*av,"xmit",strlen(*av))) {
-                       union ip6_fw_if ifu;
-                       int byname;
-
-                       if (saw_via) {
-badviacombo:
-                               show_usage("``via'' is incompatible"
-                                   " with ``xmit'' and ``recv''");
-                       }
-                       saw_xmrc = 1;
-                       av++; ac--;
-                       fill_iface("xmit", &ifu, &byname, ac, *av);
-                       rule.fw_out_if = ifu;
-                       rule.fw_flg |= IPV6_FW_F_OIFACE;
-                       if (byname)
-                               rule.fw_flg |= IPV6_FW_F_OIFNAME;
-                       av++; ac--; continue;
-               }
-               if (ac && !strncmp(*av,"recv",strlen(*av))) {
-                       union ip6_fw_if ifu;
-                       int byname;
-
-                       if (saw_via)
-                               goto badviacombo;
-                       saw_xmrc = 1;
-                       av++; ac--;
-                       fill_iface("recv", &ifu, &byname, ac, *av);
-                       rule.fw_in_if = ifu;
-                       rule.fw_flg |= IPV6_FW_F_IIFACE;
-                       if (byname)
-                               rule.fw_flg |= IPV6_FW_F_IIFNAME;
-                       av++; ac--; continue;
-               }
-               if (ac && !strncmp(*av,"via",strlen(*av))) {
-                       union ip6_fw_if ifu;
-                       int byname = 0;
-
-                       if (saw_xmrc)
-                               goto badviacombo;
-                       saw_via = 1;
-                       av++; ac--;
-                       fill_iface("via", &ifu, &byname, ac, *av);
-                       rule.fw_out_if = rule.fw_in_if = ifu;
-                       if (byname)
-                               rule.fw_flg |=
-                                   (IPV6_FW_F_IIFNAME | IPV6_FW_F_OIFNAME);
-                       av++; ac--; continue;
-               }
-               if (!strncmp(*av,"fragment",strlen(*av))) {
-                       rule.fw_flg |= IPV6_FW_F_FRAG;
-                       av++; ac--; continue;
-               }
-               if (!strncmp(*av,"ipv6options",strlen(*av))) {
-                       av++; ac--;
-                       if (!ac)
-                               show_usage("missing argument"
-                                   " for ``ipv6options''");
-                       fill_ip6opt(&rule.fw_ip6opt, &rule.fw_ip6nopt, av);
-                       av++; ac--; continue;
-               }
-               if (rule.fw_prot == IPPROTO_TCP) {
-                       if (!strncmp(*av,"established",strlen(*av))) {
-                               rule.fw_ipflg |= IPV6_FW_IF_TCPEST;
-                               av++; ac--; continue;
-                       }
-                       if (!strncmp(*av,"setup",strlen(*av))) {
-                               rule.fw_tcpf  |= IPV6_FW_TCPF_SYN;
-                               rule.fw_tcpnf  |= IPV6_FW_TCPF_ACK;
-                               av++; ac--; continue;
-                       }
-                       if (!strncmp(*av,"tcpflags",strlen(*av))) {
-                               av++; ac--;
-                               if (!ac)
-                                       show_usage("missing argument"
-                                           " for ``tcpflags''");
-                               fill_tcpflag(&rule.fw_tcpf, &rule.fw_tcpnf, av);
-                               av++; ac--; continue;
-                       }
-               }
-               if (rule.fw_prot == IPPROTO_ICMPV6) {
-                       if (!strncmp(*av,"icmptypes",strlen(*av))) {
-                               av++; ac--;
-                               if (!ac)
-                                       show_usage("missing argument"
-                                           " for ``icmptypes''");
-                               fill_icmptypes(rule.fw_icmp6types,
-                                   av, &rule.fw_flg);
-                               av++; ac--; continue;
-                       }
-               }
-               show_usage("unknown argument ``%s''", *av);
-       }
-
-       /* No direction specified -> do both directions */
-       if (!(rule.fw_flg & (IPV6_FW_F_OUT|IPV6_FW_F_IN)))
-               rule.fw_flg |= (IPV6_FW_F_OUT|IPV6_FW_F_IN);
-
-       /* Sanity check interface check, but handle "via" case separately */
-       if (saw_via) {
-               if (rule.fw_flg & IPV6_FW_F_IN)
-                       rule.fw_flg |= IPV6_FW_F_IIFACE;
-               if (rule.fw_flg & IPV6_FW_F_OUT)
-                       rule.fw_flg |= IPV6_FW_F_OIFACE;
-       } else if ((rule.fw_flg & IPV6_FW_F_OIFACE) && (rule.fw_flg & IPV6_FW_F_IN))
-               show_usage("can't check xmit interface of incoming packets");
-
-       /* frag may not be used in conjunction with ports or TCP flags */
-       if (rule.fw_flg & IPV6_FW_F_FRAG) {
-               if (rule.fw_tcpf || rule.fw_tcpnf)
-                       show_usage("can't mix 'frag' and tcpflags");
-
-               if (rule.fw_nports)
-                       show_usage("can't mix 'frag' and port specifications");
-       }
-
-       i = setsockopt(s, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof rule);
-       if (i)
-               err(EX_UNAVAILABLE, "setsockopt(%s)", "IPV6_FW_ADD");
-       if (!do_quiet)
-               show_ip6fw(&rule);
-}
-
-static void
-zero (ac, av)
-       int ac;
-       char **av;
-{
-       struct ip6_fw rule;
-
-       av++; ac--;
-       memset(&rule, 0, sizeof rule);
-       rule.version = IPV6_FW_CURRENT_API_VERSION;
-
-       if (!ac) {
-               /* clear all entries */
-               if (setsockopt(s, IPPROTO_IPV6, IPV6_FW_ZERO, &rule, sizeof rule) < 0)
-                       err(EX_UNAVAILABLE, "setsockopt(%s)", "IPV6_FW_ZERO");
-               if (!do_quiet)
-                       printf("Accounting cleared.\n");
-       } else {
-               int failed = 0;
-
-               while (ac) {
-                       /* Rule number */
-                       if (isdigit(**av)) {
-                               rule.fw_number = atoi(*av); av++; ac--;
-                               if (setsockopt(s, IPPROTO_IPV6,
-                                   IPV6_FW_ZERO, &rule, sizeof rule)) {
-                                       warn("rule %u: setsockopt(%s)", rule.fw_number,
-                                                "IPV6_FW_ZERO");
-                                       failed = 1;
-                               }
-                               else if (!do_quiet)
-                                       printf("Entry %d cleared\n",
-                                           rule.fw_number);
-                       } else
-                               show_usage("invalid rule number ``%s''", *av);
-               }
-               if (failed != 0)
-                       exit(failed);
-       }
-}
-
-int
-ip6fw_main(ac,av)
-       int     ac;
-       char    **av;
-{
-       int             ch;
-       extern int      optind;
-
-       /* init optind to 1 */
-       optind = 1;
-
-       if ( ac == 1 ) {
-               show_usage(NULL);
-       }
-
-       /* Set the force flag for non-interactive processes */
-       do_force = !isatty(STDIN_FILENO);
-
-       while ((ch = getopt(ac, av ,"afqtN")) != -1)
-       switch(ch) {
-               case 'a':
-                       do_acct=1;
-                       break;
-               case 'f':
-                       do_force=1;
-                       break;
-               case 'q':
-                       do_quiet=1;
-                       break;
-               case 't':
-                       do_time=1;
-                       break;
-               case 'N':
-                       do_resolv=1;
-                       break;
-               default:
-                       show_usage(NULL);
-       }
-
-       ac -= optind;
-       if (*(av+=optind)==NULL) {
-                show_usage("Bad arguments");
-       }
-
-       if (!strncmp(*av, "add", strlen(*av))) {
-               add(ac,av);
-       } else if (!strncmp(*av, "delete", strlen(*av))) {
-               delete(ac,av);
-       } else if (!strncmp(*av, "flush", strlen(*av))) {
-               int do_flush = 0;
-
-               if ( do_force || do_quiet )
-                       do_flush = 1;
-               else {
-                       int c;
-
-                       /* Ask the user */
-                       printf("Are you sure? [yn] ");
-                       do {
-                               fflush(stdout);
-                               c = toupper(getc(stdin));
-                               while (c != '\n' && getc(stdin) != '\n')
-                                       if (feof(stdin))
-                                               return (0);
-                       } while (c != 'Y' && c != 'N');
-                       printf("\n");
-                       if (c == 'Y')
-                               do_flush = 1;
-               }
-               if ( do_flush ) {
-                       struct ip6_fw rule;
-
-                       memset(&rule, 0, sizeof rule);
-                       rule.version = IPV6_FW_CURRENT_API_VERSION;
-                       if (setsockopt(s, IPPROTO_IPV6, IPV6_FW_FLUSH, &rule, sizeof rule) < 0)
-                               err(EX_UNAVAILABLE, "setsockopt(%s)", "IPV6_FW_FLUSH");
-                       if (!do_quiet)
-                               printf("Flushed all rules.\n");
-               }
-       } else if (!strncmp(*av, "zero", strlen(*av))) {
-               zero(ac,av);
-       } else if (!strncmp(*av, "print", strlen(*av))) {
-               list(--ac,++av);
-       } else if (!strncmp(*av, "list", strlen(*av))) {
-               list(--ac,++av);
-       } else if (!strncmp(*av, "show", strlen(*av))) {
-               do_acct++;
-               list(--ac,++av);
-       } else {
-               show_usage("Bad arguments");
-       }
-       return 0;
-}
-
-int
-main(ac, av)
-       int     ac;
-       char    **av;
-{
-#define        MAX_ARGS        32
-#define        WHITESP         " \t\f\v\n\r"
-       char    buf[BUFSIZ];
-       char    *a, *p, *args[MAX_ARGS], *cmd = NULL;
-       char    linename[16];
-       int     i, c, lineno, qflag, pflag, status;
-       FILE    *f = NULL;
-       pid_t   preproc = 0;
-
-       s = socket( AF_INET6, SOCK_RAW, IPPROTO_RAW );
-       if ( s < 0 )
-               err(EX_UNAVAILABLE, "socket");
-
-       setbuf(stdout,0);
-
-       /*
-        * Only interpret the last command line argument as a file to
-        * be preprocessed if it is specified as an absolute pathname.
-        */
-
-       if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0) {
-               qflag = pflag = i = 0;
-               lineno = 0;
-
-               while ((c = getopt(ac, av, "D:U:p:q")) != -1)
-                       switch(c) {
-                       case 'D':
-                               if (!pflag)
-                                       errx(EX_USAGE, "-D requires -p");
-                               if (i > MAX_ARGS - 2)
-                                       errx(EX_USAGE,
-                                            "too many -D or -U options");
-                               args[i++] = "-D";
-                               args[i++] = optarg;
-                               break;
-
-                       case 'U':
-                               if (!pflag)
-                                       errx(EX_USAGE, "-U requires -p");
-                               if (i > MAX_ARGS - 2)
-                                       errx(EX_USAGE,
-                                            "too many -D or -U options");
-                               args[i++] = "-U";
-                               args[i++] = optarg;
-                               break;
-
-                       case 'p':
-                               pflag = 1;
-                               cmd = optarg;
-                               args[0] = cmd;
-                               i = 1;
-                               break;
-
-                       case 'q':
-                               qflag = 1;
-                               break;
-
-                       default:
-                               show_usage(NULL);
-                       }
-
-               av += optind;
-               ac -= optind;
-               if (ac != 1)
-                       show_usage("extraneous filename arguments");
-
-               if ((f = fopen(av[0], "r")) == NULL)
-                       err(EX_UNAVAILABLE, "fopen: %s", av[0]);
-
-               if (pflag) {
-                       /* pipe through preprocessor (cpp or m4) */
-                       int pipedes[2];
-
-                       args[i] = 0;
-
-                       if (pipe(pipedes) == -1)
-                               err(EX_OSERR, "cannot create pipe");
-
-                       switch((preproc = fork())) {
-                       case -1:
-                               err(EX_OSERR, "cannot fork");
-
-                       case 0:
-                               /* child */
-                               if (dup2(fileno(f), 0) == -1 ||
-                                   dup2(pipedes[1], 1) == -1)
-                                       err(EX_OSERR, "dup2()");
-                               fclose(f);
-                               close(pipedes[1]);
-                               close(pipedes[0]);
-                               execvp(cmd, args);
-                               err(EX_OSERR, "execvp(%s) failed", cmd);
-
-                       default:
-                               /* parent */
-                               fclose(f);
-                               close(pipedes[1]);
-                               if ((f = fdopen(pipedes[0], "r")) == NULL) {
-                                       int savederrno = errno;
-
-                                       (void)kill(preproc, SIGTERM);
-                                       errno = savederrno;
-                                       err(EX_OSERR, "fdopen()");
-                               }
-                       }
-               }
-
-               while (fgets(buf, BUFSIZ, f)) {
-                       lineno++;
-                       snprintf(linename, sizeof(linename), "Line %d", lineno);
-                       args[0] = linename;
-
-                       if (*buf == '#')
-                               continue;
-                       if ((p = strchr(buf, '#')) != NULL)
-                               *p = '\0';
-                       i=1;
-                       if (qflag) args[i++]="-q";
-                       for (a = strtok(buf, WHITESP);
-                           a && i < MAX_ARGS; a = strtok(NULL, WHITESP), i++)
-                               args[i] = a;
-                       if (i == (qflag? 2: 1))
-                               continue;
-                       if (i == MAX_ARGS)
-                               errx(EX_USAGE, "%s: too many arguments", linename);
-                       args[i] = NULL;
-
-                       ip6fw_main(i, args);
-               }
-               fclose(f);
-               if (pflag) {
-                       if (waitpid(preproc, &status, 0) != -1) {
-                               if (WIFEXITED(status)) {
-                                       if (WEXITSTATUS(status) != EX_OK)
-                                               errx(EX_UNAVAILABLE,
-                                                    "preprocessor exited with status %d",
-                                                    WEXITSTATUS(status));
-                               } else if (WIFSIGNALED(status)) {
-                                       errx(EX_UNAVAILABLE,
-                                            "preprocessor exited with signal %d",
-                                            WTERMSIG(status));
-                               }
-                       }
-               }
-       } else
-               ip6fw_main(ac,av);
-       return 0;
-}
diff --git a/ipfw.tproj/ipfw.8 b/ipfw.tproj/ipfw.8
deleted file mode 100644 (file)
index 71e3aed..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-.Dd September 27, 2012
-.Dt IPFW 8
-.Os Darwin
-.Sh NAME
-.Nm ipfw
-.Sh DESCRIPTION
-This utility is
-.Cm DEPRECATED.
-Please use
-.Xr pfctl 8
-instead.
diff --git a/ipfw.tproj/ipfw2.c b/ipfw.tproj/ipfw2.c
deleted file mode 100644 (file)
index c6c35af..0000000
+++ /dev/null
@@ -1,4064 +0,0 @@
-/*
- * Copyright (c) 2002-2009 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) 2002-2003 Luigi Rizzo
- * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Idea and grammar partially left from:
- * Copyright (c) 1993 Daniel Boulet
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- *
- * NEW command line interface for IP firewall facility
- *
- * $FreeBSD: /repoman/r/ncvs/src/sbin/ipfw/ipfw2.c,v 1.4.2.18 2003/09/15 10:27:03 luigi Exp $
- */
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <grp.h>
-#include <limits.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <sysexits.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#define IPFW2
-#include <netinet/ip_fw.h>
-#undef IPFW2
-#include <net/route.h> /* def. of struct route */
-#include <netinet/ip_dummynet.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-
-int
-               do_resolv,              /* Would try to resolve all */
-               do_time,                /* Show time stamps */
-               do_quiet,               /* Be quiet in add and flush */
-               do_pipe,                /* this cmd refers to a pipe */
-               do_sort,                /* field to sort results (0 = no) */
-               do_dynamic,             /* display dynamic rules */
-               do_expired,             /* display expired dynamic rules */
-               do_compact,             /* show rules in compact mode */
-               show_sets,              /* display rule sets */
-               test_only,              /* only check syntax */
-               verbose;
-
-#define        IP_MASK_ALL     0xffffffff
-
-/*
- * _s_x is a structure that stores a string <-> token pairs, used in
- * various places in the parser. Entries are stored in arrays,
- * with an entry with s=NULL as terminator.
- * The search routines are match_token() and match_value().
- * Often, an element with x=0 contains an error string.
- *
- */
-struct _s_x {
-       char const *s;
-       int x;
-};
-
-static struct _s_x f_tcpflags[] = {
-       { "syn", TH_SYN },
-       { "fin", TH_FIN },
-       { "ack", TH_ACK },
-       { "psh", TH_PUSH },
-       { "rst", TH_RST },
-       { "urg", TH_URG },
-       { "tcp flag", 0 },
-       { NULL, 0 }
-};
-
-static struct _s_x f_tcpopts[] = {
-       { "mss",        IP_FW_TCPOPT_MSS },
-       { "maxseg",     IP_FW_TCPOPT_MSS },
-       { "window",     IP_FW_TCPOPT_WINDOW },
-       { "sack",       IP_FW_TCPOPT_SACK },
-       { "ts",         IP_FW_TCPOPT_TS },
-       { "timestamp",  IP_FW_TCPOPT_TS },
-       { "cc",         IP_FW_TCPOPT_CC },
-       { "tcp option", 0 },
-       { NULL, 0 }
-};
-
-/*
- * IP options span the range 0 to 255 so we need to remap them
- * (though in fact only the low 5 bits are significant).
- */
-static struct _s_x f_ipopts[] = {
-       { "ssrr",       IP_FW_IPOPT_SSRR},
-       { "lsrr",       IP_FW_IPOPT_LSRR},
-       { "rr",         IP_FW_IPOPT_RR},
-       { "ts",         IP_FW_IPOPT_TS},
-       { "ip option",  0 },
-       { NULL, 0 }
-};
-
-static struct _s_x f_iptos[] = {
-       { "lowdelay",   IPTOS_LOWDELAY},
-       { "throughput", IPTOS_THROUGHPUT},
-       { "reliability", IPTOS_RELIABILITY},
-       { "mincost",    IPTOS_MINCOST},
-       { "congestion", IPTOS_CE},
-       { "ecntransport", IPTOS_ECT},
-       { "ip tos option", 0},
-       { NULL, 0 }
-};
-
-static struct _s_x limit_masks[] = {
-       {"all",         DYN_SRC_ADDR|DYN_SRC_PORT|DYN_DST_ADDR|DYN_DST_PORT},
-       {"src-addr",    DYN_SRC_ADDR},
-       {"src-port",    DYN_SRC_PORT},
-       {"dst-addr",    DYN_DST_ADDR},
-       {"dst-port",    DYN_DST_PORT},
-       {NULL,          0}
-};
-
-/*
- * we use IPPROTO_ETHERTYPE as a fake protocol id to call the print routines
- * This is only used in this code.
- */
-#define IPPROTO_ETHERTYPE      0x1000
-static struct _s_x ether_types[] = {
-    /*
-     * Note, we cannot use "-:&/" in the names because they are field
-     * separators in the type specifications. Also, we use s = NULL as
-     * end-delimiter, because a type of 0 can be legal.
-     */
-       { "ip",         0x0800 },
-       { "ipv4",       0x0800 },
-       { "ipv6",       0x86dd },
-       { "arp",        0x0806 },
-       { "rarp",       0x8035 },
-       { "vlan",       0x8100 },
-       { "loop",       0x9000 },
-       { "trail",      0x1000 },
-       { "at",         0x809b },
-       { "atalk",      0x809b },
-       { "aarp",       0x80f3 },
-       { "pppoe_disc", 0x8863 },
-       { "pppoe_sess", 0x8864 },
-       { "ipx_8022",   0x00E0 },
-       { "ipx_8023",   0x0000 },
-       { "ipx_ii",     0x8137 },
-       { "ipx_snap",   0x8137 },
-       { "ipx",        0x8137 },
-       { "ns",         0x0600 },
-       { NULL,         0 }
-};
-
-static struct _s_x exception_types[] = {
-       { "to",         1},
-       { "dst",        2},
-       { "in",         3},
-       { "out",        4},
-       { "xmit",       5},
-       { "recv",       6},
-       { "via",        7},
-       { "src",        8},
-       { NULL,         0}
-};
-
-static void show_usage(void);
-
-enum tokens {
-       TOK_NULL=0,
-
-       TOK_OR,
-       TOK_NOT,
-       TOK_STARTBRACE,
-       TOK_ENDBRACE,
-
-       TOK_ACCEPT,
-       TOK_COUNT,
-       TOK_PIPE,
-       TOK_QUEUE,
-       TOK_DIVERT,
-       TOK_TEE,
-       TOK_FORWARD,
-       TOK_SKIPTO,
-       TOK_DENY,
-       TOK_REJECT,
-       TOK_RESET,
-       TOK_UNREACH,
-       TOK_CHECKSTATE,
-
-       TOK_UID,
-       TOK_GID,
-       TOK_IN,
-       TOK_LIMIT,
-       TOK_KEEPSTATE,
-       TOK_LAYER2,
-       TOK_OUT,
-       TOK_XMIT,
-       TOK_RECV,
-       TOK_VIA,
-       TOK_FRAG,
-       TOK_IPOPTS,
-       TOK_IPLEN,
-       TOK_IPID,
-       TOK_IPPRECEDENCE,
-       TOK_IPTOS,
-       TOK_IPTTL,
-       TOK_IPVER,
-       TOK_ESTAB,
-       TOK_SETUP,
-       TOK_TCPFLAGS,
-       TOK_TCPOPTS,
-       TOK_TCPSEQ,
-       TOK_TCPACK,
-       TOK_TCPWIN,
-       TOK_ICMPTYPES,
-       TOK_MAC,
-       TOK_MACTYPE,
-       TOK_VERREVPATH,
-       TOK_IPSEC,
-       TOK_COMMENT,
-
-       TOK_PLR,
-       TOK_NOERROR,
-       TOK_BUCKETS,
-       TOK_DSTIP,
-       TOK_SRCIP,
-       TOK_DSTPORT,
-       TOK_SRCPORT,
-       TOK_ALL,
-       TOK_MASK,
-       TOK_BW,
-       TOK_DELAY,
-       TOK_RED,
-       TOK_GRED,
-       TOK_DROPTAIL,
-       TOK_PROTO,
-       TOK_WEIGHT,
-};
-
-struct _s_x dummynet_params[] = {
-       { "plr",                TOK_PLR },
-       { "noerror",            TOK_NOERROR },
-       { "buckets",            TOK_BUCKETS },
-       { "dst-ip",             TOK_DSTIP },
-       { "src-ip",             TOK_SRCIP },
-       { "dst-port",           TOK_DSTPORT },
-       { "src-port",           TOK_SRCPORT },
-       { "proto",              TOK_PROTO },
-       { "weight",             TOK_WEIGHT },
-       { "all",                TOK_ALL },
-       { "mask",               TOK_MASK },
-       { "droptail",           TOK_DROPTAIL },
-       { "red",                TOK_RED },
-       { "gred",               TOK_GRED },
-       { "bw",                 TOK_BW },
-       { "bandwidth",          TOK_BW },
-       { "delay",              TOK_DELAY },
-       { "pipe",               TOK_PIPE },
-       { "queue",              TOK_QUEUE },
-       { "dummynet-params",    TOK_NULL },
-       { NULL, 0 }     /* terminator */
-};
-
-struct _s_x rule_actions[] = {
-       { "accept",             TOK_ACCEPT },
-       { "pass",               TOK_ACCEPT },
-       { "allow",              TOK_ACCEPT },
-       { "permit",             TOK_ACCEPT },
-       { "count",              TOK_COUNT },
-       { "pipe",               TOK_PIPE },
-       { "queue",              TOK_QUEUE },
-       { "divert",             TOK_DIVERT },
-       { "tee",                TOK_TEE },
-       { "fwd",                TOK_FORWARD },
-       { "forward",            TOK_FORWARD },
-       { "skipto",             TOK_SKIPTO },
-       { "deny",               TOK_DENY },
-       { "drop",               TOK_DENY },
-       { "reject",             TOK_REJECT },
-       { "reset",              TOK_RESET },
-       { "unreach",            TOK_UNREACH },
-       { "check-state",        TOK_CHECKSTATE },
-       { "//",                 TOK_COMMENT },
-       { NULL, 0 }     /* terminator */
-};
-
-struct _s_x rule_options[] = {
-       { "uid",                TOK_UID },
-       { "gid",                TOK_GID },
-       { "in",                 TOK_IN },
-       { "limit",              TOK_LIMIT },
-       { "keep-state",         TOK_KEEPSTATE },
-       { "bridged",            TOK_LAYER2 },
-       { "layer2",             TOK_LAYER2 },
-       { "out",                TOK_OUT },
-       { "xmit",               TOK_XMIT },
-       { "recv",               TOK_RECV },
-       { "via",                TOK_VIA },
-       { "fragment",           TOK_FRAG },
-       { "frag",               TOK_FRAG },
-       { "ipoptions",          TOK_IPOPTS },
-       { "ipopts",             TOK_IPOPTS },
-       { "iplen",              TOK_IPLEN },
-       { "ipid",               TOK_IPID },
-       { "ipprecedence",       TOK_IPPRECEDENCE },
-       { "iptos",              TOK_IPTOS },
-       { "ipttl",              TOK_IPTTL },
-       { "ipversion",          TOK_IPVER },
-       { "ipver",              TOK_IPVER },
-       { "estab",              TOK_ESTAB },
-       { "established",        TOK_ESTAB },
-       { "setup",              TOK_SETUP },
-       { "tcpflags",           TOK_TCPFLAGS },
-       { "tcpflgs",            TOK_TCPFLAGS },
-       { "tcpoptions",         TOK_TCPOPTS },
-       { "tcpopts",            TOK_TCPOPTS },
-       { "tcpseq",             TOK_TCPSEQ },
-       { "tcpack",             TOK_TCPACK },
-       { "tcpwin",             TOK_TCPWIN },
-       { "icmptype",           TOK_ICMPTYPES },
-       { "icmptypes",          TOK_ICMPTYPES },
-       { "dst-ip",             TOK_DSTIP },
-       { "src-ip",             TOK_SRCIP },
-       { "dst-port",           TOK_DSTPORT },
-       { "src-port",           TOK_SRCPORT },
-       { "proto",              TOK_PROTO },
-       { "MAC",                TOK_MAC },
-       { "mac",                TOK_MAC },
-       { "mac-type",           TOK_MACTYPE },
-       { "verrevpath",         TOK_VERREVPATH },
-       { "ipsec",              TOK_IPSEC },
-       { "//",                 TOK_COMMENT },
-
-       { "not",                TOK_NOT },              /* pseudo option */
-       { "!", /* escape ? */   TOK_NOT },              /* pseudo option */
-       { "or",                 TOK_OR },               /* pseudo option */
-       { "|", /* escape */     TOK_OR },               /* pseudo option */
-       { "{",                  TOK_STARTBRACE },       /* pseudo option */
-       { "(",                  TOK_STARTBRACE },       /* pseudo option */
-       { "}",                  TOK_ENDBRACE },         /* pseudo option */
-       { ")",                  TOK_ENDBRACE },         /* pseudo option */
-       { NULL, 0 }     /* terminator */
-};
-
-static __inline uint64_t
-align_uint64(uint64_t *pll) {
-       uint64_t ret;
-
-       bcopy (pll, &ret, sizeof(ret));
-       return ret;
-};
-
-/*
- * conditionally runs the command.
- */
-static int
-do_cmd(int optname, void *optval, uintptr_t optlen)
-{
-       static int s = -1;      /* the socket */
-       int i;
-
-       if (test_only)
-               return 0;
-
-       if (s == -1)
-               s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-       if (s < 0)
-               err(EX_UNAVAILABLE, "socket");
-       
-       switch (optname) {
-               case IP_FW_GET:
-               case IP_FW_FLUSH:
-               case IP_FW_ADD:
-               case IP_FW_DEL:
-               case IP_FW_ZERO:
-               case IP_FW_RESETLOG:
-                       ((struct ip_fw *)optval)->version = IP_FW_CURRENT_API_VERSION;
-               default:
-                       break;
-       }
-
-       if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET ||
-           optname == IP_FW_ADD)
-               i = getsockopt(s, IPPROTO_IP, optname, optval,
-                       (socklen_t *)optlen);
-       else
-               i = setsockopt(s, IPPROTO_IP, optname, optval, optlen);
-       return i;
-}
-
-/**
- * match_token takes a table and a string, returns the value associated
- * with the string (-1 in case of failure).
- */
-static int
-match_token(struct _s_x *table, char *string)
-{
-       struct _s_x *pt;
-       uint i = strlen(string);
-
-       for (pt = table ; i && pt->s != NULL ; pt++)
-               if (strlen(pt->s) == i && !bcmp(string, pt->s, i))
-                       return pt->x;
-       return -1;
-};
-
-/**
- * match_value takes a table and a value, returns the string associated
- * with the value (NULL in case of failure).
- */
-static char const *
-match_value(struct _s_x *p, int value)
-{
-       for (; p->s != NULL; p++)
-               if (p->x == value)
-                       return p->s;
-       return NULL;
-}
-
-/*
- * prints one port, symbolic or numeric
- */
-static void
-print_port(int proto, uint16_t port)
-{
-
-       if (proto == IPPROTO_ETHERTYPE) {
-               char const *s;
-
-               if (do_resolv && (s = match_value(ether_types, port)) )
-                       printf("%s", s);
-               else
-                       printf("0x%04x", port);
-       } else {
-               struct servent *se = NULL;
-               if (do_resolv) {
-                       struct protoent *pe = getprotobynumber(proto);
-
-                       se = getservbyport(htons(port), pe ? pe->p_name : NULL);
-               }
-               if (se)
-                       printf("%s", se->s_name);
-               else
-                       printf("%d", port);
-       }
-}
-
-struct _s_x _port_name[] = {
-       {"dst-port",    O_IP_DSTPORT},
-       {"src-port",    O_IP_SRCPORT},
-       {"ipid",        O_IPID},
-       {"iplen",       O_IPLEN},
-       {"ipttl",       O_IPTTL},
-       {"mac-type",    O_MAC_TYPE},
-       {NULL,          0}
-};
-
-/*
- * Print the values in a list 16-bit items of the types above.
- * XXX todo: add support for mask.
- */
-static void
-print_newports(ipfw_insn_u16 *cmd, int proto, int opcode)
-{
-       uint16_t *p = cmd->ports;
-       int i;
-       char const *sep;
-
-       if (cmd->o.len & F_NOT)
-               printf(" not");
-       if (opcode != 0) {
-               sep = match_value(_port_name, opcode);
-               if (sep == NULL)
-                       sep = "???";
-               printf (" %s", sep);
-       }
-       sep = " ";
-       for (i = F_LEN((ipfw_insn *)cmd) - 1; i > 0; i--, p += 2) {
-               printf("%s", sep);
-               print_port(proto, p[0]);
-               if (p[0] != p[1]) {
-                       printf("-");
-                       print_port(proto, p[1]);
-               }
-               sep = ",";
-       }
-}
-
-/*
- * Like strtol, but also translates service names into port numbers
- * for some protocols.
- * In particular:
- *     proto == -1 disables the protocol check;
- *     proto == IPPROTO_ETHERTYPE looks up an internal table
- *     proto == <some value in /etc/protocols> matches the values there.
- * Returns *end == s in case the parameter is not found.
- */
-static int
-strtoport(char *s, char **end, int base, int proto)
-{
-       char *p, *buf;
-       char *s1;
-       int i;
-
-       *end = s;               /* default - not found */
-       if (*s == '\0')
-               return 0;       /* not found */
-
-       if (isdigit(*s))
-               return strtol(s, end, base);
-
-       /*
-        * find separator. '\\' escapes the next char.
-        */
-       for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\') ; s1++)
-               if (*s1 == '\\' && s1[1] != '\0')
-                       s1++;
-
-       buf = malloc(s1 - s + 1);
-       if (buf == NULL)
-               return 0;
-
-       /*
-        * copy into a buffer skipping backslashes
-        */
-       for (p = s, i = 0; p != s1 ; p++)
-               if (*p != '\\')
-                       buf[i++] = *p;
-       buf[i++] = '\0';
-
-       if ( match_token( exception_types, buf) != -1 ){
-               free(buf);
-               return 0;
-       }
-
-       if (proto == IPPROTO_ETHERTYPE) {
-               i = match_token(ether_types, buf);
-               free(buf);
-               if (i != -1) {  /* found */
-                       *end = s1;
-                       return i;
-               }
-       } else {
-               struct protoent *pe = NULL;
-               struct servent *se;
-
-               if (proto != 0)
-                       pe = getprotobynumber(proto);
-               setservent(1);
-               se = getservbyname(buf, pe ? pe->p_name : NULL);
-               free(buf);
-               if (se != NULL) {
-                       *end = s1;
-                       return ntohs(se->s_port);
-               }
-       }
-       return 0;       /* not found */
-}
-
-/*
- * Fill the body of the command with the list of port ranges.
- */
-static int
-fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
-{
-       uint16_t a, b, *p = cmd->ports;
-       int i = 0;
-       char *s = av;
-
-       while (*s) {
-               a = strtoport(av, &s, 0, proto);
-               if (s == av) /* no parameter */
-                       break;
-               if (*s == '-') { /* a range */
-                       av = s+1;
-                       b = strtoport(av, &s, 0, proto);
-                       if (s == av) /* no parameter */
-                               break;
-                       p[0] = a;
-                       p[1] = b;
-               } else if (*s == ',' || *s == '\0' )
-                       p[0] = p[1] = a;
-               else    /* invalid separator */
-                       errx(EX_DATAERR, "invalid separator <%c> in <%s>",
-                               *s, av);
-               i++;
-               p += 2;
-               av = s+1;
-       }
-       if (i > 0) {
-               if (i+1 > F_LEN_MASK)
-                       errx(EX_DATAERR, "too many ports/ranges");
-               cmd->o.len |= i+1; /* leave F_NOT and F_OR untouched */
-       }
-       return i;
-}
-
-static struct _s_x icmpcodes[] = {
-      { "net",                 ICMP_UNREACH_NET },
-      { "host",                        ICMP_UNREACH_HOST },
-      { "protocol",            ICMP_UNREACH_PROTOCOL },
-      { "port",                        ICMP_UNREACH_PORT },
-      { "needfrag",            ICMP_UNREACH_NEEDFRAG },
-      { "srcfail",             ICMP_UNREACH_SRCFAIL },
-      { "net-unknown",         ICMP_UNREACH_NET_UNKNOWN },
-      { "host-unknown",                ICMP_UNREACH_HOST_UNKNOWN },
-      { "isolated",            ICMP_UNREACH_ISOLATED },
-      { "net-prohib",          ICMP_UNREACH_NET_PROHIB },
-      { "host-prohib",         ICMP_UNREACH_HOST_PROHIB },
-      { "tosnet",              ICMP_UNREACH_TOSNET },
-      { "toshost",             ICMP_UNREACH_TOSHOST },
-      { "filter-prohib",       ICMP_UNREACH_FILTER_PROHIB },
-      { "host-precedence",     ICMP_UNREACH_HOST_PRECEDENCE },
-      { "precedence-cutoff",   ICMP_UNREACH_PRECEDENCE_CUTOFF },
-      { NULL, 0 }
-};
-
-static void
-fill_reject_code(u_short *codep, char *str)
-{
-       int val;
-       char *s;
-
-       val = strtoul(str, &s, 0);
-       if (s == str || *s != '\0' || val >= 0x100)
-               val = match_token(icmpcodes, str);
-       if (val < 0)
-               errx(EX_DATAERR, "unknown ICMP unreachable code ``%s''", str);
-       *codep = val;
-       return;
-}
-
-static void
-print_reject_code(uint16_t code)
-{
-       char const *s = match_value(icmpcodes, code);
-
-       if (s != NULL)
-               printf("unreach %s", s);
-       else
-               printf("unreach %u", code);
-}
-
-/*
- * Returns the number of bits set (from left) in a contiguous bitmask,
- * or -1 if the mask is not contiguous.
- * XXX this needs a proper fix.
- * This effectively works on masks in big-endian (network) format.
- * when compiled on little endian architectures.
- *
- * First bit is bit 7 of the first byte -- note, for MAC addresses,
- * the first bit on the wire is bit 0 of the first byte.
- * len is the max length in bits.
- */
-static int
-contigmask(uint8_t *p, int len)
-{
-       int i, n;
-
-       for (i=0; i<len ; i++)
-               if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
-                       break;
-       for (n=i+1; n < len; n++)
-               if ( (p[n/8] & (1 << (7 - (n%8)))) != 0)
-                       return -1; /* mask not contiguous */
-       return i;
-}
-
-/*
- * print flags set/clear in the two bitmasks passed as parameters.
- * There is a specialized check for f_tcpflags.
- */
-static void
-print_flags(char const *name, ipfw_insn *cmd, struct _s_x *list)
-{
-       char const *comma = "";
-       int i;
-       uint8_t set = cmd->arg1 & 0xff;
-       uint8_t clear = (cmd->arg1 >> 8) & 0xff;
-
-       if (list == f_tcpflags && set == TH_SYN && clear == TH_ACK) {
-               printf(" setup");
-               return;
-       }
-
-       printf(" %s ", name);
-       for (i=0; list[i].x != 0; i++) {
-               if (set & list[i].x) {
-                       set &= ~list[i].x;
-                       printf("%s%s", comma, list[i].s);
-                       comma = ",";
-               }
-               if (clear & list[i].x) {
-                       clear &= ~list[i].x;
-                       printf("%s!%s", comma, list[i].s);
-                       comma = ",";
-               }
-       }
-}
-
-/*
- * Print the ip address contained in a command.
- */
-static void
-print_ip(ipfw_insn_ip *cmd, char const *s)
-{
-       struct hostent *he = NULL;
-       int len = F_LEN((ipfw_insn *)cmd);
-       uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
-
-       printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
-
-       if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) {
-               printf("me");
-               return;
-       }
-       if (cmd->o.opcode == O_IP_SRC_SET || cmd->o.opcode == O_IP_DST_SET) {
-               uint32_t x, *map = (uint32_t *)&(cmd->mask);
-               int i, j;
-               char comma = '{';
-
-               x = cmd->o.arg1 - 1;
-               x = htonl( ~x );
-               cmd->addr.s_addr = htonl(cmd->addr.s_addr);
-               printf("%s/%d", inet_ntoa(cmd->addr),
-                       contigmask((uint8_t *)&x, 32));
-               x = cmd->addr.s_addr = htonl(cmd->addr.s_addr);
-               x &= 0xff; /* base */
-               /*
-                * Print bits and ranges.
-                * Locate first bit set (i), then locate first bit unset (j).
-                * If we have 3+ consecutive bits set, then print them as a
-                * range, otherwise only print the initial bit and rescan.
-                */
-               for (i=0; i < cmd->o.arg1; i++)
-                       if (map[i/32] & (1<<(i & 31))) {
-                               for (j=i+1; j < cmd->o.arg1; j++)
-                                       if (!(map[ j/32] & (1<<(j & 31))))
-                                               break;
-                               printf("%c%d", comma, i+x);
-                               if (j>i+2) { /* range has at least 3 elements */
-                                       printf("-%d", j-1+x);
-                                       i = j-1;
-                               }
-                               comma = ',';
-                       }
-               printf("}");
-               return;
-       }
-       /*
-        * len == 2 indicates a single IP, whereas lists of 1 or more
-        * addr/mask pairs have len = (2n+1). We convert len to n so we
-        * use that to count the number of entries.
-        */
-    for (len = len / 2; len > 0; len--, a += 2) {
-       int mb =        /* mask length */
-           (cmd->o.opcode == O_IP_SRC || cmd->o.opcode == O_IP_DST) ?
-               32 : contigmask((uint8_t *)&(a[1]), 32);
-       if (mb == 32 && do_resolv)
-               he = gethostbyaddr((char *)&(a[0]), sizeof(in_addr_t), AF_INET);
-       if (he != NULL)         /* resolved to name */
-               printf("%s", he->h_name);
-       else if (mb == 0)       /* any */
-               printf("any");
-       else {          /* numeric IP followed by some kind of mask */
-               printf("%s", inet_ntoa( *((struct in_addr *)&a[0]) ) );
-               if (mb < 0)
-                       printf(":%s", inet_ntoa( *((struct in_addr *)&a[1]) ) );
-               else if (mb < 32)
-                       printf("/%d", mb);
-       }
-       if (len > 1)
-               printf(",");
-    }
-}
-
-/*
- * prints a MAC address/mask pair
- */
-static void
-print_mac(uint8_t *addr, uint8_t *mask)
-{
-       int l = contigmask(mask, 48);
-
-       if (l == 0)
-               printf(" any");
-       else {
-               printf(" %02x:%02x:%02x:%02x:%02x:%02x",
-                   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
-               if (l == -1)
-                       printf("&%02x:%02x:%02x:%02x:%02x:%02x",
-                           mask[0], mask[1], mask[2],
-                           mask[3], mask[4], mask[5]);
-               else if (l < 48)
-                       printf("/%d", l);
-       }
-}
-
-static void
-fill_icmptypes(ipfw_insn_u32 *cmd, char *av)
-{
-       uint8_t type;
-
-       cmd->d[0] = 0;
-       while (*av) {
-               if (*av == ',')
-                       av++;
-
-               type = strtoul(av, &av, 0);
-
-               if (*av != ',' && *av != '\0')
-                       errx(EX_DATAERR, "invalid ICMP type");
-
-               if (type > 31)
-                       errx(EX_DATAERR, "ICMP type out of range");
-
-               cmd->d[0] |= 1 << type;
-       }
-       cmd->o.opcode = O_ICMPTYPE;
-       cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
-}
-
-static void
-print_icmptypes(ipfw_insn_u32 *cmd)
-{
-       int i;
-       char sep= ' ';
-
-       printf(" icmptypes");
-       for (i = 0; i < 32; i++) {
-               if ( (cmd->d[0] & (1 << (i))) == 0)
-                       continue;
-               printf("%c%d", sep, i);
-               sep = ',';
-       }
-}
-
-/*
- * show_ipfw() prints the body of an ipfw rule.
- * Because the standard rule has at least proto src_ip dst_ip, we use
- * a helper function to produce these entries if not provided explicitly.
- * The first argument is the list of fields we have, the second is
- * the list of fields we want to be printed.
- *
- * Special cases if we have provided a MAC header:
- *   + if the rule does not contain IP addresses/ports, do not print them;
- *   + if the rule does not contain an IP proto, print "all" instead of "ip";
- *
- * Once we have 'have_options', IP header fields are printed as options.
- */
-#define        HAVE_PROTO      0x0001
-#define        HAVE_SRCIP      0x0002
-#define        HAVE_DSTIP      0x0004
-#define        HAVE_MAC        0x0008
-#define        HAVE_MACTYPE    0x0010
-#define        HAVE_OPTIONS    0x8000
-
-#define        HAVE_IP         (HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)
-static void
-show_prerequisites(int *flags, int want, int cmd)
-{
-       if ( (*flags & HAVE_IP) == HAVE_IP)
-               *flags |= HAVE_OPTIONS;
-
-       if ( (*flags & (HAVE_MAC|HAVE_MACTYPE|HAVE_OPTIONS)) == HAVE_MAC &&
-            cmd != O_MAC_TYPE) {
-               /*
-                * mac-type was optimized out by the compiler,
-                * restore it
-                */
-               printf(" any");
-               *flags |= HAVE_MACTYPE | HAVE_OPTIONS;
-               return;
-       }
-       if ( !(*flags & HAVE_OPTIONS)) {
-               if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))
-                       printf(" ip");
-               if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))
-                       printf(" from any");
-               if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP))
-                       printf(" to any");
-       }
-       *flags |= want;
-}
-
-static void
-show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
-{
-       static int twidth = 0;
-       int l;
-       ipfw_insn *cmd;
-       char *comment = NULL;   /* ptr to comment if we have one */
-       int proto = 0;          /* default */
-       int flags = 0;  /* prerequisites */
-       ipfw_insn_log *logptr = NULL; /* set if we find an O_LOG */
-       int or_block = 0;       /* we are in an or block */
-       uint32_t set_disable;
-
-       bcopy(&rule->next_rule, &set_disable, sizeof(set_disable));
-
-       if (set_disable & (1 << rule->set)) { /* disabled */
-               if (!show_sets)
-                       return;
-               else
-                       printf("# DISABLED ");
-       }
-       printf("%05u ", rule->rulenum);
-
-       if (pcwidth>0 || bcwidth>0)
-               printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt),
-                   bcwidth, align_uint64(&rule->bcnt));
-
-       if (do_time == 2)
-               printf("%10u ", rule->timestamp);
-       else if (do_time == 1) {
-               char timestr[30];
-               time_t t = (time_t)0;
-
-               if (twidth == 0) {
-                       strlcpy(timestr, ctime(&t), sizeof(timestr));
-                       *strchr(timestr, '\n') = '\0';
-                       twidth = strlen(timestr);
-               }
-               if (rule->timestamp) {
-#if _FreeBSD_version < 500000 /* XXX check */
-#define        _long_to_time(x)        (time_t)(x)
-#endif
-                       t = _long_to_time(rule->timestamp);
-
-                       strlcpy(timestr, ctime(&t), sizeof(timestr));
-                       *strchr(timestr, '\n') = '\0';
-                       printf("%s ", timestr);
-               } else {
-                       printf("%*s", twidth, " ");
-               }
-       }
-
-       if (show_sets)
-               printf("set %d ", rule->set);
-
-       /*
-        * print the optional "match probability"
-        */
-       if (rule->cmd_len > 0) {
-               cmd = rule->cmd ;
-               if (cmd->opcode == O_PROB) {
-                       ipfw_insn_u32 *p = (ipfw_insn_u32 *)cmd;
-                       double d = 1.0 * p->d[0];
-
-                       d = (d / 0x7fffffff);
-                       printf("prob %f ", d);
-               }
-       }
-
-       /*
-        * first print actions
-        */
-        for (l = rule->cmd_len - rule->act_ofs, cmd = ACTION_PTR(rule);
-                       l > 0 ; l -= F_LEN(cmd), cmd += F_LEN(cmd)) {
-               switch(cmd->opcode) {
-               case O_CHECK_STATE:
-                       printf("check-state");
-                       flags = HAVE_IP; /* avoid printing anything else */
-                       break;
-
-               case O_ACCEPT:
-                       printf("allow");
-                       break;
-
-               case O_COUNT:
-                       printf("count");
-                       break;
-
-               case O_DENY:
-                       printf("deny");
-                       break;
-
-               case O_REJECT:
-                       if (cmd->arg1 == ICMP_REJECT_RST)
-                               printf("reset");
-                       else if (cmd->arg1 == ICMP_UNREACH_HOST)
-                               printf("reject");
-                       else
-                               print_reject_code(cmd->arg1);
-                       break;
-
-               case O_SKIPTO:
-                       printf("skipto %u", cmd->arg1);
-                       break;
-
-               case O_PIPE:
-                       printf("pipe %u", cmd->arg1);
-                       break;
-
-               case O_QUEUE:
-                       printf("queue %u", cmd->arg1);
-                       break;
-
-               case O_DIVERT:
-                       printf("divert %u", cmd->arg1);
-                       break;
-
-               case O_TEE:
-                       printf("tee %u", cmd->arg1);
-                       break;
-
-               case O_FORWARD_IP:
-                   {
-                       ipfw_insn_sa *s = (ipfw_insn_sa *)cmd;
-
-                       printf("fwd %s", inet_ntoa(s->sa.sin_addr));
-                       if (s->sa.sin_port)
-                               printf(",%d", s->sa.sin_port);
-                   }
-                       break;
-
-               case O_LOG: /* O_LOG is printed last */
-                       logptr = (ipfw_insn_log *)cmd;
-                       break;
-
-               default:
-                       printf("** unrecognized action %d len %d",
-                               cmd->opcode, cmd->len);
-               }
-       }
-       if (logptr) {
-               if (logptr->max_log > 0)
-                       printf(" log logamount %d", logptr->max_log);
-               else
-                       printf(" log");
-       }
-
-       /*
-        * then print the body.
-        */
-       if (rule->_pad & 1) {   /* empty rules before options */
-               if (!do_compact)
-                       printf(" ip from any to any");
-               flags |= HAVE_IP | HAVE_OPTIONS;
-       }
-
-        for (l = rule->act_ofs, cmd = rule->cmd ;
-                       l > 0 ; l -= F_LEN(cmd) , cmd += F_LEN(cmd)) {
-               /* useful alias */
-               ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
-
-               show_prerequisites(&flags, 0, cmd->opcode);
-
-               switch(cmd->opcode) {
-               case O_PROB:
-                       break;  /* done already */
-
-               case O_PROBE_STATE:
-                       break; /* no need to print anything here */
-
-               case O_MACADDR2: {
-                       ipfw_insn_mac *m = (ipfw_insn_mac *)cmd;
-
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       if (cmd->len & F_NOT)
-                               printf(" not");
-                       printf(" MAC");
-                       flags |= HAVE_MAC;
-                       print_mac(m->addr, m->mask);
-                       print_mac(m->addr + 6, m->mask + 6);
-                       }
-                       break;
-
-               case O_MAC_TYPE:
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       print_newports((ipfw_insn_u16 *)cmd, IPPROTO_ETHERTYPE,
-                               (flags & HAVE_OPTIONS) ? cmd->opcode : 0);
-                       flags |= HAVE_MAC | HAVE_MACTYPE | HAVE_OPTIONS;
-                       break;
-
-               case O_IP_SRC:
-               case O_IP_SRC_MASK:
-               case O_IP_SRC_ME:
-               case O_IP_SRC_SET:
-                       show_prerequisites(&flags, HAVE_PROTO, 0);
-                       if (!(flags & HAVE_SRCIP))
-                               printf(" from");
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       print_ip((ipfw_insn_ip *)cmd,
-                               (flags & HAVE_OPTIONS) ? " src-ip" : "");
-                       flags |= HAVE_SRCIP;
-                       break;
-
-               case O_IP_DST:
-               case O_IP_DST_MASK:
-               case O_IP_DST_ME:
-               case O_IP_DST_SET:
-                       show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);
-                       if (!(flags & HAVE_DSTIP))
-                               printf(" to");
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       print_ip((ipfw_insn_ip *)cmd,
-                               (flags & HAVE_OPTIONS) ? " dst-ip" : "");
-                       flags |= HAVE_DSTIP;
-                       break;
-
-               case O_IP_DSTPORT:
-                       show_prerequisites(&flags, HAVE_IP, 0);
-               case O_IP_SRCPORT:
-                       show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       print_newports((ipfw_insn_u16 *)cmd, proto,
-                               (flags & HAVE_OPTIONS) ? cmd->opcode : 0);
-                       break;
-
-               case O_PROTO: {
-                       struct protoent *pe;
-
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       if (cmd->len & F_NOT)
-                               printf(" not");
-                       proto = cmd->arg1;
-                       pe = getprotobynumber(cmd->arg1);
-                       if (flags & HAVE_OPTIONS)
-                               printf(" proto");
-                       if (pe)
-                               printf(" %s", pe->p_name);
-                       else
-                               printf(" %u", cmd->arg1);
-                       }
-                       flags |= HAVE_PROTO;
-                       break;
-
-               default: /*options ... */
-                       show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
-                       if ((cmd->len & F_OR) && !or_block)
-                               printf(" {");
-                       if (cmd->len & F_NOT && cmd->opcode != O_IN)
-                               printf(" not");
-                       switch(cmd->opcode) {
-                       case O_FRAG:
-                               printf(" frag");
-                               break;
-
-                       case O_IN:
-                               printf(cmd->len & F_NOT ? " out" : " in");
-                               break;
-
-                       case O_LAYER2:
-                               printf(" layer2");
-                               break;
-                       case O_XMIT:
-                       case O_RECV:
-                       case O_VIA: {
-                               char const *s;
-                               ipfw_insn_if *cmdif = (ipfw_insn_if *)cmd;
-
-                               if (cmd->opcode == O_XMIT)
-                                       s = "xmit";
-                               else if (cmd->opcode == O_RECV)
-                                       s = "recv";
-                               else /* if (cmd->opcode == O_VIA) */
-                                       s = "via";
-                               if (cmdif->name[0] == '\0')
-                                       printf(" %s %s", s,
-                                           inet_ntoa(cmdif->p.ip));
-                               else if (cmdif->p.unit == -1)
-                                       printf(" %s %s*", s, cmdif->name);
-                               else
-                                       printf(" %s %s%d", s, cmdif->name,
-                                           cmdif->p.unit);
-                               }
-                               break;
-
-                       case O_IPID:
-                               if (F_LEN(cmd) == 1)
-                                   printf(" ipid %u", cmd->arg1 );
-                               else
-                                   print_newports((ipfw_insn_u16 *)cmd, 0,
-                                       O_IPID);
-                               break;
-
-                       case O_IPTTL:
-                               if (F_LEN(cmd) == 1)
-                                   printf(" ipttl %u", cmd->arg1 );
-                               else
-                                   print_newports((ipfw_insn_u16 *)cmd, 0,
-                                       O_IPTTL);
-                               break;
-
-                       case O_IPVER:
-                               printf(" ipver %u", cmd->arg1 );
-                               break;
-
-                       case O_IPPRECEDENCE:
-                               printf(" ipprecedence %u", (cmd->arg1) >> 5 );
-                               break;
-
-                       case O_IPLEN:
-                               if (F_LEN(cmd) == 1)
-                                   printf(" iplen %u", cmd->arg1 );
-                               else
-                                   print_newports((ipfw_insn_u16 *)cmd, 0,
-                                       O_IPLEN);
-                               break;
-
-                       case O_IPOPT:
-                               print_flags("ipoptions", cmd, f_ipopts);
-                               break;
-
-                       case O_IPTOS:
-                               print_flags("iptos", cmd, f_iptos);
-                               break;
-
-                       case O_ICMPTYPE:
-                               print_icmptypes((ipfw_insn_u32 *)cmd);
-                               break;
-
-                       case O_ESTAB:
-                               printf(" established");
-                               break;
-
-                       case O_TCPFLAGS:
-                               print_flags("tcpflags", cmd, f_tcpflags);
-                               break;
-
-                       case O_TCPOPTS:
-                               print_flags("tcpoptions", cmd, f_tcpopts);
-                               break;
-
-                       case O_TCPWIN:
-                               printf(" tcpwin %d", ntohs(cmd->arg1));
-                               break;
-
-                       case O_TCPACK:
-                               printf(" tcpack %d", ntohl(cmd32->d[0]));
-                               break;
-
-                       case O_TCPSEQ:
-                               printf(" tcpseq %d", ntohl(cmd32->d[0]));
-                               break;
-
-                       case O_UID:
-                           {
-                               struct passwd *pwd = getpwuid(cmd32->d[0]);
-
-                               if (pwd)
-                                       printf(" uid %s", pwd->pw_name);
-                               else
-                                       printf(" uid %u", cmd32->d[0]);
-                           }
-                               break;
-
-                       case O_GID:
-                           {
-                               struct group *grp = getgrgid(cmd32->d[0]);
-
-                               if (grp)
-                                       printf(" gid %s", grp->gr_name);
-                               else
-                                       printf(" gid %u", cmd32->d[0]);
-                           }
-                               break;
-
-                       case O_VERREVPATH:
-                               printf(" verrevpath");
-                               break;
-
-                       case O_IPSEC:
-                               printf(" ipsec");
-                               break;
-
-                       case O_NOP:
-                               comment = (char *)(cmd + 1);
-                               break;
-
-                       case O_KEEP_STATE:
-                               printf(" keep-state");
-                               break;
-
-                       case O_LIMIT:
-                           {
-                               struct _s_x *p = limit_masks;
-                               ipfw_insn_limit *c = (ipfw_insn_limit *)cmd;
-                               uint8_t x = c->limit_mask;
-                               char const *comma = " ";
-
-                               printf(" limit");
-                               for (; p->x != 0 ; p++)
-                                       if ((x & p->x) == p->x) {
-                                               x &= ~p->x;
-                                               printf("%s%s", comma, p->s);
-                                               comma = ",";
-                                       }
-                               printf(" %d", c->conn_limit);
-                           }
-                               break;
-
-                       default:
-                               printf(" [opcode %d len %d]",
-                                   cmd->opcode, cmd->len);
-                       }
-               }
-               if (cmd->len & F_OR) {
-                       printf(" or");
-                       or_block = 1;
-               } else if (or_block) {
-                       printf(" }");
-                       or_block = 0;
-               }
-       }
-       show_prerequisites(&flags, HAVE_IP, 0);
-       if (comment)
-               printf(" // %s", comment);
-       printf("\n");
-}
-
-static void
-show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
-{
-       struct protoent *pe;
-       struct in_addr a;
-       uint16_t rulenum;
-
-       if (!do_expired) {
-               if (!d->expire && !(d->dyn_type == O_LIMIT_PARENT))
-                       return;
-       }
-       bcopy(&d->rule, &rulenum, sizeof(rulenum));
-       printf("%05d", rulenum);
-       if (pcwidth>0 || bcwidth>0)
-           printf(" %*llu %*llu (%ds)", pcwidth,
-               align_uint64(&d->pcnt), bcwidth,
-               align_uint64(&d->bcnt), d->expire);
-       switch (d->dyn_type) {
-       case O_LIMIT_PARENT:
-               printf(" PARENT %d", d->count);
-               break;
-       case O_LIMIT:
-               printf(" LIMIT");
-               break;
-       case O_KEEP_STATE: /* bidir, no mask */
-               printf(" STATE");
-               break;
-       }
-
-       if ((pe = getprotobynumber(d->id.proto)) != NULL)
-               printf(" %s", pe->p_name);
-       else
-               printf(" proto %u", d->id.proto);
-
-       a.s_addr = htonl(d->id.src_ip);
-       printf(" %s %d", inet_ntoa(a), d->id.src_port);
-
-       a.s_addr = htonl(d->id.dst_ip);
-       printf(" <-> %s %d", inet_ntoa(a), d->id.dst_port);
-       printf("\n");
-}
-
-static int
-sort_q(const void *pa, const void *pb)
-{
-       int rev = (do_sort < 0);
-       int field = rev ? -do_sort : do_sort;
-       long long res = 0;
-       const struct dn_flow_queue *a = pa;
-       const struct dn_flow_queue *b = pb;
-
-       switch (field) {
-       case 1: /* pkts */
-               res = a->len - b->len;
-               break;
-       case 2: /* bytes */
-               res = a->len_bytes - b->len_bytes;
-               break;
-
-       case 3: /* tot pkts */
-               res = a->tot_pkts - b->tot_pkts;
-               break;
-
-       case 4: /* tot bytes */
-               res = a->tot_bytes - b->tot_bytes;
-               break;
-       }
-       if (res < 0)
-               res = -1;
-       if (res > 0)
-               res = 1;
-       return (int)(rev ? res : -res);
-}
-
-static void
-list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
-{
-       int l;
-
-       printf("    mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
-           fs->flow_mask.proto,
-           fs->flow_mask.src_ip, fs->flow_mask.src_port,
-           fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
-       if (fs->rq_elements == 0)
-               return;
-
-       printf("BKT Prot ___Source IP/port____ "
-           "____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp\n");
-       if (do_sort != 0)
-               heapsort(q, fs->rq_elements, sizeof *q, sort_q);
-       for (l = 0; l < fs->rq_elements; l++) {
-               struct in_addr ina;
-               struct protoent *pe;
-
-               ina.s_addr = htonl(q[l].id.src_ip);
-               printf("%3d ", q[l].hash_slot);
-               pe = getprotobynumber(q[l].id.proto);
-               if (pe)
-                       printf("%-4s ", pe->p_name);
-               else
-                       printf("%4u ", q[l].id.proto);
-               printf("%15s/%-5d ",
-                   inet_ntoa(ina), q[l].id.src_port);
-               ina.s_addr = htonl(q[l].id.dst_ip);
-               printf("%15s/%-5d ",
-                   inet_ntoa(ina), q[l].id.dst_port);
-               printf("%4qu %8qu %2u %4u %3u\n",
-                   q[l].tot_pkts, q[l].tot_bytes,
-                   q[l].len, q[l].len_bytes, q[l].drops);
-               if (verbose)
-                       printf("   S %20qd  F %20qd\n",
-                           q[l].S, q[l].F);
-       }
-}
-
-static void
-print_flowset_parms(struct dn_flow_set *fs, char *prefix)
-{
-       int l;
-       char qs[30];
-       char plr[30];
-       char red[90];   /* Display RED parameters */
-
-       l = fs->qsize;
-       if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
-               if (l >= 8192)
-                       snprintf(qs, sizeof(qs), "%d KB", l / 1024);
-               else
-                       snprintf(qs, sizeof(qs), "%d B", l);
-       } else
-               snprintf(qs, sizeof(qs), "%3d sl.", l);
-       if (fs->plr)
-               snprintf(plr, sizeof(plr), "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
-       else
-               plr[0] = '\0';
-       if (fs->flags_fs & DN_IS_RED)   /* RED parameters */
-               snprintf(red, sizeof(red),
-                   "\n\t  %cRED w_q %f min_th %d max_th %d max_p %f",
-                   (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
-                   1.0 * fs->w_q / (double)(1 << SCALE_RED),
-                   SCALE_VAL(fs->min_th),
-                   SCALE_VAL(fs->max_th),
-                   1.0 * fs->max_p / (double)(1 << SCALE_RED));
-       else
-               snprintf(red, sizeof(red), "droptail");
-
-       printf("%s %s%s %d queues (%d buckets) %s\n",
-           prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
-}
-
-static void
-list_pipes(void *data, uint nbytes, int ac, char *av[])
-{
-       int rulenum;
-       void *next = data;
-       struct dn_pipe *p = (struct dn_pipe *) data;
-       struct dn_flow_set *fs;
-       struct dn_flow_queue *q;
-       int l;
-
-       if (ac > 0)
-               rulenum = strtoul(*av++, NULL, 10);
-       else
-               rulenum = 0;
-       for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
-               double b = p->bandwidth;
-               char buf[30];
-               char prefix[80];
-
-               if (p->next.sle_next != (struct dn_pipe *)DN_IS_PIPE)
-                       break;  /* done with pipes, now queues */
-
-               /*
-                * compute length, as pipe have variable size
-                */
-               l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
-               next = (char *)p + l;
-               nbytes -= l;
-
-               if (rulenum != 0 && rulenum != p->pipe_nr)
-                       continue;
-
-               /*
-                * Print rate (or clocking interface)
-                */
-               if (p->if_name[0] != '\0')
-                       snprintf(buf, sizeof(buf), "%s", p->if_name);
-               else if (b == 0)
-                       snprintf(buf, sizeof(buf), "unlimited");
-               else if (b >= 1000000)
-                       snprintf(buf, sizeof(buf), "%7.3f Mbit/s", b/1000000);
-               else if (b >= 1000)
-                       snprintf(buf, sizeof(buf), "%7.3f Kbit/s", b/1000);
-               else
-                       snprintf(buf, sizeof(buf), "%7.3f bit/s ", b);
-
-               snprintf(prefix, sizeof(prefix), "%05d: %s %4d ms ",
-                   p->pipe_nr, buf, p->delay);
-               print_flowset_parms(&(p->fs), prefix);
-               if (verbose)
-                       printf("   V %20qd\n", p->V >> MY_M);
-
-               q = (struct dn_flow_queue *)(p+1);
-               list_queues(&(p->fs), q);
-       }
-       for (fs = next; nbytes >= sizeof *fs; fs = next) {
-               char prefix[80];
-
-               if (fs->next.sle_next != (struct dn_flow_set *)DN_IS_QUEUE)
-                       break;
-               l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
-               next = (char *)fs + l;
-               nbytes -= l;
-               q = (struct dn_flow_queue *)(fs+1);
-               snprintf(prefix, sizeof(prefix), "q%05d: weight %d pipe %d ",
-                   fs->fs_nr, fs->weight, fs->parent_nr);
-               print_flowset_parms(fs, prefix);
-               list_queues(fs, q);
-       }
-}
-
-/*
- * This one handles all set-related commands
- *     ipfw set { show | enable | disable }
- *     ipfw set swap X Y
- *     ipfw set move X to Y
- *     ipfw set move rule X to Y
- */
-static void
-sets_handler(int ac, char *av[])
-{
-       uint32_t set_disable, masks[2];
-       int i, nbytes;
-       uint16_t rulenum;
-       uint8_t cmd, new_set;
-
-       ac--;
-       av++;
-
-       if (!ac)
-               errx(EX_USAGE, "set needs command");
-       if (!strncmp(*av, "show", strlen(*av)) ) {
-               void *data;
-               char const *msg;
-
-               nbytes = sizeof(struct ip_fw);
-               if ((data = calloc(1, nbytes)) == NULL)
-                       err(EX_OSERR, "calloc");
-               
-               if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0)
-                       err(EX_OSERR, "getsockopt(IP_FW_GET)");
-               bcopy(&((struct ip_fw *)data)->next_rule,
-                       &set_disable, sizeof(set_disable));
-
-               for (i = 0, msg = "disable" ; i < RESVD_SET; i++)
-                       if ((set_disable & (1<<i))) {
-                               printf("%s %d", msg, i);
-                               msg = "";
-                       }
-               msg = (set_disable) ? " enable" : "enable";
-               for (i = 0; i < RESVD_SET; i++)
-                       if (!(set_disable & (1<<i))) {
-                               printf("%s %d", msg, i);
-                               msg = "";
-                       }
-               printf("\n");
-       } else if (!strncmp(*av, "swap", strlen(*av))) {
-               struct ip_fw    rule;
-               ac--; av++;
-               if (ac != 2)
-                       errx(EX_USAGE, "set swap needs 2 set numbers");
-               rulenum = atoi(av[0]);
-               new_set = atoi(av[1]);
-               if (!isdigit(*(av[0])) || rulenum > RESVD_SET)
-                       errx(EX_DATAERR, "invalid set number %s", av[0]);
-               if (!isdigit(*(av[1])) || new_set > RESVD_SET)
-                       errx(EX_DATAERR, "invalid set number %s", av[1]);
-               masks[0] = (4 << 24) | (new_set << 16) | (rulenum);
-               
-               bzero(&rule, sizeof(rule));
-               rule.set_masks[0] = masks[0];
-               
-               i = do_cmd(IP_FW_DEL, &rule, sizeof(rule));
-       } else if (!strncmp(*av, "move", strlen(*av))) {
-               struct ip_fw    rule;
-               ac--; av++;
-               if (ac && !strncmp(*av, "rule", strlen(*av))) {
-                       cmd = 2;
-                       ac--; av++;
-               } else
-                       cmd = 3;
-               if (ac != 3 || strncmp(av[1], "to", strlen(*av)))
-                       errx(EX_USAGE, "syntax: set move [rule] X to Y");
-               rulenum = atoi(av[0]);
-               new_set = atoi(av[2]);
-               if (!isdigit(*(av[0])) || (cmd == 3 && rulenum > RESVD_SET) ||
-                       (cmd == 2 && rulenum == 65535) )
-                       errx(EX_DATAERR, "invalid source number %s", av[0]);
-               if (!isdigit(*(av[2])) || new_set > RESVD_SET)
-                       errx(EX_DATAERR, "invalid dest. set %s", av[1]);
-               masks[0] = (cmd << 24) | (new_set << 16) | (rulenum);
-               
-               bzero(&rule, sizeof(rule));
-               rule.set_masks[0] = masks[0];
-               
-               i = do_cmd(IP_FW_DEL, &rule, sizeof(rule));
-       } else if (!strncmp(*av, "disable", strlen(*av)) ||
-                  !strncmp(*av, "enable",  strlen(*av)) ) {
-               int which = !strncmp(*av, "enable",  strlen(*av)) ? 1 : 0;
-               struct ip_fw    rule;
-
-               ac--; av++;
-               masks[0] = masks[1] = 0;
-
-               while (ac) {
-                       if (isdigit(**av)) {
-                               i = atoi(*av);
-                               if (i < 0 || i > RESVD_SET)
-                                       errx(EX_DATAERR,
-                                           "invalid set number %d", i);
-                               masks[which] |= (1<<i);
-                       } else if (!strncmp(*av, "disable", strlen(*av)))
-                               which = 0;
-                       else if (!strncmp(*av, "enable", strlen(*av)))
-                               which = 1;
-                       else
-                               errx(EX_DATAERR,
-                                       "invalid set command %s", *av);
-                       av++; ac--;
-               }
-               if ( (masks[0] & masks[1]) != 0 )
-                       errx(EX_DATAERR,
-                           "cannot enable and disable the same set");
-               
-               bzero(&rule, sizeof(rule));
-               rule.set_masks[0] = masks[0];
-               rule.set_masks[1] = masks[1];
-               
-               i = do_cmd(IP_FW_DEL, &rule, sizeof(rule));
-               if (i)
-                       warn("set enable/disable: setsockopt(IP_FW_DEL)");
-       } else
-               errx(EX_USAGE, "invalid set command %s", *av);
-}
-
-static void
-sysctl_handler(int ac, char *av[], int which)
-{
-       ac--;
-       av++;
-
-       if (ac == 0) {
-               warnx("missing keyword to enable/disable");
-       } else if (strncmp(*av, "firewall", strlen(*av)) == 0) {
-               sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
-                   &which, sizeof(which));
-       } else if (strncmp(*av, "one_pass", strlen(*av)) == 0) {
-               sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0,
-                   &which, sizeof(which));
-       } else if (strncmp(*av, "debug", strlen(*av)) == 0) {
-               sysctlbyname("net.inet.ip.fw.debug", NULL, 0,
-                   &which, sizeof(which));
-       } else if (strncmp(*av, "verbose", strlen(*av)) == 0) {
-               sysctlbyname("net.inet.ip.fw.verbose", NULL, 0,
-                   &which, sizeof(which));
-       } else if (strncmp(*av, "dyn_keepalive", strlen(*av)) == 0) {
-               sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0,
-                   &which, sizeof(which));
-       } else {
-               warnx("unrecognize enable/disable keyword: %s", *av);
-       }
-}
-
-static void
-list(int ac, char *av[], int show_counters)
-{
-       struct ip_fw *r;
-       ipfw_dyn_rule *dynrules, *d;
-
-#define NEXT(r)        ((struct ip_fw *)((char *)r + RULESIZE(r)))
-       char *lim;
-       void *data = NULL;
-       int bcwidth, n, nbytes, nstat, ndyn, pcwidth, width;
-       int exitval = EX_OK;
-       int lac;
-       char **lav;
-       u_long rnum, last;
-       char *endptr;
-       int seen = 0;
-
-       const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
-       int nalloc = 1024;      /* start somewhere... */
-
-       if (test_only) {
-               fprintf(stderr, "Testing only, list disabled\n");
-               return;
-       }
-
-       ac--;
-       av++;
-
-       /* get rules or pipes from kernel, resizing array as necessary */
-       nbytes = nalloc;
-
-       while (nbytes >= nalloc) {
-               nalloc = nalloc * 2 + 200;
-               nbytes = nalloc;
-               if ((data = realloc(data, nbytes)) == NULL)
-                       err(EX_OSERR, "realloc");
-               
-               if (do_cmd(ocmd, data, (uintptr_t)&nbytes) < 0)
-                       err(EX_OSERR, "getsockopt(IP_%s_GET)",
-                               do_pipe ? "DUMMYNET" : "FW");
-       }
-
-       if (do_pipe) {
-               list_pipes(data, nbytes, ac, av);
-               goto done;
-       }
-
-       /*
-        * Count static rules. They have variable size so we
-        * need to scan the list to count them.
-        */
-       for (nstat = 1, r = data, lim = (char *)data + nbytes;
-                   r->rulenum < 65535 && (char *)r < lim;
-                   ++nstat, r = NEXT(r) )
-               ; /* nothing */
-
-       /*
-        * Count dynamic rules. This is easier as they have
-        * fixed size.
-        */
-       r = NEXT(r);
-       dynrules = (ipfw_dyn_rule *)r ;
-       n = (char *)r - (char *)data;
-       ndyn = (nbytes - n) / sizeof *dynrules;
-
-       /* if showing stats, figure out column widths ahead of time */
-       bcwidth = pcwidth = 0;
-       if (show_counters) {
-               for (n = 0, r = data; n < nstat; n++, r = NEXT(r)) {
-                       /* packet counter */
-                       width = snprintf(NULL, 0, "%llu",
-                           align_uint64(&r->pcnt));
-                       if (width > pcwidth)
-                               pcwidth = width;
-
-                       /* byte counter */
-                       width = snprintf(NULL, 0, "%llu",
-                           align_uint64(&r->bcnt));
-                       if (width > bcwidth)
-                               bcwidth = width;
-               }
-       }
-       if (do_dynamic && ndyn) {
-               for (n = 0, d = dynrules; n < ndyn; n++, d++) {
-                       width = snprintf(NULL, 0, "%llu",
-                           align_uint64(&d->pcnt));
-                       if (width > pcwidth)
-                               pcwidth = width;
-
-                       width = snprintf(NULL, 0, "%llu",
-                           align_uint64(&d->bcnt));
-                       if (width > bcwidth)
-                               bcwidth = width;
-               }
-       }
-       /* if no rule numbers were specified, list all rules */
-       if (ac == 0) {
-               for (n = 0, r = data; n < nstat; n++, r = NEXT(r) )
-                       show_ipfw(r, pcwidth, bcwidth);
-
-               if (do_dynamic && ndyn) {
-                       printf("## Dynamic rules (%d):\n", ndyn);
-                       for (n = 0, d = dynrules; n < ndyn; n++, d++)
-                               show_dyn_ipfw(d, pcwidth, bcwidth);
-               }
-               goto done;
-       }
-
-       /* display specific rules requested on command line */
-
-       for (lac = ac, lav = av; lac != 0; lac--) {
-               /* convert command line rule # */
-               last = rnum = strtoul(*lav++, &endptr, 10);
-               if (*endptr == '-')
-                       last = strtoul(endptr+1, &endptr, 10);
-               if (*endptr) {
-                       exitval = EX_USAGE;
-                       warnx("invalid rule number: %s", *(lav - 1));
-                       continue;
-               }
-               for (n = seen = 0, r = data; n < nstat; n++, r = NEXT(r) ) {
-                       if (r->rulenum > last)
-                               break;
-                       if (r->rulenum >= rnum && r->rulenum <= last) {
-                               show_ipfw(r, pcwidth, bcwidth);
-                               seen = 1;
-                       }
-               }
-               if (!seen) {
-                       /* give precedence to other error(s) */
-                       if (exitval == EX_OK)
-                               exitval = EX_UNAVAILABLE;
-                       warnx("rule %lu does not exist", rnum);
-               }
-       }
-
-       if (do_dynamic && ndyn) {
-               printf("## Dynamic rules:\n");
-               for (lac = ac, lav = av; lac != 0; lac--) {
-                       rnum = strtoul(*lav++, &endptr, 10);
-                       if (*endptr == '-')
-                               last = strtoul(endptr+1, &endptr, 10);
-                       if (*endptr)
-                               /* already warned */
-                               continue;
-                       for (n = 0, d = dynrules; n < ndyn; n++, d++) {
-                               uint16_t rulenum;
-
-                               bcopy(&d->rule, &rulenum, sizeof(rulenum));
-                               if (rulenum > rnum)
-                                       break;
-                               if (r->rulenum >= rnum && r->rulenum <= last)
-                                       show_dyn_ipfw(d, pcwidth, bcwidth);
-                       }
-               }
-       }
-
-       ac = 0;
-
-done:
-       free(data);
-
-       if (exitval != EX_OK)
-               exit(exitval);
-#undef NEXT
-}
-
-static void
-show_usage(void)
-{
-       fprintf(stderr, "usage: ipfw [options]\n"
-"do \"ipfw -h\" or see ipfw manpage for details\n"
-);
-       exit(EX_USAGE);
-}
-
-static void
-help(void)
-{
-       fprintf(stderr,
-"ipfw syntax summary (but please do read the ipfw(8) manpage):\n"
-"ipfw [-acdeftTnNpqS] <command> where <command> is one of:\n"
-"add [num] [set N] [prob x] RULE-BODY\n"
-"{pipe|queue} N config PIPE-BODY\n"
-"[pipe|queue] {zero|delete|show} [N{,N}]\n"
-"set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n"
-"\n"
-"RULE-BODY:    check-state [LOG] | ACTION [LOG] ADDR [OPTION_LIST]\n"
-"ACTION:       check-state | allow | count | deny | reject | skipto N |\n"
-"              {divert|tee} PORT | forward ADDR | pipe N | queue N\n"
-"ADDR:         [ MAC dst src ether_type ] \n"
-"              [ from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
-"IPADDR:       [not] { any | me | ip/bits{x,y,z} | IPLIST }\n"
-"IPLIST:       { ip | ip/bits | ip:mask }[,IPLIST]\n"
-"OPTION_LIST:  OPTION [OPTION_LIST]\n"
-"OPTION:       bridged | {dst-ip|src-ip} ADDR | {dst-port|src-port} LIST |\n"
-"      estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n"
-"      iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n"
-"      ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n"
-"      mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} |\n"
-"      setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC |\n"
-"      verrevpath\n"
-);
-exit(0);
-}
-
-
-static int
-lookup_host (char *host, struct in_addr *ipaddr)
-{
-       struct hostent *he;
-
-       if (!inet_aton(host, ipaddr)) {
-               if ((he = gethostbyname(host)) == NULL)
-                       return(-1);
-               *ipaddr = *(struct in_addr *)he->h_addr_list[0];
-       }
-       return(0);
-}
-
-/*
- * fills the addr and mask fields in the instruction as appropriate from av.
- * Update length as appropriate.
- * The following formats are allowed:
- *     any     matches any IP. Actually returns an empty instruction.
- *     me      returns O_IP_*_ME
- *     1.2.3.4         single IP address
- *     1.2.3.4:5.6.7.8 address:mask
- *     1.2.3.4/24      address/mask
- *     1.2.3.4/26{1,6,5,4,23}  set of addresses in a subnet
- * We can have multiple comma-separated address/mask entries.
- */
-static void
-fill_ip(ipfw_insn_ip *cmd, char *av)
-{
-       int len = 0;
-       uint32_t *d = ((ipfw_insn_u32 *)cmd)->d;
-
-       cmd->o.len &= ~F_LEN_MASK;      /* zero len */
-
-       if (!strncmp(av, "any", strlen(av)))
-               return;
-
-       if (!strncmp(av, "me", strlen(av))) {
-               cmd->o.len |= F_INSN_SIZE(ipfw_insn);
-               return;
-       }
-
-    while (av) {
-       /*
-        * After the address we can have '/' or ':' indicating a mask,
-        * ',' indicating another address follows, '{' indicating a
-        * set of addresses of unspecified size.
-        */
-       char *p = strpbrk(av, "/:,{");
-       int masklen;
-       char md;
-
-       if (p) {
-               md = *p;
-               *p++ = '\0';
-       } else
-               md = '\0';
-
-       if (lookup_host(av, (struct in_addr *)&d[0]) != 0)
-               errx(EX_NOHOST, "hostname ``%s'' unknown", av);
-       switch (md) {
-       case ':':
-               if (!inet_aton(p, (struct in_addr *)&d[1]))
-                       errx(EX_DATAERR, "bad netmask ``%s''", p);
-               break;
-       case '/':
-               masklen = atoi(p);
-               if (masklen == 0)
-                       d[1] = htonl(0);        /* mask */
-               else if (masklen > 32)
-                       errx(EX_DATAERR, "bad width ``%s''", p);
-               else
-                       d[1] = htonl(~0 << (32 - masklen));
-               break;
-       case '{':       /* no mask, assume /24 and put back the '{' */
-               d[1] = htonl(~0 << (32 - 24));
-               *(--p) = md;
-               break;
-
-       case ',':       /* single address plus continuation */
-               *(--p) = md;
-               /* FALLTHROUGH */
-       case 0:         /* initialization value */
-       default:
-               d[1] = htonl(~0);       /* force /32 */
-               break;
-       }
-       d[0] &= d[1];           /* mask base address with mask */
-       /* find next separator */
-       if (p)
-               p = strpbrk(p, ",{");
-       if (p && *p == '{') {
-               /*
-                * We have a set of addresses. They are stored as follows:
-                *   arg1       is the set size (powers of 2, 2..256)
-                *   addr       is the base address IN HOST FORMAT
-                *   mask..     is an array of arg1 bits (rounded up to
-                *              the next multiple of 32) with bits set
-                *              for each host in the map.
-                */
-               uint32_t *map = (uint32_t *)&cmd->mask;
-               int low, high;
-               int i = contigmask((uint8_t *)&(d[1]), 32);
-
-               if (len > 0)
-                       errx(EX_DATAERR, "address set cannot be in a list");
-               if (i < 24 || i > 31)
-                       errx(EX_DATAERR, "invalid set with mask %d", i);
-               cmd->o.arg1 = 1<<(32-i);        /* map length           */
-               d[0] = ntohl(d[0]);             /* base addr in host format */
-               cmd->o.opcode = O_IP_DST_SET;   /* default */
-               cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32) + (cmd->o.arg1+31)/32;
-               for (i = 0; i < (cmd->o.arg1+31)/32 ; i++)
-                       map[i] = 0;     /* clear map */
-
-               av = p + 1;
-               low = d[0] & 0xff;
-               high = low + cmd->o.arg1 - 1;
-               /*
-                * Here, i stores the previous value when we specify a range
-                * of addresses within a mask, e.g. 45-63. i = -1 means we
-                * have no previous value.
-                */
-               i = -1; /* previous value in a range */
-               while (isdigit(*av)) {
-                       char *s;
-                       int a = strtol(av, &s, 0);
-
-                       if (s == av) { /* no parameter */
-                           if (*av != '}')
-                               errx(EX_DATAERR, "set not closed");
-                           if (i != -1)
-                               errx(EX_DATAERR, "incomplete range %d-", i);
-                           break;
-                       }
-                       if (a < low || a > high)
-                           errx(EX_DATAERR, "addr %d out of range [%d-%d]",
-                               a, low, high);
-                       a -= low;
-                       if (i == -1)    /* no previous in range */
-                           i = a;
-                       else {          /* check that range is valid */
-                           if (i > a)
-                               errx(EX_DATAERR, "invalid range %d-%d",
-                                       i+low, a+low);
-                           if (*s == '-')
-                               errx(EX_DATAERR, "double '-' in range");
-                       }
-                       for (; i <= a; i++)
-                           map[i/32] |= 1<<(i & 31);
-                       i = -1;
-                       if (*s == '-')
-                           i = a;
-                       else if (*s == '}')
-                           break;
-                       av = s+1;
-               }
-               return;
-       }
-       av = p;
-       if (av)                 /* then *av must be a ',' */
-               av++;
-
-       /* Check this entry */
-       if (d[1] == 0) { /* "any", specified as x.x.x.x/0 */
-               /*
-                * 'any' turns the entire list into a NOP.
-                * 'not any' never matches, so it is removed from the
-                * list unless it is the only item, in which case we
-                * report an error.
-                */
-               if (cmd->o.len & F_NOT) {       /* "not any" never matches */
-                       if (av == NULL && len == 0) /* only this entry */
-                               errx(EX_DATAERR, "not any never matches");
-               }
-               /* else do nothing and return */
-               return;
-       }
-       /* A single IP can be stored in an optimized format */
-       if (d[1] == IP_MASK_ALL && av == NULL && len == 0) {
-               cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
-               return;
-       }
-       len += 2;       /* two words... */
-       d += 2;
-    } /* end while */
-    cmd->o.len |= len+1;
-}
-
-
-/*
- * helper function to process a set of flags and set bits in the
- * appropriate masks.
- */
-static void
-fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode,
-       struct _s_x *flags, char *p)
-{
-       uint8_t set=0, clear=0;
-
-       while (p && *p) {
-               char *q;        /* points to the separator */
-               int val;
-               uint8_t *which; /* mask we are working on */
-
-               if (*p == '!') {
-                       p++;
-                       which = &clear;
-               } else
-                       which = &set;
-               q = strchr(p, ',');
-               if (q)
-                       *q++ = '\0';
-               val = match_token(flags, p);
-               if (val <= 0)
-                       errx(EX_DATAERR, "invalid flag %s", p);
-               *which |= (uint8_t)val;
-               p = q;
-       }
-        cmd->opcode = opcode;
-        cmd->len =  (cmd->len & (F_NOT | F_OR)) | 1;
-        cmd->arg1 = (set & 0xff) | ( (clear & 0xff) << 8);
-}
-
-
-static void
-delete(int ac, char *av[])
-{
-       struct ip_fw rule;
-       struct dn_pipe p;
-       int i;
-       int exitval = EX_OK;
-       int do_set = 0;
-
-       memset(&p, 0, sizeof p);
-
-       av++; ac--;
-       if (ac > 0 && !strncmp(*av, "set", strlen(*av))) {
-               do_set = 1;     /* delete set */
-               ac--; av++;
-       }
-
-       /* Rule number */
-       while (ac && isdigit(**av)) {
-               i = atoi(*av); av++; ac--;
-               if (do_pipe) {
-                       if (do_pipe == 1)
-                               p.pipe_nr = i;
-                       else
-                               p.fs.fs_nr = i;
-                       i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p);
-                       if (i) {
-                               exitval = 1;
-                               warn("rule %u: setsockopt(IP_DUMMYNET_DEL)",
-                                   do_pipe == 1 ? p.pipe_nr : p.fs.fs_nr);
-                       }
-               } else {
-                       bzero(&rule, sizeof(rule));
-                       if (do_set) {
-                               rule.set_masks[0] = (i & 0xffff) | (do_set << 24);
-                       }
-                       else {
-                               rule.rulenum = i;
-                       }
-                       i = do_cmd(IP_FW_DEL, &rule, sizeof(rule));
-                       if (i) {
-                               exitval = EX_UNAVAILABLE;
-                               warn("rule %u: setsockopt(IP_FW_DEL)",
-                                   rule.rulenum);
-                       }
-               }
-       }
-       if (exitval != EX_OK)
-               exit(exitval);
-}
-
-
-/*
- * fill the interface structure. We do not check the name as we can
- * create interfaces dynamically, so checking them at insert time
- * makes relatively little sense.
- * A '*' following the name means any unit.
- */
-static void
-fill_iface(ipfw_insn_if *cmd, char *arg)
-{
-       cmd->name[0] = '\0';
-       cmd->o.len |= F_INSN_SIZE(ipfw_insn_if);
-
-       /* Parse the interface or address */
-       if (!strcmp(arg, "any"))
-               cmd->o.len = 0;         /* effectively ignore this command */
-       else if (!isdigit(*arg)) {
-               char *q;
-
-               strncpy(cmd->name, arg, sizeof(cmd->name));
-               cmd->name[sizeof(cmd->name) - 1] = '\0';
-               /* find first digit or wildcard */
-               for (q = cmd->name; *q && !isdigit(*q) && *q != '*'; q++)
-                       continue;
-               cmd->p.unit = (*q == '*') ? -1 : atoi(q);
-               *q = '\0';
-       } else if (!inet_aton(arg, &cmd->p.ip))
-               errx(EX_DATAERR, "bad ip address ``%s''", arg);
-}
-
-/*
- * the following macro returns an error message if we run out of
- * arguments.
- */
-#define        NEED1(msg)      {if (!ac) errx(EX_USAGE, msg);}
-
-static void
-config_pipe(int ac, char **av)
-{
-       struct dn_pipe p;
-       int i;
-       char *end;
-       uint32_t a;
-       void *par = NULL;
-
-       memset(&p, 0, sizeof p);
-
-       av++; ac--;
-       /* Pipe number */
-       if (ac && isdigit(**av)) {
-               i = atoi(*av); av++; ac--;
-               if (do_pipe == 1)
-                       p.pipe_nr = i;
-               else
-                       p.fs.fs_nr = i;
-       }
-       while (ac > 0) {
-               double d;
-               int tok = match_token(dummynet_params, *av);
-               ac--; av++;
-
-               switch(tok) {
-               case TOK_NOERROR:
-                       p.fs.flags_fs |= DN_NOERROR;
-                       break;
-
-               case TOK_PLR:
-                       NEED1("plr needs argument 0..1\n");
-                       d = strtod(av[0], NULL);
-                       if (d > 1)
-                               d = 1;
-                       else if (d < 0)
-                               d = 0;
-                       p.fs.plr = (int)(d*0x7fffffff);
-                       ac--; av++;
-                       break;
-
-               case TOK_QUEUE:
-                       NEED1("queue needs queue size\n");
-                       end = NULL;
-                       p.fs.qsize = strtoul(av[0], &end, 0);
-                       if (*end == 'K' || *end == 'k') {
-                               p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
-                               p.fs.qsize *= 1024;
-                       } else if (*end == 'B' || !strncmp(end, "by", 2)) {
-                               p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
-                       }
-                       ac--; av++;
-                       break;
-
-               case TOK_BUCKETS:
-                       NEED1("buckets needs argument\n");
-                       p.fs.rq_size = strtoul(av[0], NULL, 0);
-                       ac--; av++;
-                       break;
-
-               case TOK_MASK:
-                       NEED1("mask needs mask specifier\n");
-                       /*
-                        * per-flow queue, mask is dst_ip, dst_port,
-                        * src_ip, src_port, proto measured in bits
-                        */
-                       par = NULL;
-
-                       p.fs.flow_mask.dst_ip = 0;
-                       p.fs.flow_mask.src_ip = 0;
-                       p.fs.flow_mask.dst_port = 0;
-                       p.fs.flow_mask.src_port = 0;
-                       p.fs.flow_mask.proto = 0;
-                       end = NULL;
-
-                       while (ac >= 1) {
-                           uint32_t *p32 = NULL;
-                           uint16_t *p16 = NULL;
-
-                           tok = match_token(dummynet_params, *av);
-                           ac--; av++;
-                           switch(tok) {
-                           case TOK_ALL:
-                                   /*
-                                    * special case, all bits significant
-                                    */
-                                   p.fs.flow_mask.dst_ip = ~0;
-                                   p.fs.flow_mask.src_ip = ~0;
-                                   p.fs.flow_mask.dst_port = ~0;
-                                   p.fs.flow_mask.src_port = ~0;
-                                   p.fs.flow_mask.proto = ~0;
-                                   p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
-                                   goto end_mask;
-
-                           case TOK_DSTIP:
-                                   p32 = &p.fs.flow_mask.dst_ip;
-                                   break;
-
-                           case TOK_SRCIP:
-                                   p32 = &p.fs.flow_mask.src_ip;
-                                   break;
-
-                           case TOK_DSTPORT:
-                                   p16 = &p.fs.flow_mask.dst_port;
-                                   break;
-
-                           case TOK_SRCPORT:
-                                   p16 = &p.fs.flow_mask.src_port;
-                                   break;
-
-                           case TOK_PROTO:
-                                   break;
-
-                           default:
-                                   ac++; av--; /* backtrack */
-                                   goto end_mask;
-                           }
-                           if (ac < 1)
-                                   errx(EX_USAGE, "mask: value missing");
-                           if (*av[0] == '/') {
-                                   a = strtoul(av[0]+1, &end, 0);
-                                   a = (a == 32) ? ~0 : (1 << a) - 1;
-                           } else
-                                   a = strtoul(av[0], &end, 0);
-                           if (p32 != NULL)
-                                   *p32 = a;
-                           else if (p16 != NULL) {
-                                   if (a > 65535)
-                                           errx(EX_DATAERR,
-                                               "mask: must be 16 bit");
-                                   *p16 = (uint16_t)a;
-                           } else {
-                                   if (a > 255)
-                                           errx(EX_DATAERR,
-                                               "mask: must be 8 bit");
-                                   p.fs.flow_mask.proto = (uint8_t)a;
-                           }
-                           if (a != 0)
-                                   p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
-                           ac--; av++;
-                       } /* end while, config masks */
-end_mask:
-                       break;
-
-               case TOK_RED:
-               case TOK_GRED:
-                       NEED1("red/gred needs w_q/min_th/max_th/max_p\n");
-                       p.fs.flags_fs |= DN_IS_RED;
-                       if (tok == TOK_GRED)
-                               p.fs.flags_fs |= DN_IS_GENTLE_RED;
-                       /*
-                        * the format for parameters is w_q/min_th/max_th/max_p
-                        */
-                       if ((end = strsep(&av[0], "/"))) {
-                           double w_q = strtod(end, NULL);
-                           if (w_q > 1 || w_q <= 0)
-                               errx(EX_DATAERR, "0 < w_q <= 1");
-                           p.fs.w_q = (int) (w_q * (1 << SCALE_RED));
-                       }
-                       if ((end = strsep(&av[0], "/"))) {
-                           p.fs.min_th = strtoul(end, &end, 0);
-                           if (*end == 'K' || *end == 'k')
-                               p.fs.min_th *= 1024;
-                       }
-                       if ((end = strsep(&av[0], "/"))) {
-                           p.fs.max_th = strtoul(end, &end, 0);
-                           if (*end == 'K' || *end == 'k')
-                               p.fs.max_th *= 1024;
-                       }
-                       if ((end = strsep(&av[0], "/"))) {
-                           double max_p = strtod(end, NULL);
-                           if (max_p > 1 || max_p <= 0)
-                               errx(EX_DATAERR, "0 < max_p <= 1");
-                           p.fs.max_p = (int)(max_p * (1 << SCALE_RED));
-                       }
-                       ac--; av++;
-                       break;
-
-               case TOK_DROPTAIL:
-                       p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
-                       break;
-
-               case TOK_BW:
-                       NEED1("bw needs bandwidth or interface\n");
-                       if (do_pipe != 1)
-                           errx(EX_DATAERR, "bandwidth only valid for pipes");
-                       /*
-                        * set clocking interface or bandwidth value
-                        */
-                       if (av[0][0] >= 'a' && av[0][0] <= 'z') {
-                           int l = sizeof(p.if_name)-1;
-                           /* interface name */
-                           strncpy(p.if_name, av[0], l);
-                           p.if_name[l] = '\0';
-                           p.bandwidth = 0;
-                       } else {
-                           p.if_name[0] = '\0';
-                           p.bandwidth = strtoul(av[0], &end, 0);
-                           if (*end == 'K' || *end == 'k') {
-                               end++;
-                               p.bandwidth *= 1000;
-                           } else if (*end == 'M') {
-                               end++;
-                               p.bandwidth *= 1000000;
-                           }
-                           if (*end == 'B' || !strncmp(end, "by", 2))
-                               p.bandwidth *= 8;
-                           if (p.bandwidth < 0)
-                               errx(EX_DATAERR, "bandwidth too large");
-                       }
-                       ac--; av++;
-                       break;
-
-               case TOK_DELAY:
-                       if (do_pipe != 1)
-                               errx(EX_DATAERR, "delay only valid for pipes");
-                       NEED1("delay needs argument 0..10000ms\n");
-                       p.delay = strtoul(av[0], NULL, 0);
-                       ac--; av++;
-                       break;
-
-               case TOK_WEIGHT:
-                       if (do_pipe == 1)
-                               errx(EX_DATAERR,"weight only valid for queues");
-                       NEED1("weight needs argument 0..100\n");
-                       p.fs.weight = strtoul(av[0], &end, 0);
-                       ac--; av++;
-                       break;
-
-               case TOK_PIPE:
-                       if (do_pipe == 1)
-                               errx(EX_DATAERR,"pipe only valid for queues");
-                       NEED1("pipe needs pipe_number\n");
-                       p.fs.parent_nr = strtoul(av[0], &end, 0);
-                       ac--; av++;
-                       break;
-
-               default:
-                       errx(EX_DATAERR, "unrecognised option ``%s''", *(--av));
-               }
-       }
-       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");
-       } else { /* do_pipe == 2, queue */
-               if (p.fs.parent_nr == 0)
-                       errx(EX_DATAERR, "pipe must be > 0");
-               if (p.fs.weight >100)
-                       errx(EX_DATAERR, "weight must be <= 100");
-       }
-       if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
-               if (p.fs.qsize > 1024*1024)
-                       errx(EX_DATAERR, "queue size must be < 1MB");
-       } else {
-               if (p.fs.qsize > 100)
-                       errx(EX_DATAERR, "2 <= queue size <= 100");
-       }
-       if (p.fs.flags_fs & DN_IS_RED) {
-               size_t len;
-               int lookup_depth, avg_pkt_size;
-               double s, idle, weight, w_q;
-               struct clockinfo ck;
-               int t;
-
-               if (p.fs.min_th >= p.fs.max_th)
-                   errx(EX_DATAERR, "min_th %d must be < than max_th %d",
-                       p.fs.min_th, p.fs.max_th);
-               if (p.fs.max_th == 0)
-                   errx(EX_DATAERR, "max_th must be > 0");
-
-               len = sizeof(int);
-               if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth",
-                       &lookup_depth, &len, NULL, 0) == -1)
-
-                   errx(1, "sysctlbyname(\"%s\")",
-                       "net.inet.ip.dummynet.red_lookup_depth");
-               if (lookup_depth == 0)
-                   errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
-                       " must be greater than zero");
-
-               len = sizeof(int);
-               if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
-                       &avg_pkt_size, &len, NULL, 0) == -1)
-
-                   errx(1, "sysctlbyname(\"%s\")",
-                       "net.inet.ip.dummynet.red_avg_pkt_size");
-               if (avg_pkt_size == 0)
-                       errx(EX_DATAERR,
-                           "net.inet.ip.dummynet.red_avg_pkt_size must"
-                           " be greater than zero");
-
-               len = sizeof(struct clockinfo);
-               if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1)
-                       errx(1, "sysctlbyname(\"%s\")", "kern.clockrate");
-
-               /*
-                * Ticks needed for sending a medium-sized packet.
-                * Unfortunately, when we are configuring a WF2Q+ queue, we
-                * do not have bandwidth information, because that is stored
-                * in the parent pipe, and also we have multiple queues
-                * competing for it. So we set s=0, which is not very
-                * correct. But on the other hand, why do we want RED with
-                * WF2Q+ ?
-                */
-               if (p.bandwidth==0) /* this is a WF2Q+ queue */
-                       s = 0;
-               else
-                       s = ck.hz * avg_pkt_size * 8 / p.bandwidth;
-
-               /*
-                * max idle time (in ticks) before avg queue size becomes 0.
-                * NOTA:  (3/w_q) is approx the value x so that
-                * (1-w_q)^x < 10^-3.
-                */
-               w_q = ((double)p.fs.w_q) / (1 << SCALE_RED);
-               idle = s * 3. / w_q;
-               p.fs.lookup_step = (int)idle / lookup_depth;
-               if (!p.fs.lookup_step)
-                       p.fs.lookup_step = 1;
-               weight = 1 - w_q;
-               for (t = p.fs.lookup_step; t > 0; --t)
-                       weight *= weight;
-               p.fs.lookup_weight = (int)(weight * (1 << SCALE_RED));
-       }
-       i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p);
-       if (i)
-               err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
-}
-
-static void
-get_mac_addr_mask(char *p, uint8_t *addr, uint8_t *mask)
-{
-       int i, l;
-
-       for (i=0; i<6; i++)
-               addr[i] = mask[i] = 0;
-       if (!strcmp(p, "any"))
-               return;
-
-       for (i=0; *p && i<6;i++, p++) {
-               addr[i] = strtol(p, &p, 16);
-               if (*p != ':') /* we start with the mask */
-                       break;
-       }
-       if (*p == '/') { /* mask len */
-               l = strtol(p+1, &p, 0);
-               for (i=0; l>0; l -=8, i++)
-                       mask[i] = (l >=8) ? 0xff : (~0) << (8-l);
-       } else if (*p == '&') { /* mask */
-               for (i=0, p++; *p && i<6;i++, p++) {
-                       mask[i] = strtol(p, &p, 16);
-                       if (*p != ':')
-                               break;
-               }
-       } else if (*p == '\0') {
-               for (i=0; i<6; i++)
-                       mask[i] = 0xff;
-       }
-       for (i=0; i<6; i++)
-               addr[i] &= mask[i];
-}
-
-/*
- * helper function, updates the pointer to cmd with the length
- * of the current command, and also cleans up the first word of
- * the new command in case it has been clobbered before.
- */
-static ipfw_insn *
-next_cmd(ipfw_insn *cmd)
-{
-       cmd += F_LEN(cmd);
-       bzero(cmd, sizeof(*cmd));
-       return cmd;
-}
-
-/*
- * Takes arguments and copies them into a comment
- */
-static void
-fill_comment(ipfw_insn *cmd, int ac, char **av)
-{
-       int i, l;
-       char *p = (char *)(cmd + 1);
-
-       cmd->opcode = O_NOP;
-       cmd->len =  (cmd->len & (F_NOT | F_OR));
-
-       /* Compute length of comment string. */
-       for (i = 0, l = 0; i < ac; i++)
-               l += strlen(av[i]) + 1;
-       if (l == 0)
-               return;
-       if (l > 84)
-               errx(EX_DATAERR,
-                   "comment too long (max 80 chars)");
-       l = 1 + (l+3)/4;
-       cmd->len =  (cmd->len & (F_NOT | F_OR)) | l;
-       for (i = 0; i < ac; i++) {
-               /* length being checked above (max 80 chars) */
-               strlcpy(p, av[i], 80);
-               p += strlen(av[i]);
-               *p++ = ' ';
-       }
-       *(--p) = '\0';
-}
-
-/*
- * A function to fill simple commands of size 1.
- * Existing flags are preserved.
- */
-static void
-fill_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, int flags, uint16_t arg)
-{
-       cmd->opcode = opcode;
-       cmd->len =  ((cmd->len | flags) & (F_NOT | F_OR)) | 1;
-       cmd->arg1 = arg;
-}
-
-/*
- * Fetch and add the MAC address and type, with masks. This generates one or
- * two microinstructions, and returns the pointer to the last one.
- */
-static ipfw_insn *
-add_mac(ipfw_insn *cmd, int ac, char *av[])
-{
-       ipfw_insn_mac *mac;
-
-       if (ac < 2)
-               errx(EX_DATAERR, "MAC dst src");
-
-       cmd->opcode = O_MACADDR2;
-       cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac);
-
-       mac = (ipfw_insn_mac *)cmd;
-       get_mac_addr_mask(av[0], mac->addr, mac->mask); /* dst */
-       get_mac_addr_mask(av[1], &(mac->addr[6]), &(mac->mask[6])); /* src */
-       return cmd;
-}
-
-static ipfw_insn *
-add_mactype(ipfw_insn *cmd, int ac, char *av)
-{
-       if (ac < 1)
-               errx(EX_DATAERR, "missing MAC type");
-       if (strcmp(av, "any") != 0) { /* we have a non-null type */
-               fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE);
-               cmd->opcode = O_MAC_TYPE;
-               return cmd;
-       } else
-               return NULL;
-}
-
-static ipfw_insn *
-add_proto(ipfw_insn *cmd, char *av)
-{
-       struct protoent *pe;
-       u_char proto = 0;
-
-       if (!strncmp(av, "all", strlen(av)))
-               ; /* same as "ip" */
-       else if ((proto = atoi(av)) > 0)
-               ; /* all done! */
-       else if ((pe = getprotobyname(av)) != NULL)
-               proto = pe->p_proto;
-       else
-               return NULL;
-       if (proto != IPPROTO_IP)
-               fill_cmd(cmd, O_PROTO, 0, proto);
-       return cmd;
-}
-
-static ipfw_insn *
-add_srcip(ipfw_insn *cmd, char *av)
-{
-       fill_ip((ipfw_insn_ip *)cmd, av);
-       if (cmd->opcode == O_IP_DST_SET)                        /* set */
-               cmd->opcode = O_IP_SRC_SET;
-       else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn))          /* me */
-               cmd->opcode = O_IP_SRC_ME;
-       else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32))      /* one IP */
-               cmd->opcode = O_IP_SRC;
-       else                                                    /* addr/mask */
-               cmd->opcode = O_IP_SRC_MASK;
-       return cmd;
-}
-
-static ipfw_insn *
-add_dstip(ipfw_insn *cmd, char *av)
-{
-       fill_ip((ipfw_insn_ip *)cmd, av);
-       if (cmd->opcode == O_IP_DST_SET)                        /* set */
-               ;
-       else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn))          /* me */
-               cmd->opcode = O_IP_DST_ME;
-       else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32))      /* one IP */
-               cmd->opcode = O_IP_DST;
-       else                                                    /* addr/mask */
-               cmd->opcode = O_IP_DST_MASK;
-       return cmd;
-}
-
-static ipfw_insn *
-add_ports(ipfw_insn *cmd, char *av, u_char proto, int opcode)
-{
-       if (!strncmp(av, "any", strlen(av))) {
-               return NULL;
-       } else if (fill_newports((ipfw_insn_u16 *)cmd, av, proto)) {
-               /* XXX todo: check that we have a protocol with ports */
-               cmd->opcode = opcode;
-               return cmd;
-       }
-       return NULL;
-}
-
-/*
- * Parse arguments and assemble the microinstructions which make up a rule.
- * Rules are added into the 'rulebuf' and then copied in the correct order
- * into the actual rule.
- *
- * The syntax for a rule starts with the action, followed by an
- * optional log action, and the various match patterns.
- * In the assembled microcode, the first opcode must be an O_PROBE_STATE
- * (generated if the rule includes a keep-state option), then the
- * various match patterns, the "log" action, and the actual action.
- *
- */
-static void
-add(int ac, char *av[])
-{
-       /*
-        * rules are added into the 'rulebuf' and then copied in
-        * the correct order into the actual rule.
-        * Some things that need to go out of order (prob, action etc.)
-        * go into actbuf[].
-        */
-       static uint32_t rulebuf[255], actbuf[255], cmdbuf[255];
-
-       ipfw_insn *src, *dst, *cmd, *action, *prev=NULL;
-       ipfw_insn *first_cmd;   /* first match pattern */
-
-       struct ip_fw *rule;
-
-       /*
-        * various flags used to record that we entered some fields.
-        */
-       ipfw_insn *have_state = NULL;   /* check-state or keep-state */
-
-       int i;
-
-       int open_par = 0;       /* open parenthesis ( */
-
-       /* proto is here because it is used to fetch ports */
-       u_char proto = IPPROTO_IP;      /* default protocol */
-
-       double match_prob = 1; /* match probability, default is always match */
-
-       bzero(actbuf, sizeof(actbuf));          /* actions go here */
-       bzero(cmdbuf, sizeof(cmdbuf));
-       bzero(rulebuf, sizeof(rulebuf));
-
-       rule = (struct ip_fw *)rulebuf;
-       cmd = (ipfw_insn *)cmdbuf;
-       action = (ipfw_insn *)actbuf;
-
-       av++; ac--;
-
-       /* [rule N]     -- Rule number optional */
-       if (ac && isdigit(**av)) {
-               rule->rulenum = atoi(*av);
-               av++;
-               ac--;
-       }
-
-       /* [set N]      -- set number (0..RESVD_SET), optional */
-       if (ac > 1 && !strncmp(*av, "set", strlen(*av))) {
-               int set = strtoul(av[1], NULL, 10);
-               if (set < 0 || set > RESVD_SET)
-                       errx(EX_DATAERR, "illegal set %s", av[1]);
-               rule->set = set;
-               av += 2; ac -= 2;
-       }
-
-       /* [prob D]     -- match probability, optional */
-       if (ac > 1 && !strncmp(*av, "prob", strlen(*av))) {
-               match_prob = strtod(av[1], NULL);
-
-               if (match_prob <= 0 || match_prob > 1)
-                       errx(EX_DATAERR, "illegal match prob. %s", av[1]);
-               av += 2; ac -= 2;
-       }
-
-       /* action       -- mandatory */
-       NEED1("missing action");
-       i = match_token(rule_actions, *av);
-       ac--; av++;
-       action->len = 1;        /* default */
-       switch(i) {
-       case TOK_CHECKSTATE:
-               have_state = action;
-               action->opcode = O_CHECK_STATE;
-               break;
-
-       case TOK_ACCEPT:
-               action->opcode = O_ACCEPT;
-               break;
-
-       case TOK_DENY:
-               action->opcode = O_DENY;
-               action->arg1 = 0;
-               break;
-
-       case TOK_REJECT:
-               action->opcode = O_REJECT;
-               action->arg1 = ICMP_UNREACH_HOST;
-               break;
-
-       case TOK_RESET:
-               action->opcode = O_REJECT;
-               action->arg1 = ICMP_REJECT_RST;
-               break;
-
-       case TOK_UNREACH:
-               action->opcode = O_REJECT;
-               NEED1("missing reject code");
-               fill_reject_code(&action->arg1, *av);
-               ac--; av++;
-               break;
-
-       case TOK_COUNT:
-               action->opcode = O_COUNT;
-               break;
-
-       case TOK_QUEUE:
-       case TOK_PIPE:
-               action->len = F_INSN_SIZE(ipfw_insn_pipe);
-       case TOK_SKIPTO:
-               if (i == TOK_QUEUE)
-                       action->opcode = O_QUEUE;
-               else if (i == TOK_PIPE)
-                       action->opcode = O_PIPE;
-               else if (i == TOK_SKIPTO)
-                       action->opcode = O_SKIPTO;
-               NEED1("missing skipto/pipe/queue number");
-               action->arg1 = strtoul(*av, NULL, 10);
-               av++; ac--;
-               break;
-
-       case TOK_DIVERT:
-       case TOK_TEE:
-               action->opcode = (i == TOK_DIVERT) ? O_DIVERT : O_TEE;
-               NEED1("missing divert/tee port");
-               action->arg1 = strtoul(*av, NULL, 0);
-               if (action->arg1 == 0) {
-                       struct servent *s;
-                       setservent(1);
-                       s = getservbyname(av[0], "divert");
-                       if (s != NULL)
-                               action->arg1 = ntohs(s->s_port);
-                       else
-                               errx(EX_DATAERR, "illegal divert/tee port");
-               }
-               ac--; av++;
-               break;
-
-       case TOK_FORWARD: {
-               ipfw_insn_sa *p = (ipfw_insn_sa *)action;
-               char *s, *end;
-
-               NEED1("missing forward address[:port]");
-
-               action->opcode = O_FORWARD_IP;
-               action->len = F_INSN_SIZE(ipfw_insn_sa);
-
-               p->sa.sin_len = sizeof(struct sockaddr_in);
-               p->sa.sin_family = AF_INET;
-               p->sa.sin_port = 0;
-               /*
-                * locate the address-port separator (':' or ',')
-                */
-               s = strchr(*av, ':');
-               if (s == NULL)
-                       s = strchr(*av, ',');
-               if (s != NULL) {
-                       *(s++) = '\0';
-                       i = strtoport(s, &end, 0 /* base */, 0 /* proto */);
-                       if (s == end)
-                               errx(EX_DATAERR,
-                                   "illegal forwarding port ``%s''", s);
-                       p->sa.sin_port = (u_short)i;
-               }
-               lookup_host(*av, &(p->sa.sin_addr));
-               }
-               ac--; av++;
-               break;
-
-       case TOK_COMMENT:
-               /* pretend it is a 'count' rule followed by the comment */
-               action->opcode = O_COUNT;
-               ac++; av--;     /* go back... */
-               break;
-
-       default:
-               errx(EX_DATAERR, "invalid action %s", av[-1]);
-       }
-       action = next_cmd(action);
-
-       /*
-        * [log [logamount N]]  -- log, optional
-        *
-        * If exists, it goes first in the cmdbuf, but then it is
-        * skipped in the copy section to the end of the buffer.
-        */
-       if (ac && !strncmp(*av, "log", strlen(*av))) {
-               ipfw_insn_log *c = (ipfw_insn_log *)cmd;
-               int l;
-
-               cmd->len = F_INSN_SIZE(ipfw_insn_log);
-               cmd->opcode = O_LOG;
-               av++; ac--;
-               if (ac && !strncmp(*av, "logamount", strlen(*av))) {
-                       ac--; av++;
-                       NEED1("logamount requires argument");
-                       l = atoi(*av);
-                       if (l < 0)
-                               errx(EX_DATAERR, "logamount must be positive");
-                       c->max_log = l;
-                       ac--; av++;
-               }
-               cmd = next_cmd(cmd);
-       }
-
-       if (have_state) /* must be a check-state, we are done */
-               goto done;
-
-#define OR_START(target)                                       \
-       if (ac && (*av[0] == '(' || *av[0] == '{')) {           \
-               if (open_par)                                   \
-                       errx(EX_USAGE, "nested \"(\" not allowed"); \
-               prev = NULL;                                    \
-               open_par = 1;                                   \
-               if ( (av[0])[1] == '\0') {                      \
-                       ac--; av++;                             \
-               } else                                          \
-                       (*av)++;                                \
-       }                                                       \
-       target:                                                 \
-
-
-#define        CLOSE_PAR                                               \
-       if (open_par) {                                         \
-               if (ac && (                                     \
-                   !strncmp(*av, ")", strlen(*av)) ||          \
-                   !strncmp(*av, "}", strlen(*av)) )) {        \
-                       prev = NULL;                            \
-                       open_par = 0;                           \
-                       ac--; av++;                             \
-               } else                                          \
-                       errx(EX_USAGE, "missing \")\"");        \
-       }
-
-#define NOT_BLOCK                                              \
-       if (ac && !strncmp(*av, "not", strlen(*av))) {          \
-               if (cmd->len & F_NOT)                           \
-                       errx(EX_USAGE, "double \"not\" not allowed"); \
-               cmd->len |= F_NOT;                              \
-               ac--; av++;                                     \
-       }
-
-#define OR_BLOCK(target)                                       \
-       if (ac && !strncmp(*av, "or", strlen(*av))) {           \
-               if (prev == NULL || open_par == 0)              \
-                       errx(EX_DATAERR, "invalid OR block");   \
-               prev->len |= F_OR;                              \
-               ac--; av++;                                     \
-               goto target;                                    \
-       }                                                       \
-       CLOSE_PAR;
-
-       first_cmd = cmd;
-
-#if 0
-       /*
-        * MAC addresses, optional.
-        * If we have this, we skip the part "proto from src to dst"
-        * and jump straight to the option parsing.
-        */
-       NOT_BLOCK;
-       NEED1("missing protocol");
-       if (!strncmp(*av, "MAC", strlen(*av)) ||
-           !strncmp(*av, "mac", strlen(*av))) {
-               ac--; av++;     /* the "MAC" keyword */
-               add_mac(cmd, ac, av); /* exits in case of errors */
-               cmd = next_cmd(cmd);
-               ac -= 2; av += 2;       /* dst-mac and src-mac */
-               NOT_BLOCK;
-               NEED1("missing mac type");
-               if (add_mactype(cmd, ac, av[0]))
-                       cmd = next_cmd(cmd);
-               ac--; av++;     /* any or mac-type */
-               goto read_options;
-       }
-#endif
-
-       /*
-        * protocol, mandatory
-        */
-    OR_START(get_proto);
-       NOT_BLOCK;
-       NEED1("missing protocol");
-       if (add_proto(cmd, *av)) {
-               av++; ac--;
-               if (F_LEN(cmd) == 0)    /* plain IP */
-                       proto = 0;
-               else {
-                       proto = cmd->arg1;
-                       prev = cmd;
-                       cmd = next_cmd(cmd);
-               }
-       } else if (first_cmd != cmd) {
-               errx(EX_DATAERR, "invalid protocol ``%s''", *av);
-       } else
-               goto read_options;
-    OR_BLOCK(get_proto);
-
-       /*
-        * "from", mandatory
-        */
-       if (!ac || strncmp(*av, "from", strlen(*av)))
-               errx(EX_USAGE, "missing ``from''");
-       ac--; av++;
-
-       /*
-        * source IP, mandatory
-        */
-    OR_START(source_ip);
-       NOT_BLOCK;      /* optional "not" */
-       NEED1("missing source address");
-       if (add_srcip(cmd, *av)) {
-               ac--; av++;
-               if (F_LEN(cmd) != 0) {  /* ! any */
-                       prev = cmd;
-                       cmd = next_cmd(cmd);
-               }
-       }
-    OR_BLOCK(source_ip);
-
-       /*
-        * source ports, optional
-        */
-       NOT_BLOCK;      /* optional "not" */
-       if (ac) {
-               if (!strncmp(*av, "any", strlen(*av)) ||
-                   add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
-                       ac--; av++;
-                       if (F_LEN(cmd) != 0)
-                               cmd = next_cmd(cmd);
-               }
-       }
-
-       /*
-        * "to", mandatory
-        */
-       if (!ac || strncmp(*av, "to", strlen(*av)))
-               errx(EX_USAGE, "missing ``to''");
-       av++; ac--;
-
-       /*
-        * destination, mandatory
-        */
-    OR_START(dest_ip);
-       NOT_BLOCK;      /* optional "not" */
-       NEED1("missing dst address");
-       if (add_dstip(cmd, *av)) {
-               ac--; av++;
-               if (F_LEN(cmd) != 0) {  /* ! any */
-                       prev = cmd;
-                       cmd = next_cmd(cmd);
-               }
-       }
-    OR_BLOCK(dest_ip);
-
-       /*
-        * dest. ports, optional
-        */
-       NOT_BLOCK;      /* optional "not" */
-       if (ac) {
-               if (!strncmp(*av, "any", strlen(*av)) ||
-                   add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
-                       ac--; av++;
-                       if (F_LEN(cmd) != 0)
-                               cmd = next_cmd(cmd);
-               }
-       }
-
-read_options:
-       if (ac && first_cmd == cmd) {
-               /*
-                * nothing specified so far, store in the rule to ease
-                * printout later.
-                */
-                rule->_pad = 1;
-       }
-       prev = NULL;
-       while (ac) {
-               char *s;
-               ipfw_insn_u32 *cmd32;   /* alias for cmd */
-
-               s = *av;
-               cmd32 = (ipfw_insn_u32 *)cmd;
-
-               if (*s == '!') {        /* alternate syntax for NOT */
-                       if (cmd->len & F_NOT)
-                               errx(EX_USAGE, "double \"not\" not allowed");
-                       cmd->len = F_NOT;
-                       s++;
-               }
-               i = match_token(rule_options, s);
-               ac--; av++;
-               switch(i) {
-               case TOK_NOT:
-                       if (cmd->len & F_NOT)
-                               errx(EX_USAGE, "double \"not\" not allowed");
-                       cmd->len = F_NOT;
-                       break;
-
-               case TOK_OR:
-                       if (open_par == 0 || prev == NULL)
-                               errx(EX_USAGE, "invalid \"or\" block");
-                       prev->len |= F_OR;
-                       break;
-
-               case TOK_STARTBRACE:
-                       if (open_par)
-                               errx(EX_USAGE, "+nested \"(\" not allowed");
-                       open_par = 1;
-                       break;
-
-               case TOK_ENDBRACE:
-                       if (!open_par)
-                               errx(EX_USAGE, "+missing \")\"");
-                       open_par = 0;
-                       prev = NULL;
-                       break;
-
-               case TOK_IN:
-                       fill_cmd(cmd, O_IN, 0, 0);
-                       break;
-
-               case TOK_OUT:
-                       cmd->len ^= F_NOT; /* toggle F_NOT */
-                       fill_cmd(cmd, O_IN, 0, 0);
-                       break;
-
-               case TOK_FRAG:
-                       fill_cmd(cmd, O_FRAG, 0, 0);
-                       break;
-
-               case TOK_LAYER2:
-                       fill_cmd(cmd, O_LAYER2, 0, 0);
-                       break;
-
-               case TOK_XMIT:
-               case TOK_RECV:
-               case TOK_VIA:
-                       NEED1("recv, xmit, via require interface name"
-                               " or address");
-                       fill_iface((ipfw_insn_if *)cmd, av[0]);
-                       ac--; av++;
-                       if (F_LEN(cmd) == 0)    /* not a valid address */
-                               break;
-                       if (i == TOK_XMIT)
-                               cmd->opcode = O_XMIT;
-                       else if (i == TOK_RECV)
-                               cmd->opcode = O_RECV;
-                       else if (i == TOK_VIA)
-                               cmd->opcode = O_VIA;
-                       break;
-
-               case TOK_ICMPTYPES:
-                       NEED1("icmptypes requires list of types");
-                       fill_icmptypes((ipfw_insn_u32 *)cmd, *av);
-                       av++; ac--;
-                       break;
-
-               case TOK_IPTTL:
-                       NEED1("ipttl requires TTL");
-                       if (strpbrk(*av, "-,")) {
-                           if (!add_ports(cmd, *av, 0, O_IPTTL))
-                               errx(EX_DATAERR, "invalid ipttl %s", *av);
-                       } else
-                           fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
-                       ac--; av++;
-                       break;
-
-               case TOK_IPID:
-                       NEED1("ipid requires id");
-                       if (strpbrk(*av, "-,")) {
-                           if (!add_ports(cmd, *av, 0, O_IPID))
-                               errx(EX_DATAERR, "invalid ipid %s", *av);
-                       } else
-                           fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
-                       ac--; av++;
-                       break;
-
-               case TOK_IPLEN:
-                       NEED1("iplen requires length");
-                       if (strpbrk(*av, "-,")) {
-                           if (!add_ports(cmd, *av, 0, O_IPLEN))
-                               errx(EX_DATAERR, "invalid ip len %s", *av);
-                       } else
-                           fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
-                       ac--; av++;
-                       break;
-
-               case TOK_IPVER:
-                       NEED1("ipver requires version");
-                       fill_cmd(cmd, O_IPVER, 0, strtoul(*av, NULL, 0));
-                       ac--; av++;
-                       break;
-
-               case TOK_IPPRECEDENCE:
-                       NEED1("ipprecedence requires value");
-                       fill_cmd(cmd, O_IPPRECEDENCE, 0,
-                           (strtoul(*av, NULL, 0) & 7) << 5);
-                       ac--; av++;
-                       break;
-
-               case TOK_IPOPTS:
-                       NEED1("missing argument for ipoptions");
-                       fill_flags(cmd, O_IPOPT, f_ipopts, *av);
-                       ac--; av++;
-                       break;
-
-               case TOK_IPTOS:
-                       NEED1("missing argument for iptos");
-                       fill_flags(cmd, O_IPTOS, f_iptos, *av);
-                       ac--; av++;
-                       break;
-
-               case TOK_UID:
-                       NEED1("uid requires argument");
-                   {
-                       char *end;
-                       uid_t uid;
-                       struct passwd *pwd;
-
-                       cmd->opcode = O_UID;
-                       uid = strtoul(*av, &end, 0);
-                       pwd = (*end == '\0') ? getpwuid(uid) : getpwnam(*av);
-                       if (pwd == NULL)
-                               errx(EX_DATAERR, "uid \"%s\" nonexistent", *av);
-                       cmd32->d[0] = pwd->pw_uid;
-                       cmd->len = F_INSN_SIZE(ipfw_insn_u32);
-                       ac--; av++;
-                   }
-                       break;
-
-               case TOK_GID:
-                       NEED1("gid requires argument");
-                   {
-                       char *end;
-                       gid_t gid;
-                       struct group *grp;
-
-                       cmd->opcode = O_GID;
-                       gid = strtoul(*av, &end, 0);
-                       grp = (*end == '\0') ? getgrgid(gid) : getgrnam(*av);
-                       if (grp == NULL)
-                               errx(EX_DATAERR, "gid \"%s\" nonexistent", *av);
-                       cmd32->d[0] = grp->gr_gid;
-                       cmd->len = F_INSN_SIZE(ipfw_insn_u32);
-                       ac--; av++;
-                   }
-                       break;
-
-               case TOK_ESTAB:
-                       fill_cmd(cmd, O_ESTAB, 0, 0);
-                       break;
-
-               case TOK_SETUP:
-                       fill_cmd(cmd, O_TCPFLAGS, 0,
-                               (TH_SYN) | ( (TH_ACK) & 0xff) <<8 );
-                       break;
-
-               case TOK_TCPOPTS:
-                       NEED1("missing argument for tcpoptions");
-                       fill_flags(cmd, O_TCPOPTS, f_tcpopts, *av);
-                       ac--; av++;
-                       break;
-
-               case TOK_TCPSEQ:
-               case TOK_TCPACK:
-                       NEED1("tcpseq/tcpack requires argument");
-                       cmd->len = F_INSN_SIZE(ipfw_insn_u32);
-                       cmd->opcode = (i == TOK_TCPSEQ) ? O_TCPSEQ : O_TCPACK;
-                       cmd32->d[0] = htonl(strtoul(*av, NULL, 0));
-                       ac--; av++;
-                       break;
-
-               case TOK_TCPWIN:
-                       NEED1("tcpwin requires length");
-                       fill_cmd(cmd, O_TCPWIN, 0,
-                           htons(strtoul(*av, NULL, 0)));
-                       ac--; av++;
-                       break;
-
-               case TOK_TCPFLAGS:
-                       NEED1("missing argument for tcpflags");
-                       cmd->opcode = O_TCPFLAGS;
-                       fill_flags(cmd, O_TCPFLAGS, f_tcpflags, *av);
-                       ac--; av++;
-                       break;
-
-               case TOK_KEEPSTATE:
-                       if (open_par)
-                               errx(EX_USAGE, "keep-state cannot be part "
-                                   "of an or block");
-                       if (have_state)
-                               errx(EX_USAGE, "only one of keep-state "
-                                       "and limit is allowed");
-                       have_state = cmd;
-                       fill_cmd(cmd, O_KEEP_STATE, 0, 0);
-                       break;
-
-               case TOK_LIMIT:
-                       if (open_par)
-                               errx(EX_USAGE, "limit cannot be part "
-                                   "of an or block");
-                       if (have_state)
-                               errx(EX_USAGE, "only one of keep-state "
-                                       "and limit is allowed");
-                       NEED1("limit needs mask and # of connections");
-                       have_state = cmd;
-                   {
-                       ipfw_insn_limit *c = (ipfw_insn_limit *)cmd;
-
-                       cmd->len = F_INSN_SIZE(ipfw_insn_limit);
-                       cmd->opcode = O_LIMIT;
-                       c->limit_mask = 0;
-                       c->conn_limit = 0;
-                       for (; ac >1 ;) {
-                               int val;
-
-                               val = match_token(limit_masks, *av);
-                               if (val <= 0)
-                                       break;
-                               c->limit_mask |= val;
-                               ac--; av++;
-                       }
-                       c->conn_limit = atoi(*av);
-                       if (c->conn_limit == 0)
-                               errx(EX_USAGE, "limit: limit must be >0");
-                       if (c->limit_mask == 0)
-                               errx(EX_USAGE, "missing limit mask");
-                       ac--; av++;
-                   }
-                       break;
-
-               case TOK_PROTO:
-                       NEED1("missing protocol");
-                       if (add_proto(cmd, *av)) {
-                               proto = cmd->arg1;
-                               ac--; av++;
-                       } else
-                               errx(EX_DATAERR, "invalid protocol ``%s''",
-                                   *av);
-                       break;
-
-               case TOK_SRCIP:
-                       NEED1("missing source IP");
-                       if (add_srcip(cmd, *av)) {
-                               ac--; av++;
-                       }
-                       break;
-
-               case TOK_DSTIP:
-                       NEED1("missing destination IP");
-                       if (add_dstip(cmd, *av)) {
-                               ac--; av++;
-                       }
-                       break;
-
-               case TOK_SRCPORT:
-                       NEED1("missing source port");
-                       if (!strncmp(*av, "any", strlen(*av)) ||
-                           add_ports(cmd, *av, proto, O_IP_SRCPORT)) {
-                               ac--; av++;
-                       } else
-                               errx(EX_DATAERR, "invalid source port %s", *av);
-                       break;
-
-               case TOK_DSTPORT:
-                       NEED1("missing destination port");
-                       if (!strncmp(*av, "any", strlen(*av)) ||
-                           add_ports(cmd, *av, proto, O_IP_DSTPORT)) {
-                               ac--; av++;
-                       } else
-                               errx(EX_DATAERR, "invalid destination port %s",
-                                   *av);
-                       break;
-
-               case TOK_MAC:
-                       if (ac < 2)
-                               errx(EX_USAGE, "MAC dst-mac src-mac");
-                       if (add_mac(cmd, ac, av)) {
-                               ac -= 2; av += 2;
-                       }
-                       break;
-
-               case TOK_MACTYPE:
-                       NEED1("missing mac type");
-                       if (!add_mactype(cmd, ac, *av))
-                               errx(EX_DATAERR, "invalid mac type %s", *av);
-                       ac--; av++;
-                       break;
-
-               case TOK_VERREVPATH:
-                       fill_cmd(cmd, O_VERREVPATH, 0, 0);
-                       break;
-
-               case TOK_IPSEC:
-                       fill_cmd(cmd, O_IPSEC, 0, 0);
-                       break;
-
-               case TOK_COMMENT:
-                       fill_comment(cmd, ac, av);
-                       av += ac;
-                       ac = 0;
-                       break;
-
-               default:
-                       errx(EX_USAGE, "unrecognised option [%d] %s", i, s);
-               }
-               if (F_LEN(cmd) > 0) {   /* prepare to advance */
-                       prev = cmd;
-                       cmd = next_cmd(cmd);
-               }
-       }
-
-done:
-       /*
-        * Now copy stuff into the rule.
-        * If we have a keep-state option, the first instruction
-        * must be a PROBE_STATE (which is generated here).
-        * If we have a LOG option, it was stored as the first command,
-        * and now must be moved to the top of the action part.
-        */
-       dst = (ipfw_insn *)rule->cmd;
-
-       /*
-        * First thing to write into the command stream is the match probability.
-        */
-       if (match_prob != 1) { /* 1 means always match */
-               dst->opcode = O_PROB;
-               dst->len = 2;
-               *((int32_t *)(dst+1)) = (int32_t)(match_prob * 0x7fffffff);
-               dst += dst->len;
-       }
-
-       /*
-        * generate O_PROBE_STATE if necessary
-        */
-       if (have_state && have_state->opcode != O_CHECK_STATE) {
-               fill_cmd(dst, O_PROBE_STATE, 0, 0);
-               dst = next_cmd(dst);
-       }
-       /*
-        * copy all commands but O_LOG, O_KEEP_STATE, O_LIMIT
-        */
-       for (src = (ipfw_insn *)cmdbuf; src != cmd; src += i) {
-               i = F_LEN(src);
-
-               switch (src->opcode) {
-               case O_LOG:
-               case O_KEEP_STATE:
-               case O_LIMIT:
-                       break;
-               default:
-                       bcopy(src, dst, i * sizeof(uint32_t));
-                       dst += i;
-               }
-       }
-
-       /*
-        * put back the have_state command as last opcode
-        */
-       if (have_state && have_state->opcode != O_CHECK_STATE) {
-               i = F_LEN(have_state);
-               bcopy(have_state, dst, i * sizeof(uint32_t));
-               dst += i;
-       }
-       /*
-        * start action section
-        */
-       rule->act_ofs = dst - rule->cmd;
-
-       /*
-        * put back O_LOG if necessary
-        */
-       src = (ipfw_insn *)cmdbuf;
-       if (src->opcode == O_LOG) {
-               i = F_LEN(src);
-               bcopy(src, dst, i * sizeof(uint32_t));
-               dst += i;
-       }
-       /*
-        * copy all other actions
-        */
-       for (src = (ipfw_insn *)actbuf; src != action; src += i) {
-               i = F_LEN(src);
-               bcopy(src, dst, i * sizeof(uint32_t));
-               dst += i;
-       }
-
-       rule->cmd_len = (uint32_t *)dst - (uint32_t *)(rule->cmd);
-       i = (char *)dst - (char *)rule;
-       
-       if (do_cmd(IP_FW_ADD, rule, (uintptr_t)&i) == -1)
-               err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD");
-       if (!do_quiet)
-               show_ipfw(rule, 0, 0);
-}
-
-static void
-zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
-{
-       struct ip_fw    rule;
-       int rulenum;
-       int failed = EX_OK;
-       char const *name = optname == IP_FW_ZERO ?  "ZERO" : "RESETLOG";
-
-       av++; ac--;
-       bzero(&rule, sizeof(rule));
-
-       if (!ac) {
-               /* clear all entries - send empty rule */
-               if (do_cmd(optname, &rule, sizeof(rule)) < 0)
-                       err(EX_UNAVAILABLE, "setsockopt(IP_FW_%s)", name);
-               if (!do_quiet)
-                       printf("%s.\n", optname == IP_FW_ZERO ?
-                           "Accounting cleared":"Logging counts reset");
-
-               return;
-       }
-
-       while (ac) {
-               /* Rule number */
-               if (isdigit(**av)) {
-                       rulenum = atoi(*av);
-                       av++;
-                       ac--;
-                       rule.rulenum = rulenum;
-                       if (do_cmd(optname, &rule, sizeof(rule))) {
-                               warn("rule %u: setsockopt(IP_FW_%s)",
-                                   rulenum, name);
-                               failed = EX_UNAVAILABLE;
-                       } else if (!do_quiet)
-                               printf("Entry %d %s.\n", rulenum,
-                                   optname == IP_FW_ZERO ?
-                                       "cleared" : "logging count reset");
-               } else {
-                       errx(EX_USAGE, "invalid rule number ``%s''", *av);
-               }
-       }
-       if (failed != EX_OK)
-               exit(failed);
-}
-
-static void
-flush(int force)
-{
-       int cmd = do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH;
-       struct ip_fw    rule;
-
-       if (!force && !do_quiet) { /* need to ask user */
-               int c;
-
-               printf("Are you sure? [yn] ");
-               fflush(stdout);
-               do {
-                       c = toupper(getc(stdin));
-                       while (c != '\n' && getc(stdin) != '\n')
-                               if (feof(stdin))
-                                       return; /* and do not flush */
-               } while (c != 'Y' && c != 'N');
-               printf("\n");
-               if (c == 'N')   /* user said no */
-                       return;
-       }
-       
-       if (cmd == IP_FW_FLUSH) {
-               /* send empty rule */
-               bzero(&rule, sizeof(rule));
-               if (do_cmd(cmd, &rule, sizeof(rule)) < 0)
-                       err(EX_UNAVAILABLE, "setsockopt(IP_FW_FLUSH)");
-       }
-       else {
-               if (do_cmd(cmd, NULL, 0) < 0)
-                       err(EX_UNAVAILABLE, "setsockopt(IP_DUMMYNET_FLUSH)");
-       }
-       if (!do_quiet)
-               printf("Flushed all %s.\n", do_pipe ? "pipes" : "rules");
-}
-
-/*
- * Free a the (locally allocated) copy of command line arguments.
- */
-static void
-free_args(int ac, char **av)
-{
-       int i;
-
-       for (i=0; i < ac; i++)
-               free(av[i]);
-       free(av);
-}
-
-/*
- * Called with the arguments (excluding program name).
- * Returns 0 if successful, 1 if empty command, errx() in case of errors.
- */
-static int
-ipfw_main(int oldac, char **oldav)
-{
-       int ch, ac, save_ac;
-       char **av, **save_av;
-       int do_acct = 0;                /* Show packet/byte count */
-       int do_force = 0;               /* Don't ask for confirmation */
-
-#define WHITESP                " \t\f\v\n\r"
-       if (oldac == 0)
-               return 1;
-       else if (oldac == 1) {
-               /*
-                * If we are called with a single string, try to split it into
-                * arguments for subsequent parsing.
-                * But first, remove spaces after a ',', by copying the string
-                * in-place.
-                */
-               char *arg = oldav[0];   /* The string... */
-               int l = strlen(arg);
-               int copy = 0;           /* 1 if we need to copy, 0 otherwise */
-               int i, j;
-               for (i = j = 0; i < l; i++) {
-                       if (arg[i] == '#')      /* comment marker */
-                               break;
-                       if (copy) {
-                               arg[j++] = arg[i];
-                               copy = !index("," WHITESP, arg[i]);
-                       } else {
-                               copy = !index(WHITESP, arg[i]);
-                               if (copy)
-                                       arg[j++] = arg[i];
-                       }
-               }
-               if (!copy && j > 0)     /* last char was a 'blank', remove it */
-                       j--;
-               l = j;                  /* the new argument length */
-               arg[j++] = '\0';
-               if (l == 0)             /* empty string! */
-                       return 1;
-
-               /*
-                * First, count number of arguments. Because of the previous
-                * processing, this is just the number of blanks plus 1.
-                */
-               for (i = 0, ac = 1; i < l; i++)
-                       if (index(WHITESP, arg[i]) != NULL)
-                               ac++;
-
-               av = calloc(ac, sizeof(char *));
-
-               /*
-                * Second, copy arguments from cmd[] to av[]. For each one,
-                * j is the initial character, i is the one past the end.
-                */
-               for (ac = 0, i = j = 0; i < l; i++)
-                       if (index(WHITESP, arg[i]) != NULL || i == l-1) {
-                               if (i == l-1)
-                                       i++;
-                               av[ac] = calloc(i-j+1, 1);
-                               bcopy(arg+j, av[ac], i-j);
-                               ac++;
-                               j = i + 1;
-                       }
-       } else {
-               /*
-                * If an argument ends with ',' join with the next one.
-                * Just add its length to 'l' and continue. When we have a string
-                * without a ',' ending, we'll have the combined length in 'l' 
-                */
-               int first, i, l;
-
-               av = calloc(oldac, sizeof(char *));
-               for (first = i = ac = 0, l = 0; i < oldac; i++) {
-                       char *arg = oldav[i];
-                       int k = strlen(arg);
-                       
-                       l += k;
-                       if (arg[k-1] != ',' || i == oldac-1) {
-                               int buflen = l+1;
-                               /* Time to copy. */
-                               av[ac] = calloc(l+1, 1);
-                               for (l=0; first <= i; first++) {
-                                       strlcat(av[ac]+l, oldav[first], buflen-l);
-                                       l += strlen(oldav[first]);
-                               }
-                               ac++;
-                               l = 0;
-                               first = i+1;
-                       }
-               }
-       }
-
-       /* Set the force flag for non-interactive processes */
-       do_force = !isatty(STDIN_FILENO);
-
-       /* Save arguments for final freeing of memory. */
-       save_ac = ac;
-       save_av = av;
-
-       optind = optreset = 0;
-       while ((ch = getopt(ac, av, "acdefhnNqs:STtv")) != -1)
-               switch (ch) {
-               case 'a':
-                       do_acct = 1;
-                       break;
-
-               case 'c':
-                       do_compact = 1;
-                       break;
-
-               case 'd':
-                       do_dynamic = 1;
-                       break;
-
-               case 'e':
-                       do_expired = 1;
-                       break;
-
-               case 'f':
-                       do_force = 1;
-                       break;
-
-               case 'h': /* help */
-                       free_args(save_ac, save_av);
-                       help();
-                       break;  /* NOTREACHED */
-
-               case 'n':
-                       test_only = 1;
-                       break;
-
-               case 'N':
-                       do_resolv = 1;
-                       break;
-
-               case 'q':
-                       do_quiet = 1;
-                       break;
-
-               case 's': /* sort */
-                       do_sort = atoi(optarg);
-                       break;
-
-               case 'S':
-                       show_sets = 1;
-                       break;
-
-               case 't':
-                       do_time = 1;
-                       break;
-
-               case 'T':
-                       do_time = 2;    /* numeric timestamp */
-                       break;
-
-               case 'v': /* verbose */
-                       verbose = 1;
-                       break;
-
-               default:
-                       free_args(save_ac, save_av);
-                       return 1;
-               }
-
-       ac -= optind;
-       av += optind;
-       NEED1("bad arguments, for usage summary ``ipfw''");
-
-       /*
-        * An undocumented behaviour of ipfw1 was to allow rule numbers first,
-        * e.g. "100 add allow ..." instead of "add 100 allow ...".
-        * In case, swap first and second argument to get the normal form.
-        */
-       if (ac > 1 && isdigit(*av[0])) {
-               char *p = av[0];
-
-               av[0] = av[1];
-               av[1] = p;
-       }
-
-       /*
-        * optional: pipe or queue
-        */
-       do_pipe = 0;
-       if (!strncmp(*av, "pipe", strlen(*av)))
-               do_pipe = 1;
-       else if (!strncmp(*av, "queue", strlen(*av)))
-               do_pipe = 2;
-       if (do_pipe) {
-               ac--;
-               av++;
-       }
-       NEED1("missing command");
-
-       /*
-        * For pipes and queues we normally say 'pipe NN config'
-        * but the code is easier to parse as 'pipe config NN'
-        * so we swap the two arguments.
-        */
-       if (do_pipe > 0 && ac > 1 && isdigit(*av[0])) {
-               char *p = av[0];
-
-               av[0] = av[1];
-               av[1] = p;
-       }
-
-       if (!strncmp(*av, "add", strlen(*av)))
-               add(ac, av);
-       else if (do_pipe && !strncmp(*av, "config", strlen(*av)))
-               config_pipe(ac, av);
-       else if (!strncmp(*av, "delete", strlen(*av)))
-               delete(ac, av);
-       else if (!strncmp(*av, "flush", strlen(*av)))
-               flush(do_force);
-       else if (!strncmp(*av, "zero", strlen(*av)))
-               zero(ac, av, IP_FW_ZERO);
-       else if (!strncmp(*av, "resetlog", strlen(*av)))
-               zero(ac, av, IP_FW_RESETLOG);
-       else if (!strncmp(*av, "print", strlen(*av)) ||
-                !strncmp(*av, "list", strlen(*av)))
-               list(ac, av, do_acct);
-       else if (!strncmp(*av, "set", strlen(*av)))
-               sets_handler(ac, av);
-       else if (!strncmp(*av, "enable", strlen(*av)))
-               sysctl_handler(ac, av, 1);
-       else if (!strncmp(*av, "disable", strlen(*av)))
-               sysctl_handler(ac, av, 0);
-       else if (!strncmp(*av, "show", strlen(*av)))
-               list(ac, av, 1 /* show counters */);
-       else
-               errx(EX_USAGE, "bad command `%s'", *av);
-
-       /* Free memory allocated in the argument parsing. */
-       free_args(save_ac, save_av);
-       return 0;
-}
-
-
-static void
-ipfw_readfile(int ac, char *av[])
-{
-#define MAX_ARGS       32
-       char    buf[BUFSIZ];
-       char    *cmd = NULL, *filename = av[ac-1];
-       int     c, lineno=0;
-       FILE    *f = NULL;
-       pid_t   preproc = 0;
-
-       filename = av[ac-1];
-
-       while ((c = getopt(ac, av, "cNnp:qS")) != -1) {
-               switch(c) {
-               case 'c':
-                       do_compact = 1;
-                       break;
-
-               case 'N':
-                       do_resolv = 1;
-                       break;
-
-               case 'n':
-                       test_only = 1;
-                       break;
-
-               case 'p':
-                       cmd = optarg;
-                       /*
-                        * Skip previous args and delete last one, so we
-                        * pass all but the last argument to the preprocessor
-                        * via av[optind-1]
-                        */
-                       av += optind - 1;
-                       ac -= optind - 1;
-                       av[ac-1] = NULL;
-                       fprintf(stderr, "command is %s\n", av[0]);
-                       break;
-
-               case 'q':
-                       do_quiet = 1;
-                       break;
-
-               case 'S':
-                       show_sets = 1;
-                       break;
-
-               default:
-                       errx(EX_USAGE, "bad arguments, for usage"
-                            " summary ``ipfw''");
-               }
-
-               if (cmd != NULL)
-                       break;
-       }
-
-       if (cmd == NULL && ac != optind + 1) {
-               fprintf(stderr, "ac %d, optind %d\n", ac, optind);
-               errx(EX_USAGE, "extraneous filename arguments");
-       }
-
-       if ((f = fopen(filename, "r")) == NULL)
-               err(EX_UNAVAILABLE, "fopen: %s", filename);
-
-       if (cmd != NULL) {                      /* pipe through preprocessor */
-               int pipedes[2];
-
-               if (pipe(pipedes) == -1)
-                       err(EX_OSERR, "cannot create pipe");
-
-               preproc = fork();
-               if (preproc == -1)
-                       err(EX_OSERR, "cannot fork");
-
-               if (preproc == 0) {
-                       /*
-                        * Child, will run the preprocessor with the
-                        * file on stdin and the pipe on stdout.
-                        */
-                       if (dup2(fileno(f), 0) == -1
-                           || dup2(pipedes[1], 1) == -1)
-                               err(EX_OSERR, "dup2()");
-                       fclose(f);
-                       close(pipedes[1]);
-                       close(pipedes[0]);
-                       execvp(cmd, av);
-                       err(EX_OSERR, "execvp(%s) failed", cmd);
-               } else { /* parent, will reopen f as the pipe */
-                       fclose(f);
-                       close(pipedes[1]);
-                       if ((f = fdopen(pipedes[0], "r")) == NULL) {
-                               int savederrno = errno;
-
-                               (void)kill(preproc, SIGTERM);
-                               errno = savederrno;
-                               err(EX_OSERR, "fdopen()");
-                       }
-               }
-       }
-
-       while (fgets(buf, BUFSIZ, f)) {         /* read commands */
-               char linename[16];
-               char *args[1];
-
-               lineno++;
-               snprintf(linename, sizeof(linename), "Line %d", lineno);
-               setprogname(linename); /* XXX */
-               args[0] = buf;
-               ipfw_main(1, args);
-       }
-       fclose(f);
-       if (cmd != NULL) {
-               int status;
-
-               if (waitpid(preproc, &status, 0) == -1)
-                       errx(EX_OSERR, "waitpid()");
-               if (WIFEXITED(status) && WEXITSTATUS(status) != EX_OK)
-                       errx(EX_UNAVAILABLE,
-                           "preprocessor exited with status %d",
-                           WEXITSTATUS(status));
-               else if (WIFSIGNALED(status))
-                       errx(EX_UNAVAILABLE,
-                           "preprocessor exited with signal %d",
-                           WTERMSIG(status));
-       }
-}
-
-int
-main(int ac, char *av[])
-{
-       /*
-        * If the last argument is an absolute pathname, interpret it
-        * as a file to be preprocessed.
-        */
-
-       if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0)
-               ipfw_readfile(ac, av);
-       else {
-               if (ipfw_main(ac-1, av+1))
-                       show_usage();
-       }
-       return EX_OK;
-}
index 040def3346a057b5b325ab3acf3954a952cd0aab..61762fe4e8f5421aa7409d26cc28d7b4172d0a50 100644 (file)
@@ -63,6 +63,7 @@ __unused static const char copyright[] =
 #include "kdump.h"
 #include <arpa/inet.h>
 
 #include "kdump.h"
 #include <arpa/inet.h>
 
+#include <assert.h>
 #include <stdint.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdint.h>
 #include <ctype.h>
 #include <errno.h>
@@ -80,6 +81,7 @@ __unused static const char copyright[] =
 
 #include "kdumpsubs.h"
 
 
 #include "kdumpsubs.h"
 
+#define DEFAULT_KDUMPD_PORTNO (1069)
 #define        TIMEOUT         2
 
 int    peer;
 #define        TIMEOUT         2
 
 int    peer;
@@ -110,6 +112,7 @@ static struct dirlist {
 static int     suppress_naks;
 static int     logging = 1;
 static int     ipchroot;
 static int     suppress_naks;
 static int     logging = 1;
 static int     ipchroot;
+static int  server_mode = 1;
 
 static char *errtomsg __P((int));
 static void  nak __P((int));
 
 static char *errtomsg __P((int));
 static void  nak __P((int));
@@ -137,7 +140,7 @@ main(argc, argv)
        char *chuser = "nobody";
 
        openlog("kdumpd", LOG_PID | LOG_NDELAY, LOG_FTP);
        char *chuser = "nobody";
 
        openlog("kdumpd", LOG_PID | LOG_NDELAY, LOG_FTP);
-       while ((ch = getopt(argc, argv, "cClns:u:")) != -1) {
+       while ((ch = getopt(argc, argv, "cClns:u:w")) != -1) {
                switch (ch) {
                case 'c':
                        ipchroot = 1;
                switch (ch) {
                case 'c':
                        ipchroot = 1;
@@ -157,6 +160,9 @@ main(argc, argv)
                case 'u':
                        chuser = optarg;
                        break;
                case 'u':
                        chuser = optarg;
                        break;
+               case 'w':
+                       server_mode = 0;
+                       break;
                default:
                        syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
                }
                default:
                        syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
                }
@@ -184,67 +190,70 @@ main(argc, argv)
                exit(1);
        }
 
                exit(1);
        }
 
-       on = 1;
-       if (ioctl(0, FIONBIO, &on) < 0) {
-               syslog(LOG_ERR, "ioctl(FIONBIO): %m");
-               exit(1);
-       }
-       fromlen = sizeof (from);
-       n = recvfrom(0, buf, sizeof (buf), 0,
-           (struct sockaddr *)&from, &fromlen);
-       if (n < 0) {
-               syslog(LOG_ERR, "recvfrom: %m");
-               exit(1);
-       }
-       /*
-        * Now that we have read the message out of the UDP
-        * socket, we fork and exit.  Thus, inetd will go back
-        * to listening to the kdump port, and the next request
-        * to come in will start up a new instance of kdumpd.
-        *
-        * We do this so that inetd can run kdumpd in "wait" mode.
-        * The problem with kdumpd running in "nowait" mode is that
-        * inetd may get one or more successful "selects" on the
-        * kdump port before we do our receive, so more than one
-        * instance of kdumpd may be started up.  Worse, if kdumpd
-        * breaks before doing the above "recvfrom", inetd would
-        * spawn endless instances, clogging the system.
-        */
-       {
-               int pid;
-               int i;
-               socklen_t j;
-
-               for (i = 1; i < 20; i++) {
-                   pid = fork();
-                   if (pid < 0) {
-                               sleep(i);
-                               /*
-                                * flush out to most recently sent request.
-                                *
-                                * This may drop some requests, but those
-                                * will be resent by the clients when
-                                * they timeout.  The positive effect of
-                                * this flush is to (try to) prevent more
-                                * than one kdumpd being started up to service
-                                * a single request from a single client.
-                                */
-                               j = sizeof from;
-                               i = recvfrom(0, buf, sizeof (buf), 0,
-                                   (struct sockaddr *)&from, &j);
-                               if (i > 0) {
-                                       n = i;
-                                       fromlen = j;
-                               }
-                   } else {
-                               break;
-                   }
+       /* If we are not in server mode, skip the whole 'inetd' logic below. */
+       if (server_mode) {
+               on = 1;
+               if (ioctl(0, FIONBIO, &on) < 0) {
+                       syslog(LOG_ERR, "ioctl(FIONBIO): %m");
+                       exit(1);
                }
                }
-               if (pid < 0) {
-                       syslog(LOG_ERR, "fork: %m");
+               fromlen = sizeof (from);
+               n = recvfrom(0, buf, sizeof (buf), 0,
+                       (struct sockaddr *)&from, &fromlen);
+               if (n < 0) {
+                       syslog(LOG_ERR, "recvfrom: %m");
                        exit(1);
                        exit(1);
-               } else if (pid != 0) {
-                       exit(0);
+               }
+               /*
+                * Now that we have read the message out of the UDP
+                * socket, we fork and exit.  Thus, inetd will go back
+                * to listening to the kdump port, and the next request
+                * to come in will start up a new instance of kdumpd.
+                *
+                * We do this so that inetd can run kdumpd in "wait" mode.
+                * The problem with kdumpd running in "nowait" mode is that
+                * inetd may get one or more successful "selects" on the
+                * kdump port before we do our receive, so more than one
+                * instance of kdumpd may be started up.  Worse, if kdumpd
+                * breaks before doing the above "recvfrom", inetd would
+                * spawn endless instances, clogging the system.
+                */
+               {
+                       int pid;
+                       int i;
+                       socklen_t j;
+
+                       for (i = 1; i < 20; i++) {
+                               pid = fork();
+                               if (pid < 0) {
+                                       sleep(i);
+                                       /*
+                                        * flush out to most recently sent request.
+                                        *
+                                        * This may drop some requests, but those
+                                        * will be resent by the clients when
+                                        * they timeout.  The positive effect of
+                                        * this flush is to (try to) prevent more
+                                        * than one kdumpd being started up to service
+                                        * a single request from a single client.
+                                        */
+                                       j = sizeof from;
+                                       i = recvfrom(0, buf, sizeof (buf), 0,
+                                               (struct sockaddr *)&from, &j);
+                                       if (i > 0) {
+                                               n = i;
+                                               fromlen = j;
+                                       }
+                               } else {
+                                       break;
+                               }
+                       }
+                       if (pid < 0) {
+                               syslog(LOG_ERR, "fork: %m");
+                               exit(1);
+                       } else if (pid != 0) {
+                               exit(0);
+                       }
                }
        }
 
                }
        }
 
@@ -278,10 +287,9 @@ main(argc, argv)
                }
                chdir( "/" );
                setuid(nobody->pw_uid);
                }
                chdir( "/" );
                setuid(nobody->pw_uid);
-       }
-       else
-         if (0 !=  chdir(dirs->name))
+       } else if (0 !=  chdir(dirs->name)) {
            syslog(LOG_ERR, "chdir%s: %m", dirs->name);
            syslog(LOG_ERR, "chdir%s: %m", dirs->name);
+       }
 
        from.sin_family = AF_INET;
        alarm(0);
 
        from.sin_family = AF_INET;
        alarm(0);
@@ -294,10 +302,32 @@ main(argc, argv)
        }
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        }
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
+
+       if (!server_mode) {
+               sin.sin_addr.s_addr = htonl(INADDR_ANY);
+               sin.sin_port = htons((uint16_t) DEFAULT_KDUMPD_PORTNO);
+       }
+
        if (bind(peer, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
                syslog(LOG_ERR, "bind: %m");
                exit(1);
        }
        if (bind(peer, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
                syslog(LOG_ERR, "bind: %m");
                exit(1);
        }
+
+       if (!server_mode) {
+               /*
+                * Wait for an incoming message from a remote peer, note that we need to
+                * populate n since kdump() expect the first message to be in buf
+                * already.
+                */
+               socklen_t slen = sizeof(from);
+               n = recvfrom(peer, buf, sizeof(buf), 0,
+                       (struct sockaddr *) &from, &slen);
+               if (n <= 0) {
+                       syslog(LOG_ERR, "recvfrom: %m");
+                       exit(1);
+               }
+       }
+
        if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
                syslog(LOG_ERR, "connect: %m");
                exit(1);
        if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
                syslog(LOG_ERR, "connect: %m");
                exit(1);
index a96e169f3a0475f8d5ae852d7f3d3aeff1afd7a9..b1217ebe51af076cf3baa6dc98af94993cdfa576 100644 (file)
@@ -170,13 +170,16 @@ another device on the network is using the same link-local address.
 the interface is enabled to proxy neighbor discovery for global scope prefixes
 matching those on link at other interfaces.
 .It Xo
 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
 .Ic insecure
 do not use cryptographically generated addresses (CGA) on this interface.
 .Xc
+.It Xo
+.Ic replicated
+Address autoconfiguration proceeds under the assumption that interface
+configuration is replicated by a sleep proxy at another node on the link.
+Disables optimistic DAD and sends unsolicited NA with O=1 when DAD completes.
+Ignores DAD failures from other hardware addresses.
+.Xc
 .El
 .It Fl l
 Show link-layer reachability information.
 .El
 .It Fl l
 Show link-layer reachability information.
index 2afce5dc12a8331ba7783962a4e919100d2a26d8..01d64aa77a9ca26a0b101cb7d2e7390b83de506b 100644 (file)
@@ -1205,9 +1205,9 @@ ifinfo(int argc, char **argv)
        } while (0)
                SETFLAG("nud", ND6_IFF_PERFORMNUD);
                SETFLAG("proxy_prefixes", ND6_IFF_PROXY_PREFIXES);
        } while (0)
                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);
                SETFLAG("disabled", ND6_IFF_IFDISABLED);
                SETFLAG("insecure", ND6_IFF_INSECURE);
+               SETFLAG("replicated", ND6_IFF_REPLICATED);
 
                ND.flags = newflags;
                if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
 
                ND.flags = newflags;
                if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
@@ -1248,17 +1248,19 @@ ifinfo(int argc, char **argv)
                }
        }
        if (ND.flags) {
                }
        }
        if (ND.flags) {
-               printf("\nFlags: ");
+               printf("\nFlags: 0x%x ", ND.flags);
                if ((ND.flags & ND6_IFF_IFDISABLED) != 0)
                        printf("IFDISABLED ");
                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 ");
                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 ");
+               if ((ND.flags & ND6_IFF_REPLICATED) != 0)
+                       printf("REPLICATED ");
+               if ((ND.flags & ND6_IFF_DAD) != 0)
+                       printf("DAD ");
        }
        putc('\n', stdout);
 #undef ND
        }
        putc('\n', stdout);
 #undef ND
index 714e6511ba168efb42674bc9fbe8d1d2d9b578cd..a0ef208bfa5741973e1be66a83d86d9ab1306678 100644 (file)
@@ -115,6 +115,7 @@ static char *qid2str(unsigned int);
 static char *qstate2str(unsigned int);
 static char *tcqslot2str(unsigned int);
 static char *rate2str(long double);
 static char *qstate2str(unsigned int);
 static char *tcqslot2str(unsigned int);
 static char *rate2str(long double);
+static char *pri2str(unsigned int i);
 
 #define AVGN_MAX       8
 
 
 #define AVGN_MAX       8
 
@@ -142,6 +143,8 @@ static void print_qfqstats(int slot, struct qfq_classstats *,
     struct queue_stats *);
 static void print_sfbstats(struct sfb_stats *);
 static void update_avg(struct if_ifclassq_stats *, struct queue_stats *);
     struct queue_stats *);
 static void print_sfbstats(struct sfb_stats *);
 static void update_avg(struct if_ifclassq_stats *, struct queue_stats *);
+static void print_fq_codel_stats(int slot, struct fq_codel_classstats *,
+    struct queue_stats *);
 
 struct queue_stats qstats[IFCQ_SC_MAX];
 
 
 struct queue_stats qstats[IFCQ_SC_MAX];
 
@@ -1064,6 +1067,8 @@ loop:
                                    sum->ift_fb - total->ift_fb);
                }
                *total = *sum;
                                    sum->ift_fb - total->ift_fb);
                }
                *total = *sum;
+               
+               free(ifmsuppall);
        }
        if (!first)
                putchar('\n');
        }
        if (!first)
                putchar('\n');
@@ -1468,6 +1473,11 @@ loop:
                                print_qfqstats(n, &ifcqs->ifqs_qfq_stats,
                                    &qstats[n]);
                                break;
                                print_qfqstats(n, &ifcqs->ifqs_qfq_stats,
                                    &qstats[n]);
                                break;
+                       case PKTSCHEDT_FQ_CODEL:
+                               print_fq_codel_stats(n,
+                                   &ifcqs->ifqs_fq_codel_stats,
+                                   &qstats[n]);
+                               break;
                        case PKTSCHEDT_NONE:
                        default:
                                break;
                        case PKTSCHEDT_NONE:
                        default:
                                break;
@@ -1699,6 +1709,35 @@ print_qfqstats(int slot, struct qfq_classstats *cs, struct queue_stats *qs)
        }
 }
 
        }
 }
 
+static void
+print_fq_codel_stats(int pri, struct fq_codel_classstats *fqst,
+    struct queue_stats *qs)
+{
+       printf("     [ pri: %s (%d)\tsrv_cl: 0x%x\tquantum: %d\tdrr_max: %d ]\n",
+           pri2str(fqst->fcls_pri), fqst->fcls_pri,
+           fqst->fcls_service_class, fqst->fcls_quantum,
+           fqst->fcls_drr_max);
+       printf("     [ budget: %lld\t\ttarget qdelay: %14s ]\n",
+           fqst->fcls_budget, nsec_to_str(fqst->fcls_target_qdelay));
+       printf("     [ flow control: %u\tfeedback: %u\tstalls: %u\tfailed: %u ]\n",
+           fqst->fcls_flow_control, fqst->fcls_flow_feedback,
+           fqst->fcls_dequeue_stall, fqst->fcls_flow_control_fail);
+       printf("     [ drop overflow: %llu\tearly: %llu\tmemfail: %u\tduprexmt:%u ]\n",
+           fqst->fcls_drop_overflow, fqst->fcls_drop_early,
+           fqst->fcls_drop_memfailure, fqst->fcls_dup_rexmts);
+       printf("     [ flows total: %u\tnew: %u\told: %u ]\n",
+           fqst->fcls_flows_cnt,
+           fqst->fcls_newflows_cnt, fqst->fcls_oldflows_cnt);
+       printf("     [ queued pkts: %llu\tbytes: %llu ]\n",
+           fqst->fcls_pkt_cnt, fqst->fcls_byte_cnt);
+       printf("     [ dequeued pkts: %llu\tbytes: %llu ]\n",
+           fqst->fcls_dequeue, fqst->fcls_dequeue_bytes);
+       printf("     [ throttle on: %u\toff: %u\tdrop: %u ]\n",
+           fqst->fcls_throttle_on, fqst->fcls_throttle_off,
+           fqst->fcls_throttle_drops);
+       printf("=====================================================\n");
+}
+
 static void
 print_sfbstats(struct sfb_stats *sfb)
 {
 static void
 print_sfbstats(struct sfb_stats *sfb)
 {
@@ -1808,6 +1847,10 @@ update_avg(struct if_ifclassq_stats *ifcqs, struct queue_stats *qs)
                b = ifcqs->ifqs_qfq_stats.xmitcnt.bytes;
                p = ifcqs->ifqs_qfq_stats.xmitcnt.packets;
                break;
                b = ifcqs->ifqs_qfq_stats.xmitcnt.bytes;
                p = ifcqs->ifqs_qfq_stats.xmitcnt.packets;
                break;
+       case PKTSCHEDT_FQ_CODEL:
+               b = ifcqs->ifqs_fq_codel_stats.fcls_dequeue_bytes;
+               p = ifcqs->ifqs_fq_codel_stats.fcls_dequeue;
+               break;
        default:
                b = 0;
                p = 0;
        default:
                b = 0;
                p = 0;
@@ -1868,8 +1911,8 @@ qtype2str(classq_type_t t)
 }
 
 #define NSEC_PER_SEC    1000000000      /* nanoseconds per second */
 }
 
 #define NSEC_PER_SEC    1000000000      /* nanoseconds per second */
-#define USEC_PER_SEC    1000000                /* nanoseconds per second */
-#define MSEC_PER_SEC    1000           /* nanoseconds per second */
+#define USEC_PER_SEC    1000000                /* microseconds per second */
+#define MSEC_PER_SEC    1000           /* milliseconds per second */
 
 static char *
 nsec_to_str(unsigned long long nsec)
 
 static char *
 nsec_to_str(unsigned long long nsec)
@@ -1923,6 +1966,9 @@ sched2str(unsigned int s)
        case PKTSCHEDT_QFQ:
                c = "QFQ";
                break;
        case PKTSCHEDT_QFQ:
                c = "QFQ";
                break;
+       case PKTSCHEDT_FQ_CODEL:
+               c = "FQ_CODEL";
+               break;
        default:
                c = "UNKNOWN";
                break;
        default:
                c = "UNKNOWN";
                break;
@@ -2007,6 +2053,48 @@ tcqslot2str(unsigned int s)
        return (c);
 }
 
        return (c);
 }
 
+static char *
+pri2str(unsigned int i)
+{
+       char *c;
+       switch (i) {
+       case 9:
+               c = "BK_SYS";
+               break;
+       case 8:
+               c = "BK";
+               break;
+       case 7:
+               c = "BE";
+               break;
+       case 6:
+               c = "RD";
+               break;
+       case 5:
+               c = "OAM";
+               break;
+       case 4:
+               c = "AV";
+               break;
+       case 3:
+               c = "RV";
+               break;
+       case 2:
+               c = "VI";
+               break;
+       case 1:
+               c = "VO";
+               break;
+       case 0:
+               c = "CTL";
+               break;
+       default:
+               c = "?";
+               break;
+       }
+       return (c);
+}
+
 static char *
 qstate2str(unsigned int s)
 {
 static char *
 qstate2str(unsigned int s)
 {
@@ -2295,8 +2383,8 @@ rem_nstat_src(int fd, nstat_src_ref_t sref)
        }
 
        if (remrsp->srcref != sref) {
        }
 
        if (remrsp->srcref != sref) {
-               fprintf(stderr, "%s: received invalid srcref, received %u "
-                       "expected %u\n", __func__, remrsp->srcref, sref);
+               fprintf(stderr, "%s: received invalid srcref, received %llu "
+                       "expected %llu\n", __func__, remrsp->srcref, sref);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -2352,7 +2440,7 @@ get_src_decsription(int fd, nstat_src_ref_t srcref,
        if (drsp->srcref != srcref)
        {
                fprintf(stderr, "%s: received message for wrong source, "
        if (drsp->srcref != srcref)
        {
                fprintf(stderr, "%s: received message for wrong source, "
-                       "received 0x%x expected 0x%x\n",
+                       "received 0x%llx expected 0x%llx\n",
                        __func__, drsp->srcref, srcref);
                return -1;
        }
                        __func__, drsp->srcref, srcref);
                return -1;
        }
@@ -2427,7 +2515,7 @@ print_wifi_status(nstat_ifnet_desc_wifi_status *status)
 static void
 print_cellular_status(nstat_ifnet_desc_cellular_status *status)
 {
 static void
 print_cellular_status(nstat_ifnet_desc_cellular_status *status)
 {
-       int tmp;
+       int tmp, tmp_mss;
 #define val(x, f)      \
        ((status->valid_bitmask & NSTAT_IFNET_DESC_CELL_ ## f ## _VALID) ?\
         status->x : -1)
 #define val(x, f)      \
        ((status->valid_bitmask & NSTAT_IFNET_DESC_CELL_ ## f ## _VALID) ?\
         status->x : -1)
@@ -2439,6 +2527,12 @@ print_cellular_status(nstat_ifnet_desc_cellular_status *status)
        ((tmp == NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_MEDIUM) ? "(medium)" : \
        ((tmp == NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_HIGH) ? "(high)" : \
        "(?)")))))
        ((tmp == NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_MEDIUM) ? "(medium)" : \
        ((tmp == NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_HIGH) ? "(high)" : \
        "(?)")))))
+#define pretxtm(n, un) \
+       (((tmp_mss = val(n,un)) == -1) ? "(not valid)" : \
+       ((tmp_mss == NSTAT_IFNET_DESC_MSS_RECOMMENDED_NONE) ? "(none)" : \
+       ((tmp_mss == NSTAT_IFNET_DESC_MSS_RECOMMENDED_MEDIUM) ? "(medium)" : \
+       ((tmp_mss == NSTAT_IFNET_DESC_MSS_RECOMMENDED_LOW) ? "(low)" : \
+       "(?)"))))
 
        printf("\ncellular status:\n");
        printf(
 
        printf("\ncellular status:\n");
        printf(
@@ -2456,7 +2550,8 @@ print_cellular_status(nstat_ifnet_desc_cellular_status *status)
            "\t%s:\t%d\n"
            "\t%s:\t%d\n"
            "\t%s:\t%d\n"
            "\t%s:\t%d\n"
            "\t%s:\t%d\n"
            "\t%s:\t%d\n"
-           "\t%s:\t%d\n",
+           "\t%s:\t%d\n"
+           "\t%s:\t%d %s\n",
            parg(link_quality_metric, LINK_QUALITY_METRIC),
            parg(ul_effective_bandwidth, UL_EFFECTIVE_BANDWIDTH),
            parg(ul_max_bandwidth, UL_MAX_BANDWIDTH),
            parg(link_quality_metric, LINK_QUALITY_METRIC),
            parg(ul_effective_bandwidth, UL_EFFECTIVE_BANDWIDTH),
            parg(ul_max_bandwidth, UL_MAX_BANDWIDTH),
@@ -2472,7 +2567,9 @@ print_cellular_status(nstat_ifnet_desc_cellular_status *status)
            parg(dl_effective_bandwidth, DL_EFFECTIVE_BANDWIDTH),
            parg(dl_max_bandwidth, DL_MAX_BANDWIDTH),
            parg(config_inactivity_time, CONFIG_INACTIVITY_TIME),
            parg(dl_effective_bandwidth, DL_EFFECTIVE_BANDWIDTH),
            parg(dl_max_bandwidth, DL_MAX_BANDWIDTH),
            parg(config_inactivity_time, CONFIG_INACTIVITY_TIME),
-           parg(config_backoff_time, CONFIG_BACKOFF_TIME)
+           parg(config_backoff_time, CONFIG_BACKOFF_TIME),
+           parg(mss_recommended, MSS_RECOMMENDED),
+           pretxtm(mss_recommended, MSS_RECOMMENDED)
            );
 #undef pretxtl
 #undef parg
            );
 #undef pretxtl
 #undef parg
index 47eeaea9c86efc7ab9489e28a34acc245bf466cf..d614aecd6dc791c0fdd2e147fb6cc5fcca80f8d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -697,6 +697,9 @@ tcp_stats(uint32_t off , char *name, int af)
        p(tcps_ecn_conn_plnoce, "\t\t%u connection%s using ECN have seen packet loss but no CE\n");
        p(tcps_ecn_conn_pl_ce, "\t\t%u connection%s using ECN have seen packet loss and CE\n");
        p(tcps_ecn_conn_nopl_ce, "\t\t%u connection%s using ECN received CE but no packet loss\n");
        p(tcps_ecn_conn_plnoce, "\t\t%u connection%s using ECN have seen packet loss but no CE\n");
        p(tcps_ecn_conn_pl_ce, "\t\t%u connection%s using ECN have seen packet loss and CE\n");
        p(tcps_ecn_conn_nopl_ce, "\t\t%u connection%s using ECN received CE but no packet loss\n");
+       p(tcps_ecn_fallback_synloss, "\t\t%u connection%s fell back to non-ECN due to SYN-loss\n");
+       p(tcps_ecn_fallback_reorder, "\t\t%u connection%s fell back to non-ECN due to reordering\n");
+       p(tcps_ecn_fallback_ce, "\t\t%u connection%s fell back to non-ECN due to excessive CE-markings\n");
        p(tcps_detect_reordering, "\t%u time%s packet reordering was detected on a connection\n");
        p(tcps_reordered_pkts, "\t\t%u time%s transmitted packets were reordered\n");
        p(tcps_delay_recovery, "\t\t%u time%s fast recovery was delayed to handle reordering\n");
        p(tcps_detect_reordering, "\t%u time%s packet reordering was detected on a connection\n");
        p(tcps_reordered_pkts, "\t\t%u time%s transmitted packets were reordered\n");
        p(tcps_delay_recovery, "\t\t%u time%s fast recovery was delayed to handle reordering\n");
@@ -721,6 +724,9 @@ tcp_stats(uint32_t off , char *name, int af)
        p(tcps_tfo_syn_data_acked,"\t\t%u time%s our SYN with data has been acknowledged\n");
        p(tcps_tfo_syn_loss,"\t%u time%s a connection-attempt with TFO fell back to regular TCP\n");
        p(tcps_tfo_blackhole,"\t%u time%s a TFO-connection blackhole'd\n");
        p(tcps_tfo_syn_data_acked,"\t\t%u time%s our SYN with data has been acknowledged\n");
        p(tcps_tfo_syn_loss,"\t%u time%s a connection-attempt with TFO fell back to regular TCP\n");
        p(tcps_tfo_blackhole,"\t%u time%s a TFO-connection blackhole'd\n");
+       p(tcps_mss_to_default,"\t%u time%s maximum segment size was changed to default\n");
+       p(tcps_mss_to_medium,"\t%u time%s maximum segment size was changed to medium\n");
+       p(tcps_mss_to_low,"\t%u time%s maximum segment size was changed to low\n");
 
        if (interval > 0) {
                bcopy(&tcpstat, &ptcpstat, len);
 
        if (interval > 0) {
                bcopy(&tcpstat, &ptcpstat, len);
@@ -791,10 +797,10 @@ mptcp_stats(uint32_t off , char *name, int af)
        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");
        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");
-       p3(tcps_mp_sel_symtomsd, "\t%u subflow switche%s due to advisory\n");
-       p3(tcps_mp_sel_rtt, "\t%u subflow switche%s due to rtt\n");
-       p3(tcps_mp_sel_rto, "\t%u subflow switche%s due to rto\n");
-       p3(tcps_mp_sel_peer, "\t%u subflow switche%s due to peer\n");
+       p3(tcps_mp_sel_symtomsd, "\t%u subflow switch%s due to advisory\n");
+       p3(tcps_mp_sel_rtt, "\t%u subflow switch%s due to rtt\n");
+       p3(tcps_mp_sel_rto, "\t%u subflow switch%s due to rto\n");
+       p3(tcps_mp_sel_peer, "\t%u subflow switch%s due to peer\n");
        p3(tcps_mp_num_probes, "\t%u number of subflow probe%s\n");
 
        if (interval > 0) {
        p3(tcps_mp_num_probes, "\t%u number of subflow probe%s\n");
 
        if (interval > 0) {
@@ -1079,8 +1085,11 @@ arp_stats(uint32_t off, char *name, int af)
     printf(m, ARPDIFF(f), plural(ARPDIFF(f)))
 #define        p2(f, m) if (ARPDIFF(f) || sflag <= 1) \
     printf(m, ARPDIFF(f), pluralies(ARPDIFF(f)))
     printf(m, ARPDIFF(f), plural(ARPDIFF(f)))
 #define        p2(f, m) if (ARPDIFF(f) || sflag <= 1) \
     printf(m, ARPDIFF(f), pluralies(ARPDIFF(f)))
+#define        p3(f, m) if (ARPDIFF(f) || sflag <= 1) \
+    printf(m, ARPDIFF(f), plural(ARPDIFF(f)), pluralies(ARPDIFF(f)))
 
 
-       p(txrequests, "\t%u ARP request%s sent\n");
+       p(txrequests, "\t%u broadast ARP request%s sent\n");
+       p(txurequests, "\t%u unicast 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(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");
@@ -1089,6 +1098,7 @@ arp_stats(uint32_t off, char *name, int af)
        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(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");
+       p3(held, "\t%u total packet%s held awaiting ARP repl%s\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(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");
index a741196571c1c58d8cc0c8d0ffd8dc657268c6cd..6e81df7d1581edeeaa7cf71f9e2042623fe1a49a 100644 (file)
@@ -436,6 +436,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
        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");
        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");
+       p1a(ip6s_atmfrag_rcvd, "\t\t\t%llu atomic fragments received\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_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");
@@ -616,7 +617,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
        for (first = 1, i = 0; i < IP6S_SRCRULE_COUNT; i++) {
                if (IP6DIFF(ip6s_sources_rule[i]) || 1) {
                        if (first) {
        for (first = 1, i = 0; i < IP6S_SRCRULE_COUNT; i++) {
                if (IP6DIFF(ip6s_sources_rule[i]) || 1) {
                        if (first) {
-                               printf("\t\tsource addresse selection\n");
+                               printf("\t\tsource address selection\n");
                                first = 0;
                        }
                        PRINT_SRCRULESTAT(ip6s_sources_rule[i], i);
                                first = 0;
                        }
                        PRINT_SRCRULESTAT(ip6s_sources_rule[i], i);
@@ -624,8 +625,10 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused)
        }
        
        p(ip6s_dad_collide, "\t\t%llu duplicate address detection collision%s\n");
        }
        
        p(ip6s_dad_collide, "\t\t%llu duplicate address detection collision%s\n");
+       
+       p(ip6s_dad_loopcount, "\t\t%llu duplicate address detection NS loop%s\n");
 
 
-       p(ip6s_sources_skip_expensive_secondary_if, "\t\t%llu times%s ignored source on secondary expensive I/F\n");
+       p(ip6s_sources_skip_expensive_secondary_if, "\t\t%llu time%s ignored source on secondary expensive I/F\n");
 
        if (interval > 0) {
                bcopy(&ip6stat, &pip6stat, len);
 
        if (interval > 0) {
                bcopy(&ip6stat, &pip6stat, len);
@@ -684,6 +687,7 @@ ip6_ifstats(char *ifname)
        p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
        p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
        p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
        p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
        p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
        p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
+       p(ifs6_atmfrag_rcvd, "\t%llu atomic fragments%s received\n");
        p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
        p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
        p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
        p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
        p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
        p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
@@ -1039,6 +1043,7 @@ icmp6_stats(uint32_t off __unused, char *name, int af __unused)
        p(icp6s_badra, "\t%qu bad router advertisement message%s\n");
        p(icp6s_badredirect, "\t%qu bad redirect message%s\n");
        p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
        p(icp6s_badra, "\t%qu bad router advertisement message%s\n");
        p(icp6s_badredirect, "\t%qu bad redirect message%s\n");
        p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
+       p(icp6s_rfc6980_drop, "\t%qu dropped fragmented NDP message%s\n");
 
        if (interval > 0)
                bcopy(&icmp6stat, &picmp6stat, len);
 
        if (interval > 0)
                bcopy(&icmp6stat, &picmp6stat, len);
@@ -1145,7 +1150,7 @@ rip6_stats(uint32_t off __unused, char *name, int af __unused)
 #define        p(f, m) if (RIP6DIFF(f) || sflag <= 1) \
     printf(m, (unsigned long long)RIP6DIFF(f), plural(RIP6DIFF(f)))
        p(rip6s_ipackets, "\t%llu message%s received\n");
 #define        p(f, m) if (RIP6DIFF(f) || sflag <= 1) \
     printf(m, (unsigned long long)RIP6DIFF(f), plural(RIP6DIFF(f)))
        p(rip6s_ipackets, "\t%llu message%s received\n");
-       p(rip6s_isum, "\t%llu checksum calcuration%s on inbound\n");
+       p(rip6s_isum, "\t%llu checksum calculation%s on inbound\n");
        p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
        p(rip6s_nosock, "\t%llu message%s dropped due to no socket\n");
        p(rip6s_nosockmcast,
        p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
        p(rip6s_nosock, "\t%llu message%s dropped due to no socket\n");
        p(rip6s_nosockmcast,
@@ -1208,7 +1213,7 @@ inet6print(struct in6_addr *in6, int port, char *proto, int numeric)
        if (!numeric && port)
                GETSERVBYPORT6(port, proto, sp);
        if (sp || port == 0)
        if (!numeric && port)
                GETSERVBYPORT6(port, proto, sp);
        if (sp || port == 0)
-               snprintf(cp, sizeof(line) - (cp - line), "%.8s", sp ? sp->s_name : "*");
+               snprintf(cp, sizeof(line) - (cp - line), "%.15s", sp ? sp->s_name : "*");
        else
                snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port));
        width = lflag ? 45 : Aflag ? 18 : 22;
        else
                snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port));
        width = lflag ? 45 : Aflag ? 18 : 22;
index 4d6977070d5345da2b8fabbab4400a78849c8251..b3e13ffc0f80db477716fcde80d2d4f854219c76 100644 (file)
@@ -57,7 +57,7 @@ static const char *tcpstates[] = {
 
 static const char *mptcpstates[] = {
        "CLOSED", "LISTEN", "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1",
 
 static const char *mptcpstates[] = {
        "CLOSED", "LISTEN", "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1",
-       "CLOSING", "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", "FASTCLOSE_WAIT"
+       "CLOSING", "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", "TERMINATE"
 };
 
 int mptcp_done = 0;
 };
 
 int mptcp_done = 0;
index a3c170e1caeb60b6de059640611cde94ac5b7560..d94dec0c49b6e11c716d7df08f3b015156abca46 100644 (file)
@@ -377,7 +377,7 @@ kevt_stats(uint32_t off __unused, char *name, int af __unused)
 {
        static struct kevtstat pkevtstat;
        struct kevtstat kevtstat;
 {
        static struct kevtstat pkevtstat;
        struct kevtstat kevtstat;
-       size_t len = sizeof(struct kctlstat);
+       size_t len = sizeof(struct kevtstat);
        const char *mibvar = "net.systm.kevt.stats";
        
        if (sysctlbyname(mibvar, &kevtstat, &len, 0, 0) < 0) {
        const char *mibvar = "net.systm.kevt.stats";
        
        if (sysctlbyname(mibvar, &kevtstat, &len, 0, 0) < 0) {
index 215480947e68b852e4d3d3f17f8852551d5f53f9..2c7b2efcd141bc4bd4312e5b73fe0b5b04c21fdf 100644 (file)
@@ -86,7 +86,7 @@ static        void unixdomainpr __P((struct xunpcb *, struct xsocket *));
 #endif
 
 static const char *const socktype[] =
 #endif
 
 static const char *const socktype[] =
-    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
+    { "#0", "stream", "dgram", "raw" };
 
 void
 unixpr()
 
 void
 unixpr()
@@ -105,7 +105,7 @@ unixpr()
        char mibvar[sizeof "net.local.seqpacket.pcblist"];
 #endif
 
        char mibvar[sizeof "net.local.seqpacket.pcblist"];
 #endif
 
-       for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
+       for (type = SOCK_STREAM; type <= SOCK_RAW; type++) {
 #if !TARGET_OS_EMBEDDED
                snprintf(mibvar, sizeof(mibvar), "net.local.%s.pcblist64", socktype[type]);
 #else
 #if !TARGET_OS_EMBEDDED
                snprintf(mibvar, sizeof(mibvar), "net.local.%s.pcblist64", socktype[type]);
 #else
index d7b9d4c1753aeba5f1fc6b5df6dc43b1e7abb8b6..511810c66a3585140f8b3eb0c63ce89f7bb2359a 100755 (executable)
@@ -17,6 +17,7 @@
                                72B732EB1899B19A0060E6D4 /* PBXTargetDependency */,
                                72179EAE146233390098FB3E /* PBXTargetDependency */,
                                7282BA571AFBDEAD005DE836 /* PBXTargetDependency */,
                                72B732EB1899B19A0060E6D4 /* PBXTargetDependency */,
                                72179EAE146233390098FB3E /* PBXTargetDependency */,
                                7282BA571AFBDEAD005DE836 /* PBXTargetDependency */,
+                               72946F4C1BBF063800087E35 /* PBXTargetDependency */,
                                034E4469100BDD00009CA3DC /* PBXTargetDependency */,
                                565825AF13392239003E5FA5 /* PBXTargetDependency */,
                                72311F4D194A34F500EB4788 /* PBXTargetDependency */,
                                034E4469100BDD00009CA3DC /* PBXTargetDependency */,
                                565825AF13392239003E5FA5 /* PBXTargetDependency */,
                                72311F4D194A34F500EB4788 /* PBXTargetDependency */,
@@ -46,6 +47,7 @@
                                72B732E91899B18F0060E6D4 /* PBXTargetDependency */,
                                723C7074142BB003007C87E9 /* PBXTargetDependency */,
                                7282BA5B1AFBDED3005DE836 /* PBXTargetDependency */,
                                72B732E91899B18F0060E6D4 /* PBXTargetDependency */,
                                723C7074142BB003007C87E9 /* PBXTargetDependency */,
                                7282BA5B1AFBDED3005DE836 /* PBXTargetDependency */,
+                               7263724B1BCC709900E4B026 /* PBXTargetDependency */,
                                7261217D0EE8896800AFED1B /* PBXTargetDependency */,
                                4D2B05141208C6BB0004A3F3 /* PBXTargetDependency */,
                                724DABC30EE890A6008900D0 /* PBXTargetDependency */,
                                7261217D0EE8896800AFED1B /* PBXTargetDependency */,
                                4D2B05141208C6BB0004A3F3 /* PBXTargetDependency */,
                                724DABC30EE890A6008900D0 /* PBXTargetDependency */,
@@ -79,6 +81,7 @@
                                72ABD0A41083D818008C721C /* PBXTargetDependency */,
                                72ABD0881083D750008C721C /* PBXTargetDependency */,
                                7282BA591AFBDEC2005DE836 /* PBXTargetDependency */,
                                72ABD0A41083D818008C721C /* PBXTargetDependency */,
                                72ABD0881083D750008C721C /* PBXTargetDependency */,
                                7282BA591AFBDEC2005DE836 /* PBXTargetDependency */,
+                               72946F4E1BBF063F00087E35 /* PBXTargetDependency */,
                                565825B113392242003E5FA5 /* PBXTargetDependency */,
                                72311F4F194A34FE00EB4788 /* PBXTargetDependency */,
                                690D97BA12DE7130004323A7 /* PBXTargetDependency */,
                                565825B113392242003E5FA5 /* PBXTargetDependency */,
                                72311F4F194A34FE00EB4788 /* PBXTargetDependency */,
                                690D97BA12DE7130004323A7 /* PBXTargetDependency */,
                72311F55194A354F00EB4788 /* mptcp_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 72311F53194A354F00EB4788 /* mptcp_client.c */; };
                72311F56194A76DA00EB4788 /* mptcp_client.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 72311F52194A354F00EB4788 /* mptcp_client.1 */; };
                724753E7144905E300F6A941 /* dnctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724753E61448E1EF00F6A941 /* dnctl.8 */; };
                72311F55194A354F00EB4788 /* mptcp_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 72311F53194A354F00EB4788 /* mptcp_client.c */; };
                72311F56194A76DA00EB4788 /* mptcp_client.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 72311F52194A354F00EB4788 /* mptcp_client.1 */; };
                724753E7144905E300F6A941 /* dnctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 724753E61448E1EF00F6A941 /* dnctl.8 */; };
+               724769371CE2B1FF00AAB5F0 /* gmt2local.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA3C1AFAD58E005DE836 /* gmt2local.c */; };
+               724769381CE2C1E400AAB5F0 /* gmt2local.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA3C1AFAD58E005DE836 /* gmt2local.c */; };
                7247B83616165EDC00873B3C /* pktapctl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7247B83516165EDC00873B3C /* pktapctl.8 */; };
                7247B83C16165F0100873B3C /* pktapctl.c in Sources */ = {isa = PBXBuildFile; fileRef = 7247B83B16165F0100873B3C /* pktapctl.c */; };
                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 */; };
-               724DAB8A0EE88F24008900D0 /* ip6fw.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120680EE86F2300AFED1B /* ip6fw.8 */; };
                724DABA60EE88FED008900D0 /* kdumpd.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120710EE86F2D00AFED1B /* kdumpd.c */; };
                724DABA70EE88FED008900D0 /* kdumpsubs.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120720EE86F2D00AFED1B /* kdumpsubs.c */; };
                724DABAB0EE89006008900D0 /* kdumpd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120700EE86F2D00AFED1B /* kdumpd.8 */; };
                724DABA60EE88FED008900D0 /* kdumpd.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120710EE86F2D00AFED1B /* kdumpd.c */; };
                724DABA70EE88FED008900D0 /* kdumpsubs.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120720EE86F2D00AFED1B /* kdumpsubs.c */; };
                724DABAB0EE89006008900D0 /* kdumpd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120700EE86F2D00AFED1B /* kdumpd.8 */; };
                7282BA521AFAD58E005DE836 /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA451AFAD58E005DE836 /* session.c */; };
                7282BA531AFAD58E005DE836 /* support.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA471AFAD58E005DE836 /* support.c */; };
                7282BA551AFBCA66005DE836 /* libpcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7282BA541AFBCA66005DE836 /* libpcap.dylib */; };
                7282BA521AFAD58E005DE836 /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA451AFAD58E005DE836 /* session.c */; };
                7282BA531AFAD58E005DE836 /* support.c in Sources */ = {isa = PBXBuildFile; fileRef = 7282BA471AFAD58E005DE836 /* support.c */; };
                7282BA551AFBCA66005DE836 /* libpcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7282BA541AFBCA66005DE836 /* libpcap.dylib */; };
+               72946F501BBF07FF00087E35 /* frame_delay.c in Sources */ = {isa = PBXBuildFile; fileRef = 72946F4F1BBF07FF00087E35 /* frame_delay.c */; };
                7294F0DF0EE8BA730052EC88 /* spray.x in Sources */ = {isa = PBXBuildFile; fileRef = 726120E10EE86F9D00AFED1B /* spray.x */; };
                7294F1000EE8BB990052EC88 /* as.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120E50EE86FA700AFED1B /* as.c */; };
                7294F1010EE8BB990052EC88 /* findsaddr-socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120E70EE86FA700AFED1B /* findsaddr-socket.c */; };
                7294F0DF0EE8BA730052EC88 /* spray.x in Sources */ = {isa = PBXBuildFile; fileRef = 726120E10EE86F9D00AFED1B /* spray.x */; };
                7294F1000EE8BB990052EC88 /* as.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120E50EE86FA700AFED1B /* as.c */; };
                7294F1010EE8BB990052EC88 /* findsaddr-socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120E70EE86FA700AFED1B /* findsaddr-socket.c */; };
                        remoteGlobalIDString = 726121530EE8881700AFED1B;
                        remoteInfo = ifconfig;
                };
                        remoteGlobalIDString = 726121530EE8881700AFED1B;
                        remoteInfo = ifconfig;
                };
+               7263724A1BCC709900E4B026 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72946F421BBF055700087E35;
+                       remoteInfo = frame_delay;
+               };
                7282BA561AFBDEAD005DE836 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
                7282BA561AFBDEAD005DE836 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
                        remoteGlobalIDString = 7282BA0B1AFAD4C9005DE836;
                        remoteInfo = ecnprobe;
                };
                        remoteGlobalIDString = 7282BA0B1AFAD4C9005DE836;
                        remoteInfo = ecnprobe;
                };
+               72946F4B1BBF063800087E35 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72946F421BBF055700087E35;
+                       remoteInfo = frame_delay;
+               };
+               72946F4D1BBF063F00087E35 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72946F421BBF055700087E35;
+                       remoteInfo = frame_delay;
+               };
                7294F0E90EE8BAC80052EC88 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
                7294F0E90EE8BAC80052EC88 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 724862310EE86EB7001D0DE9 /* Project object */;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               724DAB760EE88E9C008900D0 /* CopyFiles */ = {
-                       isa = PBXCopyFilesBuildPhase;
-                       buildActionMask = 8;
-                       dstPath = /usr/share/man/man8;
-                       dstSubfolderSpec = 0;
-                       files = (
-                               724DAB680EE88E78008900D0 /* ipfw.8 in CopyFiles */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-               };
-               724DAB970EE88F56008900D0 /* CopyFiles */ = {
-                       isa = PBXCopyFilesBuildPhase;
-                       buildActionMask = 8;
-                       dstPath = /usr/share/man/man8;
-                       dstSubfolderSpec = 0;
-                       files = (
-                               724DAB8A0EE88F24008900D0 /* ip6fw.8 in CopyFiles */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-               };
                724DABB70EE89035008900D0 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                724DABB70EE89035008900D0 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               72946F411BBF055700087E35 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
                7294F11A0EE8BC0C0052EC88 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                7294F11A0EE8BC0C0052EC88 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                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 = "<group>"; };
                7247B83B16165F0100873B3C /* pktapctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pktapctl.c; sourceTree = "<group>"; };
                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 = "<group>"; };
                7247B83B16165F0100873B3C /* pktapctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pktapctl.c; sourceTree = "<group>"; };
-               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; };
                724DABDB0EE8912D008900D0 /* natd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = natd; sourceTree = BUILT_PRODUCTS_DIR; };
                724DAC0D0EE8940D008900D0 /* ndp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ndp; sourceTree = BUILT_PRODUCTS_DIR; };
                724DABA20EE88FE3008900D0 /* kdumpd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kdumpd; sourceTree = BUILT_PRODUCTS_DIR; };
                724DABDB0EE8912D008900D0 /* natd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = natd; sourceTree = BUILT_PRODUCTS_DIR; };
                724DAC0D0EE8940D008900D0 /* ndp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ndp; sourceTree = BUILT_PRODUCTS_DIR; };
                726120580EE86F0900AFED1B /* ifconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ifconfig.h; sourceTree = "<group>"; };
                726120590EE86F0900AFED1B /* ifmedia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifmedia.c; sourceTree = "<group>"; };
                7261205A0EE86F0900AFED1B /* ifvlan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifvlan.c; sourceTree = "<group>"; };
                726120580EE86F0900AFED1B /* ifconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ifconfig.h; sourceTree = "<group>"; };
                726120590EE86F0900AFED1B /* ifmedia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifmedia.c; sourceTree = "<group>"; };
                7261205A0EE86F0900AFED1B /* ifvlan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifvlan.c; sourceTree = "<group>"; };
-               726120680EE86F2300AFED1B /* ip6fw.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ip6fw.8; sourceTree = "<group>"; };
-               726120690EE86F2300AFED1B /* ip6fw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip6fw.c; sourceTree = "<group>"; };
                7261206E0EE86F2D00AFED1B /* com.apple.kdumpd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.kdumpd.plist; sourceTree = "<group>"; };
                7261206F0EE86F2D00AFED1B /* kdump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kdump.h; sourceTree = "<group>"; };
                726120700EE86F2D00AFED1B /* kdumpd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = kdumpd.8; sourceTree = "<group>"; };
                7261206E0EE86F2D00AFED1B /* com.apple.kdumpd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.kdumpd.plist; sourceTree = "<group>"; };
                7261206F0EE86F2D00AFED1B /* kdump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kdump.h; sourceTree = "<group>"; };
                726120700EE86F2D00AFED1B /* kdumpd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = kdumpd.8; sourceTree = "<group>"; };
                7261209B0EE86F4800AFED1B /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = "<group>"; };
                726120A00EE86F5000AFED1B /* ping.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ping.8; sourceTree = "<group>"; };
                726120A10EE86F5000AFED1B /* ping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ping.c; sourceTree = "<group>"; };
                7261209B0EE86F4800AFED1B /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = "<group>"; };
                726120A00EE86F5000AFED1B /* ping.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ping.8; sourceTree = "<group>"; };
                726120A10EE86F5000AFED1B /* ping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ping.c; sourceTree = "<group>"; };
-               726120A50EE86F5C00AFED1B /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
                726120A60EE86F5C00AFED1B /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = "<group>"; };
                726120A70EE86F5C00AFED1B /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; };
                726120A80EE86F5C00AFED1B /* ping6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ping6.8; sourceTree = "<group>"; };
                726120A60EE86F5C00AFED1B /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = "<group>"; };
                726120A70EE86F5C00AFED1B /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; };
                726120A80EE86F5C00AFED1B /* ping6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ping6.8; sourceTree = "<group>"; };
                726120F10EE86FA700AFED1B /* traceroute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute.c; sourceTree = "<group>"; };
                726120F20EE86FA700AFED1B /* traceroute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = traceroute.h; sourceTree = "<group>"; };
                726120F30EE86FA700AFED1B /* version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = version.c; sourceTree = "<group>"; };
                726120F10EE86FA700AFED1B /* traceroute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute.c; sourceTree = "<group>"; };
                726120F20EE86FA700AFED1B /* traceroute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = traceroute.h; sourceTree = "<group>"; };
                726120F30EE86FA700AFED1B /* version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = version.c; sourceTree = "<group>"; };
-               726120F90EE86FB500AFED1B /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
                726120FA0EE86FB500AFED1B /* traceroute6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = traceroute6.8; sourceTree = "<group>"; };
                726120FB0EE86FB500AFED1B /* traceroute6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute6.c; sourceTree = "<group>"; };
                726120FA0EE86FB500AFED1B /* traceroute6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = traceroute6.8; sourceTree = "<group>"; };
                726120FB0EE86FB500AFED1B /* traceroute6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute6.c; sourceTree = "<group>"; };
-               726120FF0EE8701100AFED1B /* ipfw.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ipfw.8; sourceTree = "<group>"; };
-               726121000EE8701100AFED1B /* ipfw2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipfw2.c; sourceTree = "<group>"; };
                7261210C0EE8707500AFED1B /* libalias.A.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libalias.A.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                726121220EE870D400AFED1B /* alias_local.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias_local.h; sourceTree = "<group>"; };
                726121230EE870D400AFED1B /* alias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias.h; sourceTree = "<group>"; };
                726121240EE870D400AFED1B /* libalias.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libalias.3; sourceTree = "<group>"; };
                7261212D0EE8710B00AFED1B /* arp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = arp; sourceTree = BUILT_PRODUCTS_DIR; };
                726121540EE8881700AFED1B /* ifconfig */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ifconfig; sourceTree = BUILT_PRODUCTS_DIR; };
                7261210C0EE8707500AFED1B /* libalias.A.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libalias.A.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                726121220EE870D400AFED1B /* alias_local.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias_local.h; sourceTree = "<group>"; };
                726121230EE870D400AFED1B /* alias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias.h; sourceTree = "<group>"; };
                726121240EE870D400AFED1B /* libalias.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libalias.3; sourceTree = "<group>"; };
                7261212D0EE8710B00AFED1B /* arp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = arp; sourceTree = BUILT_PRODUCTS_DIR; };
                726121540EE8881700AFED1B /* ifconfig */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ifconfig; sourceTree = BUILT_PRODUCTS_DIR; };
+               7263724C1BCC718B00E4B026 /* frame_delay.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = frame_delay.8; sourceTree = "<group>"; };
                7282BA0C1AFAD4C9005DE836 /* ecnprobe */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ecnprobe; sourceTree = BUILT_PRODUCTS_DIR; };
                7282BA341AFAD58E005DE836 /* base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base.h; sourceTree = "<group>"; };
                7282BA351AFAD58E005DE836 /* capture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = capture.c; sourceTree = "<group>"; };
                7282BA0C1AFAD4C9005DE836 /* ecnprobe */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ecnprobe; sourceTree = BUILT_PRODUCTS_DIR; };
                7282BA341AFAD58E005DE836 /* base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base.h; sourceTree = "<group>"; };
                7282BA351AFAD58E005DE836 /* capture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = capture.c; sourceTree = "<group>"; };
                7282BA481AFAD58E005DE836 /* support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = support.h; sourceTree = "<group>"; };
                7282BA541AFBCA66005DE836 /* libpcap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpcap.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/lib/libpcap.dylib; sourceTree = DEVELOPER_DIR; };
                7282BA5C1AFBED07005DE836 /* ecnprobe.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = ecnprobe.1; sourceTree = "<group>"; };
                7282BA481AFAD58E005DE836 /* support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = support.h; sourceTree = "<group>"; };
                7282BA541AFBCA66005DE836 /* libpcap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpcap.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/lib/libpcap.dylib; sourceTree = DEVELOPER_DIR; };
                7282BA5C1AFBED07005DE836 /* ecnprobe.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = ecnprobe.1; sourceTree = "<group>"; };
+               72946F431BBF055700087E35 /* frame_delay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = frame_delay; sourceTree = BUILT_PRODUCTS_DIR; };
+               72946F4F1BBF07FF00087E35 /* frame_delay.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = frame_delay.c; sourceTree = "<group>"; };
                7294F0F90EE8BB460052EC88 /* traceroute */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = traceroute; sourceTree = BUILT_PRODUCTS_DIR; };
                7294F12A0EE8BD280052EC88 /* traceroute6 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = traceroute6; sourceTree = BUILT_PRODUCTS_DIR; };
                72B732DA1899B0380060E6D4 /* cfilutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cfilutil; sourceTree = BUILT_PRODUCTS_DIR; };
                7294F0F90EE8BB460052EC88 /* traceroute */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = traceroute; sourceTree = BUILT_PRODUCTS_DIR; };
                7294F12A0EE8BD280052EC88 /* traceroute6 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = traceroute6; sourceTree = BUILT_PRODUCTS_DIR; };
                72B732DA1899B0380060E6D4 /* cfilutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cfilutil; sourceTree = BUILT_PRODUCTS_DIR; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               724DAB5D0EE88E2A008900D0 /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               724DAB800EE88EFA008900D0 /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                724DABA00EE88FE3008900D0 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                724DABA00EE88FE3008900D0 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               72946F401BBF055700087E35 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                7294F0F70EE8BB460052EC88 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                7294F0F70EE8BB460052EC88 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                                72B732DB1899B0380060E6D4 /* cfilutil */,
                                723C706A142BAFEA007C87E9 /* dnctl */,
                                7282BA0D1AFAD4C9005DE836 /* ecnprobe */,
                                72B732DB1899B0380060E6D4 /* cfilutil */,
                                723C706A142BAFEA007C87E9 /* dnctl */,
                                7282BA0D1AFAD4C9005DE836 /* ecnprobe */,
+                               72946F441BBF055700087E35 /* frame_delay */,
                                726120540EE86F0900AFED1B /* ifconfig.tproj */,
                                4D2B04E31208C12F0004A3F3 /* ip6addrctl.tproj */,
                                726120540EE86F0900AFED1B /* ifconfig.tproj */,
                                4D2B04E31208C12F0004A3F3 /* ip6addrctl.tproj */,
-                               726120670EE86F2300AFED1B /* ip6fw.tproj */,
-                               726120FE0EE8701100AFED1B /* ipfw.tproj */,
                                7261206D0EE86F2D00AFED1B /* kdumpd.tproj */,
                                56582591133920B5003E5FA5 /* mnc.tproj */,
                                72311F43194A349100EB4788 /* mptcp_client */,
                                7261206D0EE86F2D00AFED1B /* kdumpd.tproj */,
                                56582591133920B5003E5FA5 /* mnc.tproj */,
                                72311F43194A349100EB4788 /* mptcp_client */,
                        path = ifconfig.tproj;
                        sourceTree = "<group>";
                };
                        path = ifconfig.tproj;
                        sourceTree = "<group>";
                };
-               726120670EE86F2300AFED1B /* ip6fw.tproj */ = {
-                       isa = PBXGroup;
-                       children = (
-                               726120680EE86F2300AFED1B /* ip6fw.8 */,
-                               726120690EE86F2300AFED1B /* ip6fw.c */,
-                       );
-                       path = ip6fw.tproj;
-                       sourceTree = "<group>";
-               };
                7261206D0EE86F2D00AFED1B /* kdumpd.tproj */ = {
                        isa = PBXGroup;
                        children = (
                7261206D0EE86F2D00AFED1B /* kdumpd.tproj */ = {
                        isa = PBXGroup;
                        children = (
                726120A40EE86F5C00AFED1B /* ping6.tproj */ = {
                        isa = PBXGroup;
                        children = (
                726120A40EE86F5C00AFED1B /* ping6.tproj */ = {
                        isa = PBXGroup;
                        children = (
-                               726120A50EE86F5C00AFED1B /* Makefile */,
                                726120A60EE86F5C00AFED1B /* md5.c */,
                                726120A70EE86F5C00AFED1B /* md5.h */,
                                726120A80EE86F5C00AFED1B /* ping6.8 */,
                                726120A60EE86F5C00AFED1B /* md5.c */,
                                726120A70EE86F5C00AFED1B /* md5.h */,
                                726120A80EE86F5C00AFED1B /* ping6.8 */,
                726120F80EE86FB500AFED1B /* traceroute6.tproj */ = {
                        isa = PBXGroup;
                        children = (
                726120F80EE86FB500AFED1B /* traceroute6.tproj */ = {
                        isa = PBXGroup;
                        children = (
-                               726120F90EE86FB500AFED1B /* Makefile */,
                                726120FA0EE86FB500AFED1B /* traceroute6.8 */,
                                726120FB0EE86FB500AFED1B /* traceroute6.c */,
                        );
                        path = traceroute6.tproj;
                        sourceTree = "<group>";
                };
                                726120FA0EE86FB500AFED1B /* traceroute6.8 */,
                                726120FB0EE86FB500AFED1B /* traceroute6.c */,
                        );
                        path = traceroute6.tproj;
                        sourceTree = "<group>";
                };
-               726120FE0EE8701100AFED1B /* ipfw.tproj */ = {
-                       isa = PBXGroup;
-                       children = (
-                               726120FF0EE8701100AFED1B /* ipfw.8 */,
-                               726121000EE8701100AFED1B /* ipfw2.c */,
-                       );
-                       path = ipfw.tproj;
-                       sourceTree = "<group>";
-               };
                7261210D0EE8707500AFED1B /* Products */ = {
                        isa = PBXGroup;
                        children = (
                                7261210C0EE8707500AFED1B /* libalias.A.dylib */,
                                7261212D0EE8710B00AFED1B /* arp */,
                                726121540EE8881700AFED1B /* ifconfig */,
                7261210D0EE8707500AFED1B /* Products */ = {
                        isa = PBXGroup;
                        children = (
                                7261210C0EE8707500AFED1B /* libalias.A.dylib */,
                                7261212D0EE8710B00AFED1B /* arp */,
                                726121540EE8881700AFED1B /* ifconfig */,
-                               724DAB5F0EE88E2A008900D0 /* ipfw */,
-                               724DAB820EE88EFA008900D0 /* ip6fw */,
                                724DABA20EE88FE3008900D0 /* kdumpd */,
                                724DABDB0EE8912D008900D0 /* natd */,
                                724DAC0D0EE8940D008900D0 /* ndp */,
                                724DABA20EE88FE3008900D0 /* kdumpd */,
                                724DABDB0EE8912D008900D0 /* natd */,
                                724DAC0D0EE8940D008900D0 /* ndp */,
                                7200F2FA1958A34D0033E22C /* pktmnglr */,
                                713297681A93C743002359CF /* unbound */,
                                7282BA0C1AFAD4C9005DE836 /* ecnprobe */,
                                7200F2FA1958A34D0033E22C /* pktmnglr */,
                                713297681A93C743002359CF /* unbound */,
                                7282BA0C1AFAD4C9005DE836 /* ecnprobe */,
+                               72946F431BBF055700087E35 /* frame_delay */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                        path = ecnprobe;
                        sourceTree = "<group>";
                };
                        path = ecnprobe;
                        sourceTree = "<group>";
                };
+               72946F441BBF055700087E35 /* frame_delay */ = {
+                       isa = PBXGroup;
+                       children = (
+                               72946F4F1BBF07FF00087E35 /* frame_delay.c */,
+                               7263724C1BCC718B00E4B026 /* frame_delay.8 */,
+                       );
+                       path = frame_delay;
+                       sourceTree = "<group>";
+               };
                72B732DB1899B0380060E6D4 /* cfilutil */ = {
                        isa = PBXGroup;
                        children = (
                72B732DB1899B0380060E6D4 /* cfilutil */ = {
                        isa = PBXGroup;
                        children = (
                        productReference = 7247B83116165EDC00873B3C /* pktapctl */;
                        productType = "com.apple.product-type.tool";
                };
                        productReference = 7247B83116165EDC00873B3C /* pktapctl */;
                        productType = "com.apple.product-type.tool";
                };
-               724DAB5E0EE88E2A008900D0 /* ipfw */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 724DAB770EE88E9C008900D0 /* Build configuration list for PBXNativeTarget "ipfw" */;
-                       buildPhases = (
-                               724DAB5C0EE88E2A008900D0 /* Sources */,
-                               724DAB5D0EE88E2A008900D0 /* Frameworks */,
-                               724DAB760EE88E9C008900D0 /* CopyFiles */,
-                               72CD1DB00EE8C551005F825D /* ShellScript */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = ipfw;
-                       productName = ipfw;
-                       productReference = 724DAB5F0EE88E2A008900D0 /* ipfw */;
-                       productType = "com.apple.product-type.tool";
-               };
-               724DAB810EE88EFA008900D0 /* ip6fw */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 724DAB980EE88F56008900D0 /* Build configuration list for PBXNativeTarget "ip6fw" */;
-                       buildPhases = (
-                               724DAB7F0EE88EFA008900D0 /* Sources */,
-                               724DAB800EE88EFA008900D0 /* Frameworks */,
-                               724DAB970EE88F56008900D0 /* CopyFiles */,
-                               724DAC1B0EE89440008900D0 /* ShellScript */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = ip6fw;
-                       productName = ip6fw;
-                       productReference = 724DAB820EE88EFA008900D0 /* ip6fw */;
-                       productType = "com.apple.product-type.tool";
-               };
                724DABA10EE88FE3008900D0 /* kdumpd */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 724DABB80EE89035008900D0 /* Build configuration list for PBXNativeTarget "kdumpd" */;
                724DABA10EE88FE3008900D0 /* kdumpd */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 724DABB80EE89035008900D0 /* Build configuration list for PBXNativeTarget "kdumpd" */;
                        productReference = 7282BA0C1AFAD4C9005DE836 /* ecnprobe */;
                        productType = "com.apple.product-type.tool";
                };
                        productReference = 7282BA0C1AFAD4C9005DE836 /* ecnprobe */;
                        productType = "com.apple.product-type.tool";
                };
+               72946F421BBF055700087E35 /* frame_delay */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 72946F4A1BBF055700087E35 /* Build configuration list for PBXNativeTarget "frame_delay" */;
+                       buildPhases = (
+                               72946F3F1BBF055700087E35 /* Sources */,
+                               72946F401BBF055700087E35 /* Frameworks */,
+                               72946F411BBF055700087E35 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = frame_delay;
+                       productName = frame_delay;
+                       productReference = 72946F431BBF055700087E35 /* frame_delay */;
+                       productType = "com.apple.product-type.tool";
+               };
                7294F0F80EE8BB460052EC88 /* traceroute */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 7294F0FD0EE8BB550052EC88 /* Build configuration list for PBXNativeTarget "traceroute" */;
                7294F0F80EE8BB460052EC88 /* traceroute */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 7294F0FD0EE8BB550052EC88 /* Build configuration list for PBXNativeTarget "traceroute" */;
                724862310EE86EB7001D0DE9 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                724862310EE86EB7001D0DE9 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0500;
+                               LastUpgradeCheck = 0800;
                                TargetAttributes = {
                                        713297671A93C743002359CF = {
                                                CreatedOnToolsVersion = 6.3;
                                TargetAttributes = {
                                        713297671A93C743002359CF = {
                                                CreatedOnToolsVersion = 6.3;
                                        7282BA0B1AFAD4C9005DE836 = {
                                                CreatedOnToolsVersion = 7.0;
                                        };
                                        7282BA0B1AFAD4C9005DE836 = {
                                                CreatedOnToolsVersion = 7.0;
                                        };
+                                       72946F421BBF055700087E35 = {
+                                               CreatedOnToolsVersion = 6.3;
+                                       };
                                };
                        };
                        buildConfigurationList = 724862340EE86EB7001D0DE9 /* Build configuration list for PBXProject "network_cmds" */;
                                };
                        };
                        buildConfigurationList = 724862340EE86EB7001D0DE9 /* Build configuration list for PBXProject "network_cmds" */;
                                72B732D91899B0380060E6D4 /* cfilutil */,
                                723C7067142BAFEA007C87E9 /* dnctl */,
                                7282BA0B1AFAD4C9005DE836 /* ecnprobe */,
                                72B732D91899B0380060E6D4 /* cfilutil */,
                                723C7067142BAFEA007C87E9 /* dnctl */,
                                7282BA0B1AFAD4C9005DE836 /* ecnprobe */,
+                               72946F421BBF055700087E35 /* frame_delay */,
                                726121530EE8881700AFED1B /* ifconfig */,
                                4D2B04F21208C2040004A3F3 /* ip6addrctl */,
                                726121530EE8881700AFED1B /* ifconfig */,
                                4D2B04F21208C2040004A3F3 /* ip6addrctl */,
-                               724DAB810EE88EFA008900D0 /* ip6fw */,
-                               724DAB5E0EE88E2A008900D0 /* ipfw */,
                                724DABA10EE88FE3008900D0 /* kdumpd */,
                                5658259E1339218F003E5FA5 /* mnc */,
                                72311F41194A349000EB4788 /* mptcp_client */,
                                724DABA10EE88FE3008900D0 /* kdumpd */,
                                5658259E1339218F003E5FA5 /* mnc */,
                                72311F41194A349000EB4788 /* mptcp_client */,
                        shellPath = /bin/sh;
                        shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/natd.8\t";
                };
                        shellPath = /bin/sh;
                        shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/natd.8\t";
                };
-               724DAC1B0EE89440008900D0 /* ShellScript */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 8;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-                       shellPath = /bin/sh;
-                       shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/ip6fw.8\t";
-               };
                724DAC440EE89562008900D0 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
                724DAC440EE89562008900D0 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
                        shellPath = /bin/sh;
                        shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/ifconfig.8\t";
                };
                        shellPath = /bin/sh;
                        shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/ifconfig.8\t";
                };
-               72CD1DB00EE8C551005F825D /* ShellScript */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 8;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-                       shellPath = /bin/sh;
-                       shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/ipfw.8\n";
-               };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               724769381CE2C1E400AAB5F0 /* gmt2local.c in Sources */,
                                7216D2800EE8981C00AE70E4 /* ping.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                7216D2800EE8981C00AE70E4 /* ping.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               724769371CE2B1FF00AAB5F0 /* gmt2local.c in Sources */,
                                7216D2A00EE898DF00AE70E4 /* md5.c in Sources */,
                                7216D2A10EE898DF00AE70E4 /* ping6.c in Sources */,
                        );
                                7216D2A00EE898DF00AE70E4 /* md5.c in Sources */,
                                7216D2A10EE898DF00AE70E4 /* ping6.c in Sources */,
                        );
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               724DAB5C0EE88E2A008900D0 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               724DAB640EE88E63008900D0 /* ipfw2.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               724DAB7F0EE88EFA008900D0 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               724DAB860EE88F0D008900D0 /* ip6fw.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                724DAB9F0EE88FE3008900D0 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                724DAB9F0EE88FE3008900D0 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               72946F3F1BBF055700087E35 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               72946F501BBF07FF00087E35 /* frame_delay.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                7294F0F60EE8BB460052EC88 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                7294F0F60EE8BB460052EC88 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        target = 726121530EE8881700AFED1B /* ifconfig */;
                        targetProxy = 7261217C0EE8896800AFED1B /* PBXContainerItemProxy */;
                };
                        target = 726121530EE8881700AFED1B /* ifconfig */;
                        targetProxy = 7261217C0EE8896800AFED1B /* PBXContainerItemProxy */;
                };
+               7263724B1BCC709900E4B026 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72946F421BBF055700087E35 /* frame_delay */;
+                       targetProxy = 7263724A1BCC709900E4B026 /* PBXContainerItemProxy */;
+               };
                7282BA571AFBDEAD005DE836 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 7282BA0B1AFAD4C9005DE836 /* ecnprobe */;
                7282BA571AFBDEAD005DE836 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 7282BA0B1AFAD4C9005DE836 /* ecnprobe */;
                        target = 7282BA0B1AFAD4C9005DE836 /* ecnprobe */;
                        targetProxy = 7282BA5A1AFBDED3005DE836 /* PBXContainerItemProxy */;
                };
                        target = 7282BA0B1AFAD4C9005DE836 /* ecnprobe */;
                        targetProxy = 7282BA5A1AFBDED3005DE836 /* PBXContainerItemProxy */;
                };
+               72946F4C1BBF063800087E35 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72946F421BBF055700087E35 /* frame_delay */;
+                       targetProxy = 72946F4B1BBF063800087E35 /* PBXContainerItemProxy */;
+               };
+               72946F4E1BBF063F00087E35 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72946F421BBF055700087E35 /* frame_delay */;
+                       targetProxy = 72946F4D1BBF063F00087E35 /* PBXContainerItemProxy */;
+               };
                7294F0EA0EE8BAC80052EC88 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 7216D3A60EE8A3BA00AE70E4 /* spray */;
                7294F0EA0EE8BAC80052EC88 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 7216D3A60EE8A3BA00AE70E4 /* spray */;
                        };
                        name = "Ignore Me";
                };
                        };
                        name = "Ignore Me";
                };
-               03B2DBE9100BE71D005349BC /* Ignore Me */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ipfw;
-                       };
-                       name = "Ignore Me";
-               };
-               03B2DBEA100BE71D005349BC /* Ignore Me */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ip6fw;
-                       };
-                       name = "Ignore Me";
-               };
                03B2DBEB100BE71D005349BC /* Ignore Me */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                03B2DBEB100BE71D005349BC /* Ignore Me */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
-                               SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
                        };
                        name = "Ignore Me";
                };
                        };
                        name = "Ignore Me";
                };
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = YES;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = YES;
-                               ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Debug;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Debug;
                        buildSettings = {
                                CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist";
                                CODE_SIGN_IDENTITY = "-";
                        buildSettings = {
                                CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist";
                                CODE_SIGN_IDENTITY = "-";
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "USE_RFC2292BIS=1",
+                                       "__APPLE_USE_RFC_3542=1",
+                                       "__APPLE_API_OBSOLETE=1",
+                                       "DEBUG=1",
+                               );
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                INSTALL_GROUP = wheel;
                                INSTALL_MODE_FLAG = 0555;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                INSTALL_GROUP = wheel;
                                INSTALL_MODE_FLAG = 0555;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
-                               SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /sbin;
                                PRODUCT_NAME = ping;
-                               SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = YES;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = YES;
-                               ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Debug;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Debug;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = NO;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = NO;
-                               ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = NO;
                                HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                METAL_ENABLE_DEBUG_INFO = NO;
-                               ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = "Ignore Me";
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = "Ignore Me";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
+                               ASSETCATALOG_COMPRESSION = lossless;
                                COPY_PHASE_STRIP = NO;
                                DEAD_CODE_STRIPPING = YES;
                                COPY_PHASE_STRIP = NO;
                                DEAD_CODE_STRIPPING = YES;
+                               ENABLE_TESTABILITY = YES;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_ENABLE_FIX_AND_CONTINUE = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_ENABLE_FIX_AND_CONTINUE = YES;
                                GCC_MODEL_TUNING = G5;
                                );
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
                                );
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
-                               ONLY_ACTIVE_ARCH = YES;
                                PREBINDING = NO;
                                SDKROOT = macosx.internal;
                                SUPPORTED_PLATFORMS = "macosx iphoneos";
                                PREBINDING = NO;
                                SDKROOT = macosx.internal;
                                SUPPORTED_PLATFORMS = "macosx iphoneos";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
+                               ASSETCATALOG_COMPRESSION = "respect-asset-catalog";
                                COPY_PHASE_STRIP = YES;
                                DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                COPY_PHASE_STRIP = YES;
                                DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               724DAB610EE88E2B008900D0 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ipfw;
-                       };
-                       name = Debug;
-               };
-               724DAB620EE88E2B008900D0 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ipfw;
-                       };
-                       name = Release;
-               };
-               724DAB840EE88EFA008900D0 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ip6fw;
-                       };
-                       name = Debug;
-               };
-               724DAB850EE88EFA008900D0 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = (
-                                       "$(inherited)",
-                                       IP_FW_PRIVATE,
-                               );
-                               HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
-                               INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = 0555;
-                               INSTALL_OWNER = root;
-                               INSTALL_PATH = /sbin;
-                               PRODUCT_NAME = ip6fw;
-                       };
-                       name = Release;
-               };
                724DABA40EE88FE3008900D0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                724DABA40EE88FE3008900D0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        };
                        name = "Ignore Me";
                };
                        };
                        name = "Ignore Me";
                };
+               72946F471BBF055700087E35 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.11.xctoolchain/usr/include,
+                                       /System/Library/Frameworks/System.framework/PrivateHeaders,
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.10;
+                               MTL_ENABLE_DEBUG_INFO = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               72946F481BBF055700087E35 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = NO;
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.11.xctoolchain/usr/include,
+                                       /System/Library/Frameworks/System.framework/PrivateHeaders,
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.10;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               72946F491BBF055700087E35 /* Ignore Me */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist";
+                               CODE_SIGN_IDENTITY = "-";
+                               COPY_PHASE_STRIP = NO;
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.11.xctoolchain/usr/include,
+                                       /System/Library/Frameworks/System.framework/PrivateHeaders,
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.10;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = "Ignore Me";
+               };
                7294F0FB0EE8BB460052EC88 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                7294F0FB0EE8BB460052EC88 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               724DAB770EE88E9C008900D0 /* Build configuration list for PBXNativeTarget "ipfw" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               724DAB610EE88E2B008900D0 /* Debug */,
-                               724DAB620EE88E2B008900D0 /* Release */,
-                               03B2DBE9100BE71D005349BC /* Ignore Me */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               724DAB980EE88F56008900D0 /* Build configuration list for PBXNativeTarget "ip6fw" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               724DAB840EE88EFA008900D0 /* Debug */,
-                               724DAB850EE88EFA008900D0 /* Release */,
-                               03B2DBEA100BE71D005349BC /* Ignore Me */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
                724DABB80EE89035008900D0 /* Build configuration list for PBXNativeTarget "kdumpd" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                724DABB80EE89035008900D0 /* Build configuration list for PBXNativeTarget "kdumpd" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               72946F4A1BBF055700087E35 /* Build configuration list for PBXNativeTarget "frame_delay" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               72946F471BBF055700087E35 /* Debug */,
+                               72946F481BBF055700087E35 /* Release */,
+                               72946F491BBF055700087E35 /* Ignore Me */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                7294F0FD0EE8BB550052EC88 /* Build configuration list for PBXNativeTarget "traceroute" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                7294F0FD0EE8BB550052EC88 /* Build configuration list for PBXNativeTarget "traceroute" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 6c60deeed4aa417bb426c019a8f3c00e76965f6d..defb856241f5c94e87ae916983e855b3d021247f 100644 (file)
@@ -71,6 +71,7 @@ packets to network hosts
 .Op Fl h Ar sweepincrsize
 .Op Fl i Ar wait
 .Op Fl k Ar trafficclass
 .Op Fl h Ar sweepincrsize
 .Op Fl i Ar wait
 .Op Fl k Ar trafficclass
+.Op Fl K Ar netservicetype
 .Op Fl l Ar preload
 .Op Fl M Cm mask | time
 .Op Fl m Ar ttl
 .Op Fl l Ar preload
 .Op Fl M Cm mask | time
 .Op Fl m Ar ttl
@@ -81,6 +82,8 @@ packets to network hosts
 .Op Fl t Ar timeout
 .Op Fl W Ar waittime
 .Op Fl z Ar tos
 .Op Fl t Ar timeout
 .Op Fl W Ar waittime
 .Op Fl z Ar tos
+.Op Fl Fl apple-connect
+.Op Fl Fl apple-print
 .Ar host
 .Nm
 .Op Fl AaDdfLnoQqRrv
 .Ar host
 .Nm
 .Op Fl AaDdfLnoQqRrv
@@ -89,6 +92,7 @@ packets to network hosts
 .Op Fl I Ar iface
 .Op Fl i Ar wait
 .Op Fl k Ar trafficclass
 .Op Fl I Ar iface
 .Op Fl i Ar wait
 .Op Fl k Ar trafficclass
+.Op Fl K Ar netservicetype
 .Op Fl l Ar preload
 .Op Fl M Cm mask | time
 .Op Fl m Ar ttl
 .Op Fl l Ar preload
 .Op Fl M Cm mask | time
 .Op Fl m Ar ttl
@@ -100,6 +104,8 @@ packets to network hosts
 .Op Fl t Ar timeout
 .Op Fl W Ar waittime
 .Op Fl z Ar tos
 .Op Fl t Ar timeout
 .Op Fl W Ar waittime
 .Op Fl z Ar tos
+.Op Fl Fl apple-connect
+.Op Fl Fl apple-print
 .Ar mcast-group
 .Sh DESCRIPTION
 The
 .Ar mcast-group
 .Sh DESCRIPTION
 The
@@ -145,8 +151,10 @@ if other format options are present.
 Bind the socket to interface
 .Ar boundif
 for sending.
 Bind the socket to interface
 .Ar boundif
 for sending.
+This option is an Apple addition.
 .It Fl C
 Prohibit the socket from using the cellular network interface.
 .It Fl C
 Prohibit the socket from using the cellular network interface.
+This option is an Apple addition.
 .It Fl c Ar count
 Stop after sending
 (and receiving)
 .It Fl c Ar count
 Stop after sending
 (and receiving)
@@ -212,13 +220,19 @@ values less than 0.1 second.
 This option is incompatible with the
 .Fl f
 option.
 This option is incompatible with the
 .Fl f
 option.
-.It Fl k Ar trafficlass
+.It Fl k Ar trafficclass
 Specifies the traffic class to use for sending ICMP packets.
 The supported traffic classes are
 BK_SYS, BK, BE, RD, OAM, AV, RV, VI, VO and CTL.
 By default 
 .Nm
 uses the control traffic class (CTL).
 Specifies the traffic class to use for sending ICMP packets.
 The supported traffic classes are
 BK_SYS, BK, BE, RD, OAM, AV, RV, VI, VO and CTL.
 By default 
 .Nm
 uses the control traffic class (CTL).
+This option is an Apple addition.
+.It Fl K Ar netservicetype
+Specifies the network service type to use for sending ICMP packets.
+The supported network service type are BK_SYS, BK, BE, RV, AV, RD, OAM, VI, SIG and VO.
+Note this overrides the default traffic class (-k can still be specified after -K to use both).
+This option is an Apple addition.
 .It Fl L
 Suppress loopback of multicast packets.
 This flag only applies if the ping destination is a multicast address.
 .It Fl L
 Suppress loopback of multicast packets.
 This flag only applies if the ping destination is a multicast address.
@@ -355,6 +369,12 @@ If a reply arrives later, the packet is not printed as replied, but
 considered as replied when calculating statistics.
 .It Fl z Ar tos
 Use the specified type of service.
 considered as replied when calculating statistics.
 .It Fl z Ar tos
 Use the specified type of service.
+.It Fl Fl apple-connect
+Connects the socket to the destination address.
+This option is an Apple addition.
+.It Fl Fl apple-print
+Prints the time a packet was received.
+This option is an Apple addition.
 .El
 .Pp
 When using
 .El
 .Pp
 When using
index fa79b60c58e089cb1d15f953b6c39ff60891675c..ad5ea7a535139aaafa6b4cb7c0c139ec95ad9b29 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1999-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -107,12 +107,14 @@ __unused static const char copyright[] =
 #include <math.h>
 #include <netdb.h>
 #include <signal.h>
 #include <math.h>
 #include <netdb.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
 #include <unistd.h>
 #include <ifaddrs.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
 #include <unistd.h>
 #include <ifaddrs.h>
+#include <getopt.h>
 
 #define        INADDR_LEN      ((int)sizeof(in_addr_t))
 #define        TIMEVAL_LEN     ((int)sizeof(struct tv32))
 
 #define        INADDR_LEN      ((int)sizeof(in_addr_t))
 #define        TIMEVAL_LEN     ((int)sizeof(struct tv32))
@@ -167,6 +169,8 @@ int options;
 #define        F_TIME          0x100000
 #define        F_SWEEP         0x200000
 #define        F_WAITTIME      0x400000
 #define        F_TIME          0x100000
 #define        F_SWEEP         0x200000
 #define        F_WAITTIME      0x400000
+#define        F_CONNECT       0x800000
+#define F_PRTIME       0x1000000
 
 /*
  * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
 
 /*
  * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
@@ -195,12 +199,11 @@ int phdr_len = 0;
 int send_len;
 char *boundif;
 unsigned int ifscope;
 int send_len;
 char *boundif;
 unsigned int ifscope;
-#if defined(IP_FORCE_OUT_IFP) && TARGET_OS_EMBEDDED
-char boundifname[IFNAMSIZ];
-#endif /* IP_FORCE_OUT_IFP */
 int nocell;
 int nocell;
-int how_traffic_class = 0;
+int use_sendmsg = 0;
+int use_recvmsg = 0;
 int traffic_class = SO_TC_CTL; /* use control class, by default */
 int traffic_class = SO_TC_CTL; /* use control class, by default */
+int net_service_type = -1;
 int no_dup = 0;
 
 /* counters */
 int no_dup = 0;
 
 /* counters */
@@ -244,9 +247,26 @@ static void pr_retip(struct ip *);
 static void status(int);
 static void stopit(int);
 static void tvsub(struct timeval *, const struct timeval *);
 static void status(int);
 static void stopit(int);
 static void tvsub(struct timeval *, const struct timeval *);
-static uint32_t str2svc(const char *);
+static int str2sotc(const char *, bool *);
+static int str2netservicetype(const char *, bool *);
+static u_int8_t str2tos(const char *, bool *);
 static void usage(void) __dead2;
 
 static void usage(void) __dead2;
 
+int32_t thiszone;              /* seconds offset from gmt to local time */
+extern int32_t gmt2local(time_t);
+static void pr_currenttime(void);
+
+static int longopt_flag = 0;
+
+#define        LOF_CONNECT     0x01
+#define        LOF_PRTIME      0x02
+
+static const struct option longopts[] = {
+       { "apple-connect", no_argument, &longopt_flag, LOF_CONNECT },
+       { "apple-time", no_argument, &longopt_flag, LOF_PRTIME },
+       { NULL, 0, NULL, 0 }
+};
+
 int
 main(int argc, char *const *argv)
 {
 int
 main(int argc, char *const *argv)
 {
@@ -280,6 +300,7 @@ main(int argc, char *const *argv)
 #ifdef IPSEC_POLICY_IPSEC
        policy_in = policy_out = NULL;
 #endif
 #ifdef IPSEC_POLICY_IPSEC
        policy_in = policy_out = NULL;
 #endif
+       bool valid;
 
        /*
         * Do the stuff that we need root priv's for *first*, and
 
        /*
         * Do the stuff that we need root priv's for *first*, and
@@ -299,17 +320,9 @@ main(int argc, char *const *argv)
        alarmtimeout = df = preload = tos = 0;
 
        outpack = outpackhdr + sizeof(struct ip);
        alarmtimeout = df = preload = tos = 0;
 
        outpack = outpackhdr + sizeof(struct ip);
-       while ((ch = getopt(argc, argv,
-               "Aab:Cc:DdfG:g:h:I:i:k:Ll:M:m:nop:QqRrS:s:T:t:vW:z:"
-#ifdef IPSEC
-#ifdef IPSEC_POLICY_IPSEC
-               "P:"
-#endif /*IPSEC_POLICY_IPSEC*/
-#endif /*IPSEC*/
-#if defined(IP_FORCE_OUT_IFP) && TARGET_OS_EMBEDDED
-               "B:"
-#endif /* IP_FORCE_OUT_IFP */
-               )) != -1)
+       while ((ch = getopt_long(argc, argv,
+           "AaB:b:Cc:DdfG:g:h:I:i:k:K:Ll:M:m:noP:p:QqRrS:s:T:t:vW:z:",
+           longopts, NULL)) != -1)
        {
                switch(ch) {
                case 'A':
        {
                switch(ch) {
                case 'A':
@@ -318,12 +331,7 @@ main(int argc, char *const *argv)
                case 'a':
                        options |= F_AUDIBLE;
                        break;
                case 'a':
                        options |= F_AUDIBLE;
                        break;
-#if defined(IP_FORCE_OUT_IFP) && TARGET_OS_EMBEDDED
                case 'B':
                case 'B':
-                       (void) snprintf(boundifname, sizeof (boundifname),
-                           "%s", optarg);
-                       break;
-#endif /* IP_FORCE_OUT_IFP */
                case 'b':
                        boundif = optarg;
                        break;
                case 'b':
                        boundif = optarg;
                        break;
@@ -421,12 +429,31 @@ main(int argc, char *const *argv)
                        }
                        break;
                case 'k':
                        }
                        break;
                case 'k':
-                       how_traffic_class++;
-                       traffic_class = str2svc(optarg);
-                       if (traffic_class == UINT32_MAX)
+                       if (strcasecmp(optarg, "sendmsg") == 0) {
+                               use_sendmsg++;
+                               break;
+                       }
+                       if (strcasecmp(optarg, "recvmsg") == 0) {
+                               use_recvmsg++;
+                               break;
+                       }
+                       traffic_class = str2sotc(optarg, &valid);
+                       if (valid == false)
                                errx(EX_USAGE, "bad traffic class: `%s'",
                                     optarg);
                        break;
                                errx(EX_USAGE, "bad traffic class: `%s'",
                                     optarg);
                        break;
+               case 'K':
+                       if (strcasecmp(optarg, "sendmsg") == 0) {
+                               use_sendmsg++;
+                               break;
+                       }
+                       net_service_type = str2netservicetype(optarg, &valid);
+                       if (valid == false)
+                               errx(EX_USAGE, "bad network service type: `%s'",
+                                    optarg);
+                       /* suppress default traffic class (-k can still be specified after -K) */
+                       traffic_class = -1;
+                       break;
                case 'L':
                        options |= F_NOLOOP;
                        loop = 0;
                case 'L':
                        options |= F_NOLOOP;
                        loop = 0;
@@ -470,9 +497,9 @@ main(int argc, char *const *argv)
                case 'o':
                        options |= F_ONCE;
                        break;
                case 'o':
                        options |= F_ONCE;
                        break;
+               case 'P':
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
-               case 'P':
                        options |= F_POLICY;
                        if (!strncmp("in", optarg, 2))
                                policy_in = strdup(optarg);
                        options |= F_POLICY;
                        if (!strncmp("in", optarg, 2))
                                policy_in = strdup(optarg);
@@ -480,9 +507,9 @@ main(int argc, char *const *argv)
                                policy_out = strdup(optarg);
                        else
                                errx(1, "invalid security policy");
                                policy_out = strdup(optarg);
                        else
                                errx(1, "invalid security policy");
-                       break;
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/
+                       break;
                case 'p':               /* fill buffer with user pattern */
                        options |= F_PINGFILLED;
                        payload = optarg;
                case 'p':               /* fill buffer with user pattern */
                        options |= F_PINGFILLED;
                        payload = optarg;
@@ -548,10 +575,23 @@ main(int argc, char *const *argv)
                        break;
                case 'z':
                        options |= F_HDRINCL;
                        break;
                case 'z':
                        options |= F_HDRINCL;
-                       ultmp = strtoul(optarg, &ep, 0);
-                       if (*ep || ep == optarg || ultmp > MAXTOS)
+                       tos = str2tos(optarg, &valid);
+                       if (valid == false)
                                errx(EX_USAGE, "invalid TOS: `%s'", optarg);
                                errx(EX_USAGE, "invalid TOS: `%s'", optarg);
-                       tos = ultmp;
+                       break;
+               case 0:
+                       switch (longopt_flag) {
+                               case LOF_CONNECT:
+                                       options |= F_CONNECT;
+                                       break;
+                               case LOF_PRTIME:
+                                       options |= F_PRTIME;
+                                       thiszone = gmt2local(0);
+                                       break;
+                               default:
+                                       break;
+                       }
+                       longopt_flag = 0;
                        break;
                default:
                        usage();
                        break;
                default:
                        usage();
@@ -620,7 +660,11 @@ main(int argc, char *const *argv)
                        shostname = snamebuf;
                }
                if (bind(s, (struct sockaddr *)&sock_in, sizeof sock_in) == -1)
                        shostname = snamebuf;
                }
                if (bind(s, (struct sockaddr *)&sock_in, sizeof sock_in) == -1)
+#if (DEBUG || DEVELOPMENT)
+                       options |= F_HDRINCL;
+#else
                        err(1, "bind");
                        err(1, "bind");
+#endif /* DEBUG || DEVELOPMENT */
        }
 
        bzero(&whereto, sizeof(whereto));
        }
 
        bzero(&whereto, sizeof(whereto));
@@ -678,9 +722,6 @@ main(int argc, char *const *argv)
                errx(EX_USAGE,
                    "-I, -L, -T flags cannot be used with unicast destination");
 
                errx(EX_USAGE,
                    "-I, -L, -T flags cannot be used with unicast destination");
 
-       if (datalen >= TIMEVAL_LEN)     /* can we time transfer */
-               timing = 1;
-
        if (!(options & F_PINGFILLED))
                for (i = TIMEVAL_LEN; i < MAX(datalen, sweepmax); ++i)
                        *datap++ = i;
        if (!(options & F_PINGFILLED))
                for (i = TIMEVAL_LEN; i < MAX(datalen, sweepmax); ++i)
                        *datap++ = i;
@@ -699,13 +740,6 @@ main(int argc, char *const *argv)
                    (char *)&ifscope, sizeof (ifscope)) != 0)
                        err(EX_OSERR, "setsockopt(IP_BOUND_IF)");
        }
                    (char *)&ifscope, sizeof (ifscope)) != 0)
                        err(EX_OSERR, "setsockopt(IP_BOUND_IF)");
        }
-#if defined(IP_FORCE_OUT_IFP) && TARGET_OS_EMBEDDED
-       else if (boundifname[0] != 0) {
-               if (setsockopt(s, IPPROTO_IP, IP_FORCE_OUT_IFP, boundifname,
-                   sizeof (boundifname)) != 0)
-                       err(EX_OSERR, "setsockopt(IP_FORCE_OUT_IFP)");
-       }
-#endif /* IP_FORCE_OUT_IFP */
        if (nocell) {
                if (setsockopt(s, IPPROTO_IP, IP_NO_IFT_CELLULAR,
                    (char *)&nocell, sizeof (nocell)) != 0)
        if (nocell) {
                if (setsockopt(s, IPPROTO_IP, IP_NO_IFT_CELLULAR,
                    (char *)&nocell, sizeof (nocell)) != 0)
@@ -717,11 +751,19 @@ main(int argc, char *const *argv)
        if (options & F_SO_DONTROUTE)
                (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
                    sizeof(hold));
        if (options & F_SO_DONTROUTE)
                (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
                    sizeof(hold));
-       if (how_traffic_class < 2 && traffic_class >= 0) {
-               (void) setsockopt(s, SOL_SOCKET, SO_TRAFFIC_CLASS,
-                   (void *)&traffic_class, sizeof (traffic_class));
+       if (use_sendmsg == 0) {
+               if (net_service_type != -1)
+                       if (setsockopt(s, SOL_SOCKET, SO_NET_SERVICE_TYPE,
+                                      (void *)&net_service_type, sizeof (net_service_type)) != 0)
+                               warn("setsockopt(SO_NET_SERVICE_TYPE");
+               if (traffic_class != -1) {
+                       if (setsockopt(s, SOL_SOCKET, SO_TRAFFIC_CLASS,
+                                      (void *)&traffic_class, sizeof (traffic_class)) != 0)
+                               warn("setsockopt(SO_TRAFFIC_CLASS");
+                       
+               }
        }
        }
-       if (how_traffic_class > 0) {
+       if (use_recvmsg > 0) {
                int on = 1;
                (void) setsockopt(s, SOL_SOCKET, SO_RECV_TRAFFIC_CLASS,
                    (void *)&on, sizeof (on));
                int on = 1;
                (void) setsockopt(s, SOL_SOCKET, SO_RECV_TRAFFIC_CLASS,
                    (void *)&on, sizeof (on));
@@ -824,6 +866,12 @@ main(int argc, char *const *argv)
                err(EX_OSERR, "setsockopt SO_TIMESTAMP");
        }
 #endif
                err(EX_OSERR, "setsockopt SO_TIMESTAMP");
        }
 #endif
+
+       if ((options & F_CONNECT)) {
+               if (connect(s, (struct sockaddr *)&whereto, sizeof whereto) == -1)
+                       err(EX_OSERR, "connect");
+       }
+
        if (sweepmax) {
                if (sweepmin >= sweepmax)
                        errx(EX_USAGE, "Maximum packet size must be greater than the minimum packet size");
        if (sweepmax) {
                if (sweepmin >= sweepmax)
                        errx(EX_USAGE, "Maximum packet size must be greater than the minimum packet size");
@@ -880,6 +928,16 @@ main(int argc, char *const *argv)
                        (void)printf("PING %s: %d data bytes\n", hostname, datalen);
        }
 
                        (void)printf("PING %s: %d data bytes\n", hostname, datalen);
        }
 
+       /*
+        * rdar://25829310
+        *
+        * Clear blocked signals inherited from the parent
+        */
+       sigset_t newset;
+       sigemptyset(&newset);
+       if (sigprocmask(SIG_SETMASK, &newset, NULL) != 0)
+               err(EX_OSERR, "sigprocmask(newset)");
+
        /*
         * Use sigaction() instead of signal() to get unambiguous semantics,
         * in particular with SA_RESTART not set.
        /*
         * Use sigaction() instead of signal() to get unambiguous semantics,
         * in particular with SA_RESTART not set.
@@ -967,7 +1025,7 @@ main(int argc, char *const *argv)
                if (n == 1) {
                        struct timeval *tv = NULL;
 #ifdef SO_TIMESTAMP
                if (n == 1) {
                        struct timeval *tv = NULL;
 #ifdef SO_TIMESTAMP
-                       struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl;
+                       struct cmsghdr *cmsg;
 
                        msg.msg_controllen = sizeof(ctrl);
 #endif
 
                        msg.msg_controllen = sizeof(ctrl);
 #endif
@@ -1094,6 +1152,11 @@ pinger(void)
 
        CLR(ntransmitted % mx_dup_ck);
 
 
        CLR(ntransmitted % mx_dup_ck);
 
+       if (datalen >= TIMEVAL_LEN)     /* can we time transfer */
+               timing = 1;
+       else
+               timing = 0;
+       
        if ((options & F_TIME) || timing) {
                (void)gettimeofday(&now, NULL);
 
        if ((options & F_TIME) || timing) {
                (void)gettimeofday(&now, NULL);
 
@@ -1120,34 +1183,55 @@ pinger(void)
                ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
                packet = outpackhdr;
        }
                ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
                packet = outpackhdr;
        }
-       if (how_traffic_class > 1 && traffic_class >= 0) {
+       if (use_sendmsg > 0) {
                struct msghdr msg;
                struct iovec iov;
                struct msghdr msg;
                struct iovec iov;
-               char *cmbuf[CMSG_SPACE(sizeof(int))];
+               char cmbuf[2 * CMSG_SPACE(sizeof(int))];
                struct cmsghdr *cm = (struct cmsghdr *)cmbuf;
 
                struct cmsghdr *cm = (struct cmsghdr *)cmbuf;
 
+               if ((options & F_CONNECT)) {
+                       msg.msg_name = NULL;
+                       msg.msg_namelen = 0;
+               } else {
                msg.msg_name = &whereto;
                msg.msg_namelen = sizeof(whereto);
                msg.msg_name = &whereto;
                msg.msg_namelen = sizeof(whereto);
-
+               }
                iov.iov_base = packet;
                iov.iov_len = cc;
                msg.msg_iov = &iov;
                msg.msg_iovlen = 1;
 
                iov.iov_base = packet;
                iov.iov_len = cc;
                msg.msg_iov = &iov;
                msg.msg_iovlen = 1;
 
-               cm->cmsg_len = CMSG_LEN(sizeof(int));
-               cm->cmsg_level = SOL_SOCKET;
-               cm->cmsg_type = SO_TRAFFIC_CLASS;
-               *(int *)CMSG_DATA(cm) = traffic_class;
-               msg.msg_control = cm;
-               msg.msg_controllen = CMSG_SPACE(sizeof(int));
+               msg.msg_controllen = 0;
+               msg.msg_control = NULL;
+               
+               if (traffic_class >= 0) {
+                       cm->cmsg_len = CMSG_LEN(sizeof(int));
+                       cm->cmsg_level = SOL_SOCKET;
+                       cm->cmsg_type = SO_TRAFFIC_CLASS;
+                       *(int *)CMSG_DATA(cm) = traffic_class;
+                       msg.msg_controllen += CMSG_SPACE(sizeof(int));
+                       cm = (struct cmsghdr *)(((char *)cm) + CMSG_SPACE(sizeof(int)));
+               }
+               if (net_service_type >= 0) {
+                       cm->cmsg_len = CMSG_LEN(sizeof(int));
+                       cm->cmsg_level = SOL_SOCKET;
+                       cm->cmsg_type = SO_NET_SERVICE_TYPE;
+                       msg.msg_controllen += CMSG_SPACE(sizeof(int));
+                       *(int *)CMSG_DATA(cm) = net_service_type;
+               }
+               msg.msg_control = cmbuf;
 
                msg.msg_flags = 0;
 
                i = sendmsg(s, &msg, 0);
        } else {
 
                msg.msg_flags = 0;
 
                i = sendmsg(s, &msg, 0);
        } else {
+               if ((options & F_CONNECT)) {
+                       i = send(s, (char *)packet, cc, 0);
+               } else {
                i = sendto(s, (char *)packet, cc, 0, (struct sockaddr *)&whereto,
                        sizeof(whereto));
        }
                i = sendto(s, (char *)packet, cc, 0, (struct sockaddr *)&whereto,
                        sizeof(whereto));
        }
+       }
        if (i < 0 || i != cc)  {
                if (i < 0) {
                        if (options & F_FLOOD && errno == ENOBUFS) {
        if (i < 0 || i != cc)  {
                if (i < 0) {
                        if (options & F_FLOOD && errno == ENOBUFS) {
@@ -1267,6 +1351,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv,
                                seq_datalen = sweepmin + (seq / snpackets) * sweepincr;
                                seq_sent_len = icmp_len + seq_datalen;
                        }
                                seq_datalen = sweepmin + (seq / snpackets) * sweepincr;
                                seq_sent_len = icmp_len + seq_datalen;
                        }
+                       if (options & F_PRTIME)
+                               pr_currenttime();
                        (void)printf("%d bytes from %s: icmp_seq=%u", cc,
                           inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
                           seq);
                        (void)printf("%d bytes from %s: icmp_seq=%u", cc,
                           inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
                           seq);
@@ -1353,6 +1439,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv,
                     (oip->ip_p == IPPROTO_ICMP) &&
                     (oicmp->icmp_type == ICMP_ECHO) &&
                     (oicmp->icmp_id == ident))) {
                     (oip->ip_p == IPPROTO_ICMP) &&
                     (oicmp->icmp_type == ICMP_ECHO) &&
                     (oicmp->icmp_id == ident))) {
+                   if (options & F_PRTIME)
+                           pr_currenttime();
                    (void)printf("%d bytes from %s: ", cc,
                        pr_addr(from->sin_addr));
                    pr_icmph(icp);
                    (void)printf("%d bytes from %s: ", cc,
                        pr_addr(from->sin_addr));
                    pr_icmph(icp);
@@ -1862,14 +1950,16 @@ fill(char *bp, char *patp)
        }
 }
 
        }
 }
 
-uint32_t
-str2svc(const char *str)
+int
+str2sotc(const char *str, bool *valid)
 {
 {
-       uint32_t svc;
+       int sotc = -1;
        char *endptr;
        
        char *endptr;
        
+       *valid = true;
+       
        if (str == NULL || *str == '\0')
        if (str == NULL || *str == '\0')
-               svc = UINT32_MAX;
+               *valid = false;
        else if (strcasecmp(str, "BK_SYS") == 0)
                return SO_TC_BK_SYS;
        else if (strcasecmp(str, "BK") == 0)
        else if (strcasecmp(str, "BK_SYS") == 0)
                return SO_TC_BK_SYS;
        else if (strcasecmp(str, "BK") == 0)
@@ -1891,13 +1981,132 @@ str2svc(const char *str)
        else if (strcasecmp(str, "CTL") == 0)
                return SO_TC_CTL;
        else {
        else if (strcasecmp(str, "CTL") == 0)
                return SO_TC_CTL;
        else {
-               svc = strtoul(str, &endptr, 0);
+               sotc = (int)strtol(str, &endptr, 0);
                if (*endptr != '\0')
                if (*endptr != '\0')
-                       svc = UINT32_MAX;
+                       *valid = false;
+       }
+       return (sotc);
+}
+
+int
+str2netservicetype(const char *str, bool *valid)
+{
+       int svc = -1;
+       char *endptr;
+       
+       *valid = true;
+       
+       if (str == NULL || *str == '\0')
+               *valid = false;
+       else if (strcasecmp(str, "BK") == 0)
+               return NET_SERVICE_TYPE_BK;
+       else if (strcasecmp(str, "BE") == 0)
+               return NET_SERVICE_TYPE_BE;
+       else if (strcasecmp(str, "VI") == 0)
+               return NET_SERVICE_TYPE_VI;
+       else if (strcasecmp(str, "SIG") == 0)
+               return NET_SERVICE_TYPE_SIG;
+       else if (strcasecmp(str, "VO") == 0)
+               return NET_SERVICE_TYPE_VO;
+       else if (strcasecmp(str, "RV") == 0)
+               return NET_SERVICE_TYPE_RV;
+       else if (strcasecmp(str, "AV") == 0)
+               return NET_SERVICE_TYPE_AV;
+       else if (strcasecmp(str, "OAM") == 0)
+               return NET_SERVICE_TYPE_OAM;
+       else if (strcasecmp(str, "RD") == 0)
+               return NET_SERVICE_TYPE_RD;
+       else {
+               svc = (int)strtol(str, &endptr, 0);
+               if (*endptr != '\0')
+                       *valid = false;
        }
        return (svc);
 }
 
        }
        return (svc);
 }
 
+u_int8_t
+str2tos(const char *str, bool *valid)
+{
+       u_int8_t dscp = -1;
+       char *endptr;
+       
+       *valid = true;
+       
+       if (str == NULL || *str == '\0')
+               *valid = false;
+       else if (strcasecmp(str, "DF") == 0)
+               dscp = _DSCP_DF;
+       else if (strcasecmp(str, "EF") == 0)
+               dscp = _DSCP_EF;
+       else if (strcasecmp(str, "VA") == 0)
+               dscp = _DSCP_VA;
+       
+       else if (strcasecmp(str, "CS0") == 0)
+               dscp = _DSCP_CS0;
+       else if (strcasecmp(str, "CS1") == 0)
+               dscp = _DSCP_CS1;
+       else if (strcasecmp(str, "CS2") == 0)
+               dscp = _DSCP_CS2;
+       else if (strcasecmp(str, "CS3") == 0)
+               dscp = _DSCP_CS3;
+       else if (strcasecmp(str, "CS4") == 0)
+               dscp = _DSCP_CS4;
+       else if (strcasecmp(str, "CS5") == 0)
+               dscp = _DSCP_CS5;
+       else if (strcasecmp(str, "CS6") == 0)
+               dscp = _DSCP_CS6;
+       else if (strcasecmp(str, "CS7") == 0)
+               dscp = _DSCP_CS7;
+       
+       else if (strcasecmp(str, "AF11") == 0)
+               dscp = _DSCP_AF11;
+       else if (strcasecmp(str, "AF12") == 0)
+               dscp = _DSCP_AF12;
+       else if (strcasecmp(str, "AF13") == 0)
+               dscp = _DSCP_AF13;
+       else if (strcasecmp(str, "AF21") == 0)
+               dscp = _DSCP_AF21;
+       else if (strcasecmp(str, "AF22") == 0)
+               dscp = _DSCP_AF22;
+       else if (strcasecmp(str, "AF23") == 0)
+               dscp = _DSCP_AF23;
+       else if (strcasecmp(str, "AF31") == 0)
+               dscp = _DSCP_AF31;
+       else if (strcasecmp(str, "AF32") == 0)
+               dscp = _DSCP_AF32;
+       else if (strcasecmp(str, "AF33") == 0)
+               dscp = _DSCP_AF33;
+       else if (strcasecmp(str, "AF41") == 0)
+               dscp = _DSCP_AF41;
+       else if (strcasecmp(str, "AF42") == 0)
+               dscp = _DSCP_AF42;
+       else if (strcasecmp(str, "AF43") == 0)
+               dscp = _DSCP_AF43;
+       
+       else {
+               unsigned long val = strtoul(str, &endptr, 0);
+               if (*endptr != '\0' || val > 255)
+                       *valid = false;
+               else
+                       return ((u_int8_t)val);
+       }
+       /* DSCP occupies the 6 upper bits of the TOS field */
+       return (dscp << 2);
+}
+
+void
+pr_currenttime(void)
+{
+       int s;
+       struct timeval tv;
+       
+       gettimeofday(&tv, NULL);
+       
+       s = (tv.tv_sec + thiszone) % 86400;
+       printf("%02d:%02d:%02d.%06u ", s / 3600, (s % 3600) / 60, s % 60,
+              (u_int32_t)tv.tv_usec);
+}
+
 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
 #define        SECOPT          " [-P policy]"
 #else
 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
 #define        SECOPT          " [-P policy]"
 #else
@@ -1908,14 +2117,20 @@ usage(void)
 {
 
        (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
 {
 
        (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: ping [-AaDdfnoQqRrv] [-b boundif] [-c count] [-G sweepmaxsize]",
-"            [-g sweepminsize] [-h sweepincrsize] [-i wait] [−k trafficclass]",
+"usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize]",
+"            [-g sweepminsize] [-h sweepincrsize] [-i wait]",
 "            [-l preload] [-M mask | time] [-m ttl]" SECOPT " [-p pattern]",
 "            [-l preload] [-M mask | time] [-m ttl]" SECOPT " [-p pattern]",
-"            [-S src_addr] [-s packetsize] [-t timeout][-W waittime] [-z tos]",
-"            host",
-"       ping [-AaDdfLnoQqRrv] [-b boundif] [-c count] [-I iface] [-i wait]",
-"            [−k trafficclass] [-l preload] [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]",
+"            [-S src_addr] [-s packetsize] [-t timeout][-W waittime]",
+"            [-z tos] host",
+"       ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait]",
+"            [-l preload] [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]",
 "            [-s packetsize] [-T ttl] [-t timeout] [-W waittime]",
 "            [-z tos] mcast-group");
 "            [-s packetsize] [-T ttl] [-t timeout] [-W waittime]",
 "            [-z tos] mcast-group");
+       (void)fprintf(stderr, "Apple specific options (to be specified before mcast-group or host like all options)\n");
+       (void)fprintf(stderr, "            -b boundif           # bind the socket to the interface\n");
+       (void)fprintf(stderr, "            -k traffic_class     # set traffic class socket option\n");
+       (void)fprintf(stderr, "            -K net_service_type  # set traffic class socket options\n");
+       (void)fprintf(stderr, "            -apple-connect       # call connect(2) in the socket\n");
+       (void)fprintf(stderr, "            -apple-time          # display current time\n");
        exit(EX_USAGE);
 }
        exit(EX_USAGE);
 }
index 716668cf6529ed705027247b6df784a4a1891269..e19b066ebc8d39a7acae307f7ceeca12cd9fe5fb 100644 (file)
@@ -79,9 +79,15 @@ packets to network hosts
 .Op Fl c Ar count
 .Ek
 .Bk -words
 .Op Fl c Ar count
 .Ek
 .Bk -words
+.Op Fl G Ar sweepmaxsize[,sweepminsize[,sweepincrsize]]
+.Ek
+.Bk -words
 .Op Fl g Ar gateway
 .Ek
 .Bk -words
 .Op Fl g Ar gateway
 .Ek
 .Bk -words
+.Op Fl G Ar sweep
+.Ek
+.Bk -words
 .Op Fl h Ar hoplimit
 .Ek
 .Bk -words
 .Op Fl h Ar hoplimit
 .Ek
 .Bk -words
@@ -94,6 +100,9 @@ packets to network hosts
 .Op Fl k Ar trafficclass
 .Ek
 .Bk -words
 .Op Fl k Ar trafficclass
 .Ek
 .Bk -words
+.Op Fl K Ar netservicetype
+.Ek
+.Bk -words
 .Op Fl l Ar preload
 .Ek
 .Bk -words
 .Op Fl l Ar preload
 .Ek
 .Bk -words
@@ -113,6 +122,12 @@ packets to network hosts
 .Op Fl z Ar tclass
 .Ek
 .Bk -words
 .Op Fl z Ar tclass
 .Ek
 .Bk -words
+.Op Fl Fl apple-connect
+.Ek
+.Bk -words
+.Op Fl Fl apple-print
+.Ek
+.Bk -words
 .Op Ar hops ...
 .Ek
 .Bk -words
 .Op Ar hops ...
 .Ek
 .Bk -words
@@ -169,6 +184,7 @@ This is an experimental option.
 Set socket buffer size.
 .It Fl B Ar boundif
 Bind the socket to interface
 Set socket buffer size.
 .It Fl B Ar boundif
 Bind the socket to interface
+This option is an Apple addition.
 .Ar boundif
 for sending.
 .It Fl C
 .Ar boundif
 for sending.
 .It Fl C
@@ -179,6 +195,10 @@ Stop after sending
 .Ar count
 .Tn ECHO_RESPONSE
 packets.
 .Ar count
 .Tn ECHO_RESPONSE
 packets.
+If this option is specified in conjunction with ping sweeps,
+each sweep will consist of
+.Ar count
+packets.
 .It Fl D
 Disable IPv6 fragmentation.
 .It Fl d
 .It Fl D
 Disable IPv6 fragmentation.
 .It Fl d
@@ -204,6 +224,18 @@ Only the super-user may use this option.
 .Bf -emphasis
 This can be very hard on a network and should be used with caution.
 .Ef
 .Bf -emphasis
 This can be very hard on a network and should be used with caution.
 .Ef
+.It Fl G Ar sweepmaxsize[,sweepminsize[,sweepincrsize]]
+.Ar sweepmaxsize
+specifies the maximum size of the payload when sending sweeping
+pings and is required for sweeps.
+.Ar sweepminsize
+specifies the size of the payload to start with when sending
+sweeping pings -- the default value is 0.
+.Ar sweepincrsize
+specifies the number of bytes to increment the size of the payload
+after each sweep when sending sweeping pings -- the default value
+is 1.
+This option is an Apple addition.
 .It Fl g Ar gateway
 Specifies to use
 .Ar gateway
 .It Fl g Ar gateway
 Specifies to use
 .Ar gateway
@@ -231,13 +263,19 @@ values less than 0.1 second.
 This option is incompatible with the
 .Fl f
 option.
 This option is incompatible with the
 .Fl f
 option.
-.It Fl k Ar trafficlass
+.It Fl k Ar trafficclass
 Specifies the traffic class to use for sending ICMPv6 packets.
 The supported traffic classes are
 BK_SYS, BK, BE, RD, OAM, AV, RV, VI, VO and CTL.
 By default 
 .Nm
 uses the control traffic class (CTL).
 Specifies the traffic class to use for sending ICMPv6 packets.
 The supported traffic classes are
 BK_SYS, BK, BE, RD, OAM, AV, RV, VI, VO and CTL.
 By default 
 .Nm
 uses the control traffic class (CTL).
+This option is an Apple addition.
+.It Fl K Ar netservicetype
+Specifies the network service type to use for sending ICMPv6 packets.
+The supported network service type are BK_SYS, BK, BE, RV, AV, RD, OAM, VI, SIG and VO.
+Note this overrides the default traffic class (-k can still be specified after -K to use both).
+This option is an Apple addition.
 .It Fl l Ar preload
 If
 .Ar preload
 .It Fl l Ar preload
 If
 .Ar preload
@@ -354,6 +392,12 @@ has no effect if
 is specified.
 .It Fl z Ar tclass
 Use the specified traffic class.
 is specified.
 .It Fl z Ar tclass
 Use the specified traffic class.
+.It Fl Fl apple-connect
+Connects the socket to the destination address.
+This option is an Apple addition.
+.It Fl Fl apple-print
+Prints the time a packet was received.
+This option is an Apple addition.
 .It Ar hops
 IPv6 addresses for intermediate nodes,
 which will be put into type 0 routing header.
 .It Ar hops
 IPv6 addresses for intermediate nodes,
 which will be put into type 0 routing header.
index 90da21a9f726341617dccd6f5e8315d2304124bf..c5b0785cdef74e86471d4e84fb1c49f3ed9a365b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -143,6 +143,7 @@ __unused static const char copyright[] =
 #include <fcntl.h>
 #include <math.h>
 #include <signal.h>
 #include <fcntl.h>
 #include <math.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -151,6 +152,7 @@ __unused static const char copyright[] =
 #include <poll.h>
 #endif
 #include <sysexits.h>
 #include <poll.h>
 #endif
 #include <sysexits.h>
+#include <getopt.h>
 
 #ifdef IPSEC
 #include <netinet6/ah.h>
 
 #ifdef IPSEC
 #include <netinet6/ah.h>
@@ -189,6 +191,7 @@ struct tv32 {
 #define        F_QUIET         0x0010
 #define        F_RROUTE        0x0020
 #define        F_SO_DEBUG      0x0040
 #define        F_QUIET         0x0010
 #define        F_RROUTE        0x0020
 #define        F_SO_DEBUG      0x0040
+#define        F_PRTIME        0x0080
 #define        F_VERBOSE       0x0100
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
 #define        F_VERBOSE       0x0100
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
@@ -211,9 +214,23 @@ struct tv32 {
 #define F_AUDIBLE      0x400000
 #define F_MISSED       0x800000
 #define F_DONTFRAG     0x1000000
 #define F_AUDIBLE      0x400000
 #define F_MISSED       0x800000
 #define F_DONTFRAG     0x1000000
+#define        F_SWEEP         0x2000000
+#define F_CONNECT      0x4000000
 #define F_NOUSERDATA   (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
 u_int options;
 
 #define F_NOUSERDATA   (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
 u_int options;
 
+static int longopt_flag = 0;
+
+#define        LOF_CONNECT     0x01
+#define LOF_PRTIME     0x02
+
+static const struct option longopts[] = {
+       { "apple-connect", no_argument, &longopt_flag, LOF_CONNECT },
+       { "apple-time", no_argument, &longopt_flag, LOF_PRTIME },
+       { NULL, 0, NULL, 0 }
+};
+
+
 #define IN6LEN         sizeof(struct in6_addr)
 #define SA6LEN         sizeof(struct sockaddr_in6)
 #define DUMMY_PORT     10101
 #define IN6LEN         sizeof(struct in6_addr)
 #define SA6LEN         sizeof(struct sockaddr_in6)
 #define DUMMY_PORT     10101
@@ -264,6 +281,11 @@ long nreceived;                    /* # of packets we got back */
 long nrepeats;                 /* number of duplicates */
 long ntransmitted;             /* sequence # for outbound packets = #sent */
 struct timeval interval = {1, 0}; /* interval between packets */
 long nrepeats;                 /* number of duplicates */
 long ntransmitted;             /* sequence # for outbound packets = #sent */
 struct timeval interval = {1, 0}; /* interval between packets */
+long snpackets = 0;            /* max packets to transmit in one sweep */
+long sntransmitted = 0;                /* # of packets we sent in this sweep */
+int sweepmax = 0;              /* max value of payload in sweep */
+int sweepmin = 0;              /* start value of payload in sweep */
+int sweepincr = 1;             /* payload increment in sweep */
 
 /* timing */
 int timing;                    /* flag to do timing */
 
 /* timing */
 int timing;                    /* flag to do timing */
@@ -277,7 +299,7 @@ u_short naflags;
 
 /* for ancillary data(advanced API) */
 struct msghdr smsghdr;
 
 /* for ancillary data(advanced API) */
 struct msghdr smsghdr;
-struct iovec smsgiov;
+struct iovec smsgiov[2];
 char *scmsg = NULL;
 
 volatile sig_atomic_t seenalrm;
 char *scmsg = NULL;
 
 volatile sig_atomic_t seenalrm;
@@ -288,8 +310,14 @@ volatile sig_atomic_t seeninfo;
 
 int rcvtclass = 0;
 
 
 int rcvtclass = 0;
 
-int how_so_traffic_class = 0;
+int use_sendmsg = 0;
+int use_recvmsg = 0;
 int so_traffic_class = SO_TC_CTL;      /* use control class, by default */
 int so_traffic_class = SO_TC_CTL;      /* use control class, by default */
+int net_service_type = -1;
+
+int32_t thiszone;              /* seconds offset from gmt to local time */
+extern int32_t gmt2local(time_t);
+static void pr_currenttime(void);
 
 int     main(int, char *[]);
 void    fill(char *, char *);
 
 int     main(int, char *[]);
 void    fill(char *, char *);
@@ -322,7 +350,9 @@ void         summary(void);
 void    tvsub(struct timeval *, struct timeval *);
 int     setpolicy(int, char *);
 char   *nigroup(char *);
 void    tvsub(struct timeval *, struct timeval *);
 int     setpolicy(int, char *);
 char   *nigroup(char *);
-static uint32_t str2svc(const char *);
+static int str2sotc(const char *, bool *);
+static int str2netservicetype(const char *, bool *);
+static u_int8_t str2tclass(const char *, bool *);
 void    usage(void);
 
 int
 void    usage(void);
 
 int
@@ -365,6 +395,8 @@ main(int argc, char *argv[])
 #endif
        /* T_CLASS value -1 means default, so -2 means do not bother */
        int tclass = -2;
 #endif
        /* T_CLASS value -1 means default, so -2 means do not bother */
        int tclass = -2;
+       bool valid;
+       struct timeval intvl;
 
        /* just to be sure */
        memset(&smsghdr, 0, sizeof(smsghdr));
 
        /* just to be sure */
        memset(&smsghdr, 0, sizeof(smsghdr));
@@ -381,8 +413,9 @@ main(int argc, char *argv[])
 #define ADDOPTS        "AE"
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
 #define ADDOPTS        "AE"
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
-       while ((ch = getopt(argc, argv,
-           "a:b:B:Cc:DdfHg:h:I:i:k:l:mnNop:qrRS:s:tvwWz:" ADDOPTS)) != -1) {
+       while ((ch = getopt_long(argc, argv,
+           "a:b:B:Cc:DdfHG:g:h:I:i:k:K:l:mnNop:qrRS:s:tvwWz:" ADDOPTS,
+           longopts, NULL)) != -1) {
 #undef ADDOPTS
                switch (ch) {
                case 'a':
 #undef ADDOPTS
                switch (ch) {
                case 'a':
@@ -471,6 +504,66 @@ main(int argc, char *argv[])
                case 'g':
                        gateway = optarg;
                        break;
                case 'g':
                        gateway = optarg;
                        break;
+               case 'G': {
+                       char *ptr ;
+                       char *tofree;
+                       unsigned long ultmp;
+
+                       tofree = strdup(optarg);
+                       if (tofree == NULL)
+                               errx(1, "### strdup() failed");
+                       ptr = tofree;
+                       do {
+                               char *str;
+                               char *ep;
+                               
+                               if ((str = strsep(&ptr, ",")) == NULL)
+                                       errx(1, "-G requires maximum packet size");
+                               ultmp = strtoul(str, &ep, 0);
+                               if (*ep || ep == optarg)
+                                       errx(EX_USAGE, "option -G invalid maximum packet size: `%s'",
+                                            str);
+                               options |= F_SWEEP;
+                               sweepmax = ultmp;
+                               if (sweepmax < 1 || sweepmax > MAXDATALEN) {
+                                       errx(1,
+                                            "-G invalid maximum packet size, needs to be between 1 and %d",
+                                            MAXDATALEN);
+                               }
+
+                               if ((str = strsep(&ptr, ",")) == NULL)
+                                       break;
+                               if (*str != 0) {
+                                       ultmp = strtoul(str, &ep, 0);
+                                       if (*ep || ep == optarg)
+                                               errx(EX_USAGE, "option -G invalid minimum packet size: `%s'",
+                                                    str);
+                                       sweepmin = ultmp;
+                                       if (sweepmin < 0 || sweepmin > MAXDATALEN) {
+                                               errx(1,
+                                                    "-G invalid minimum packet size, needs to be between 0 and %d",
+                                                    MAXDATALEN);
+                                       }
+                               }
+                               
+                               if ((str = strsep(&ptr, ",")) == NULL)
+                                       break;
+                               if (*str == 0)
+                                       break;
+                               ultmp = strtoul(str, &ep, 0);
+                               if (*ep || ep == optarg)
+                                       errx(EX_USAGE, "option -G invalid sweep increment size: `%s'",
+                                            str);
+                               sweepincr = ultmp;
+                               if (sweepincr < 1 || sweepincr > MAXDATALEN) {
+                                       errx(1,
+                                            "-G invalid sweep increment size, needs to be between 1 and %d",
+                                            MAXDATALEN);
+                               }
+                       } while (0);
+                       free(tofree);
+                       break;
+               }
                case 'H':
                        options |= F_HOSTNAME;
                        break;
                case 'H':
                        options |= F_HOSTNAME;
                        break;
@@ -510,13 +603,31 @@ main(int argc, char *argv[])
                        options |= F_INTERVAL;
                        break;
                case 'k':
                        options |= F_INTERVAL;
                        break;
                case 'k':
-                       how_so_traffic_class++;
-                       so_traffic_class = str2svc(optarg);
-                       if (so_traffic_class == UINT32_MAX)
+                       if (strcasecmp(optarg, "sendmsg") == 0) {
+                               use_sendmsg++;
+                               break;
+                       }
+                       if (strcasecmp(optarg, "recvmsg") == 0) {
+                               use_recvmsg++;
+                               break;
+                       }
+                       so_traffic_class = str2sotc(optarg, &valid);
+                       if (valid == false)
                                errx(EX_USAGE, "bad traffic class: `%s'",
                                     optarg);
                        break;
                                errx(EX_USAGE, "bad traffic class: `%s'",
                                     optarg);
                        break;
-
+               case 'K':
+                       if (strcasecmp(optarg, "sendmsg") == 0) {
+                               use_sendmsg++;
+                               break;
+                       }
+                       net_service_type = str2netservicetype(optarg, &valid);
+                       if (valid == false)
+                               errx(EX_USAGE, "bad network service type: `%s'",
+                                    optarg);
+                       /* suppress default traffic class (-k can still be specified after -K) */
+                       so_traffic_class = -1;
+                       break;
                case 'l':
                        if (getuid()) {
                                errno = EPERM;
                case 'l':
                        if (getuid()) {
                                errno = EPERM;
@@ -546,7 +657,7 @@ main(int argc, char *argv[])
                case 'p':               /* fill buffer with user pattern */
                        options |= F_PINGFILLED;
                        fill((char *)datap, optarg);
                case 'p':               /* fill buffer with user pattern */
                        options |= F_PINGFILLED;
                        fill((char *)datap, optarg);
-                               break;
+                       break;
                case 'q':
                        options |= F_QUIET;
                        break;
                case 'q':
                        options |= F_QUIET;
                        break;
@@ -604,13 +715,9 @@ main(int argc, char *argv[])
                        options |= F_FQDNOLD;
                        break;
                case 'z':
                        options |= F_FQDNOLD;
                        break;
                case 'z':
-                       tclass = (int)strtol(optarg, &e, 10);
-                       if (tclass < -1 || *optarg == '\0' || *e != '\0')
+                       tclass = str2tclass(optarg, &valid);
+                       if (valid == false)
                                errx(1, "illegal TOS value -- %s", optarg);
                                errx(1, "illegal TOS value -- %s", optarg);
-                       if (tclass > MAXTOS)
-                               errx(1,
-                                   "TOS value too large, maximum is %d",
-                                   MAXTOS);
                        rcvtclass = 1;
                        break;
 #ifdef IPSEC
                        rcvtclass = 1;
                        break;
 #ifdef IPSEC
@@ -635,6 +742,20 @@ main(int argc, char *argv[])
                        break;
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/
                        break;
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/
+               case 0:
+                       switch (longopt_flag) {
+                               case LOF_CONNECT:
+                                       options |= F_CONNECT;
+                                       break;
+                               case LOF_PRTIME:
+                                       options |= F_PRTIME;
+                                       thiszone = gmt2local(0);
+                                       break;
+                               default:
+                                       break;
+                       }
+                       longopt_flag = 0;
+                       break;
                default:
                        usage();
                        /*NOTREACHED*/
                default:
                        usage();
                        /*NOTREACHED*/
@@ -644,6 +765,12 @@ main(int argc, char *argv[])
        if (boundif != NULL && (ifscope = if_nametoindex(boundif)) == 0)
                errx(1, "bad interface name");
 
        if (boundif != NULL && (ifscope = if_nametoindex(boundif)) == 0)
                errx(1, "bad interface name");
 
+       if ((options & F_SWEEP) && !sweepmax)
+               errx(EX_USAGE, "Maximum sweep size must be specified");
+
+       if ((options & F_SWEEP) && (options & F_NOUSERDATA))
+               errx(EX_USAGE, "Option -G incompatible with -t, -w and -W");
+       
        argc -= optind;
        argv += optind;
 
        argc -= optind;
        argv += optind;
 
@@ -787,17 +914,32 @@ main(int argc, char *argv[])
        if ((options & F_FLOOD) && (options & F_INTERVAL))
                errx(1, "-f and -i incompatible options");
 
        if ((options & F_FLOOD) && (options & F_INTERVAL))
                errx(1, "-f and -i incompatible options");
 
-       if ((options & F_NOUSERDATA) == 0) {
-               if (datalen >= sizeof(struct tv32)) {
-                       /* we can time transfer */
-                       timing = 1;
+       if ((options & F_CONNECT)) {
+               if (connect(s, (struct sockaddr *)&dst, sizeof(dst)) == -1)
+                       err(EX_OSERR, "connect");
+       }
+       
+       if (sweepmax) {
+               if (sweepmin >= sweepmax)
+                       errx(EX_USAGE, "Maximum packet size must be greater than the minimum packet size");
+               
+               if (datalen != DEFDATALEN)
+                       errx(EX_USAGE, "Packet size and ping sweep are mutually exclusive");
+               
+               if (npackets > 0) {
+                       snpackets = npackets;
+                       npackets = 0;
                } else
                } else
-                       timing = 0;
+                       snpackets = 1;
+               datalen = sweepmin;
+       }
+       
+       if ((options & F_NOUSERDATA) == 0) {
                /* in F_VERBOSE case, we may get non-echoreply packets*/
                if (options & F_VERBOSE)
                /* in F_VERBOSE case, we may get non-echoreply packets*/
                if (options & F_VERBOSE)
-                       packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA;
+                       packlen = MAX(2048, sweepmax) + IP6LEN + ICMP6ECHOLEN + EXTRA;
                else
                else
-                       packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA;
+                       packlen = MAX(datalen, sweepmax) + IP6LEN + ICMP6ECHOLEN + EXTRA;
        } else {
                /* suppress timing for node information query */
                timing = 0;
        } else {
                /* suppress timing for node information query */
                timing = 0;
@@ -805,10 +947,10 @@ main(int argc, char *argv[])
                packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA;
        }
 
                packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA;
        }
 
-       if (!(packet = (u_char *)malloc((u_int)packlen)))
+       if (!(packet = (u_char *)malloc((u_int)MAX(datalen, sweepmax))))
                err(1, "Unable to allocate packet");
        if (!(options & F_PINGFILLED))
                err(1, "Unable to allocate packet");
        if (!(options & F_PINGFILLED))
-               for (i = ICMP6ECHOLEN; i < packlen; ++i)
+               for (i = ICMP6ECHOLEN; i < MAX(datalen, sweepmax); ++i)
                        *datap++ = i;
 
        ident = getpid() & 0xFFFF;
                        *datap++ = i;
 
        ident = getpid() & 0xFFFF;
@@ -959,17 +1101,29 @@ main(int argc, char *argv[])
        if (tclass != -2)
                ip6optlen += CMSG_SPACE(sizeof(int));
 
        if (tclass != -2)
                ip6optlen += CMSG_SPACE(sizeof(int));
 
-       if (how_so_traffic_class < 2 && so_traffic_class >= 0) {
-               (void) setsockopt(s, SOL_SOCKET, SO_TRAFFIC_CLASS,
-                   (void *)&so_traffic_class, sizeof (so_traffic_class));
+       if (use_sendmsg == 0) {
+               if (net_service_type != -1)
+                       if (setsockopt(s, SOL_SOCKET, SO_NET_SERVICE_TYPE,
+                                      (void *)&net_service_type, sizeof (net_service_type)) != 0)
+                               warn("setsockopt(SO_NET_SERVICE_TYPE");
+               if (so_traffic_class != -1) {
+                       if (setsockopt(s, SOL_SOCKET, SO_TRAFFIC_CLASS,
+                           (void *)&so_traffic_class, sizeof (so_traffic_class)) != 0)
+                               warn("setsockopt(SO_TRAFFIC_CLASS");
+                       
+               }
+       } else {
+               if (net_service_type != -1)
+                       ip6optlen += CMSG_SPACE(sizeof(int));
+               if (so_traffic_class != -1)
+                       ip6optlen += CMSG_SPACE(sizeof(int));
        }
        }
-       if (how_so_traffic_class > 0) {
+       if (use_recvmsg > 0) {
                int on = 1;
                int on = 1;
-               (void) setsockopt(s, SOL_SOCKET, SO_RECV_TRAFFIC_CLASS,
-                   (void *)&on, sizeof (on));
+               if (setsockopt(s, SOL_SOCKET, SO_RECV_TRAFFIC_CLASS,
+                   (void *)&on, sizeof (on)) != 0)
+                       warn("setsockopt(SO_RECV_TRAFFIC_CLASS");
        }
        }
-       if (how_so_traffic_class > 1)
-               ip6optlen += CMSG_SPACE(sizeof(int));
 
        /* set IP6 packet options */
        if (ip6optlen) {
 
        /* set IP6 packet options */
        if (ip6optlen) {
@@ -1082,13 +1236,21 @@ main(int argc, char *argv[])
 
                scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
        }
 
                scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
        }
-       if (how_so_traffic_class > 1 && so_traffic_class >= 0) {
-               scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
-               scmsgp->cmsg_level = SOL_SOCKET;
-               scmsgp->cmsg_type = SO_TRAFFIC_CLASS;
-               *(int *)(CMSG_DATA(scmsgp)) = so_traffic_class;
+       if (use_sendmsg != 0) {
+               if (so_traffic_class != -1) {
+                       scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
+                       scmsgp->cmsg_level = SOL_SOCKET;
+                       scmsgp->cmsg_type = SO_TRAFFIC_CLASS;
+                       *(int *)(CMSG_DATA(scmsgp)) = so_traffic_class;
 
 
-               scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
+                       scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
+               }
+               if (net_service_type != -1) {
+                       scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
+                       scmsgp->cmsg_level = SOL_SOCKET;
+                       scmsgp->cmsg_type = SO_NET_SERVICE_TYPE;
+                       *(int *)(CMSG_DATA(scmsgp)) = net_service_type;
+               }
        }
        if (!(options & F_SRCADDR)) {
                /*
        }
        if (!(options & F_SRCADDR)) {
                /*
@@ -1156,7 +1318,7 @@ main(int argc, char *argv[])
 
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
        if (sockbufsize) {
 
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
        if (sockbufsize) {
-               if (datalen > sockbufsize)
+               if (MAX(datalen, sweepmax) > sockbufsize)
                        warnx("you need -b to increase socket buffer size");
                if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
                    sizeof(sockbufsize)) < 0)
                        warnx("you need -b to increase socket buffer size");
                if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
                    sizeof(sockbufsize)) < 0)
@@ -1166,7 +1328,7 @@ main(int argc, char *argv[])
                        err(1, "setsockopt(SO_RCVBUF)");
        }
        else {
                        err(1, "setsockopt(SO_RCVBUF)");
        }
        else {
-               if (datalen > 8 * 1024) /*XXX*/
+               if (MAX(datalen, sweepmax) > 8 * 1024)  /*XXX*/
                        warnx("you need -b to increase socket buffer size");
                /*
                 * When pinging the broadcast address, you can get a lot of
                        warnx("you need -b to increase socket buffer size");
                /*
                 * When pinging the broadcast address, you can get a lot of
@@ -1203,21 +1365,42 @@ main(int argc, char *argv[])
                    optval, sizeof(optval)); /* XXX err? */
 #endif
 
                    optval, sizeof(optval)); /* XXX err? */
 #endif
 
-       printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
-           (unsigned long)(pingerlen() - 8));
+       if (sweepmax)
+               printf("PING6(40+8+[%lu...%lu] bytes) ",
+                      (unsigned long)(sweepmin),
+                      (unsigned long)(sweepmax));
+       else
+               printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
+                       (unsigned long)(pingerlen() - 8));
        printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
        printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst)));
 
        while (preload--)               /* Fire off them quickies. */
                (void)pinger();
 
        printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
        printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst)));
 
        while (preload--)               /* Fire off them quickies. */
                (void)pinger();
 
+       /*
+        * rdar://25829310
+        *
+        * Clear blocked signals inherited from the parent
+        */
+       sigset_t newset;
+       sigemptyset(&newset);
+       if (sigprocmask(SIG_SETMASK, &newset, NULL) != 0)
+               err(EX_OSERR, "sigprocmask(newset)");
+       
+       seenalrm = seenint = 0;
+#ifdef SIGINFO
+       seeninfo = 0;
+#endif
+       
        (void)signal(SIGINT, onsignal);
 #ifdef SIGINFO
        (void)signal(SIGINFO, onsignal);
 #endif
 
        if ((options & F_FLOOD) == 0) {
        (void)signal(SIGINT, onsignal);
 #ifdef SIGINFO
        (void)signal(SIGINFO, onsignal);
 #endif
 
        if ((options & F_FLOOD) == 0) {
-               (void)signal(SIGALRM, onsignal);
+               if (signal(SIGALRM, onsignal) == SIG_ERR)
+                       warn("signal(SIGALRM)");
                itimer.it_interval = interval;
                itimer.it_value = interval;
                (void)setitimer(ITIMER_REAL, &itimer, NULL);
                itimer.it_interval = interval;
                itimer.it_value = interval;
                (void)setitimer(ITIMER_REAL, &itimer, NULL);
@@ -1225,17 +1408,20 @@ main(int argc, char *argv[])
                        retransmit();
        }
 
                        retransmit();
        }
 
+       if (options & F_FLOOD) {
+               intvl.tv_sec = 0;
+               intvl.tv_usec = 10000;
+       } else {
+               intvl.tv_sec = interval.tv_sec;
+               intvl.tv_usec = interval.tv_usec;
+       }
+       
 #ifndef HAVE_POLL_H
        fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask);
        if ((fdmaskp = malloc(fdmasks)) == NULL)
                err(1, "malloc");
 #endif
 
 #ifndef HAVE_POLL_H
        fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask);
        if ((fdmaskp = malloc(fdmasks)) == NULL)
                err(1, "malloc");
 #endif
 
-       seenalrm = seenint = 0;
-#ifdef SIGINFO
-       seeninfo = 0;
-#endif
-
        /* For control (ancillary) data received from recvmsg() */
        cm = (struct cmsghdr *)malloc(CONTROLLEN);
        if (cm == NULL)
        /* For control (ancillary) data received from recvmsg() */
        cm = (struct cmsghdr *)malloc(CONTROLLEN);
        if (cm == NULL)
@@ -1247,28 +1433,32 @@ main(int argc, char *argv[])
 
                /* signal handling */
                if (seenalrm) {
 
                /* signal handling */
                if (seenalrm) {
+                       seenalrm = 0;
                        /* last packet sent, timeout reached? */
                        if (npackets && ntransmitted >= npackets)
                                break;
                        /* last packet sent, timeout reached? */
                        if (npackets && ntransmitted >= npackets)
                                break;
+                       /* sweep done ? */
+                       if (sweepmax && datalen > sweepmax)
+                               break;
                        retransmit();
                        retransmit();
-                       seenalrm = 0;
                        continue;
                }
                if (seenint) {
                        continue;
                }
                if (seenint) {
-                       onint(SIGINT);
                        seenint = 0;
                        seenint = 0;
+                       onint(SIGINT);
                        continue;
                }
 #ifdef SIGINFO
                if (seeninfo) {
                        continue;
                }
 #ifdef SIGINFO
                if (seeninfo) {
-                       summary();
                        seeninfo = 0;
                        seeninfo = 0;
+                       summary();
                        continue;
                }
 #endif
 
                if (options & F_FLOOD) {
                        continue;
                }
 #endif
 
                if (options & F_FLOOD) {
-                       (void)pinger();
+                       if (pinger() != 0)
+                               break;
 #ifdef HAVE_POLL_H
                        timeout = 10;
 #else
 #ifdef HAVE_POLL_H
                        timeout = 10;
 #else
@@ -1302,9 +1492,9 @@ main(int argc, char *argv[])
                                sleep(1);
                        }
                        continue;
                                sleep(1);
                        }
                        continue;
-               } else if (cc == 0)
+               } else if (cc == 0) {
                        continue;
                        continue;
-
+               }
                m.msg_name = (caddr_t)&from;
                m.msg_namelen = sizeof(from);
                memset(&iov, 0, sizeof(iov));
                m.msg_name = (caddr_t)&from;
                m.msg_namelen = sizeof(from);
                memset(&iov, 0, sizeof(iov));
@@ -1378,7 +1568,8 @@ main(int argc, char *argv[])
 void
 onsignal(int sig)
 {
 void
 onsignal(int sig)
 {
-
+       fflush(stdout);
+       
        switch (sig) {
        case SIGALRM:
                seenalrm++;
        switch (sig) {
        case SIGALRM:
                seenalrm++;
@@ -1403,9 +1594,9 @@ retransmit(void)
 {
        struct itimerval itimer;
 
 {
        struct itimerval itimer;
 
-       if (pinger() == 0)
+       if (pinger() == 0) {
                return;
                return;
-
+       }
        /*
         * If we're not transmitting any more packets, change the timer
         * to wait two round-trip times if we've received any packets or
        /*
         * If we're not transmitting any more packets, change the timer
         * to wait two round-trip times if we've received any packets or
@@ -1457,7 +1648,6 @@ int
 pinger(void)
 {
        struct icmp6_hdr *icp;
 pinger(void)
 {
        struct icmp6_hdr *icp;
-       struct iovec iov[2];
        int i, cc;
        struct icmp6_nodeinfo *nip;
        int seq;
        int i, cc;
        struct icmp6_nodeinfo *nip;
        int seq;
@@ -1465,6 +1655,13 @@ pinger(void)
        if (npackets && ntransmitted >= npackets)
                return(-1);     /* no more transmission */
 
        if (npackets && ntransmitted >= npackets)
                return(-1);     /* no more transmission */
 
+       if (sweepmax && sntransmitted == snpackets) {
+               datalen += sweepincr;
+               if (datalen > sweepmax)
+                       return(-1);     /* no more transmission */
+               sntransmitted = 0;
+       }
+
        icp = (struct icmp6_hdr *)outpack;
        nip = (struct icmp6_nodeinfo *)outpack;
        memset(icp, 0, sizeof(*icp));
        icp = (struct icmp6_hdr *)outpack;
        nip = (struct icmp6_nodeinfo *)outpack;
        memset(icp, 0, sizeof(*icp));
@@ -1530,6 +1727,11 @@ pinger(void)
                icp->icmp6_code = 0;
                icp->icmp6_id = htons(ident);
                icp->icmp6_seq = ntohs(seq);
                icp->icmp6_code = 0;
                icp->icmp6_id = htons(ident);
                icp->icmp6_seq = ntohs(seq);
+               if (datalen >= sizeof(struct tv32)) {
+                       /* we can time transfer */
+                       timing = 1;
+               } else
+                       timing = 0;
                if (timing) {
                        struct timeval tv;
                        struct tv32 *tv32;
                if (timing) {
                        struct timeval tv;
                        struct tv32 *tv32;
@@ -1546,12 +1748,17 @@ pinger(void)
                errx(1, "internal error; length mismatch");
 #endif
 
                errx(1, "internal error; length mismatch");
 #endif
 
+       if ((options & F_CONNECT)) {
+               smsghdr.msg_name = NULL;
+               smsghdr.msg_namelen = 0;
+       } else {
        smsghdr.msg_name = (caddr_t)&dst;
        smsghdr.msg_namelen = sizeof(dst);
        smsghdr.msg_name = (caddr_t)&dst;
        smsghdr.msg_namelen = sizeof(dst);
-       memset(&iov, 0, sizeof(iov));
-       iov[0].iov_base = (caddr_t)outpack;
-       iov[0].iov_len = cc;
-       smsghdr.msg_iov = iov;
+       }
+       memset(&smsgiov, 0, sizeof(smsgiov));
+       smsgiov[0].iov_base = (caddr_t)outpack;
+       smsgiov[0].iov_len = cc;
+       smsghdr.msg_iov = smsgiov;
        smsghdr.msg_iovlen = 1;
 
        i = sendmsg(s, &smsghdr, 0);
        smsghdr.msg_iovlen = 1;
 
        i = sendmsg(s, &smsghdr, 0);
@@ -1562,6 +1769,7 @@ pinger(void)
                (void)printf("ping6: wrote %s %d chars, ret=%d\n",
                    hostname, cc, i);
        }
                (void)printf("ping6: wrote %s %d chars, ret=%d\n",
                    hostname, cc, i);
        }
+       sntransmitted++;
        if (!(options & F_QUIET) && options & F_FLOOD)
                (void)write(STDOUT_FILENO, &DOT, 1);
 
        if (!(options & F_QUIET) && options & F_FLOOD)
                (void)write(STDOUT_FILENO, &DOT, 1);
 
@@ -1593,7 +1801,7 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
     size_t bufsiz)
        /*base for compressed name*/
 {
     size_t bufsiz)
        /*base for compressed name*/
 {
-       int i;
+       int i = 0;
        const u_char *cp;
        char cresult[NS_MAXDNAME + 1];
        const u_char *comp;
        const u_char *cp;
        char cresult[NS_MAXDNAME + 1];
        const u_char *comp;
@@ -1715,7 +1923,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
                return;
        }
 
                return;
        }
 
-       if (how_so_traffic_class > 0)
+       if (use_recvmsg > 0)
                sotc = get_so_traffic_class(mhdr);
 
        if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) {
                sotc = get_so_traffic_class(mhdr);
 
        if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) {
@@ -1753,6 +1961,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
                else {
                        if (options & F_AUDIBLE)
                                (void)write(STDOUT_FILENO, &BBELL, 1);
                else {
                        if (options & F_AUDIBLE)
                                (void)write(STDOUT_FILENO, &BBELL, 1);
+                       if (options & F_PRTIME)
+                               pr_currenttime();
                        (void)printf("%d bytes from %s, icmp_seq=%u", cc,
                            pr_addr(from, fromlen), seq);
                        (void)printf(" hlim=%d", hoplim);
                        (void)printf("%d bytes from %s, icmp_seq=%u", cc,
                            pr_addr(from, fromlen), seq);
                        (void)printf(" hlim=%d", hoplim);
@@ -1796,15 +2006,15 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
                if (TST(seq % mx_dup_ck)) {
                        ++nrepeats;
                        --nreceived;
                if (TST(seq % mx_dup_ck)) {
                        ++nrepeats;
                        --nreceived;
-                       dupflag = 1;
                } else {
                        SET(seq % mx_dup_ck);
                } else {
                        SET(seq % mx_dup_ck);
-                       dupflag = 0;
                }
 
                if (options & F_QUIET)
                        return;
 
                }
 
                if (options & F_QUIET)
                        return;
 
+               if (options & F_PRTIME)
+                       pr_currenttime();
                (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
 
                switch (ntohs(ni->ni_code)) {
                (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
 
                switch (ntohs(ni->ni_code)) {
@@ -1941,6 +2151,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
                /* We've got something other than an ECHOREPLY */
                if (!(options & F_VERBOSE))
                        return;
                /* We've got something other than an ECHOREPLY */
                if (!(options & F_VERBOSE))
                        return;
+               if (options & F_PRTIME)
+                       pr_currenttime();
                (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
                pr_icmph(icp, end);
        }
                (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
                pr_icmph(icp, end);
        }
@@ -1961,7 +2173,6 @@ pr_exthdrs(struct msghdr *mhdr)
        void    *bufp;
        struct cmsghdr *cm;
 
        void    *bufp;
        struct cmsghdr *cm;
 
-       bufsize = 0;
        bufp = mhdr->msg_control;
        for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
        bufp = mhdr->msg_control;
        for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
@@ -1998,7 +2209,7 @@ pr_ip6opt(void *extbuf, size_t bufsize)
        struct ip6_hbh *ext;
        int currentlen;
        u_int8_t type;
        struct ip6_hbh *ext;
        int currentlen;
        u_int8_t type;
-       socklen_t extlen, len, origextlen;
+       socklen_t extlen, len;
        void *databuf;
        size_t offset;
        u_int16_t value2;
        void *databuf;
        size_t offset;
        u_int16_t value2;
@@ -2014,7 +2225,6 @@ pr_ip6opt(void *extbuf, size_t bufsize)
         *     subtract the size of a cmsg structure from the buffer size.
         */
        if (bufsize < (extlen  + CMSG_SPACE(0))) {
         *     subtract the size of a cmsg structure from the buffer size.
         */
        if (bufsize < (extlen  + CMSG_SPACE(0))) {
-               origextlen = extlen;
                extlen = bufsize - CMSG_SPACE(0);
                warnx("options truncated, showing only %u (total=%u)",
                    (unsigned int)(extlen / 8 - 1),
                extlen = bufsize - CMSG_SPACE(0);
                warnx("options truncated, showing only %u (total=%u)",
                    (unsigned int)(extlen / 8 - 1),
@@ -2034,14 +2244,14 @@ pr_ip6opt(void *extbuf, size_t bufsize)
                 */
                case IP6OPT_JUMBO:
                        offset = 0;
                 */
                case IP6OPT_JUMBO:
                        offset = 0;
-                       offset = inet6_opt_get_val(databuf, offset,
+                       (void) inet6_opt_get_val(databuf, offset,
                            &value4, sizeof(value4));
                        printf("    Jumbo Payload Opt: Length %u\n",
                            (u_int32_t)ntohl(value4));
                        break;
                case IP6OPT_ROUTER_ALERT:
                        offset = 0;
                            &value4, sizeof(value4));
                        printf("    Jumbo Payload Opt: Length %u\n",
                            (u_int32_t)ntohl(value4));
                        break;
                case IP6OPT_ROUTER_ALERT:
                        offset = 0;
-                       offset = inet6_opt_get_val(databuf, offset,
+                       (void)inet6_opt_get_val(databuf, offset,
                                                   &value2, sizeof(value2));
                        printf("    Router Alert Opt: Type %u\n",
                            ntohs(value2));
                                                   &value2, sizeof(value2));
                        printf("    Router Alert Opt: Type %u\n",
                            ntohs(value2));
@@ -2187,7 +2397,7 @@ pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen)
        struct cbit {
                u_int16_t words;        /*32bit count*/
                u_int16_t skip;
        struct cbit {
                u_int16_t words;        /*32bit count*/
                u_int16_t skip;
-       } cbit;
+       } cbit = { 0, 0 };
 #define MAXQTYPES      (1 << 16)
        size_t off;
        int b;
 #define MAXQTYPES      (1 << 16)
        size_t off;
        int b;
@@ -2995,14 +3205,16 @@ nigroup(char *name)
        return strdup(hbuf);
 }
 
        return strdup(hbuf);
 }
 
-uint32_t
-str2svc(const char *str)
+int
+str2sotc(const char *str, bool *valid)
 {
 {
-       uint32_t svc;
+       int sotc = -1;
        char *endptr;
        
        char *endptr;
        
+       *valid = true;
+       
        if (str == NULL || *str == '\0')
        if (str == NULL || *str == '\0')
-               svc = UINT32_MAX;
+               *valid = false;
        else if (strcasecmp(str, "BK_SYS") == 0)
                return SO_TC_BK_SYS;
        else if (strcasecmp(str, "BK") == 0)
        else if (strcasecmp(str, "BK_SYS") == 0)
                return SO_TC_BK_SYS;
        else if (strcasecmp(str, "BK") == 0)
@@ -3024,13 +3236,132 @@ str2svc(const char *str)
        else if (strcasecmp(str, "CTL") == 0)
                return SO_TC_CTL;
        else {
        else if (strcasecmp(str, "CTL") == 0)
                return SO_TC_CTL;
        else {
-               svc = strtoul(str, &endptr, 0);
+               sotc = (int)strtol(str, &endptr, 0);
                if (*endptr != '\0')
                if (*endptr != '\0')
-                       svc = UINT32_MAX;
+                       *valid = false;
+       }
+       return (sotc);
+}
+
+int
+str2netservicetype(const char *str, bool *valid)
+{
+       int svc = -1;
+       char *endptr;
+       
+       *valid = true;
+       
+       if (str == NULL || *str == '\0')
+               *valid = false;
+       else if (strcasecmp(str, "BK") == 0)
+               return NET_SERVICE_TYPE_BK;
+       else if (strcasecmp(str, "BE") == 0)
+               return NET_SERVICE_TYPE_BE;
+       else if (strcasecmp(str, "VI") == 0)
+               return NET_SERVICE_TYPE_VI;
+       else if (strcasecmp(str, "SIG") == 0)
+               return NET_SERVICE_TYPE_SIG;
+       else if (strcasecmp(str, "VO") == 0)
+               return NET_SERVICE_TYPE_VO;
+       else if (strcasecmp(str, "RV") == 0)
+               return NET_SERVICE_TYPE_RV;
+       else if (strcasecmp(str, "AV") == 0)
+               return NET_SERVICE_TYPE_AV;
+       else if (strcasecmp(str, "OAM") == 0)
+               return NET_SERVICE_TYPE_OAM;
+       else if (strcasecmp(str, "RD") == 0)
+               return NET_SERVICE_TYPE_RD;
+       else {
+               svc = (int)strtol(str, &endptr, 0);
+               if (*endptr != '\0')
+                       *valid = false;
        }
        return (svc);
 }
 
        }
        return (svc);
 }
 
+u_int8_t
+str2tclass(const char *str, bool *valid)
+{
+       u_int8_t dscp = -1;
+       char *endptr;
+       
+       *valid = true;
+       
+       if (str == NULL || *str == '\0')
+               *valid = false;
+       else if (strcasecmp(str, "DF") == 0)
+               dscp = _DSCP_DF;
+       else if (strcasecmp(str, "EF") == 0)
+               dscp = _DSCP_EF;
+       else if (strcasecmp(str, "VA") == 0)
+               dscp = _DSCP_VA;
+       
+       else if (strcasecmp(str, "CS0") == 0)
+               dscp = _DSCP_CS0;
+       else if (strcasecmp(str, "CS1") == 0)
+               dscp = _DSCP_CS1;
+       else if (strcasecmp(str, "CS2") == 0)
+               dscp = _DSCP_CS2;
+       else if (strcasecmp(str, "CS3") == 0)
+               dscp = _DSCP_CS3;
+       else if (strcasecmp(str, "CS4") == 0)
+               dscp = _DSCP_CS4;
+       else if (strcasecmp(str, "CS5") == 0)
+               dscp = _DSCP_CS5;
+       else if (strcasecmp(str, "CS6") == 0)
+               dscp = _DSCP_CS6;
+       else if (strcasecmp(str, "CS7") == 0)
+               dscp = _DSCP_CS7;
+       
+       else if (strcasecmp(str, "AF11") == 0)
+               dscp = _DSCP_AF11;
+       else if (strcasecmp(str, "AF12") == 0)
+               dscp = _DSCP_AF12;
+       else if (strcasecmp(str, "AF13") == 0)
+               dscp = _DSCP_AF13;
+       else if (strcasecmp(str, "AF21") == 0)
+               dscp = _DSCP_AF21;
+       else if (strcasecmp(str, "AF22") == 0)
+               dscp = _DSCP_AF22;
+       else if (strcasecmp(str, "AF23") == 0)
+               dscp = _DSCP_AF23;
+       else if (strcasecmp(str, "AF31") == 0)
+               dscp = _DSCP_AF31;
+       else if (strcasecmp(str, "AF32") == 0)
+               dscp = _DSCP_AF32;
+       else if (strcasecmp(str, "AF33") == 0)
+               dscp = _DSCP_AF33;
+       else if (strcasecmp(str, "AF41") == 0)
+               dscp = _DSCP_AF41;
+       else if (strcasecmp(str, "AF42") == 0)
+               dscp = _DSCP_AF42;
+       else if (strcasecmp(str, "AF43") == 0)
+               dscp = _DSCP_AF43;
+       
+       else {
+               unsigned long val = strtoul(str, &endptr, 0);
+               if (*endptr != '\0' || val > 255)
+                       *valid = false;
+               else
+                       return ((u_int8_t)val);
+       }
+       /* DSCP occupies the 6 upper bits of the traffic class field */
+       return (dscp << 2);
+}
+
+void
+pr_currenttime(void)
+{
+       int s;
+       struct timeval tv;
+       
+       gettimeofday(&tv, NULL);
+       
+       s = (tv.tv_sec + thiszone) % 86400;
+       printf("%02d:%02d:%02d.%06u ", s / 3600, (s % 3600) / 60, s % 60,
+              (u_int32_t)tv.tv_usec);
+}
+
 void
 usage(void)
 {
 void
 usage(void)
 {
@@ -3048,13 +3379,21 @@ usage(void)
            "m"
 #endif
            "nNoqrRtvwW] "
            "m"
 #endif
            "nNoqrRtvwW] "
-           "[-a addrtype] [-b bufsiz] [-B boundif] [-c count]\n"
+           "[-a addrtype] [-b bufsiz] [-c count]\n"
            "             [-g gateway] [-h hoplimit] [-I interface] [-i wait] [-l preload]"
 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
            " [-P policy]"
 #endif
            "\n"
            "             [-p pattern] [-S sourceaddr] [-s packetsize] [-z tclass] "
            "             [-g gateway] [-h hoplimit] [-I interface] [-i wait] [-l preload]"
 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
            " [-P policy]"
 #endif
            "\n"
            "             [-p pattern] [-S sourceaddr] [-s packetsize] [-z tclass] "
+           "[-k traffic_class] [-K net_service_type] "
            "[hops ...] host\n");
            "[hops ...] host\n");
+       (void)fprintf(stderr, "Apple specific options (to be specified before hops or host like all options)\n");
+       (void)fprintf(stderr, "            -b boundif           # bind the socket to the interface\n");
+       (void)fprintf(stderr, "            -k traffic_class     # set traffic class socket option\n");
+       (void)fprintf(stderr, "            -K net_service_type  # set traffic class socket options\n");
+       (void)fprintf(stderr, "            -apple-connect       # call connect(2) in the socket\n");
+       (void)fprintf(stderr, "            -apple-time          # display current time\n");
+       (void)fprintf(stderr, "            -apple-progress      # show progress for debugging\n");
        exit(1);
 }
        exit(1);
 }
index fab5ce90d81dcd4e98458abf1ddb00a0146b9f60..8ce0f8fc2875e1d32f30d92c9da1aed01ca4555f 100644 (file)
@@ -145,7 +145,7 @@ main(int argc, char * const argv[]) {
         exit(0);
     }
     
         exit(0);
     }
     
-    while ((ch = getopt(argc, argv, "hf:l:r:t:p:m:M:L:R")) != -1) {
+    while ((ch = getopt(argc, argv, "hf:l:r:t:p:m:M:L:R:")) != -1) {
         switch (ch) {
             case 'h':
                 usage(argv[0]);
         switch (ch) {
             case 'h':
                 usage(argv[0]);
index c2508bdef7e2140610dc5eea9437b2a32af1a103..69ee7e1773487ae91fd9a3ecf4bbea5760fdeb3d 100644 (file)
@@ -127,6 +127,10 @@ int        getaddr(), rtmsg(), x25_makemask();
 int    prefixlen();
 extern char *iso_ntoa();
 
 int    prefixlen();
 extern char *iso_ntoa();
 
+static void
+inet_makenetandmask(in_addr_t net, struct sockaddr_in *sin,
+    struct sockaddr_in *sin_mask, in_addr_t bits);
+
 void usage __P((const char *)) __dead2;
 
 void
 void usage __P((const char *)) __dead2;
 
 void
@@ -414,71 +418,49 @@ routename(sa)
 
 /*
  * Return the name of the network whose address is given.
 
 /*
  * Return the name of the network whose address is given.
- * The address is assumed to be that of a net or subnet, not a host.
+ * The address is assumed to be that of a net, not a host.
  */
 const char *
 netname(sa)
        struct sockaddr *sa;
 {
  */
 const char *
 netname(sa)
        struct sockaddr *sa;
 {
-       char *cp = 0;
+       char *cp = NULL;
        static char line[MAXHOSTNAMELEN + 1];
        static char line[MAXHOSTNAMELEN + 1];
-       struct netent *np = 0;
-       in_addr_t net, mask;
+       struct netent *np = NULL;
        register in_addr_t i;
        register in_addr_t i;
-       int subnetshift;
 
        switch (sa->sa_family) {
 
 
        switch (sa->sa_family) {
 
-       case AF_INET:
-           {   struct in_addr in;
-               in = ((struct sockaddr_in *)sa)->sin_addr;
-
-               i = in.s_addr = ntohl(in.s_addr);
-               if (in.s_addr == 0)
-                       cp = "default";
-               else if (!nflag) {
-                       if (IN_CLASSA(i)) {
-                               mask = IN_CLASSA_NET;
-                               subnetshift = 8;
-                       } else if (IN_CLASSB(i)) {
-                               mask = IN_CLASSB_NET;
-                               subnetshift = 8;
-                       } else {
-                               mask = IN_CLASSC_NET;
-                               subnetshift = 4;
-                       }
-                       /*
-                        * If there are more bits than the standard mask
-                        * would suggest, subnets must be in use.
-                        * Guess at the subnet mask, assuming reasonable
-                        * width subnet fields.
-                        */
-                       while (in.s_addr &~ mask)
-                               mask = mask >> subnetshift;
-                       net = in.s_addr & mask;
-                       while ((mask & 1) == 0)
-                               mask >>= 1, net >>= 1;
-                       np = getnetbyaddr(net, AF_INET);
-                       if (np)
-                               cp = np->n_name;
-               }
-               if (cp)
-                       strncpy(line, cp, sizeof(line));
-               else if ((in.s_addr & 0xffffff) == 0)
-                       (void) snprintf(line, sizeof(line), "%u", C(in.s_addr >> 24));
-               else if ((in.s_addr & 0xffff) == 0)
-                       (void) snprintf(line, sizeof(line), "%u.%u", C(in.s_addr >> 24),
-                           C(in.s_addr >> 16));
-               else if ((in.s_addr & 0xff) == 0)
-                       (void) snprintf(line, sizeof(line), "%u.%u.%u", C(in.s_addr >> 24),
-                           C(in.s_addr >> 16), C(in.s_addr >> 8));
-               else
-                       (void) snprintf(line, sizeof(line), "%u.%u.%u.%u", C(in.s_addr >> 24),
-                           C(in.s_addr >> 16), C(in.s_addr >> 8),
-                           C(in.s_addr));
-               break;
-           }
-
+               case AF_INET:
+                  {   struct in_addr in;
+                      in = ((struct sockaddr_in *)sa)->sin_addr;
+
+                      i = in.s_addr = ntohl(in.s_addr);
+                      if (in.s_addr == 0)
+                              cp = "default";
+                      else if (!nflag) {
+                              np = getnetbyaddr(i, AF_INET);
+                              if (np != NULL)
+                                      cp = np->n_name;
+                      }
+#define C(x)    (unsigned)((x) & 0xff)
+                      if (cp != NULL)
+                              strncpy(line, cp, sizeof(line));
+                      else if ((in.s_addr & 0xffffff) == 0)
+                              (void) sprintf(line, "%u", C(in.s_addr >> 24));
+                      else if ((in.s_addr & 0xffff) == 0)
+                              (void) sprintf(line, "%u.%u", C(in.s_addr >> 24),
+                                              C(in.s_addr >> 16));
+                      else if ((in.s_addr & 0xff) == 0)
+                              (void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
+                                              C(in.s_addr >> 16), C(in.s_addr >> 8));
+                      else
+                              (void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
+                                              C(in.s_addr >> 16), C(in.s_addr >> 8),
+                                              C(in.s_addr));
+#undef C
+                      break;
+                  }
 #ifdef INET6
        case AF_INET6:
        {
 #ifdef INET6
        case AF_INET6:
        {
@@ -787,49 +769,43 @@ newroute(argc, argv)
        }
 }
 
        }
 }
 
-void
-inet_makenetandmask(net, sin, bits)
-       in_addr_t net, bits;
-       register struct sockaddr_in *sin;
+static void
+inet_makenetandmask(in_addr_t net, struct sockaddr_in *sin,
+    struct sockaddr_in *sin_mask, in_addr_t bits)
 {
 {
-       in_addr_t addr, mask = 0;
-       register char *cp;
-
+       in_addr_t mask = 0;
+       
        rtm_addrs |= RTA_NETMASK;
        rtm_addrs |= RTA_NETMASK;
-       if (bits) {
-               addr = net;
-               mask = 0xffffffff << (32 - bits);
-       } else if (net == 0)
-               mask = addr = 0;
-       else if (net < 128) {
-               addr = net << IN_CLASSA_NSHIFT;
-               mask = IN_CLASSA_NET;
-       } else if (net < 65536) {
-               addr = net << IN_CLASSB_NSHIFT;
-               mask = IN_CLASSB_NET;
-       } else if (net < 16777216L) {
-               addr = net << IN_CLASSC_NSHIFT;
-               mask = IN_CLASSC_NET;
-       } else {
-               addr = net;
-               if ((addr & IN_CLASSA_HOST) == 0)
-                       mask =  IN_CLASSA_NET;
-               else if ((addr & IN_CLASSB_HOST) == 0)
-                       mask =  IN_CLASSB_NET;
-               else if ((addr & IN_CLASSC_HOST) == 0)
-                       mask =  IN_CLASSC_NET;
-               else
-                       mask = -1;
+       /*
+        * MSB of net should be meaningful. 0/0 is exception.
+        */
+       if (net > 0)
+               while ((net & 0xff000000) == 0)
+                       net <<= 8;
+
+       /*
+        * If no /xx was specified we must calculate the
+        * CIDR address.
+        */
+       if ((bits == 0) && (net != 0)) {
+               u_long i, j;
+
+               for(i = 0, j = 0xff; i < 4; i++)  {
+                       if (net & j) {
+                               break;
+                       }
+                       j <<= 8;
+               }
+               /* i holds the first non zero bit */
+               bits = 32 - (i*8);      
        }
        }
-       sin->sin_addr.s_addr = htonl(addr);
-       sin = &so_mask.sin;
-       sin->sin_addr.s_addr = htonl(mask);
-       sin->sin_len = 0;
-       sin->sin_family = 0;
-       cp = (char *)(&sin->sin_addr + 1);
-       while (*--cp == 0 && cp > (char *)sin)
-               ;
-       sin->sin_len = 1 + cp - (char *)sin;
+       if (bits != 0)
+               mask = 0xffffffff << (32 - bits);
+
+       sin->sin_addr.s_addr = htonl(net);
+       sin_mask->sin_addr.s_addr = htonl(mask);
+       sin_mask->sin_len = sizeof(struct sockaddr_in);
+       sin_mask->sin_family = AF_INET;
 }
 
 #ifdef INET6
 }
 
 #ifdef INET6
@@ -1026,17 +1002,18 @@ getaddr(which, s, hpp)
        q = strchr(s,'/');
        if (q && which == RTA_DST) {
                *q = '\0';
        q = strchr(s,'/');
        if (q && which == RTA_DST) {
                *q = '\0';
-               if ((val = inet_addr(s)) != INADDR_NONE) {
+               if ((val = inet_network(s)) != INADDR_NONE) {
                        inet_makenetandmask(
                        inet_makenetandmask(
-                               ntohl(val), &su->sin, strtoul(q+1, 0, 0));
+                               val, &su->sin, (struct sockaddr_in *)&so_mask,
+                               strtoul(q+1, 0, 0));
                        return (0);
                }
                *q = '/';
        }
        if ((which != RTA_DST || forcenet == 0) &&
                        return (0);
                }
                *q = '/';
        }
        if ((which != RTA_DST || forcenet == 0) &&
-           (val = inet_addr(s)) != INADDR_NONE) {
-               su->sin.sin_addr.s_addr = val;
-               if (which != RTA_DST ||
+           inet_aton(s, &su->sin.sin_addr)) {
+               val = su->sin.sin_addr.s_addr;
+               if (which != RTA_DST || forcehost ||
                    inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
                        return (1);
                else {
                    inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
                        return (1);
                else {
@@ -1048,7 +1025,7 @@ getaddr(which, s, hpp)
            ((val = inet_network(s)) != INADDR_NONE ||
            ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0))) {
 netdone:
            ((val = inet_network(s)) != INADDR_NONE ||
            ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0))) {
 netdone:
-               inet_makenetandmask(val, &su->sin, 0);
+               inet_makenetandmask(val, &su->sin, (struct sockaddr_in *)&so_mask, 0);
                return (0);
        }
        hp = gethostbyname(s);
                return (0);
        }
        hp = gethostbyname(s);