Add support for IPv4 only rules to IPFW2 now that it supports IPv6 as well.
This is the last requirement before we can retire ip6fw. Reviewed by: dwhite, brooks(earlier version) Submitted by: dwhite (manpage) Silence from: -ipfw
This commit is contained in:
parent
96eb8edf03
commit
f2254cf702
@ -623,7 +623,7 @@ The search terminates.
|
||||
.It Cm fwd | forward Ar ipaddr Ns Op , Ns Ar port
|
||||
Change the next-hop on matching packets to
|
||||
.Ar ipaddr ,
|
||||
which can be an IP address in dotted quad format or a host name.
|
||||
which can be an IP address or a host name.
|
||||
The search terminates if this rule matches.
|
||||
.Pp
|
||||
If
|
||||
@ -805,14 +805,16 @@ Rule fields have the following meaning:
|
||||
.It Ar protocol : Oo Cm not Oc Ar protocol-name | protocol-number
|
||||
An IP protocol specified by number or name
|
||||
(for a complete list see
|
||||
.Pa /etc/protocols ) .
|
||||
The
|
||||
.Cm ip ,
|
||||
.Cm ip6 ,
|
||||
.Cm ipv6 ,
|
||||
or
|
||||
.Cm all
|
||||
keywords mean any protocol will match.
|
||||
.Pa /etc/protocols ) ,
|
||||
or one of the following keywords:
|
||||
.Bl -tag -width indent
|
||||
.It Cm ip4 | ipv4
|
||||
Matches IPv4 packets.
|
||||
.It Cm ip6 | ipv6
|
||||
Matches IPv6 packets.
|
||||
.It Cm ip | all
|
||||
Matches any packet.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Cm { Ar protocol Cm or ... }
|
||||
@ -861,7 +863,7 @@ Hostnames are resolved at the time the rule is added to the firewall list.
|
||||
.It Ar addr Ns / Ns Ar masklen
|
||||
Matches all addresses with base
|
||||
.Ar addr
|
||||
(specified as a dotted quad or a hostname)
|
||||
(specified as an IP address or a hostname)
|
||||
and mask width of
|
||||
.Cm masklen
|
||||
bits.
|
||||
@ -870,7 +872,7 @@ all IP numbers from 1.2.3.0 to 1.2.3.127 .
|
||||
.It Ar addr Ns : Ns Ar mask
|
||||
Matches all addresses with base
|
||||
.Ar addr
|
||||
(specified as a dotted quad or a hostname)
|
||||
(specified as an IP address or a hostname)
|
||||
and the mask of
|
||||
.Ar mask ,
|
||||
specified as a dotted quad.
|
||||
@ -887,7 +889,7 @@ error-prone.
|
||||
.It Ar list : Bro Ar num | num-num Brc Ns Op Ns , Ns Ar list
|
||||
Matches all addresses with base address
|
||||
.Ar addr
|
||||
(specified as a dotted quad or a hostname)
|
||||
(specified as an IP address or a hostname)
|
||||
and whose last byte is in the list between braces { } .
|
||||
Note that there must be no spaces between braces and
|
||||
numbers (spaces after commas are allowed).
|
||||
@ -1444,7 +1446,7 @@ Each entry is represented by an
|
||||
.Ar addr Ns Op / Ns Ar masklen
|
||||
and will match all addresses with base
|
||||
.Ar addr
|
||||
(specified as a dotted quad or a hostname)
|
||||
(specified as an IP address or a hostname)
|
||||
and mask width of
|
||||
.Ar masklen
|
||||
bits.
|
||||
|
@ -275,6 +275,8 @@ enum tokens {
|
||||
TOK_EXT6HDR,
|
||||
TOK_DSTIP6,
|
||||
TOK_SRCIP6,
|
||||
|
||||
TOK_IPV4,
|
||||
};
|
||||
|
||||
struct _s_x dummynet_params[] = {
|
||||
@ -395,6 +397,8 @@ struct _s_x rule_options[] = {
|
||||
{ "flow-id", TOK_FLOWID},
|
||||
{ "ipv6", TOK_IPV6},
|
||||
{ "ip6", TOK_IPV6},
|
||||
{ "ipv4", TOK_IPV4},
|
||||
{ "ip4", TOK_IPV4},
|
||||
{ "dst-ipv6", TOK_DSTIP6},
|
||||
{ "dst-ip6", TOK_DSTIP6},
|
||||
{ "src-ipv6", TOK_SRCIP6},
|
||||
@ -1260,6 +1264,7 @@ print_ext6hdr( ipfw_insn *cmd )
|
||||
#define HAVE_DSTIP 0x0004
|
||||
#define HAVE_MAC 0x0008
|
||||
#define HAVE_MACTYPE 0x0010
|
||||
#define HAVE_PROTO4 0x0040
|
||||
#define HAVE_PROTO6 0x0080
|
||||
#define HAVE_OPTIONS 0x8000
|
||||
|
||||
@ -1283,11 +1288,14 @@ show_prerequisites(int *flags, int want, int cmd)
|
||||
return;
|
||||
}
|
||||
if ( !(*flags & HAVE_OPTIONS)) {
|
||||
/* XXX BED: !(*flags & HAVE_PROTO) in patch */
|
||||
if ( !(*flags & HAVE_PROTO6) && (want & HAVE_PROTO6))
|
||||
printf(" ipv6");
|
||||
if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))
|
||||
printf(" ip");
|
||||
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))
|
||||
@ -1468,9 +1476,23 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
/*
|
||||
* then print the body.
|
||||
*/
|
||||
for (l = rule->act_ofs, cmd = rule->cmd ;
|
||||
l > 0 ; l -= F_LEN(cmd) , cmd += F_LEN(cmd)) {
|
||||
if ((cmd->len & F_OR) || (cmd->len & F_NOT))
|
||||
continue;
|
||||
if (cmd->opcode == O_IP4) {
|
||||
flags |= HAVE_PROTO4;
|
||||
break;
|
||||
} else if (cmd->opcode == O_IP6) {
|
||||
flags |= HAVE_PROTO6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rule->_pad & 1) { /* empty rules before options */
|
||||
if (!do_compact)
|
||||
printf(" ip from any to any");
|
||||
if (!do_compact) {
|
||||
show_prerequisites(&flags, HAVE_PROTO, 0);
|
||||
printf(" from any to any");
|
||||
}
|
||||
flags |= HAVE_IP | HAVE_OPTIONS;
|
||||
}
|
||||
|
||||
@ -1600,6 +1622,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
printf(" not");
|
||||
proto = cmd->arg1;
|
||||
pe = getprotobynumber(cmd->arg1);
|
||||
if ((flags & (HAVE_PROTO4 | HAVE_PROTO6)) &&
|
||||
!(flags & HAVE_PROTO))
|
||||
show_prerequisites(&flags,
|
||||
HAVE_IP | HAVE_OPTIONS, 0);
|
||||
if (flags & HAVE_OPTIONS)
|
||||
printf(" proto");
|
||||
if (pe)
|
||||
@ -1611,6 +1637,12 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
break;
|
||||
|
||||
default: /*options ... */
|
||||
if (!(cmd->len & (F_OR|F_NOT)))
|
||||
if (((cmd->opcode == O_IP6) &&
|
||||
(flags & HAVE_PROTO6)) ||
|
||||
((cmd->opcode == O_IP4) &&
|
||||
(flags & HAVE_PROTO4)))
|
||||
break;
|
||||
show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
|
||||
if ((cmd->len & F_OR) && !or_block)
|
||||
printf(" {");
|
||||
@ -1810,10 +1842,14 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
}
|
||||
break;
|
||||
|
||||
case O_IP6:
|
||||
case O_IP6:
|
||||
printf(" ipv6");
|
||||
break;
|
||||
|
||||
case O_IP4:
|
||||
printf(" ipv4");
|
||||
break;
|
||||
|
||||
case O_ICMP6TYPE:
|
||||
print_icmp6types((ipfw_insn_u32 *)cmd);
|
||||
break;
|
||||
@ -3506,13 +3542,18 @@ add_proto(ipfw_insn *cmd, char *av, u_char *proto)
|
||||
*proto = IPPROTO_IP;
|
||||
|
||||
if (_substrcmp(av, "all") == 0)
|
||||
; /* same as "ip" */
|
||||
else if ((*proto = atoi(av)) > 0)
|
||||
; /* do not set O_IP4 nor O_IP6 */
|
||||
else if (strcmp(av, "ipv4") == 0 || strcmp(av, "ip4") == 0)
|
||||
/* explicit "just IPv4" rule */
|
||||
fill_cmd(cmd, O_IP4, 0, 0);
|
||||
else if (strcmp(av, "ipv6") == 0 || strcmp(av, "ip6") == 0) {
|
||||
/* explicit "just IPv6" rule */
|
||||
*proto = IPPROTO_IPV6;
|
||||
fill_cmd(cmd, O_IP6, 0, 0);
|
||||
} else if ((*proto = atoi(av)) > 0)
|
||||
; /* all done! */
|
||||
else if ((pe = getprotobyname(av)) != NULL)
|
||||
*proto = pe->p_proto;
|
||||
else if (strcmp(av, "ipv6") == 0 || strcmp(av, "ip6") == 0)
|
||||
*proto = IPPROTO_IPV6;
|
||||
else
|
||||
return NULL;
|
||||
if (*proto != IPPROTO_IP && *proto != IPPROTO_IPV6)
|
||||
@ -4347,8 +4388,6 @@ add(int ac, char *av[])
|
||||
case TOK_PROTO:
|
||||
NEED1("missing protocol");
|
||||
if (add_proto(cmd, *av, &proto)) {
|
||||
if (proto == IPPROTO_IPV6)
|
||||
fill_cmd(cmd, O_IP6, 0, 0);
|
||||
ac--; av++;
|
||||
} else
|
||||
errx(EX_DATAERR, "invalid protocol ``%s''",
|
||||
@ -4435,6 +4474,10 @@ add(int ac, char *av[])
|
||||
fill_cmd(cmd, O_IP6, 0, 0);
|
||||
break;
|
||||
|
||||
case TOK_IPV4:
|
||||
fill_cmd(cmd, O_IP4, 0, 0);
|
||||
break;
|
||||
|
||||
case TOK_EXT6HDR:
|
||||
fill_ext6hdr( cmd, *av );
|
||||
ac--; av++;
|
||||
|
@ -153,6 +153,8 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
O_NETGRAPH, /* send to ng_ipfw */
|
||||
O_NGTEE, /* copy to ng_ipfw */
|
||||
|
||||
O_IP4,
|
||||
|
||||
O_LAST_OPCODE /* not an opcode! */
|
||||
};
|
||||
|
||||
|
@ -1961,6 +1961,7 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
int is_ipv6 = 0;
|
||||
u_int16_t ext_hd = 0; /* bits vector for extension header filtering */
|
||||
/* end of ipv6 variables */
|
||||
int is_ipv4 = 0;
|
||||
|
||||
if (m->m_flags & M_SKIP_FIREWALL)
|
||||
return (IP_FW_PASS); /* accept */
|
||||
@ -2076,6 +2077,7 @@ do { \
|
||||
} else if (pktlen >= sizeof(struct ip) &&
|
||||
(args->eh == NULL || ntohs(args->eh->ether_type) == ETHERTYPE_IP) &&
|
||||
mtod(m, struct ip *)->ip_v == 4) {
|
||||
is_ipv4 = 1;
|
||||
ip = mtod(m, struct ip *);
|
||||
hlen = ip->ip_hl << 2;
|
||||
args->f_id.addr_type = 4;
|
||||
@ -2677,6 +2679,10 @@ do { \
|
||||
break;
|
||||
#endif
|
||||
|
||||
case O_IP4:
|
||||
match = is_ipv4;
|
||||
break;
|
||||
|
||||
/*
|
||||
* The second set of opcodes represents 'actions',
|
||||
* i.e. the terminal part of a rule once the packet
|
||||
@ -3322,6 +3328,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
case O_IP6_DST_ME:
|
||||
case O_EXT_HDR:
|
||||
case O_IP6:
|
||||
case O_IP4:
|
||||
if (cmdlen != F_INSN_SIZE(ipfw_insn))
|
||||
goto bad_size;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user