From owner-svn-src-all@FreeBSD.ORG Sat Mar 2 18:51:27 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 1FDAA987; Sat, 2 Mar 2013 18:51:27 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 0307DDB6; Sat, 2 Mar 2013 18:51:27 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r22IpQgs001548; Sat, 2 Mar 2013 18:51:26 GMT (envelope-from melifaro@svn.freebsd.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r22IpQK4001547; Sat, 2 Mar 2013 18:51:26 GMT (envelope-from melifaro@svn.freebsd.org) Message-Id: <201303021851.r22IpQK4001547@svn.freebsd.org> From: "Alexander V. Chernikov" Date: Sat, 2 Mar 2013 18:51:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r247666 - 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-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Mar 2013 18:51:27 -0000 Author: melifaro Date: Sat Mar 2 18:51:26 2013 New Revision: 247666 URL: http://svnweb.freebsd.org/changeset/base/247666 Log: Fix ipfw table argument parsing/printing. Fix style. PR: kern/175909 Submitted by: Daniel Hagerty MFC after: 2 weeks Modified: head/sbin/ipfw/ipfw2.c Modified: head/sbin/ipfw/ipfw2.c ============================================================================== --- head/sbin/ipfw/ipfw2.c Sat Mar 2 18:40:04 2013 (r247665) +++ head/sbin/ipfw/ipfw2.c Sat Mar 2 18:51:26 2013 (r247666) @@ -3912,6 +3912,7 @@ ipfw_flush(int force) static void table_list(uint16_t num, int need_header); +static void table_fill_xentry(char *arg, ipfw_table_xentry *xent); /* * This one handles all table-related commands @@ -3927,8 +3928,7 @@ ipfw_table_handler(int ac, char *av[]) int do_add; int is_all; size_t len; - char *p; - uint32_t a, type, mask, addrlen; + uint32_t a, mask; uint32_t tables_max; mask = 0; // XXX uninitialized ? @@ -3965,57 +3965,8 @@ ipfw_table_handler(int ac, char *av[]) ac--; av++; if (!ac) errx(EX_USAGE, "address required"); - /* - * Let's try to guess type by agrument. - * Possible types: - * 1) IPv4[/mask] - * 2) IPv6[/mask] - * 3) interface name - * 4) port ? - */ - type = 0; - if (ishexnumber(*av[0])) { - /* Remove / if exists */ - if ((p = strchr(*av, '/')) != NULL) { - *p = '\0'; - mask = atoi(p + 1); - } - - if (inet_pton(AF_INET, *av, &xent.k.addr6) == 1) { - type = IPFW_TABLE_CIDR; - if ((p != NULL) && (mask > 32)) - errx(EX_DATAERR, "bad IPv4 mask width: %s", p + 1); - xent.masklen = p ? mask : 32; - addrlen = sizeof(struct in_addr); - } else if (inet_pton(AF_INET6, *av, &xent.k.addr6) == 1) { - type = IPFW_TABLE_CIDR; - if ((p != NULL) && (mask > 128)) - errx(EX_DATAERR, "bad IPv6 mask width: %s", p + 1); - xent.masklen = p ? mask : 128; - addrlen = sizeof(struct in6_addr); - } - } - - if ((type == 0) && (strchr(*av, '.') == NULL)) { - /* Assume interface name. Copy significant data only */ - mask = MIN(strlen(*av), IF_NAMESIZE - 1); - memcpy(xent.k.iface, *av, mask); - /* Set mask to exact match */ - xent.masklen = 8 * IF_NAMESIZE; - type = IPFW_TABLE_INTERFACE; - addrlen = IF_NAMESIZE; - } - if (type == 0) { - if (lookup_host(*av, (struct in_addr *)&xent.k.addr6) != 0) - errx(EX_NOHOST, "hostname ``%s'' unknown", *av); - xent.masklen = 32; - type = IPFW_TABLE_CIDR; - addrlen = sizeof(struct in_addr); - } - - xent.type = type; - xent.len = offsetof(ipfw_table_xentry, k) + addrlen; + table_fill_xentry(*av, &xent); ac--; av++; if (do_add && ac) { @@ -4065,6 +4016,93 @@ ipfw_table_handler(int ac, char *av[]) } static void +table_fill_xentry(char *arg, ipfw_table_xentry *xent) +{ + int addrlen, mask, masklen, type; + struct in6_addr *paddr; + uint32_t *pkey; + char *p; + uint32_t key; + + mask = 0; + type = 0; + addrlen = 0; + masklen = 0; + + /* + * Let's try to guess type by agrument. + * Possible types: + * 1) IPv4[/mask] + * 2) IPv6[/mask] + * 3) interface name + * 4) port, uid/gid or other u32 key (base 10 format) + * 5) hostname + */ + paddr = &xent->k.addr6; + if (ishexnumber(*arg) != 0 || *arg == ':') { + /* Remove / if exists */ + if ((p = strchr(arg, '/')) != NULL) { + *p = '\0'; + mask = atoi(p + 1); + } + + if (inet_pton(AF_INET, arg, paddr) == 1) { + if (p != NULL && mask > 32) + errx(EX_DATAERR, "bad IPv4 mask width: %s", + p + 1); + + type = IPFW_TABLE_CIDR; + masklen = p ? mask : 32; + addrlen = sizeof(struct in_addr); + } else if (inet_pton(AF_INET6, arg, paddr) == 1) { + if (IN6_IS_ADDR_V4COMPAT(paddr)) + errx(EX_DATAERR, + "Use IPv4 instead of v4-compatible"); + if (p != NULL && mask > 128) + errx(EX_DATAERR, "bad IPv6 mask width: %s", + p + 1); + + type = IPFW_TABLE_CIDR; + masklen = p ? mask : 128; + addrlen = sizeof(struct in6_addr); + } else { + /* Port or any other key */ + key = strtol(arg, &p, 10); + /* Skip non-base 10 entries like 'fa1' */ + if (p != arg) { + pkey = (uint32_t *)paddr; + *pkey = htonl(key); + type = IPFW_TABLE_CIDR; + addrlen = sizeof(uint32_t); + } + } + } + + if (type == 0 && strchr(arg, '.') == NULL) { + /* Assume interface name. Copy significant data only */ + mask = MIN(strlen(arg), IF_NAMESIZE - 1); + memcpy(xent->k.iface, arg, mask); + /* Set mask to exact match */ + masklen = 8 * IF_NAMESIZE; + type = IPFW_TABLE_INTERFACE; + addrlen = IF_NAMESIZE; + } + + if (type == 0) { + if (lookup_host(arg, (struct in_addr *)paddr) != 0) + errx(EX_NOHOST, "hostname ``%s'' unknown", arg); + + masklen = 32; + type = IPFW_TABLE_CIDR; + addrlen = sizeof(struct in_addr); + } + + xent->type = type; + xent->masklen = masklen; + xent->len = offsetof(ipfw_table_xentry, k) + addrlen; +} + +static void table_list(uint16_t num, int need_header) { ipfw_xtable *tbl; @@ -4107,8 +4145,8 @@ table_list(uint16_t num, int need_header tval = xent->value; addr6 = &xent->k.addr6; - if ((addr6->s6_addr32[0] == 0) && (addr6->s6_addr32[1] == 0) && - (addr6->s6_addr32[2] == 0)) { + + if (IN6_IS_ADDR_V4COMPAT(addr6)) { /* IPv4 address */ inet_ntop(AF_INET, &addr6->s6_addr32[3], tbuf, sizeof(tbuf)); } else {