svn commit: r187738 - user/luigi/ipfw/sbin/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Mon Jan 26 10:46:38 PST 2009
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 == <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 = 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; 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;
-}
+ nbytes = sizeof(struct ip_fw);
+ data = safe_calloc(1, nbytes);
+ 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));
-/*
- * 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<<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 (_substrcmp(*av, "swap") == 0) {
+ ac--; av++;
+ if (ac != 2)
+ errx(EX_USAGE, "set swap needs 2 set numbers\n");
+ rulenum = atoi(av[0]);
+ new_set = atoi(av[1]);
+ if (!isdigit(*(av[0])) || rulenum > 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<<i);
+ } else if (_substrcmp(*av, "disable") == 0)
+ which = 0;
+ else if (_substrcmp(*av, "enable") == 0)
+ which = 1;
+ else
+ errx(EX_DATAERR,
+ "invalid set command %s\n", *av);
+ av++; ac--;
}
- }
+ if ( (masks[0] & masks[1]) != 0 )
+ errx(EX_DATAERR,
+ "cannot enable and disable the same set\n");
+
+ i = do_cmd(IP_FW_DEL, masks, sizeof(masks));
+ if (i)
+ warn("set enable/disable: setsockopt(IP_FW_DEL)");
+ } else
+ errx(EX_USAGE, "invalid set command %s\n", *av);
}
-/*
- * Print the ip address contained in a command.
- */
static void
-print_ip(ipfw_insn_ip *cmd, char const *s)
+sysctl_handler(int ac, char *av[], int which)
{
- 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_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 ***
More information about the svn-src-user
mailing list