Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Aug 2014 17:37:18 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270424 - head/sbin/ipfw
Message-ID:  <201408231737.s7NHbIXN043185@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sat Aug 23 17:37:18 2014
New Revision: 270424
URL: http://svnweb.freebsd.org/changeset/base/270424

Log:
  Merge buffer-printing changes from from projects/ipfw as preparation
  for branch merge.
  
  Requested by:	luigi

Modified:
  head/sbin/ipfw/altq.c
  head/sbin/ipfw/dummynet.c
  head/sbin/ipfw/ipfw2.c
  head/sbin/ipfw/ipfw2.h
  head/sbin/ipfw/ipv6.c

Modified: head/sbin/ipfw/altq.c
==============================================================================
--- head/sbin/ipfw/altq.c	Sat Aug 23 17:31:56 2014	(r270423)
+++ head/sbin/ipfw/altq.c	Sat Aug 23 17:37:18 2014	(r270424)
@@ -137,15 +137,15 @@ altq_qid_to_name(u_int32_t qid)
 }
 
 void
-print_altq_cmd(ipfw_insn_altq *altqptr)
+print_altq_cmd(struct buf_pr *bp, ipfw_insn_altq *altqptr)
 {
 	if (altqptr) {
 		const char *qname;
 
 		qname = altq_qid_to_name(altqptr->qid);
 		if (qname == NULL)
-			printf(" altq ?<%u>", altqptr->qid);
+			bprintf(bp, " altq ?<%u>", altqptr->qid);
 		else
-			printf(" altq %s", qname);
+			bprintf(bp, " altq %s", qname);
 	}
 }

Modified: head/sbin/ipfw/dummynet.c
==============================================================================
--- head/sbin/ipfw/dummynet.c	Sat Aug 23 17:31:56 2014	(r270423)
+++ head/sbin/ipfw/dummynet.c	Sat Aug 23 17:37:18 2014	(r270424)
@@ -174,48 +174,44 @@ print_header(struct ipfw_flow_id *id)
 }
 
 static void
