Index: sbin/ipfw/ipfw.8 diff -u sbin/ipfw/ipfw.8.orig sbin/ipfw/ipfw.8 --- sbin/ipfw/ipfw.8.orig 2009-12-15 18:46:27.000000000 +0900 +++ sbin/ipfw/ipfw.8 2010-01-08 12:33:36.117724529 +0900 @@ -1003,7 +1003,7 @@ its use is discouraged. .It Ar addr : Oo Cm not Oc Bro .Bl -tag -width indent -.Cm any | me | me6 | +.Cm any | me | me4 | me6 | .Cm table Ns Pq Ar number Ns Op , Ns Ar value .Ar | addr-list | addr-set .Brc @@ -1011,6 +1011,8 @@ matches any IP address. .It Cm me matches any IP address configured on an interface in the system. +.It Cm me4 +matches any IPv4 address configured on an interface in the system. .It Cm me6 matches any IPv6 address configured on an interface in the system. The address list is evaluated at the time the packet is Index: sbin/ipfw/ipfw2.c diff -u -p sbin/ipfw/ipfw2.c.orig sbin/ipfw/ipfw2.c --- sbin/ipfw/ipfw2.c.orig 2009-12-15 18:46:27.000000000 +0900 +++ sbin/ipfw/ipfw2.c 2010-01-08 12:33:36.037713520 +0900 @@ -768,6 +768,10 @@ print_ip(ipfw_insn_ip *cmd, char const * printf("me"); return; } + if (cmd->o.opcode == O_IP4_SRC_ME || cmd->o.opcode == O_IP4_DST_ME) { + printf("me4"); + return; + } if (cmd->o.opcode == O_IP_SRC_LOOKUP || cmd->o.opcode == O_IP_DST_LOOKUP) { printf("table(%u", ((ipfw_insn *)cmd)->arg1); @@ -1187,6 +1191,7 @@ show_ipfw(struct ip_fw *rule, int pcwidt case O_IP_SRC_LOOKUP: case O_IP_SRC_MASK: case O_IP_SRC_ME: + case O_IP4_SRC_ME: case O_IP_SRC_SET: show_prerequisites(&flags, HAVE_PROTO, 0); if (!(flags & HAVE_SRCIP)) @@ -1202,6 +1207,7 @@ show_ipfw(struct ip_fw *rule, int pcwidt case O_IP_DST_LOOKUP: case O_IP_DST_MASK: case O_IP_DST_ME: + case O_IP4_DST_ME: case O_IP_DST_SET: show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0); if (!(flags & HAVE_DSTIP)) @@ -1972,6 +1978,12 @@ fill_ip(ipfw_insn_ip *cmd, char *av) return; } + if (strcmp(av, "me4") == 0) { + cmd->o.opcode = O_IP4_DST_ME; + cmd->o.len |= F_INSN_SIZE(ipfw_insn); + return; + } + if (strncmp(av, "table(", 6) == 0) { char *p = strchr(av + 6, ','); @@ -2478,6 +2490,8 @@ add_srcip(ipfw_insn *cmd, char *av) cmd->opcode = O_IP_SRC_SET; else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ cmd->opcode = O_IP_SRC_LOOKUP; + else if (cmd->opcode == O_IP4_DST_ME) /* me4 */ + cmd->opcode = O_IP4_SRC_ME; else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) /* me */ cmd->opcode = O_IP_SRC_ME; else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32)) /* one IP */ @@ -2495,6 +2509,8 @@ add_dstip(ipfw_insn *cmd, char *av) ; else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ ; + else if (cmd->opcode == O_IP4_DST_ME) /* me4 */ + ; else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) /* me */ cmd->opcode = O_IP_DST_ME; else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32)) /* one IP */ @@ -2534,7 +2550,7 @@ add_src(ipfw_insn *cmd, char *av, u_char ret = add_srcip6(cmd, av); /* XXX: should check for IPv4, not !IPv6 */ if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 || - !inet_pton(AF_INET6, host, &a))) + strcmp(av, "me4") == 0 || !inet_pton(AF_INET6, host, &a))) ret = add_srcip(cmd, av); if (ret == NULL && strcmp(av, "any") != 0) ret = cmd; @@ -2560,7 +2576,7 @@ add_dst(ipfw_insn *cmd, char *av, u_char ret = add_dstip6(cmd, av); /* XXX: should check for IPv4, not !IPv6 */ if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 || - !inet_pton(AF_INET6, host, &a))) + strcmp(av, "me4") == 0 || !inet_pton(AF_INET6, host, &a))) ret = add_dstip(cmd, av); if (ret == NULL && strcmp(av, "any") != 0) ret = cmd; Index: sys/netinet/ip_fw.h diff -u sys/netinet/ip_fw.h.orig sys/netinet/ip_fw.h --- sys/netinet/ip_fw.h.orig 2009-12-23 04:01:47.000000000 +0900 +++ sys/netinet/ip_fw.h 2010-01-08 12:33:36.157742465 +0900 @@ -166,6 +166,8 @@ O_ALTQ, /* u32 = altq classif. qid */ O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ O_TCPDATALEN, /* arg1 = tcp data len */ + O_IP4_SRC_ME, /* none */ + O_IP4_DST_ME, /* none */ O_IP6_SRC, /* address without mask */ O_IP6_SRC_ME, /* my addresses */ O_IP6_SRC_MASK, /* address with the mask */ Index: sys/netinet/ipfw/ip_fw2.c diff -u -p sys/netinet/ipfw/ip_fw2.c.orig sys/netinet/ipfw/ip_fw2.c --- sys/netinet/ipfw/ip_fw2.c.orig 2010-01-08 12:30:31.039834764 +0900 +++ sys/netinet/ipfw/ip_fw2.c 2010-01-08 12:38:30.778824466 +0900 @@ -1385,6 +1385,7 @@ do { \ break; case O_IP_SRC_ME: + case O_IP4_SRC_ME: if (is_ipv4) { struct ifnet *tif; @@ -1392,6 +1393,8 @@ do { \ match = (tif != NULL); break; } + if (cmd->opcode == O_IP4_SRC_ME) + break; /* FALLTHROUGH */ #ifdef INET6 case O_IP6_SRC_ME: @@ -1425,6 +1428,7 @@ do { \ break; case O_IP_DST_ME: + case O_IP4_DST_ME: if (is_ipv4) { struct ifnet *tif; @@ -1432,6 +1436,8 @@ do { \ match = (tif != NULL); break; } + if (cmd->opcode == O_IP4_DST_ME) + break; /* FALLTHROUGH */ #ifdef INET6 case O_IP6_DST_ME: Index: sys/netinet/ipfw/ip_fw_sockopt.c diff -u -p sys/netinet/ipfw/ip_fw_sockopt.c.orig sys/netinet/ipfw/ip_fw_sockopt.c --- sys/netinet/ipfw/ip_fw_sockopt.c.orig 2010-01-07 19:08:05.000000000 +0900 +++ sys/netinet/ipfw/ip_fw_sockopt.c 2010-01-08 12:33:36.237826387 +0900 @@ -529,6 +529,8 @@ check_ipfw_struct(struct ip_fw *rule, in case O_VERSRCREACH: case O_ANTISPOOF: case O_IPSEC: + case O_IP4_SRC_ME: + case O_IP4_DST_ME: #ifdef INET6 case O_IP6_SRC_ME: case O_IP6_DST_ME: