Implement the last 2-3 missing instructions for ipfw,
now it should support all the instructions of the old ipfw. Fix some bugs in the user interface, /sbin/ipfw. Please check this code against your rulesets, so i can fix the remaining bugs (if any, i think they will be mostly in /sbin/ipfw). Once we have done a bit of testing, this code is ready to be MFC'ed, together with a bunch of other changes (glue to ipfw, and also the removal of some global variables) which have been in -current for a couple of weeks now. MFC after: 7 days
This commit is contained in:
parent
17b9cc4941
commit
5e43aef891
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99475
@ -116,7 +116,6 @@ static struct _s_x f_ipopts[] = {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#if 0 /* XXX not used yet */
|
||||
static struct _s_x f_iptos[] = {
|
||||
{ "lowdelay", IPTOS_LOWDELAY},
|
||||
{ "throughput", IPTOS_THROUGHPUT},
|
||||
@ -127,7 +126,6 @@ static struct _s_x f_iptos[] = {
|
||||
{ "ip tos option", 0},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct _s_x limit_masks[] = {
|
||||
{"all", DYN_SRC_ADDR|DYN_SRC_PORT|DYN_DST_ADDR|DYN_DST_PORT},
|
||||
@ -254,6 +252,7 @@ struct _s_x dummynet_params[] = {
|
||||
{ "bw", TOK_BW },
|
||||
{ "bandwidth", TOK_BW },
|
||||
{ "delay", TOK_DELAY },
|
||||
{ "pipe", TOK_PIPE },
|
||||
{ "queue", TOK_QUEUE },
|
||||
{ "dummynet-params", TOK_NULL },
|
||||
{ NULL, 0 }
|
||||
@ -276,6 +275,7 @@ struct _s_x rule_actions[] = {
|
||||
{ "drop", TOK_DENY },
|
||||
{ "reject", TOK_REJECT },
|
||||
{ "reset", TOK_RESET },
|
||||
{ "unreach", TOK_UNREACH },
|
||||
{ "check-state", TOK_CHECKSTATE },
|
||||
{ NULL, TOK_NULL },
|
||||
{ NULL, 0 }
|
||||
@ -496,7 +496,6 @@ fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
|
||||
return i;
|
||||
}
|
||||
|
||||
#if 0 /* XXX not used yet */
|
||||
static struct _s_x icmpcodes[] = {
|
||||
{ "net", ICMP_UNREACH_NET },
|
||||
{ "host", ICMP_UNREACH_HOST },
|
||||
@ -533,16 +532,15 @@ fill_reject_code(u_short *codep, char *str)
|
||||
}
|
||||
|
||||
static void
|
||||
print_reject_code(u_int32_t code)
|
||||
print_reject_code(u_int16_t code)
|
||||
{
|
||||
char *s = match_value(icmpcodes, code);
|
||||
|
||||
if (s != NULL)
|
||||
printf("%s", s);
|
||||
printf("unreach %s", s);
|
||||
else
|
||||
printf("%u", code);
|
||||
printf("unreach %u", code);
|
||||
}
|
||||
#endif /* XXX not used yet */
|
||||
|
||||
/*
|
||||
* Returns the number of bits set (from left) in a contiguous bitmask,
|
||||
@ -678,6 +676,44 @@ print_mac(u_char *addr, u_char *mask)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_icmptypes(ipfw_insn_u32 *cmd, char *av)
|
||||
{
|
||||
u_int8_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 = ',';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* show_ipfw() prints the body of an ipfw rule.
|
||||
@ -763,6 +799,15 @@ show_ipfw(struct ip_fw *rule)
|
||||
printf("deny");
|
||||
break;
|
||||
|
||||
case O_REJECT:
|
||||
if (cmd->arg1 == ICMP_REJECT_RST)
|
||||
printf("reset");
|
||||
else if (cmd->arg1 == ICMP_UNREACH_HOST)
|
||||
printf("reject");
|
||||
else
|
||||
print_reject_code(cmd->arg1);
|
||||
break;
|
||||
|
||||
case O_SKIPTO:
|
||||
printf("skipto %u", cmd->arg1);
|
||||
break;
|
||||
@ -813,7 +858,8 @@ show_ipfw(struct ip_fw *rule)
|
||||
*/
|
||||
for (l = rule->act_ofs, cmd = rule->cmd ;
|
||||
l > 0 ; l -= F_LEN(cmd) , cmd += F_LEN(cmd)) {
|
||||
ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd; /* useful alias */
|
||||
/* useful alias */
|
||||
ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
|
||||
|
||||
switch(cmd->opcode) {
|
||||
case O_PROBE_STATE:
|
||||
@ -918,11 +964,13 @@ show_ipfw(struct ip_fw *rule)
|
||||
else if (cmd->opcode == O_VIA)
|
||||
s = "via";
|
||||
if (cmdif->name[0] == '\0')
|
||||
printf(" %s %s", s, inet_ntoa(cmdif->p.ip));
|
||||
printf(" %s %s", s,
|
||||
inet_ntoa(cmdif->p.ip));
|
||||
else if (cmdif->p.unit == -1)
|
||||
printf(" %s %s*", s, cmdif->name);
|
||||
else
|
||||
printf(" %s %s%d", s, cmdif->name, cmdif->p.unit);
|
||||
printf(" %s %s%d", s, cmdif->name,
|
||||
cmdif->p.unit);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -938,6 +986,10 @@ show_ipfw(struct ip_fw *rule)
|
||||
printf(" ipver %u", cmd->arg1 );
|
||||
break;
|
||||
|
||||
case O_IPPRECEDENCE:
|
||||
printf(" ipprecedence %u", (cmd->arg1) >> 5 );
|
||||
break;
|
||||
|
||||
case O_IPLEN:
|
||||
printf(" iplen %u", cmd->arg1 );
|
||||
break;
|
||||
@ -946,6 +998,14 @@ show_ipfw(struct ip_fw *rule)
|
||||
print_flags("ipoptions", cmd, f_ipopts);
|
||||
break;
|
||||
|
||||
case O_IPTOS:
|
||||
print_flags("iptos", cmd, f_iptos);
|
||||
break;
|
||||
|
||||
case O_ICMPTYPE:
|
||||
print_icmptypes((ipfw_insn_u32 *)cmd);
|
||||
break;
|
||||
|
||||
case O_ESTAB:
|
||||
printf(" established");
|
||||
break;
|
||||
@ -1029,45 +1089,6 @@ show_ipfw(struct ip_fw *rule)
|
||||
}
|
||||
show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP|HAVE_DSTIP);
|
||||
|
||||
#if 0 /* old stuff */
|
||||
switch (chain->fw_flg & IP_FW_F_COMMAND) {
|
||||
case IP_FW_F_REJECT:
|
||||
if (chain->fw_reject_code == IP_FW_REJECT_RST)
|
||||
printf("reset");
|
||||
else {
|
||||
printf("unreach ");
|
||||
print_reject_code(chain->fw_reject_code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
do_options:
|
||||
if (chain->fw_ipflg & IP_FW_IF_IPOPT)
|
||||
print_flags("ipopt", chain->fw_ipopt, chain->fw_ipnopt,
|
||||
f_ipopts);
|
||||
|
||||
if (chain->fw_ipflg & IP_FW_IF_IPPRE)
|
||||
printf(" ipprecedence %u", (chain->fw_iptos & 0xe0) >> 5);
|
||||
|
||||
if (chain->fw_ipflg & IP_FW_IF_IPTOS)
|
||||
print_flags("iptos", chain->fw_iptos, chain->fw_ipntos,
|
||||
f_iptos);
|
||||
|
||||
if (chain->fw_flg & IP_FW_F_ICMPBIT) {
|
||||
int i, first = 1;
|
||||
unsigned j;
|
||||
|
||||
printf(" icmptype");
|
||||
|
||||
for (i = 0; i < IP_FW_ICMPTYPES_DIM; ++i)
|
||||
for (j = 0; j < sizeof(unsigned) * 8; ++j)
|
||||
if (chain->fw_uar.fw_icmptypes[i] & (1 << j)) {
|
||||
printf("%c%d", first ? ' ' : ',',
|
||||
i * sizeof(unsigned) * 8 + j);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
#endif /* XXX old stuff */
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -1620,31 +1641,6 @@ fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode,
|
||||
cmd->arg1 = (set & 0xff) | ( (clear & 0xff) << 8);
|
||||
}
|
||||
|
||||
#if 0 /* XXX todo */
|
||||
static void
|
||||
fill_icmptypes(unsigned *types, char **vp, u_int *fw_flg)
|
||||
{
|
||||
unsigned long icmptype;
|
||||
char *c = *vp;
|
||||
|
||||
while (*c) {
|
||||
if (*c == ',')
|
||||
++c;
|
||||
|
||||
icmptype = strtoul(c, &c, 0);
|
||||
|
||||
if (*c != ',' && *c != '\0')
|
||||
errx(EX_DATAERR, "invalid ICMP type");
|
||||
|
||||
if (icmptype >= IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8)
|
||||
errx(EX_DATAERR, "ICMP type out of range");
|
||||
|
||||
types[icmptype / (sizeof(unsigned) * 8)] |=
|
||||
1 << (icmptype % (sizeof(unsigned) * 8));
|
||||
*fw_flg |= IP_FW_F_ICMPBIT;
|
||||
}
|
||||
}
|
||||
#endif /* XXX todo */
|
||||
|
||||
static void
|
||||
delete(int ac, char *av[])
|
||||
@ -1745,7 +1741,7 @@ config_pipe(int ac, char **av)
|
||||
else
|
||||
pipe.fs.fs_nr = i;
|
||||
}
|
||||
while (ac > 1) {
|
||||
while (ac > 0) {
|
||||
double d;
|
||||
int tok = match_token(dummynet_params, *av);
|
||||
ac--; av++;
|
||||
@ -2231,6 +2227,24 @@ add(int ac, char *av[])
|
||||
|
||||
case TOK_DENY:
|
||||
action->opcode = O_DENY;
|
||||
action->arg1 = 0;
|
||||
break;
|
||||
|
||||
case TOK_REJECT:
|
||||
action->opcode = O_REJECT;
|
||||
action->arg1 = ICMP_UNREACH_HOST;
|
||||
break;
|
||||
|
||||
case TOK_RESET:
|
||||
action->opcode = O_REJECT;
|
||||
action->arg1 = ICMP_REJECT_RST;
|
||||
break;
|
||||
|
||||
case TOK_UNREACH:
|
||||
action->opcode = O_REJECT;
|
||||
NEED1("missing reject code");
|
||||
fill_reject_code(&action->arg1, *av);
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_COUNT:
|
||||
@ -2305,19 +2319,6 @@ add(int ac, char *av[])
|
||||
}
|
||||
action = next_cmd(action);
|
||||
|
||||
#if 0
|
||||
} else if (!strncmp(*av, "reject", strlen(*av))) {
|
||||
rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
|
||||
rule.fw_reject_code = ICMP_UNREACH_HOST;
|
||||
} else if (!strncmp(*av, "reset", strlen(*av))) {
|
||||
rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
|
||||
rule.fw_reject_code = ICMP_REJECT_RST; /* check TCP later */
|
||||
} else if (!strncmp(*av, "unreach", strlen(*av))) {
|
||||
rule.fw_flg |= IP_FW_F_REJECT; av++; ac--;
|
||||
fill_reject_code(&rule.fw_reject_code, *av); av++; ac--;
|
||||
}
|
||||
#endif /* XXX other actions */
|
||||
|
||||
/*
|
||||
* [log [logamount N]] -- log, optional
|
||||
*
|
||||
@ -2568,6 +2569,12 @@ add(int ac, char *av[])
|
||||
cmd->opcode = O_VIA;
|
||||
break;
|
||||
|
||||
case TOK_ICMPTYPES:
|
||||
NEED1("icmptypes requires list of types");
|
||||
fill_icmptypes((ipfw_insn_u32 *)cmd, *av);
|
||||
av++; ac--;
|
||||
break;
|
||||
|
||||
case TOK_IPTTL:
|
||||
NEED1("ipttl requires TTL");
|
||||
fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
|
||||
@ -2592,12 +2599,25 @@ add(int ac, char *av[])
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_IPPRECEDENCE:
|
||||
NEED1("ipprecedence requires value");
|
||||
fill_cmd(cmd, O_IPPRECEDENCE, 0,
|
||||
(strtoul(*av, NULL, 0) & 7) << 5);
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_IPOPTS:
|
||||
NEED1("missing argument for ipoptions");
|
||||
fill_flags(cmd, O_IPOPTS, f_ipopts, *av);
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_IPTOS:
|
||||
NEED1("missing argument for iptos");
|
||||
fill_flags(cmd, O_IPOPTS, f_iptos, *av);
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_UID:
|
||||
NEED1("uid requires argument");
|
||||
{
|
||||
@ -2714,43 +2734,7 @@ add(int ac, char *av[])
|
||||
cmd = next_cmd(cmd);
|
||||
}
|
||||
}
|
||||
#if 0 /* XXX todo */
|
||||
do_options:
|
||||
while (ac) {
|
||||
} else if (!strncmp(*av, "ipprecedence", strlen(*av))) {
|
||||
u_long ippre;
|
||||
char *c;
|
||||
|
||||
av++; ac--;
|
||||
NEED1("missing argument for ``ipprecedence''");
|
||||
ippre = strtoul(*av, &c, 0);
|
||||
if (*c != '\0')
|
||||
errx(EX_DATAERR, "argument to ipprecedence"
|
||||
" must be numeric");
|
||||
if (ippre > 7)
|
||||
errx(EX_DATAERR, "argument to ipprecedence"
|
||||
" out of range");
|
||||
rule.fw_ipflg |= IP_FW_IF_IPPRE;
|
||||
rule.fw_iptos |= (u_short)(ippre << 5);
|
||||
av++; ac--;
|
||||
} else if (!strncmp(*av, "iptos", strlen(*av))) {
|
||||
av++; ac--;
|
||||
NEED1("missing argument for ``iptos''");
|
||||
rule.fw_ipflg |= IP_FW_IF_IPTOS;
|
||||
fill_flags(&rule.fw_iptos, &rule.fw_ipntos,
|
||||
f_iptos, av);
|
||||
av++; ac--;
|
||||
} else if (rule.fw_prot == IPPROTO_ICMP) {
|
||||
if (!strncmp(*av, "icmptypes", strlen(*av))) {
|
||||
av++; ac--;
|
||||
NEED1("missing argument for ``icmptypes''");
|
||||
fill_icmptypes(rule.fw_uar.fw_icmptypes,
|
||||
av, &rule.fw_flg);
|
||||
av++; ac--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* XXX todo */
|
||||
done:
|
||||
/*
|
||||
* Now copy stuff into the rule.
|
||||
|
@ -76,6 +76,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
|
||||
O_IPPRE, /* arg1 = id */
|
||||
O_IPTOS, /* arg1 = id */
|
||||
O_IPPRECEDENCE, /* arg1 = precedence << 5 */
|
||||
O_IPTTL, /* arg1 = TTL */
|
||||
|
||||
O_IPVER, /* arg1 = version */
|
||||
|
@ -73,6 +73,8 @@
|
||||
|
||||
#include <netinet/if_ether.h> /* XXX for ETHERTYPE_IP */
|
||||
|
||||
#include <machine/in_cksum.h> /* XXX for in_cksum */
|
||||
|
||||
static int fw_verbose = 0;
|
||||
static int verbose_limit = 0;
|
||||
|
||||
@ -345,16 +347,13 @@ tcpopts_match(struct ip *ip, ipfw_insn *cmd)
|
||||
return (flags_match(cmd, bits));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX done
|
||||
*/
|
||||
static int
|
||||
iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
|
||||
{
|
||||
if (ifp == NULL) /* no iface with this packet, match fails */
|
||||
return 0;
|
||||
/* Check by name or by IP address */
|
||||
if (cmd->name[0] != '\0') { /* XXX by name */
|
||||
if (cmd->name[0] != '\0') { /* match by name */
|
||||
/* Check unit number (-1 is wildcard) */
|
||||
if (cmd->p.unit != -1 && cmd->p.unit != ifp->if_unit)
|
||||
return(0);
|
||||
@ -419,10 +418,17 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ether_header *eh,
|
||||
case O_DENY:
|
||||
action = "Deny";
|
||||
break;
|
||||
|
||||
case O_REJECT:
|
||||
action = (cmd->arg1==ICMP_REJECT_RST) ?
|
||||
"Reset" : "Unreach";
|
||||
if (cmd->arg1==ICMP_REJECT_RST)
|
||||
action = "Reset";
|
||||
else if (cmd->arg1==ICMP_UNREACH_HOST)
|
||||
action = "Reject";
|
||||
else
|
||||
snprintf(SNPARGS(action2, 0), "Unreach %d",
|
||||
cmd->arg1);
|
||||
break;
|
||||
|
||||
case O_ACCEPT:
|
||||
action = "Accept";
|
||||
break;
|
||||
@ -568,7 +574,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ether_header *eh,
|
||||
|
||||
/*
|
||||
* IMPORTANT: the hash function for dynamic rules must be commutative
|
||||
* in * source and destination (ip,port), because rules are bidirectional
|
||||
* in source and destination (ip,port), because rules are bidirectional
|
||||
* and we want to find both in the same bucket.
|
||||
*/
|
||||
static __inline int
|
||||
@ -979,23 +985,94 @@ install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
send_pkt(struct ip_fw_args *args, u_int32_t seq, u_int32_t ack, int flags)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ip *ip = mtod(args->m, struct ip *);
|
||||
struct tcphdr *tcp;
|
||||
struct route sro; /* fake route */
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
if (m == 0)
|
||||
return;
|
||||
m->m_pkthdr.rcvif = (struct ifnet *)0;
|
||||
m->m_pkthdr.len = m->m_len = sizeof(struct ip) + sizeof(struct tcphdr);
|
||||
m->m_data += max_linkhdr;
|
||||
|
||||
ip->ip_v = 4;
|
||||
ip->ip_hl = 5;
|
||||
ip->ip_tos = 0;
|
||||
ip->ip_len = 0; /* set later */
|
||||
#ifdef RANDOM_IP_ID
|
||||
ip->ip_id = ip_randomid();
|
||||
#else
|
||||
ip->ip_id = htons(ip_id++);
|
||||
#endif
|
||||
ip->ip_off = 0;
|
||||
ip->ip_ttl = 0; /* set later */
|
||||
ip->ip_p = IPPROTO_TCP;
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_src.s_addr = args->f_id.dst_ip;
|
||||
ip->ip_dst.s_addr = args->f_id.src_ip;
|
||||
|
||||
tcp = L3HDR(struct tcphdr, ip);
|
||||
tcp->th_sport = htons(args->f_id.dst_port); /* swap ports */
|
||||
tcp->th_dport = htons(args->f_id.src_port);
|
||||
tcp->th_off = 4;
|
||||
tcp->th_x2 = 0;
|
||||
tcp->th_win = 0;
|
||||
tcp->th_sum = 0;
|
||||
tcp->th_urp = 0;
|
||||
if (flags & TH_ACK) {
|
||||
tcp->th_seq = htonl(ack);
|
||||
tcp->th_ack = htonl(0);
|
||||
tcp->th_flags = TH_RST;
|
||||
} else {
|
||||
if (flags & TH_SYN)
|
||||
seq++;
|
||||
tcp->th_seq = htonl(0);
|
||||
tcp->th_ack = htonl(seq);
|
||||
tcp->th_flags = TH_RST | TH_ACK;
|
||||
}
|
||||
/* compute TCP checksum... */
|
||||
tcp->th_sum = in_cksum(m, m->m_pkthdr.len);
|
||||
ip->ip_ttl = ip_defttl;
|
||||
ip->ip_len = m->m_pkthdr.len;
|
||||
bzero (&sro, sizeof (sro));
|
||||
ip_rtaddr(ip->ip_dst, &sro);
|
||||
ip_output(m, NULL, &sro, 0, NULL);
|
||||
if (sro.ro_rt)
|
||||
RTFREE(sro.ro_rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sends a reject message, consuming the mbuf passed as an argument.
|
||||
*/
|
||||
static void
|
||||
send_reject(struct mbuf *m, int code, int offset, int ip_len)
|
||||
send_reject(struct ip_fw_args *args, int code, int offset, int ip_len)
|
||||
{
|
||||
if (code != ICMP_REJECT_RST) /* Send an ICMP unreach */
|
||||
icmp_error(m, ICMP_UNREACH, code, 0L, 0);
|
||||
else {
|
||||
icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
|
||||
else if (offset == 0 && args->f_id.proto == IPPROTO_TCP) {
|
||||
#if 0
|
||||
struct tcphdr *const tcp =
|
||||
L3HDR(struct tcphdr, mtod(args->m, struct ip *));
|
||||
if ( (tcp->th_flags & TH_RST) == 0)
|
||||
send_pkt(args, tcp->th_seq, tcp->th_ack, tcp->th_flags);
|
||||
m_freem(args->m);
|
||||
#else
|
||||
/* XXX warning, this code writes into the mbuf */
|
||||
struct ip *ip = mtod(m, struct ip *);
|
||||
struct ip *ip = mtod(args->m, struct ip *);
|
||||
struct tcphdr *const tcp = L3HDR(struct tcphdr, ip);
|
||||
struct tcpiphdr ti, *const tip = (struct tcpiphdr *) ip;
|
||||
int hlen = ip->ip_hl << 2;
|
||||
|
||||
if (offset != 0 || (tcp->th_flags & TH_RST)) {
|
||||
m_freem(m); /* free the mbuf */
|
||||
if (tcp->th_flags & TH_RST) {
|
||||
m_freem(args->m); /* free the mbuf */
|
||||
args->m = NULL;
|
||||
return;
|
||||
}
|
||||
ti.ti_i = *((struct ipovly *) ip);
|
||||
@ -1005,15 +1082,18 @@ send_reject(struct mbuf *m, int code, int offset, int ip_len)
|
||||
tip->ti_ack = ntohl(tip->ti_ack);
|
||||
tip->ti_len = ip_len - hlen - (tip->ti_off << 2);
|
||||
if (tcp->th_flags & TH_ACK) {
|
||||
tcp_respond(NULL, (void *)ip, tcp, m,
|
||||
tcp_respond(NULL, (void *)ip, tcp, args->m,
|
||||
0, tcp->th_ack, TH_RST);
|
||||
} else {
|
||||
if (tcp->th_flags & TH_SYN)
|
||||
tip->ti_len++;
|
||||
tcp_respond(NULL, (void *)ip, tcp, m,
|
||||
tcp_respond(NULL, (void *)ip, tcp, args->m,
|
||||
tip->ti_seq + tip->ti_len, 0, TH_RST|TH_ACK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
m_freem(args->m);
|
||||
args->m = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1579,6 +1659,12 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
goto cmd_fail;
|
||||
goto cmd_match;
|
||||
|
||||
case O_IPPRECEDENCE:
|
||||
if (hlen == 0 ||
|
||||
(cmd->arg1 != (ip->ip_tos & 0xe0)) )
|
||||
goto cmd_fail;
|
||||
goto cmd_match;
|
||||
|
||||
case O_IPTOS:
|
||||
if (hlen == 0 ||
|
||||
!flags_match(cmd, ip->ip_tos))
|
||||
@ -1635,7 +1721,7 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
ipfw_log(f, hlen, args->eh, m, oif);
|
||||
goto cmd_match;
|
||||
|
||||
case O_PROB: /* XXX check */
|
||||
case O_PROB:
|
||||
if (random() < ((ipfw_insn_u32 *)cmd)->d[0] )
|
||||
goto cmd_match;
|
||||
goto cmd_fail;
|
||||
@ -1720,8 +1806,9 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
is_icmp_query(ip)) &&
|
||||
!(m->m_flags & (M_BCAST|M_MCAST)) &&
|
||||
!IN_MULTICAST(dst_ip.s_addr)) {
|
||||
send_reject(m,cmd->arg1,offset,ip_len);
|
||||
args->m = m = NULL;
|
||||
send_reject(args, cmd->arg1,
|
||||
offset,ip_len);
|
||||
m = args->m;
|
||||
}
|
||||
goto deny;
|
||||
|
||||
@ -1796,20 +1883,6 @@ next_rule:; /* try next rule */
|
||||
return(IP_FW_PORT_DENY_FLAG);
|
||||
}
|
||||
|
||||
#if 0 /* XXX old instructions not implemented yet XXX */
|
||||
bogusfrag:
|
||||
if (fw_verbose) {
|
||||
if (*m != NULL)
|
||||
ipfw_report(NULL, ip, ip_off, ip_len, (*m)->m_pkthdr.rcvif, oif);
|
||||
}
|
||||
return(IP_FW_PORT_DENY_FLAG);
|
||||
|
||||
if (f->fw_ipflg & IP_FW_IF_IPPRE &&
|
||||
(f->fw_iptos & 0xe0) != (ip->ip_tos & 0xe0))
|
||||
continue;
|
||||
|
||||
#endif /* XXX old instructions not implemented yet */
|
||||
|
||||
/*
|
||||
* When a rule is added/deleted, clear the next_rule pointers in all rules.
|
||||
* These will be reconstructed on the fly as packets are matched.
|
||||
@ -2119,6 +2192,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
case O_IPID:
|
||||
case O_IPPRE:
|
||||
case O_IPTOS:
|
||||
case O_IPPRECEDENCE:
|
||||
case O_IPTTL:
|
||||
case O_IPVER:
|
||||
case O_TCPWIN:
|
||||
@ -2203,12 +2277,12 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
goto bad_size;
|
||||
goto check_action;
|
||||
|
||||
case O_FORWARD_IP: /* XXX no! */
|
||||
case O_FORWARD_IP:
|
||||
if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
|
||||
goto bad_size;
|
||||
goto check_action;
|
||||
|
||||
case O_FORWARD_MAC: /* XXX no! */
|
||||
case O_FORWARD_MAC: /* XXX not implemented yet */
|
||||
case O_CHECK_STATE:
|
||||
case O_COUNT:
|
||||
case O_ACCEPT:
|
||||
|
Loading…
Reference in New Issue
Block a user