Index: sbin/ipfw/dummynet.c =================================================================== --- sbin/ipfw/dummynet.c +++ sbin/ipfw/dummynet.c @@ -56,7 +56,11 @@ { "noerror", TOK_NOERROR }, { "buckets", TOK_BUCKETS }, { "dst-ip", TOK_DSTIP }, + { "dst-ip4", TOK_DSTIP4 }, + { "dst-ipv4", TOK_DSTIP4 }, { "src-ip", TOK_SRCIP }, + { "src-ip4", TOK_SRCIP4 }, + { "src-ipv4", TOK_SRCIP4 }, { "dst-port", TOK_DSTPORT }, { "src-port", TOK_SRCPORT }, { "proto", TOK_PROTO }, @@ -1246,6 +1250,12 @@ #endif +static int +str_is6(char *str) +{ + struct in6_addr tmp; + return inet_pton(AF_INET6, str, &tmp) == 1; +} /* * configuration of pipes, schedulers, flowsets. @@ -1460,6 +1470,7 @@ uint32_t *p20 = NULL; struct in6_addr *pa6 = NULL; uint32_t a; + int is6; tok = match_token(dummynet_params, *av); ac--; av++; @@ -1486,11 +1497,29 @@ goto end_mask; case TOK_DSTIP: + is6 = str_is6(*av); + mask->addr_type = is6 ? 6 : 4; + if (is6) + pa6 = &mask->dst_ip6; + else + p32 = &mask->dst_ip; + break; + + case TOK_SRCIP: + is6 = str_is6(*av); + mask->addr_type = is6 ? 6 : 4; + if (is6) + pa6 = &mask->src_ip6; + else + p32 = &mask->src_ip; + break; + + case TOK_DSTIP4: mask->addr_type = 4; p32 = &mask->dst_ip; break; - case TOK_SRCIP: + case TOK_SRCIP4: mask->addr_type = 4; p32 = &mask->src_ip; break; Index: sbin/ipfw/ipfw.8 =================================================================== --- sbin/ipfw/ipfw.8 +++ sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 21, 2019 +.Dd April 10, 2020 .Dt IPFW 8 .Os .Sh NAME @@ -1550,6 +1550,9 @@ Matches only packets going from a divert socket back outward to the IP stack output for delivery. .It Cm dst-ip Ar ip-address +Matches IP (IPv4 or IPv6) packets whose destination IP is one of the +address(es) specified as argument. +.It Bro Cm dst-ip4 | dst-ipv4 Brc Ar ip-address Matches IPv4 packets whose destination IP is one of the address(es) specified as argument. .It Bro Cm dst-ip6 | dst-ipv6 Brc Ar ip6-address @@ -1938,9 +1941,13 @@ .Cm pipe number. .It Cm src-ip Ar ip-address +Matches IP (IPv4 or IPv6) packets whose destination IP is one of the +address(es) specified as argument. Should multiple addresses be specified, +IP address families cannot be mixed. +.It Bro Cm src-ip4 | src-ipv4 Brc Ar ip-address Matches IPv4 packets whose source IP is one of the address(es) specified as an argument. -.It Cm src-ip6 Ar ip6-address +.It Bro Cm src-ip6 | src-ipv6 Brc Ar ip-address Matches IPv6 packets whose source IP is one of the address(es) specified as an argument. .It Cm src-port Ar ports Index: sbin/ipfw/ipfw2.h =================================================================== --- sbin/ipfw/ipfw2.h +++ sbin/ipfw/ipfw2.h @@ -239,6 +239,8 @@ TOK_IPV4, TOK_UNREACH6, TOK_RESET6, + TOK_DSTIP4, + TOK_SRCIP4, TOK_FIB, TOK_SETFIB, Index: sbin/ipfw/ipfw2.c =================================================================== --- sbin/ipfw/ipfw2.c +++ sbin/ipfw/ipfw2.c @@ -347,7 +347,11 @@ { "icmptype", TOK_ICMPTYPES }, { "icmptypes", TOK_ICMPTYPES }, { "dst-ip", TOK_DSTIP }, + { "dst-ip4", TOK_DSTIP4 }, + { "dst-ipv4", TOK_DSTIP4 }, { "src-ip", TOK_SRCIP }, + { "src-ip4", TOK_SRCIP4 }, + { "src-ipv4", TOK_SRCIP4 }, { "dst-port", TOK_DSTPORT }, { "src-port", TOK_SRCPORT }, { "proto", TOK_PROTO }, @@ -1472,7 +1476,7 @@ case O_IP_SRC_ME: case O_IP_SRC_SET: if (state->flags & HAVE_SRCIP) - bprintf(bp, " src-ip"); + bprintf(bp, " src-ip4"); print_ip(bp, fo, insntod(cmd, ip)); break; case O_IP_DST: @@ -1481,7 +1485,7 @@ case O_IP_DST_ME: case O_IP_DST_SET: if (state->flags & HAVE_DSTIP) - bprintf(bp, " dst-ip"); + bprintf(bp, " dst-ip4"); print_ip(bp, fo, insntod(cmd, ip)); break; case O_IP6_SRC: @@ -3775,6 +3779,7 @@ */ static uint32_t actbuf[255], cmdbuf[255]; int rblen, ablen, cblen; + struct in6_addr tmpaddr; ipfw_insn *src, *dst, *cmd, *action, *prev=NULL; ipfw_insn *first_cmd; /* first match pattern */ @@ -3792,6 +3797,8 @@ int i; + char *p = NULL, bp; + int open_par = 0; /* open parenthesis ( */ /* proto is here because it is used to fetch ports */ @@ -4835,13 +4842,55 @@ case TOK_SRCIP: NEED1("missing source IP"); - if (add_srcip(cmd, *av, cblen, tstate)) { - av++; + if ((p = strpbrk(*av, "/,"))) { + bp = *p; + *p = '\0'; } + + if (inet_pton(AF_INET6, *av, &tmpaddr) == 1) { + if (p) + *p = bp; + if (add_srcip6(cmd, *av, cblen, tstate)) + av++; + break; + } + + if (p) + *p = bp; + if (add_srcip(cmd, *av, cblen, tstate)) + av++; break; case TOK_DSTIP: NEED1("missing destination IP"); + if ((p = strpbrk(*av, "/,"))) { + bp = *p; + *p = '\0'; + } + + if (inet_pton(AF_INET6, *av, &tmpaddr) == 1) { + if (p) + *p = ','; + if (add_dstip6(cmd, *av, cblen, tstate)) + av++; + break; + } + + if (p) + *p = ','; + if (add_dstip(cmd, *av, cblen, tstate)) + av++; + break; + + case TOK_SRCIP4: + NEED1("missing source IP4"); + if (add_srcip(cmd, *av, cblen, tstate)) { + av++; + } + break; + + case TOK_DSTIP4: + NEED1("missing destination IP4"); if (add_dstip(cmd, *av, cblen, tstate)) { av++; }