diff options
author | Stephen Suryaputra <ssuryaextr@gmail.com> | 2019-07-03 20:30:52 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-04 14:29:08 +0200 |
commit | 226a0e072d5c1edeb53cb61b959b011168c5c29a (patch) | |
tree | 07e43268efe15dc8b64b8ca9baca71e02239213f /src/exthdr.c | |
parent | 1694c01c30fba06461ca82ede070bf6a9cd9a4db (diff) |
exthdr: add support for matching IPv4 options
Add capability to have rules matching IPv4 options. This is developed
mainly to support dropping of IP packets with loose and/or strict source
route route options.
Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/exthdr.c')
-rw-r--r-- | src/exthdr.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/exthdr.c b/src/exthdr.c index c9c2bf50..e1ec6f3d 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -38,6 +38,11 @@ static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx) if (offset) nft_print(octx, "%d", offset); nft_print(octx, " %s", expr->exthdr.tmpl->token); + } else if (expr->exthdr.op == NFT_EXTHDR_OP_IPV4) { + nft_print(octx, "ip option %s", expr->exthdr.desc->name); + if (expr->exthdr.flags & NFT_EXTHDR_F_PRESENT) + return; + nft_print(octx, " %s", expr->exthdr.tmpl->token); } else { if (expr->exthdr.flags & NFT_EXTHDR_F_PRESENT) nft_print(octx, "exthdr %s", expr->exthdr.desc->name); @@ -172,6 +177,8 @@ void exthdr_init_raw(struct expr *expr, uint8_t type, assert(expr->etype == EXPR_EXTHDR); if (op == NFT_EXTHDR_OP_TCPOPT) return tcpopt_init_raw(expr, type, offset, len, flags); + if (op == NFT_EXTHDR_OP_IPV4) + return ipopt_init_raw(expr, type, offset, len, flags, true); expr->len = len; expr->exthdr.flags = flags; @@ -222,7 +229,8 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i { unsigned int off, mask_offset, mask_len; - if (expr->exthdr.tmpl != &exthdr_unknown_template) + if (expr->exthdr.op != NFT_EXTHDR_OP_IPV4 && + expr->exthdr.tmpl != &exthdr_unknown_template) return false; /* In case we are handling tcp options instead of the default ipv6 @@ -237,8 +245,18 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i off = expr->exthdr.offset; off += round_up(mask->len, BITS_PER_BYTE) - mask_len; + /* Handle ip options after the offset and mask have been calculated. */ + if (expr->exthdr.op == NFT_EXTHDR_OP_IPV4) { + if (ipopt_find_template(expr, off, mask_len - mask_offset)) { + *shift = mask_offset; + return true; + } else { + return false; + } + } + exthdr_init_raw(expr, expr->exthdr.desc->type, - off, mask_len - mask_offset, NFT_EXTHDR_OP_IPV6, 0); + off, mask_len - mask_offset, expr->exthdr.op, 0); /* still failed to find a template... Bug. */ if (expr->exthdr.tmpl == &exthdr_unknown_template) |