From owner-svn-src-user@FreeBSD.ORG Mon Jan 26 18:46:37 2009 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 858A4106568C; Mon, 26 Jan 2009 18:46:37 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7172E8FC19; Mon, 26 Jan 2009 18:46:37 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0QIkbT6059448; Mon, 26 Jan 2009 18:46:37 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0QIkbF6059447; Mon, 26 Jan 2009 18:46:37 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <200901261846.n0QIkbF6059447@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 26 Jan 2009 18:46:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187738 - user/luigi/ipfw/sbin/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jan 2009 18:46:38 -0000 Author: luigi Date: Mon Jan 26 18:46:37 2009 New Revision: 187738 URL: http://svn.freebsd.org/changeset/base/187738 Log: remove code residing in other files Modified: user/luigi/ipfw/sbin/ipfw/ipfw2.c Modified: user/luigi/ipfw/sbin/ipfw/ipfw2.c ============================================================================== --- user/luigi/ipfw/sbin/ipfw/ipfw2.c Mon Jan 26 18:40:39 2009 (r187737) +++ user/luigi/ipfw/sbin/ipfw/ipfw2.c Mon Jan 26 18:46:37 2009 (r187738) @@ -373,36 +373,6 @@ _substrcmp2(const char *str1, const char return 0; } -#if 0 -/* - * 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); - } -} -#endif - struct _s_x _port_name[] = { {"dst-port", O_IP_DSTPORT}, {"src-port", O_IP_SRCPORT}, @@ -415,256 +385,6 @@ struct _s_x _port_name[] = { {NULL, 0} }; -#if 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 (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(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 == 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 = safe_calloc(s1 - s + 1, 1); - - /* - * copy into a buffer skipping backslashes - */ - for (p = s, i = 0; p != s1 ; p++) - if (*p != '\\') - buf[i++] = *p; - buf[i++] = '\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 */ -} -#endif - -/* - * Map between current altq queue id numbers and names. - */ -#if 0 -static int altq_fetched = 0; -#endif -static TAILQ_HEAD(, pf_altq) altq_entries = - TAILQ_HEAD_INITIALIZER(altq_entries); - -static void -altq_set_enabled(int enabled) -{ - int pffd; - - pffd = open("/dev/pf", O_RDWR); - if (pffd == -1) - err(EX_UNAVAILABLE, - "altq support opening pf(4) control device"); - if (enabled) { - if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) - err(EX_UNAVAILABLE, "enabling altq"); - } else { - if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) - err(EX_UNAVAILABLE, "disabling altq"); - } - close(pffd); -} - -#if 0 -static void -altq_fetch(void) -{ - struct pfioc_altq pfioc; - struct pf_altq *altq; - int pffd; - unsigned int mnr; - - if (altq_fetched) - return; - altq_fetched = 1; - pffd = open("/dev/pf", O_RDONLY); - if (pffd == -1) { - warn("altq support opening pf(4) control device"); - return; - } - bzero(&pfioc, sizeof(pfioc)); - if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) { - warn("altq support getting queue list"); - close(pffd); - return; - } - mnr = pfioc.nr; - for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) { - if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) { - if (errno == EBUSY) - break; - warn("altq support getting queue list"); - close(pffd); - return; - } - if (pfioc.altq.qid == 0) - continue; - altq = safe_calloc(1, sizeof(*altq)); - *altq = pfioc.altq; - TAILQ_INSERT_TAIL(&altq_entries, altq, entries); - } - close(pffd); -} - -static u_int32_t -altq_name_to_qid(const char *name) -{ - struct pf_altq *altq; - - altq_fetch(); - TAILQ_FOREACH(altq, &altq_entries, entries) - if (strcmp(name, altq->qname) == 0) - break; - if (altq == NULL) - errx(EX_DATAERR, "altq has no queue named `%s'", name); - return altq->qid; -} -#endif - -#if 0 -static const char * -altq_qid_to_name(u_int32_t qid) -{ - struct pf_altq *altq; - - altq_fetch(); - TAILQ_FOREACH(altq, &altq_entries, entries) - if (qid == altq->qid) - break; - if (altq == NULL) - return NULL; - return altq->qname; -} -#endif - -#if 0 -static void -fill_altq_qid(u_int32_t *qid, const char *av) -{ - *qid = altq_name_to_qid(av); -} - -/* - * 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) /* empty or invalid argument */ - return (0); - - switch (*s) { - case '-': /* a range */ - av = s + 1; - b = strtoport(av, &s, 0, proto); - /* Reject expressions like '1-abc' or '1-2-3'. */ - if (s == av || (*s != ',' && *s != '\0')) - return (0); - p[0] = a; - p[1] = b; - break; - case ',': /* comma separated list */ - case '\0': - p[0] = p[1] = a; - break; - default: - warnx("port list: invalid separator <%c> in <%s>", - *s, av); - return (0); - } - - i++; - p += 2; - av = s + 1; - } - if (i > 0) { - if (i + 1 > F_LEN_MASK) - errx(EX_DATAERR, "too many ports/ranges\n"); - cmd->o.len |= i + 1; /* leave F_NOT and F_OR untouched */ - } - return (i); -} -#endif - struct _s_x icmpcodes[] = { { "net", ICMP_UNREACH_NET }, { "host", ICMP_UNREACH_HOST }, @@ -685,34 +405,6 @@ struct _s_x icmpcodes[] = { { NULL, 0 } }; -#if 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); -} -#endif - struct _s_x icmp6codes[] = { { "no-route", ICMP6_DST_UNREACH_NOROUTE }, { "admin-prohib", ICMP6_DST_UNREACH_ADMIN }, @@ -721,4815 +413,391 @@ struct _s_x icmp6codes[] = { { NULL, 0 } }; -#if 0 -static void -fill_unreach6_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(icmp6codes, str); - if (val < 0) - errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str); - *codep = val; - return; -} - +/* + * 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 -print_unreach6_code(uint16_t code) +sets_handler(int ac, char *av[]) { - char const *s = match_value(icmp6codes, code); + uint32_t set_disable, masks[2]; + int i, nbytes; + uint16_t rulenum; + uint8_t cmd, new_set; - if (s != NULL) - printf("unreach6 %s", s); - else - printf("unreach6 %u", code); -} + ac--; + av++; -/* - * 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; + if (!ac) + errx(EX_USAGE, "set needs command"); + if (_substrcmp(*av, "show") == 0) { + void *data; + char const *msg; - for (i=0; inext_rule, + &set_disable, sizeof(set_disable)); -/* - * 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; + for (i = 0, msg = "disable" ; i < RESVD_SET; i++) + if ((set_disable & (1< RESVD_SET) + errx(EX_DATAERR, "invalid set number %s\n", av[0]); + if (!isdigit(*(av[1])) || new_set > RESVD_SET) + errx(EX_DATAERR, "invalid set number %s\n", av[1]); + masks[0] = (4 << 24) | (new_set << 16) | (rulenum); + i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); + } else if (_substrcmp(*av, "move") == 0) { + ac--; av++; + if (ac && _substrcmp(*av, "rule") == 0) { + cmd = 2; + ac--; av++; + } else + cmd = 3; + if (ac != 3 || _substrcmp(av[1], "to") != 0) + errx(EX_USAGE, "syntax: set move [rule] X to Y\n"); + rulenum = atoi(av[0]); + new_set = atoi(av[2]); + if (!isdigit(*(av[0])) || (cmd == 3 && rulenum > RESVD_SET) || + (cmd == 2 && rulenum == IPFW_DEFAULT_RULE) ) + errx(EX_DATAERR, "invalid source number %s\n", av[0]); + if (!isdigit(*(av[2])) || new_set > RESVD_SET) + errx(EX_DATAERR, "invalid dest. set %s\n", av[1]); + masks[0] = (cmd << 24) | (new_set << 16) | (rulenum); + i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); + } else if (_substrcmp(*av, "disable") == 0 || + _substrcmp(*av, "enable") == 0 ) { + int which = _substrcmp(*av, "enable") == 0 ? 1 : 0; - if (list == f_tcpflags && set == TH_SYN && clear == TH_ACK) { - printf(" setup"); - return; - } + ac--; av++; + masks[0] = masks[1] = 0; - 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 = ","; + while (ac) { + if (isdigit(**av)) { + i = atoi(*av); + if (i < 0 || i > RESVD_SET) + errx(EX_DATAERR, + "invalid set number %d\n", i); + masks[which] |= (1<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_LOOKUP || - cmd->o.opcode == O_IP_DST_LOOKUP) { - printf("table(%u", ((ipfw_insn *)cmd)->arg1); - if (len == F_INSN_SIZE(ipfw_insn_u32)) - printf(",%u", *a); - printf(")"); - 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 = '{'; + ac--; + av++; - 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(u_long), 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 = ','; + if (ac == 0) { + warnx("missing keyword to enable/disable\n"); + } else if (_substrcmp(*av, "firewall") == 0) { + sysctlbyname("net.inet.ip.fw.enable", NULL, 0, + &which, sizeof(which)); + } else if (_substrcmp(*av, "one_pass") == 0) { + sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0, + &which, sizeof(which)); + } else if (_substrcmp(*av, "debug") == 0) { + sysctlbyname("net.inet.ip.fw.debug", NULL, 0, + &which, sizeof(which)); + } else if (_substrcmp(*av, "verbose") == 0) { + sysctlbyname("net.inet.ip.fw.verbose", NULL, 0, + &which, sizeof(which)); + } else if (_substrcmp(*av, "dyn_keepalive") == 0) { + sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0, + &which, sizeof(which)); + } else if (_substrcmp(*av, "altq") == 0) { + altq_set_enabled(which); + } else { + warnx("unrecognize enable/disable keyword: %s\n", *av); } } -/* - * Print the ip address contained in a command. - */ -static void -print_ip6(ipfw_insn_ip6 *cmd, char const *s) -{ - struct hostent *he = NULL; - int len = F_LEN((ipfw_insn *) cmd) - 1; - struct in6_addr *a = &(cmd->addr6); - char trad[255]; - - printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s); - - if (cmd->o.opcode == O_IP6_SRC_ME || cmd->o.opcode == O_IP6_DST_ME) { - printf("me6"); - return; - } - if (cmd->o.opcode == O_IP6) { - printf(" ip6"); - return; - } - - /* - * len == 4 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 / 4; len > 0; len -= 2, a += 2) { - int mb = /* mask length */ - (cmd->o.opcode == O_IP6_SRC || cmd->o.opcode == O_IP6_DST) ? - 128 : contigmask((uint8_t *)&(a[1]), 128); - - if (mb == 128 && do_resolv) - he = gethostbyaddr((char *)a, sizeof(*a), AF_INET6); - 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 */ - if (inet_ntop(AF_INET6, a, trad, sizeof( trad ) ) == NULL) - printf("Error ntop in print_ip6\n"); - printf("%s", trad ); - if (mb < 0) /* XXX not really legal... */ - printf(":%s", - inet_ntop(AF_INET6, &a[1], trad, sizeof(trad))); - else if (mb < 128) - printf("/%d", mb); - } - if (len > 2) - printf(","); - } -} - -static void -fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av) -{ - uint8_t type; - - bzero(cmd, sizeof(*cmd)); - while (*av) { - if (*av == ',') - av++; - type = strtoul(av, &av, 0); - if (*av != ',' && *av != '\0') - errx(EX_DATAERR, "invalid ICMP6 type"); - /* - * XXX: shouldn't this be 0xFF? I can't see any reason why - * we shouldn't be able to filter all possiable values - * regardless of the ability of the rest of the kernel to do - * anything useful with them. - */ - if (type > ICMP6_MAXTYPE) - errx(EX_DATAERR, "ICMP6 type out of range"); - cmd->d[type / 32] |= ( 1 << (type % 32)); - } - cmd->o.opcode = O_ICMP6TYPE; - cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6); -} - - -static void -print_icmp6types(ipfw_insn_u32 *cmd) -{ - int i, j; - char sep= ' '; - - printf(" ip6 icmp6types"); - for (i = 0; i < 7; i++) - for (j=0; j < 32; ++j) { - if ( (cmd->d[i] & (1 << (j))) == 0) - continue; - printf("%c%d", sep, (i*32 + j)); - sep = ','; - } -} - -static void -print_flow6id( ipfw_insn_u32 *cmd) -{ - uint16_t i, limit = cmd->o.arg1; - char sep = ','; - - printf(" flow-id "); - for( i=0; i < limit; ++i) { - if (i == limit - 1) - sep = ' '; - printf("%d%c", cmd->d[i], sep); - } -} - -/* structure and define for the extension header in ipv6 */ -static struct _s_x ext6hdrcodes[] = { - { "frag", EXT_FRAGMENT }, - { "hopopt", EXT_HOPOPTS }, - { "route", EXT_ROUTING }, - { "dstopt", EXT_DSTOPTS }, - { "ah", EXT_AH }, - { "esp", EXT_ESP }, - { "rthdr0", EXT_RTHDR0 }, - { "rthdr2", EXT_RTHDR2 }, - { NULL, 0 } -}; - -/* fills command for the extension header filtering */ -static int -fill_ext6hdr( ipfw_insn *cmd, char *av) -{ - int tok; - char *s = av; - - cmd->arg1 = 0; - - while(s) { - av = strsep( &s, ",") ; - tok = match_token(ext6hdrcodes, av); - switch (tok) { - case EXT_FRAGMENT: - cmd->arg1 |= EXT_FRAGMENT; - break; - - case EXT_HOPOPTS: - cmd->arg1 |= EXT_HOPOPTS; - break; - - case EXT_ROUTING: - cmd->arg1 |= EXT_ROUTING; - break; - - case EXT_DSTOPTS: - cmd->arg1 |= EXT_DSTOPTS; - break; - - case EXT_AH: - cmd->arg1 |= EXT_AH; - break; - - case EXT_ESP: - cmd->arg1 |= EXT_ESP; - break; - - case EXT_RTHDR0: - cmd->arg1 |= EXT_RTHDR0; - break; - - case EXT_RTHDR2: - cmd->arg1 |= EXT_RTHDR2; - break; - - default: - errx( EX_DATAERR, "invalid option for ipv6 exten header" ); - break; - } - } - if (cmd->arg1 == 0 ) - return 0; - cmd->opcode = O_EXT_HDR; - cmd->len |= F_INSN_SIZE( ipfw_insn ); - return 1; -} - static void -print_ext6hdr( ipfw_insn *cmd ) +show_usage(void) { - char sep = ' '; - - printf(" extension header:"); - if (cmd->arg1 & EXT_FRAGMENT ) { - printf("%cfragmentation", sep); - sep = ','; - } - if (cmd->arg1 & EXT_HOPOPTS ) { - printf("%chop options", sep); - sep = ','; - } - if (cmd->arg1 & EXT_ROUTING ) { - printf("%crouting options", sep); - sep = ','; - } - if (cmd->arg1 & EXT_RTHDR0 ) { - printf("%crthdr0", sep); - sep = ','; - } - if (cmd->arg1 & EXT_RTHDR2 ) { - printf("%crthdr2", sep); - sep = ','; - } - if (cmd->arg1 & EXT_DSTOPTS ) { - printf("%cdestination options", sep); - sep = ','; - } - if (cmd->arg1 & EXT_AH ) { - printf("%cauthentication header", sep); - sep = ','; - } - if (cmd->arg1 & EXT_ESP ) { - printf("%cencapsulated security payload", sep); - } + fprintf(stderr, "usage: ipfw [options]\n" +"do \"ipfw -h\" or see ipfw manpage for details\n" +); + exit(EX_USAGE); } -/* - * 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_PROTO4 0x0008 -#define HAVE_PROTO6 0x0010 -#define HAVE_OPTIONS 0x8000 - -#define HAVE_IP (HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP) static void -show_prerequisites(int *flags, int want, int cmd __unused) -{ - if (comment_only) - return; - if ( (*flags & HAVE_IP) == HAVE_IP) - *flags |= HAVE_OPTIONS; - - if ( !(*flags & HAVE_OPTIONS)) { - if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO)) { - if ( (*flags & HAVE_PROTO4)) - printf(" ip4"); - else if ( (*flags & HAVE_PROTO6)) - printf(" ip6"); - else - printf(" ip"); - } - if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP)) - printf(" from any"); - if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP)) - printf(" to any"); - } - *flags |= want; -} - -void -show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth) +help(void) { - static int twidth = 0; - int l; - ipfw_insn *cmd, *tagptr = NULL; - const 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 */ - 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; - - 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) { - strcpy(timestr, ctime(&t)); - *strchr(timestr, '\n') = '\0'; - twidth = strlen(timestr); - } - if (rule->timestamp) { - t = _long_to_time(rule->timestamp); - - strcpy(timestr, ctime(&t)); - *strchr(timestr, '\n') = '\0'; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***