Implement an ipfw action to reassemble ip packets: reass.
This commit is contained in:
parent
8b61c10e48
commit
eb2e411915
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=190633
@ -866,6 +866,13 @@ in any subsequent forwarding decisions.
|
||||
Initially this is limited to the values 0 through 15, see
|
||||
.Xr setfib 8 .
|
||||
Processing continues at the next rule.
|
||||
.It Cm reass
|
||||
Queue and reassemble ip fragments.
|
||||
If the packet is not fragmented, counters are updated and processing continues with the next rule.
|
||||
If the packet is the last logical fragment, the packet is reassembled and, if
|
||||
.Va net.inet.ip.fw.one_pass
|
||||
is set to 0, processing continues with the next rule, else packet is allowed to pass and search terminates.
|
||||
If the packet is a fragment in the middle, it is consumed and processing stops immediately.
|
||||
.El
|
||||
.Ss RULE BODY
|
||||
The body of a rule contains zero or more patterns (such as
|
||||
|
@ -211,6 +211,7 @@ static struct _s_x rule_actions[] = {
|
||||
{ "check-state", TOK_CHECKSTATE },
|
||||
{ "//", TOK_COMMENT },
|
||||
{ "nat", TOK_NAT },
|
||||
{ "reass", TOK_REASS },
|
||||
{ "setfib", TOK_SETFIB },
|
||||
{ NULL, 0 } /* terminator */
|
||||
};
|
||||
@ -1089,6 +1090,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
case O_SETFIB:
|
||||
PRINT_UINT_ARG("setfib ", cmd->arg1);
|
||||
break;
|
||||
|
||||
case O_REASS:
|
||||
printf("reass");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("** unrecognized action %d len %d ",
|
||||
@ -2781,6 +2786,10 @@ ipfw_add(int ac, char *av[])
|
||||
ac--; av++;
|
||||
break;
|
||||
}
|
||||
|
||||
case TOK_REASS:
|
||||
action->opcode = O_REASS;
|
||||
break;
|
||||
|
||||
default:
|
||||
errx(EX_DATAERR, "invalid action %s\n", av[-1]);
|
||||
|
@ -95,6 +95,7 @@ enum tokens {
|
||||
TOK_UNREACH,
|
||||
TOK_CHECKSTATE,
|
||||
TOK_NAT,
|
||||
TOK_REASS,
|
||||
|
||||
TOK_ALTQ,
|
||||
TOK_LOG,
|
||||
|
@ -54,7 +54,7 @@ help(void)
|
||||
"RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n"
|
||||
"ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n"
|
||||
" skipto N | {divert|tee} PORT | forward ADDR |\n"
|
||||
" pipe N | queue N | nat N | setfib FIB\n"
|
||||
" pipe N | queue N | nat N | setfib FIB | reass\n"
|
||||
"PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n"
|
||||
"ADDR: [ MAC dst src ether_type ] \n"
|
||||
" [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
|
||||
|
@ -139,7 +139,8 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
O_FORWARD_IP, /* fwd sockaddr */
|
||||
O_FORWARD_MAC, /* fwd mac */
|
||||
O_NAT, /* nope */
|
||||
|
||||
O_REASS, /* none */
|
||||
|
||||
/*
|
||||
* More opcodes.
|
||||
*/
|
||||
@ -574,6 +575,7 @@ enum {
|
||||
IP_FW_NETGRAPH,
|
||||
IP_FW_NGTEE,
|
||||
IP_FW_NAT,
|
||||
IP_FW_REASS,
|
||||
};
|
||||
|
||||
/* flags for divert mtag */
|
||||
|
@ -898,6 +898,9 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
|
||||
case O_NAT:
|
||||
action = "Nat";
|
||||
break;
|
||||
case O_REASS:
|
||||
action = "Reass";
|
||||
break;
|
||||
default:
|
||||
action = "UNKNOWN";
|
||||
break;
|
||||
@ -3375,6 +3378,55 @@ do { \
|
||||
goto done;
|
||||
}
|
||||
|
||||
case O_REASS: {
|
||||
int ip_off;
|
||||
|
||||
f->pcnt++;
|
||||
f->bcnt += pktlen;
|
||||
ip_off = (args->eh != NULL) ? ntohs(ip->ip_off) : ip->ip_off;
|
||||
if (ip_off & (IP_MF | IP_OFFMASK)) {
|
||||
/*
|
||||
* ip_reass() expects len & off in host
|
||||
* byte order: fix them in case we come
|
||||
* from layer2.
|
||||
*/
|
||||
if (args->eh != NULL) {
|
||||
ip->ip_len = ntohs(ip->ip_len);
|
||||
ip->ip_off = ntohs(ip->ip_off);
|
||||
}
|
||||
|
||||
m = ip_reass(m);
|
||||
args->m = m;
|
||||
|
||||
/*
|
||||
* IP header checksum fixup after
|
||||
* reassembly and leave header
|
||||
* in network byte order.
|
||||
*/
|
||||
if (m != NULL) {
|
||||
int hlen;
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
hlen = ip->ip_hl << 2;
|
||||
/* revert len & off for layer2 pkts */
|
||||
if (args->eh != NULL)
|
||||
ip->ip_len = htons(ip->ip_len);
|
||||
ip->ip_sum = 0;
|
||||
if (hlen == sizeof(struct ip))
|
||||
ip->ip_sum = in_cksum_hdr(ip);
|
||||
else
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
retval = IP_FW_REASS;
|
||||
args->rule = f;
|
||||
goto done;
|
||||
} else {
|
||||
retval = IP_FW_DENY;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
goto next_rule;
|
||||
}
|
||||
|
||||
default:
|
||||
panic("-- unknown opcode %d\n", cmd->opcode);
|
||||
} /* end of switch() on opcodes */
|
||||
@ -4024,6 +4076,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
case O_UNREACH6:
|
||||
#endif
|
||||
case O_SKIPTO:
|
||||
case O_REASS:
|
||||
check_size:
|
||||
if (cmdlen != F_INSN_SIZE(ipfw_insn))
|
||||
goto bad_size;
|
||||
|
@ -200,6 +200,9 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
|
||||
case IP_FW_NAT:
|
||||
goto again; /* continue with packet */
|
||||
|
||||
case IP_FW_REASS:
|
||||
goto again;
|
||||
|
||||
default:
|
||||
KASSERT(0, ("%s: unknown retval", __func__));
|
||||
}
|
||||
@ -329,6 +332,9 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
|
||||
case IP_FW_NAT:
|
||||
goto again; /* continue with packet */
|
||||
|
||||
case IP_FW_REASS:
|
||||
goto again;
|
||||
|
||||
default:
|
||||
KASSERT(0, ("%s: unknown retval", __func__));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user