-list_flow(struct dn_flow *ni, int *print)
+list_flow(struct buf_pr *bp, struct dn_flow *ni)
 {
 	char buff[255];
 	struct protoent *pe = NULL;
 	struct in_addr ina;
 	struct ipfw_flow_id *id = &ni->fid;
 
-	if (*print) {
-		print_header(&ni->fid);
-		*print = 0;
-	}
 	pe = getprotobynumber(id->proto);
 		/* XXX: Should check for IPv4 flows */
-	printf("%3u%c", (ni->oid.id) & 0xff,
+	bprintf(bp, "%3u%c", (ni->oid.id) & 0xff,
 		id->extra ? '*' : ' ');
 	if (!IS_IP6_FLOW_ID(id)) {
 		if (pe)
-			printf("%-4s ", pe->p_name);
+			bprintf(bp, "%-4s ", pe->p_name);
 		else
-			printf("%4u ", id->proto);
+			bprintf(bp, "%4u ", id->proto);
 		ina.s_addr = htonl(id->src_ip);
-		printf("%15s/%-5d ",
+		bprintf(bp, "%15s/%-5d ",
 		    inet_ntoa(ina), id->src_port);
 		ina.s_addr = htonl(id->dst_ip);
-		printf("%15s/%-5d ",
+		bprintf(bp, "%15s/%-5d ",
 		    inet_ntoa(ina), id->dst_port);
 	} else {
 		/* Print IPv6 flows */
 		if (pe != NULL)
-			printf("%9s ", pe->p_name);
+			bprintf(bp, "%9s ", pe->p_name);
 		else
-			printf("%9u ", id->proto);
-		printf("%7d  %39s/%-5d ", id->flow_id6,
+			bprintf(bp, "%9u ", id->proto);
+		bprintf(bp, "%7d  %39s/%-5d ", id->flow_id6,
 		    inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
 		    id->src_port);
-		printf(" %39s/%-5d ",
+		bprintf(bp, " %39s/%-5d ",
 		    inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
 		    id->dst_port);
 	}
-	pr_u64(&ni->tot_pkts, 4);
-	pr_u64(&ni->tot_bytes, 8);
-	printf("%2u %4u %3u\n",
+	pr_u64(bp, &ni->tot_pkts, 4);
+	pr_u64(bp, &ni->tot_bytes, 8);
+	bprintf(bp, "%2u %4u %3u",
 	    ni->length, ni->len_bytes, ni->drops);
 }
 
@@ -303,8 +299,10 @@ list_pipes(struct dn_id *oid, struct dn_
 {
     char buf[160];	/* pending buffer */
     int toPrint = 1;	/* print header */
+    struct buf_pr bp;
 
     buf[0] = '\0';
+    bp_alloc(&bp, 4096);
     for (; oid != end; oid = O_NEXT(oid, oid->len)) {
 	if (oid->len < sizeof(*oid))
 		errx(1, "invalid oid len %d\n", oid->len);
@@ -346,7 +344,12 @@ list_pipes(struct dn_id *oid, struct dn_
 	    break;
 
 	case DN_FLOW:
-	    list_flow((struct dn_flow *)oid, &toPrint);
+	    if (toPrint != 0) {
+		    print_header(&((struct dn_flow *)oid)->fid);
+		    toPrint = 0;
+	    }
+	    list_flow(&bp, (struct dn_flow *)oid);
+	    printf("%s\n", bp.buf);
 	    break;
 
 	case DN_LINK: {
@@ -384,6 +387,8 @@ list_pipes(struct dn_id *oid, struct dn_
 	}
 	flush_buf(buf); // XXX does it really go here ?
     }
+
+    bp_free(&bp);
 }
 
 /*

Modified: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c	Sat Aug 23 17:31:56 2014	(r270423)
+++ head/sbin/ipfw/ipfw2.c	Sat Aug 23 17:37:18 2014	(r270424)
@@ -35,6 +35,7 @@
 #include <netdb.h>
 #include <pwd.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
@@ -56,6 +57,21 @@
 
 struct cmdline_opts co;	/* global options */
 
+struct format_opts {
+	int bcwidth;
+	int pcwidth;
+	int show_counters;
+	uint32_t set_mask;	/* enabled sets mask */
+	uint32_t flags;		/* request flags */
+	uint32_t first;		/* first rule to request */
+	uint32_t last;		/* last rule to request */
+	uint32_t dcnt;		/* number of dynamic states */
+};
+#define	IP_FW_TARG	IP_FW_TABLEARG
+#define	ip_fw_bcounter	ip_fw
+#define	ip_fw_rule	ip_fw
+struct tidx;
+
 int resvd_set_number = RESVD_SET;
 
 int ipfw_socket = -1;
@@ -86,7 +102,7 @@ uint32_t ipfw_tables_max = 0; /* Number 
 	if (!av[0])							\
 		errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \
 	if (_substrcmp(*av, "tablearg") == 0) {				\
-		arg = IP_FW_TABLEARG;					\
+		arg = IP_FW_TARG;					\
 		break;							\
 	}								\
 									\
@@ -104,24 +120,13 @@ uint32_t ipfw_tables_max = 0; /* Number 
 		errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", \
 		    match_value(s_x, tok), min, max, *av);		\
 									\
-	if (_xval == IP_FW_TABLEARG)					\
+	if (_xval == IP_FW_TARG)					\
 		errx(EX_DATAERR, "%s: illegal argument value: %s",	\
 		    match_value(s_x, tok), *av);			\
 	arg = _xval;							\
 	}								\
 } while (0)
 
-static void
-PRINT_UINT_ARG(const char *str, uint32_t arg)
-{
-	if (str != NULL)
-		printf("%s",str);
-	if (arg == IP_FW_TABLEARG)
-		printf("tablearg");
-	else
-		printf("%u", arg);
-}
-
 static struct _s_x f_tcpflags[] = {
 	{ "syn", TH_SYN },
 	{ "fin", TH_FIN },
@@ -169,7 +174,7 @@ static struct _s_x f_iptos[] = {
 	{ NULL,	0 }
 };
 
-static struct _s_x f_ipdscp[] = {
+struct _s_x f_ipdscp[] = {
 	{ "af11", IPTOS_DSCP_AF11 >> 2 },	/* 001010 */
 	{ "af12", IPTOS_DSCP_AF12 >> 2 },	/* 001100 */
 	{ "af13", IPTOS_DSCP_AF13 >> 2 },	/* 001110 */
@@ -370,6 +375,98 @@ static struct _s_x rule_options[] = {
 	{ NULL, 0 }	/* terminator */
 };
 
+void bprint_uint_arg(struct buf_pr *bp, const char *str, uint32_t arg);
+
+/*
+ * Simple string buffer API.
+ * Used to simplify buffer passing between function and for
+ * transparent overrun handling.
+ */
+
+/*
+ * Allocates new buffer of given size @sz.
+ *
+ * Returns 0 on success.
+ */
+int
+bp_alloc(struct buf_pr *b, size_t size)
+{
+	memset(b, 0, sizeof(struct buf_pr));
+
+	if ((b->buf = calloc(1, size)) == NULL)
+		return (ENOMEM);
+
+	b->ptr = b->buf;
+	b->size = size;
+	b->avail = b->size;
+
+	return (0);
+}
+
+void
+bp_free(struct buf_pr *b)
+{
+
+	free(b->buf);
+}
+
+/*
+ * Flushes buffer so new writer start from beginning.
+ */
+void
+bp_flush(struct buf_pr *b)
+{
+
+	b->ptr = b->buf;
+	b->avail = b->size;
+}
+
+/*
+ * Print message specified by @format and args.
+ * Automatically manage buffer space and transparently handle
+ * buffer overruns.
+ *
+ * Returns number of bytes that should have been printed.
+ */
+int
+bprintf(struct buf_pr *b, char *format, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, format);
+
+	i = vsnprintf(b->ptr, b->avail, format, args);
+	va_end(args);
+
+	if (i > b->avail || i < 0) {
+		/* Overflow or print error */
+		b->avail = 0;
+	} else {
+		b->ptr += i;
+		b->avail -= i;
+	} 
+
+	b->needed += i;
+
+	return (i);
+}
+
+/*
+ * Special values printer for tablearg-aware opcodes.
+ */
+void
+bprint_uint_arg(struct buf_pr *bp, const char *str, uint32_t arg)
+{
+
+	if (str != NULL)
+		bprintf(bp, "%s", str);
+	if (arg == IP_FW_TARG)
+		bprintf(bp, "tablearg");
+	else
+		bprintf(bp, "%u", arg);
+}
+
 /*
  * Helper routine to print a possibly unaligned uint64_t on
  * various platform. If width > 0, print the value with
@@ -377,7 +474,7 @@ static struct _s_x rule_options[] = {
  * otherwise, return the required width.
  */
 int
-pr_u64(uint64_t *pd, int width)
+pr_u64(struct buf_pr *b, uint64_t *pd, int width)
 {
 #ifdef TCC
 #define U64_FMT "I64"
@@ -390,11 +487,12 @@ pr_u64(uint64_t *pd, int width)
 	bcopy (pd, &u, sizeof(u));
 	d = u;
 	return (width > 0) ?
-		printf("%*" U64_FMT " ", width, d) :
+		bprintf(b, "%*" U64_FMT " ", width, d) :
 		snprintf(NULL, 0, "%" U64_FMT, d) ;
 #undef U64_FMT
 }
 
+
 void *
 safe_calloc(size_t number, size_t size)
 {
@@ -511,6 +609,34 @@ match_value(struct _s_x *p, int value)
 }
 
 /*
+ * helper function to process a set of flags and set bits in the
+ * appropriate masks.
+ */
+void
+fill_flags(struct _s_x *flags, char *p, uint8_t *set, uint8_t *clear)
+{
+	char *q;	/* points to the separator */
+	int val;
+	uint8_t *which;	/* mask we are working on */
+
+	while (p && *p) {
+		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;
+	}
+}
+
+/*
  * _substrcmp takes two strings and returns 1 if they do not match,
  * and 0 if they match exactly or the first string is a sub-string
  * of the second.  A warning is printed to stderr in the case that the
@@ -564,16 +690,16 @@ _substrcmp2(const char *str1, const char
  * prints one port, symbolic or numeric
  */
 static void
-print_port(int proto, uint16_t port)
+print_port(struct buf_pr *bp, int proto, uint16_t port)
 {
 
 	if (proto == IPPROTO_ETHERTYPE) {
 		char const *s;
 
 		if (co.do_resolv && (s = match_value(ether_types, port)) )
-			printf("%s", s);
+			bprintf(bp, "%s", s);
 		else
-			printf("0x%04x", port);
+			bprintf(bp, "0x%04x", port);
 	} else {
 		struct servent *se = NULL;
 		if (co.do_resolv) {
@@ -582,9 +708,9 @@ print_port(int proto, uint16_t port)
 			se = getservbyport(htons(port), pe ? pe->p_name : NULL);
 		}
 		if (se)
-			printf("%s", se->s_name);
+			bprintf(bp, "%s", se->s_name);
 		else
-			printf("%d", port);
+			bprintf(bp, "%d", port);
 	}
 }
 
@@ -606,7 +732,7 @@ static struct _s_x _port_name[] = {
  * XXX todo: add support for mask.
  */
 static void
-print_newports(ipfw_insn_u16 *cmd, int proto, int opcode)
+print_newports(struct buf_pr *bp, ipfw_insn_u16 *cmd, int proto, int opcode)
 {
 	uint16_t *p = cmd->ports;
 	int i;
@@ -616,15 +742,15 @@ print_newports(ipfw_insn_u16 *cmd, int p
 		sep = match_value(_port_name, opcode);
 		if (sep == NULL)
 			sep = "???";
-		printf (" %s", sep);
+		bprintf(bp, " %s", sep);
 	}
 	sep = " ";
 	for (i = F_LEN((ipfw_insn *)cmd) - 1; i > 0; i--, p += 2) {
-		printf("%s", sep);
-		print_port(proto, p[0]);
+		bprintf(bp, "%s", sep);
+		print_port(bp, proto, p[0]);
 		if (p[0] != p[1]) {
-			printf("-");
-			print_port(proto, p[1]);
+			bprintf(bp, "-");
+			print_port(bp, proto, p[1]);
 		}
 		sep = ",";
 	}
@@ -824,14 +950,14 @@ fill_reject_code(u_short *codep, char *s
 }
 
 static void
-print_reject_code(uint16_t code)
+print_reject_code(struct buf_pr *bp, uint16_t code)
 {
-	char const *s = match_value(icmpcodes, code);
+	char const *s;
 
-	if (s != NULL)
-		printf("unreach %s", s);
+	if ((s = match_value(icmpcodes, code)) != NULL)
+		bprintf(bp, "unreach %s", s);
 	else
-		printf("unreach %u", code);
+		bprintf(bp, "unreach %u", code);
 }
 
 /*
@@ -864,7 +990,8 @@ contigmask(uint8_t *p, int len)
  * There is a specialized check for f_tcpflags.
  */
 static void
-print_flags(char const *name, ipfw_insn *cmd, struct _s_x *list)
+print_flags(struct buf_pr *bp, char const *name, ipfw_insn *cmd,
+    struct _s_x *list)
 {
 	char const *comma = "";
 	int i;
@@ -872,20 +999,20 @@ print_flags(char const *name, ipfw_insn 
 	uint8_t clear = (cmd->arg1 >> 8) & 0xff;
 
 	if (list == f_tcpflags && set == TH_SYN && clear == TH_ACK) {
-		printf(" setup");
+		bprintf(bp, " setup");
 		return;
 	}
 
-	printf(" %s ", name);
+	bprintf(bp, " %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);
+			bprintf(bp, "%s%s", comma, list[i].s);
 			comma = ",";
 		}
 		if (clear & list[i].x) {
 			clear &= ~list[i].x;
-			printf("%s!%s", comma, list[i].s);
+			bprintf(bp, "%s!%s", comma, list[i].s);
 			comma = ",";
 		}
 	}
@@ -895,9 +1022,11 @@ print_flags(char const *name, ipfw_insn 
  * Print the ip address contained in a command.
  */
 static void
-print_ip(ipfw_insn_ip *cmd, char const *s)
+print_ip(struct buf_pr *bp, struct format_opts *fo, ipfw_insn_ip *cmd,
+    char const *s)
 {
 	struct hostent *he = NULL;
+	struct in_addr *ia;
 	uint32_t len = F_LEN((ipfw_insn *)cmd);
 	uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
 
@@ -907,22 +1036,22 @@ print_ip(ipfw_insn_ip *cmd, char const *
 
 		if (d < sizeof(lookup_key)/sizeof(lookup_key[0]))
 			arg = match_value(rule_options, lookup_key[d]);
-		printf("%s lookup %s %d", cmd->o.len & F_NOT ? " not": "",
-			arg, cmd->o.arg1);
+		bprintf(bp, "%s lookup %s %d", cmd->o.len & F_NOT ? " not": "",
+		    arg, cmd->o.arg1);
 		return;
 	}
-	printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
+	bprintf(bp, "%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");
+		bprintf(bp, "me");
 		return;
 	}
 	if (cmd->o.opcode == O_IP_SRC_LOOKUP ||
 	    cmd->o.opcode == O_IP_DST_LOOKUP) {
-		printf("table(%u", ((ipfw_insn *)cmd)->arg1);
+		bprintf(bp, "table(%u", ((ipfw_insn *)cmd)->arg1);
 		if (len == F_INSN_SIZE(ipfw_insn_u32))
-			printf(",%u", *a);
-		printf(")");
+			bprintf(bp, ",%u", *a);
+		bprintf(bp, ")");
 		return;
 	}
 	if (cmd->o.opcode == O_IP_SRC_SET || cmd->o.opcode == O_IP_DST_SET) {
@@ -933,7 +1062,7 @@ print_ip(ipfw_insn_ip *cmd, char const *
 		x = cmd->o.arg1 - 1;
 		x = htonl( ~x );
 		cmd->addr.s_addr = htonl(cmd->addr.s_addr);
-		printf("%s/%d", inet_ntoa(cmd->addr),
+		bprintf(bp, "%s/%d", inet_ntoa(cmd->addr),
 			contigmask((uint8_t *)&x, 32));
 		x = cmd->addr.s_addr = htonl(cmd->addr.s_addr);
 		x &= 0xff; /* base */
@@ -948,14 +1077,14 @@ print_ip(ipfw_insn_ip *cmd, char const *
 				for (j=i+1; j < cmd->o.arg1; j++)
 					if (!(map[ j/32] & (1<<(j & 31))))
 						break;
-				printf("%c%d", comma, i+x);
+				bprintf(bp, "%c%d", comma, i+x);
 				if (j>i+2) { /* range has at least 3 elements */
-					printf("-%d", j-1+x);
+					bprintf(bp, "-%d", j-1+x);
 					i = j-1;
 				}
 				comma = ',';
 			}
-		printf("}");
+		bprintf(bp, "}");
 		return;
 	}
 	/*
@@ -970,18 +1099,19 @@ print_ip(ipfw_insn_ip *cmd, char const *
 	if (mb == 32 && co.do_resolv)
 		he = gethostbyaddr((char *)&(a[0]), sizeof(u_long), AF_INET);
 	if (he != NULL)		/* resolved to name */
-		printf("%s", he->h_name);
+		bprintf(bp, "%s", he->h_name);
 	else if (mb == 0)	/* any */
-		printf("any");
+		bprintf(bp, "any");
 	else {		/* numeric IP followed by some kind of mask */
-		printf("%s", inet_ntoa( *((struct in_addr *)&a[0]) ) );
+		ia = (struct in_addr *)&a[0];
+		bprintf(bp, "%s", inet_ntoa(*ia));
 		if (mb < 0)
-			printf(":%s", inet_ntoa( *((struct in_addr *)&a[1]) ) );
+			bprintf(bp, ":%s", inet_ntoa(*ia ) );
 		else if (mb < 32)
-			printf("/%d", mb);
+			bprintf(bp, "/%d", mb);
 	}
 	if (len > 1)
-		printf(",");
+		bprintf(bp, ",");
     }
 }
 
@@ -989,21 +1119,21 @@ print_ip(ipfw_insn_ip *cmd, char const *
  * prints a MAC address/mask pair
  */
 static void
-print_mac(uint8_t *addr, uint8_t *mask)
+print_mac(struct buf_pr *bp, uint8_t *addr, uint8_t *mask)
 {
 	int l = contigmask(mask, 48);
 
 	if (l == 0)
-		printf(" any");
+		bprintf(bp, " any");
 	else {
-		printf(" %02x:%02x:%02x:%02x:%02x:%02x",
+		bprintf(bp, " %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",
+			bprintf(bp, "&%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);
+			bprintf(bp, "/%d", l);
 	}
 }
 
@@ -1032,38 +1162,38 @@ fill_icmptypes(ipfw_insn_u32 *cmd, char 
 }
 
 static void
-print_icmptypes(ipfw_insn_u32 *cmd)
+print_icmptypes(struct buf_pr *bp, ipfw_insn_u32 *cmd)
 {
 	int i;
 	char sep= ' ';
 
-	printf(" icmptypes");
+	bprintf(bp, " icmptypes");
 	for (i = 0; i < 32; i++) {
 		if ( (cmd->d[0] & (1 << (i))) == 0)
 			continue;
-		printf("%c%d", sep, i);
+		bprintf(bp, "%c%d", sep, i);
 		sep = ',';
 	}
 }
 
 static void
-print_dscp(ipfw_insn_u32 *cmd)
+print_dscp(struct buf_pr *bp, ipfw_insn_u32 *cmd)
 {
 	int i, c;
 	uint32_t *v;
 	char sep= ' ';
 	const char *code;
 
-	printf(" dscp");
+	bprintf(bp, " dscp");
 	i = 0;
 	c = 0;
 	v = cmd->d;
 	while (i < 64) {
 		if (*v & (1 << i)) {
 			if ((code = match_value(f_ipdscp, i)) != NULL)
-				printf("%c%s", sep, code);
+				bprintf(bp, "%c%s", sep, code);
 			else
-				printf("%c%d", sep, i);
+				bprintf(bp, "%c%d", sep, i);
 			sep = ',';
 		}
 
@@ -1094,7 +1224,7 @@ print_dscp(ipfw_insn_u32 *cmd)
 #define	HAVE_OPTIONS	0x8000
 
 static void
-show_prerequisites(int *flags, int want, int cmd)
+show_prerequisites(struct buf_pr *bp, int *flags, int want, int cmd)
 {
 	(void)cmd;	/* UNUSED */
 	if (co.comment_only)
@@ -1105,22 +1235,23 @@ show_prerequisites(int *flags, int want,
 	if ( !(*flags & HAVE_OPTIONS)) {
 		if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO)) {
 			if ( (*flags & HAVE_PROTO4))
-				printf(" ip4");
+				bprintf(bp, " ip4");
 			else if ( (*flags & HAVE_PROTO6))
-				printf(" ip6");
+				bprintf(bp, " ip6");
 			else
-				printf(" ip");
+				bprintf(bp, " ip");
 		}
 		if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))
-			printf(" from any");
+			bprintf(bp, " from any");
 		if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP))
-			printf(" to any");
+			bprintf(bp, " to any");
 	}
 	*flags |= want;
 }
 
 static void
-show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
+show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
+    struct buf_pr *bp, struct ip_fw_rule *rule, struct ip_fw_bcounter *cntr)
 {
 	static int twidth = 0;
 	int l;
@@ -1132,25 +1263,28 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 	ipfw_insn_altq *altqptr = NULL; /* set if we find an O_ALTQ */
 	int or_block = 0;	/* we are in an or block */
 	uint32_t set_disable;
+	uint32_t uval;
 
 	bcopy(&rule->next_rule, &set_disable, sizeof(set_disable));
 
-	if (set_disable & (1 << rule->set)) { /* disabled */
-		if (!co.show_sets)
+	if (set_disable & (1 << rule->set)) {
+		/* disabled mask */
+		if (!co->show_sets)
 			return;
 		else
-			printf("# DISABLED ");
+			bprintf(bp, "# DISABLED ");
 	}
-	printf("%05u ", rule->rulenum);
+	bprintf(bp, "%05u ", rule->rulenum);
 
-	if (pcwidth > 0 || bcwidth > 0) {
-		pr_u64(&rule->pcnt, pcwidth);
-		pr_u64(&rule->bcnt, bcwidth);
+	/* Print counters if enabled */
+	if (fo->pcwidth > 0 || fo->bcwidth > 0) {
+		pr_u64(bp, &cntr->pcnt, fo->pcwidth);
+		pr_u64(bp, &cntr->bcnt, fo->bcwidth);
 	}
 
-	if (co.do_time == 2)
-		printf("%10u ", rule->timestamp);
-	else if (co.do_time == 1) {
+	if (co->do_time == 2)
+		bprintf(bp, "%10u ", cntr->timestamp);
+	else if (co->do_time == 1) {
 		char timestr[30];
 		time_t t = (time_t)0;
 
@@ -1159,19 +1293,19 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 			*strchr(timestr, '\n') = '\0';
 			twidth = strlen(timestr);
 		}
-		if (rule->timestamp) {
-			t = _long_to_time(rule->timestamp);
+		if (cntr->timestamp > 0) {
+			t = _long_to_time(cntr->timestamp);
 
 			strcpy(timestr, ctime(&t));
 			*strchr(timestr, '\n') = '\0';
-			printf("%s ", timestr);
+			bprintf(bp, "%s ", timestr);
 		} else {
-			printf("%*s", twidth, " ");
+			bprintf(bp, "%*s", twidth, " ");
 		}
 	}
 
-	if (co.show_sets)
-		printf("set %d ", rule->set);
+	if (co->show_sets)
+		bprintf(bp, "set %d ", rule->set);
 
 	/*
 	 * print the optional "match probability"
@@ -1183,7 +1317,7 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 			double d = 1.0 * p->d[0];
 
 			d = (d / 0x7fffffff);
-			printf("prob %f ", d);
+			bprintf(bp, "prob %f ", d);
 		}
 	}
 
@@ -1194,66 +1328,66 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 			l > 0 ; l -= F_LEN(cmd), cmd += F_LEN(cmd)) {
 		switch(cmd->opcode) {
 		case O_CHECK_STATE:
-			printf("check-state");
+			bprintf(bp, "check-state");
 			/* avoid printing anything else */
 			flags = HAVE_PROTO | HAVE_SRCIP |
 				HAVE_DSTIP | HAVE_IP;
 			break;
 
 		case O_ACCEPT:
-			printf("allow");
+			bprintf(bp, "allow");
 			break;
 
 		case O_COUNT:
-			printf("count");
+			bprintf(bp, "count");
 			break;
 
 		case O_DENY:
-			printf("deny");
+			bprintf(bp, "deny");
 			break;
 
 		case O_REJECT:
 			if (cmd->arg1 == ICMP_REJECT_RST)
-				printf("reset");
+				bprintf(bp, "reset");
 			else if (cmd->arg1 == ICMP_UNREACH_HOST)
-				printf("reject");
+				bprintf(bp, "reject");
 			else
-				print_reject_code(cmd->arg1);
+				print_reject_code(bp, cmd->arg1);
 			break;
 
 		case O_UNREACH6:
 			if (cmd->arg1 == ICMP6_UNREACH_RST)
-				printf("reset6");
+				bprintf(bp, "reset6");
 			else
 				print_unreach6_code(cmd->arg1);
 			break;
 
 		case O_SKIPTO:
-			PRINT_UINT_ARG("skipto ", cmd->arg1);
+			bprint_uint_arg(bp, "skipto ", cmd->arg1);
 			break;
 
 		case O_PIPE:
-			PRINT_UINT_ARG("pipe ", cmd->arg1);
+			bprint_uint_arg(bp, "pipe ", cmd->arg1);
 			break;
 
 		case O_QUEUE:
-			PRINT_UINT_ARG("queue ", cmd->arg1);
+			bprint_uint_arg(bp, "queue ", cmd->arg1);
 			break;
 
 		case O_DIVERT:
-			PRINT_UINT_ARG("divert ", cmd->arg1);
+			bprint_uint_arg(bp, "divert ", cmd->arg1);
 			break;
 
 		case O_TEE:
-			PRINT_UINT_ARG("tee ", cmd->arg1);
+			bprint_uint_arg(bp, "tee ", cmd->arg1);
 			break;
 
 		case O_NETGRAPH:
-			PRINT_UINT_ARG("netgraph ", cmd->arg1);
+			bprint_uint_arg(bp, "netgraph ", cmd->arg1);
 			break;
 
 		case O_NGTEE:
-			PRINT_UINT_ARG("ngtee ", cmd->arg1);
+			bprint_uint_arg(bp, "ngtee ", cmd->arg1);
 			break;
 
 		case O_FORWARD_IP:
@@ -1261,12 +1395,12 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 			ipfw_insn_sa *s = (ipfw_insn_sa *)cmd;
 
 			if (s->sa.sin_addr.s_addr == INADDR_ANY) {
-				printf("fwd tablearg");
+				bprintf(bp, "fwd tablearg");
 			} else {
-				printf("fwd %s", inet_ntoa(s->sa.sin_addr));
+				bprintf(bp, "fwd %s",inet_ntoa(s->sa.sin_addr));
 			}
 			if (s->sa.sin_port)
-				printf(",%d", s->sa.sin_port);
+				bprintf(bp, ",%d", s->sa.sin_port);
 		    }
 			break;
 
@@ -1275,10 +1409,10 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 			char buf[4 + INET6_ADDRSTRLEN + 1];
 			ipfw_insn_sa6 *s = (ipfw_insn_sa6 *)cmd;
 
-			printf("fwd %s", inet_ntop(AF_INET6, &s->sa.sin6_addr,
-			    buf, sizeof(buf)));
+			bprintf(bp, "fwd %s", inet_ntop(AF_INET6,
+			    &s->sa.sin6_addr, buf, sizeof(buf)));
 			if (s->sa.sin6_port)
-				printf(",%d", s->sa.sin6_port);
+				bprintf(bp, ",%d", s->sa.sin6_port);
 		    }
 			break;
 
@@ -1296,64 +1430,69 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 
 		case O_NAT:
 			if (cmd->arg1 != 0)
-				PRINT_UINT_ARG("nat ", cmd->arg1);
+				bprint_uint_arg(bp, "nat ", cmd->arg1);
 			else
-				printf("nat global");
+				bprintf(bp, "nat global");
 			break;
 
 		case O_SETFIB:
-			PRINT_UINT_ARG("setfib ", cmd->arg1);
+			bprint_uint_arg(bp, "setfib ", cmd->arg1 & 0x7FFF);
  			break;
 
 		case O_SETDSCP:
 		    {
 			const char *code;
 
-			if ((code = match_value(f_ipdscp, cmd->arg1)) != NULL)
-				printf("setdscp %s", code);
+			if (cmd->arg1 == IP_FW_TARG) {
+				bprint_uint_arg(bp, "setdscp ", cmd->arg1);
+				break;
+			}
+			uval = cmd->arg1 & 0x3F;
+			if ((code = match_value(f_ipdscp, uval)) != NULL)
+				bprintf(bp, "setdscp %s", code);
 			else
-				PRINT_UINT_ARG("setdscp ", cmd->arg1);
+				bprint_uint_arg(bp, "setdscp ", uval);
 		    }
  			break;
 
 		case O_REASS:
-			printf("reass");
+			bprintf(bp, "reass");
 			break;
 
 		case O_CALLRETURN:
 			if (cmd->len & F_NOT)
-				printf("return");
+				bprintf(bp, "return");
 			else
-				PRINT_UINT_ARG("call ", cmd->arg1);
+				bprint_uint_arg(bp, "call ", cmd->arg1);
 			break;
 
 		default:
-			printf("** unrecognized action %d len %d ",
+			bprintf(bp, "** unrecognized action %d len %d ",
 				cmd->opcode, cmd->len);
 		}
 	}
 	if (logptr) {
 		if (logptr->max_log > 0)
-			printf(" log logamount %d", logptr->max_log);
+			bprintf(bp, " log logamount %d", logptr->max_log);
 		else
-			printf(" log");
+			bprintf(bp, " log");
 	}
 #ifndef NO_ALTQ
 	if (altqptr) {
-		print_altq_cmd(altqptr);
+		print_altq_cmd(bp, altqptr);
 	}
 #endif
 	if (tagptr) {
 		if (tagptr->len & F_NOT)
-			PRINT_UINT_ARG(" untag ", tagptr->arg1);
+			bprint_uint_arg(bp, " untag ", tagptr->arg1);
 		else
-			PRINT_UINT_ARG(" tag ", tagptr->arg1);
+			bprint_uint_arg(bp, " tag ", tagptr->arg1);
 	}
 
 	/*
 	 * then print the body.
 	 */
-	for (l = rule->act_ofs, cmd = rule->cmd ;
+	for (l = rule->act_ofs, cmd = rule->cmd;
 			l > 0 ; l -= F_LEN(cmd) , cmd += F_LEN(cmd)) {
 		if ((cmd->len & F_OR) || (cmd->len & F_NOT))
 			continue;
@@ -1366,30 +1505,30 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 		}
 	}
 	if (rule->_pad & 1) {	/* empty rules before options */
-		if (!co.do_compact) {
-			show_prerequisites(&flags, HAVE_PROTO, 0);
-			printf(" from any to any");
+		if (!co->do_compact) {
+			show_prerequisites(bp, &flags, HAVE_PROTO, 0);
+			bprintf(bp, " from any to any");
 		}
 		flags |= HAVE_IP | HAVE_OPTIONS | HAVE_PROTO |
 			 HAVE_SRCIP | HAVE_DSTIP;
 	}
 
-	if (co.comment_only)
+	if (co->comment_only)
 		comment = "...";
 
-	for (l = rule->act_ofs, cmd = rule->cmd ;
+	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;
 
-		if (co.comment_only) {
+		if (co->comment_only) {
 			if (cmd->opcode != O_NOP)
 				continue;
-			printf(" // %s\n", (char *)(cmd + 1));
+			bprintf(bp, " // %s\n", (char *)(cmd + 1));
 			return;
 		}
 
-		show_prerequisites(&flags, 0, cmd->opcode);
+		show_prerequisites(bp, &flags, 0, cmd->opcode);
 
 		switch(cmd->opcode) {
 		case O_PROB:
@@ -1403,12 +1542,12 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 		case O_IP_SRC_MASK:
 		case O_IP_SRC_ME:
 		case O_IP_SRC_SET:
-			show_prerequisites(&flags, HAVE_PROTO, 0);
+			show_prerequisites(bp, &flags, HAVE_PROTO, 0);
 			if (!(flags & HAVE_SRCIP))
-				printf(" from");
+				bprintf(bp, " from");
 			if ((cmd->len & F_OR) && !or_block)
-				printf(" {");
-			print_ip((ipfw_insn_ip *)cmd,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408231737.s7NHbIXN043185>