From owner-svn-src-head@FreeBSD.ORG Sat Aug 23 17:37:19 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2C2FD521; Sat, 23 Aug 2014 17:37:19 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 15EC13A52; Sat, 23 Aug 2014 17:37:19 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7NHbJga043189; Sat, 23 Aug 2014 17:37:19 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7NHbIXN043185; Sat, 23 Aug 2014 17:37:18 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201408231737.s7NHbIXN043185@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sat, 23 Aug 2014 17:37:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270424 - head/sbin/ipfw X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 Aug 2014 17:37:19 -0000 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 #include #include +#include #include #include #include @@ -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 ***