Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -Nur a/include/uapi/linux/netfilter/xt_connmark.h b/include/uapi/linux/netfilter/xt_connmark.h
- --- a/include/uapi/linux/netfilter/xt_connmark.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter/xt_connmark.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,31 @@
- +#ifndef _XT_CONNMARK_H
- +#define _XT_CONNMARK_H
- +
- +#include <linux/types.h>
- +
- +/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- + * by Henrik Nordstrom <hno@marasystems.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +enum {
- + XT_CONNMARK_SET = 0,
- + XT_CONNMARK_SAVE,
- + XT_CONNMARK_RESTORE
- +};
- +
- +struct xt_connmark_tginfo1 {
- + __u32 ctmark, ctmask, nfmask;
- + __u8 mode;
- +};
- +
- +struct xt_connmark_mtinfo1 {
- + __u32 mark, mask;
- + __u8 invert;
- +};
- +
- +#endif /*_XT_CONNMARK_H*/
- diff -Nur a/include/uapi/linux/netfilter/xt_dscp.h b/include/uapi/linux/netfilter/xt_dscp.h
- --- a/include/uapi/linux/netfilter/xt_dscp.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter/xt_dscp.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,31 @@
- +/* x_tables module for matching the IPv4/IPv6 DSCP field
- + *
- + * (C) 2002 Harald Welte <laforge@gnumonks.org>
- + * This software is distributed under GNU GPL v2, 1991
- + *
- + * See RFC2474 for a description of the DSCP field within the IP Header.
- + *
- + * xt_dscp.h,v 1.3 2002/08/05 19:00:21 laforge Exp
- +*/
- +#ifndef _XT_DSCP_H
- +#define _XT_DSCP_H
- +
- +#include <linux/types.h>
- +
- +#define XT_DSCP_MASK 0xfc /* 11111100 */
- +#define XT_DSCP_SHIFT 2
- +#define XT_DSCP_MAX 0x3f /* 00111111 */
- +
- +/* match info */
- +struct xt_dscp_info {
- + __u8 dscp;
- + __u8 invert;
- +};
- +
- +struct xt_tos_match_info {
- + __u8 tos_mask;
- + __u8 tos_value;
- + __u8 invert;
- +};
- +
- +#endif /* _XT_DSCP_H */
- diff -Nur a/include/uapi/linux/netfilter/xt_mark.h b/include/uapi/linux/netfilter/xt_mark.h
- --- a/include/uapi/linux/netfilter/xt_mark.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter/xt_mark.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,15 @@
- +#ifndef _XT_MARK_H
- +#define _XT_MARK_H
- +
- +#include <linux/types.h>
- +
- +struct xt_mark_tginfo2 {
- + __u32 mark, mask;
- +};
- +
- +struct xt_mark_mtinfo1 {
- + __u32 mark, mask;
- + __u8 invert;
- +};
- +
- +#endif /*_XT_MARK_H*/
- diff -Nur a/include/uapi/linux/netfilter/xt_rateest.h b/include/uapi/linux/netfilter/xt_rateest.h
- --- a/include/uapi/linux/netfilter/xt_rateest.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter/xt_rateest.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,38 @@
- +#ifndef _XT_RATEEST_MATCH_H
- +#define _XT_RATEEST_MATCH_H
- +
- +#include <linux/types.h>
- +#include <linux/if.h>
- +
- +enum xt_rateest_match_flags {
- + XT_RATEEST_MATCH_INVERT = 1<<0,
- + XT_RATEEST_MATCH_ABS = 1<<1,
- + XT_RATEEST_MATCH_REL = 1<<2,
- + XT_RATEEST_MATCH_DELTA = 1<<3,
- + XT_RATEEST_MATCH_BPS = 1<<4,
- + XT_RATEEST_MATCH_PPS = 1<<5,
- +};
- +
- +enum xt_rateest_match_mode {
- + XT_RATEEST_MATCH_NONE,
- + XT_RATEEST_MATCH_EQ,
- + XT_RATEEST_MATCH_LT,
- + XT_RATEEST_MATCH_GT,
- +};
- +
- +struct xt_rateest_match_info {
- + char name1[IFNAMSIZ];
- + char name2[IFNAMSIZ];
- + __u16 flags;
- + __u16 mode;
- + __u32 bps1;
- + __u32 pps1;
- + __u32 bps2;
- + __u32 pps2;
- +
- + /* Used internally by the kernel */
- + struct xt_rateest *est1 __attribute__((aligned(8)));
- + struct xt_rateest *est2 __attribute__((aligned(8)));
- +};
- +
- +#endif /* _XT_RATEEST_MATCH_H */
- diff -Nur a/include/uapi/linux/netfilter/xt_tcpmss.h b/include/uapi/linux/netfilter/xt_tcpmss.h
- --- a/include/uapi/linux/netfilter/xt_tcpmss.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter/xt_tcpmss.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,11 @@
- +#ifndef _XT_TCPMSS_MATCH_H
- +#define _XT_TCPMSS_MATCH_H
- +
- +#include <linux/types.h>
- +
- +struct xt_tcpmss_match_info {
- + __u16 mss_min, mss_max;
- + __u8 invert;
- +};
- +
- +#endif /*_XT_TCPMSS_MATCH_H*/
- diff -Nur a/include/uapi/linux/netfilter_ipv4/ipt_ecn.h b/include/uapi/linux/netfilter_ipv4/ipt_ecn.h
- --- a/include/uapi/linux/netfilter_ipv4/ipt_ecn.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter_ipv4/ipt_ecn.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,15 @@
- +#ifndef _IPT_ECN_H
- +#define _IPT_ECN_H
- +
- +#include <linux/netfilter/xt_ecn.h>
- +#define ipt_ecn_info xt_ecn_info
- +
- +enum {
- + IPT_ECN_IP_MASK = XT_ECN_IP_MASK,
- + IPT_ECN_OP_MATCH_IP = XT_ECN_OP_MATCH_IP,
- + IPT_ECN_OP_MATCH_ECE = XT_ECN_OP_MATCH_ECE,
- + IPT_ECN_OP_MATCH_CWR = XT_ECN_OP_MATCH_CWR,
- + IPT_ECN_OP_MATCH_MASK = XT_ECN_OP_MATCH_MASK,
- +};
- +
- +#endif /* IPT_ECN_H */
- diff -Nur a/include/uapi/linux/netfilter_ipv4/ipt_ttl.h b/include/uapi/linux/netfilter_ipv4/ipt_ttl.h
- --- a/include/uapi/linux/netfilter_ipv4/ipt_ttl.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter_ipv4/ipt_ttl.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,23 @@
- +/* IP tables module for matching the value of the TTL
- + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
- +
- +#ifndef _IPT_TTL_H
- +#define _IPT_TTL_H
- +
- +#include <linux/types.h>
- +
- +enum {
- + IPT_TTL_EQ = 0, /* equals */
- + IPT_TTL_NE, /* not equals */
- + IPT_TTL_LT, /* less than */
- + IPT_TTL_GT, /* greater than */
- +};
- +
- +
- +struct ipt_ttl_info {
- + __u8 mode;
- + __u8 ttl;
- +};
- +
- +
- +#endif
- diff -Nur a/include/uapi/linux/netfilter_ipv6/ip6t_hl.h b/include/uapi/linux/netfilter_ipv6/ip6t_hl.h
- --- a/include/uapi/linux/netfilter_ipv6/ip6t_hl.h 1970-01-01 02:00:00.000000000 +0200
- +++ b/include/uapi/linux/netfilter_ipv6/ip6t_hl.h 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,24 @@
- +/* ip6tables module for matching the Hop Limit value
- + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
- + * Based on HW's ttl module */
- +
- +#ifndef _IP6T_HL_H
- +#define _IP6T_HL_H
- +
- +#include <linux/types.h>
- +
- +enum {
- + IP6T_HL_EQ = 0, /* equals */
- + IP6T_HL_NE, /* not equals */
- + IP6T_HL_LT, /* less than */
- + IP6T_HL_GT, /* greater than */
- +};
- +
- +
- +struct ip6t_hl_info {
- + __u8 mode;
- + __u8 hop_limit;
- +};
- +
- +
- +#endif
- diff -Nur a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
- --- a/net/netfilter/xt_dscp.c 1970-01-01 02:00:00.000000000 +0200
- +++ b/net/netfilter/xt_dscp.c 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,115 @@
- +/* IP tables module for matching the value of the IPv4/IPv6 DSCP field
- + *
- + * (C) 2002 by Harald Welte <laforge@netfilter.org>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- +#include <linux/module.h>
- +#include <linux/skbuff.h>
- +#include <linux/ip.h>
- +#include <linux/ipv6.h>
- +#include <net/dsfield.h>
- +
- +#include <linux/netfilter/x_tables.h>
- +#include <linux/netfilter/xt_dscp.h>
- +
- +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
- +MODULE_DESCRIPTION("Xtables: DSCP/TOS field match");
- +MODULE_LICENSE("GPL");
- +MODULE_ALIAS("ipt_dscp");
- +MODULE_ALIAS("ip6t_dscp");
- +MODULE_ALIAS("ipt_tos");
- +MODULE_ALIAS("ip6t_tos");
- +
- +static bool
- +dscp_mt(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct xt_dscp_info *info = par->matchinfo;
- + u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
- +
- + return (dscp == info->dscp) ^ !!info->invert;
- +}
- +
- +static bool
- +dscp_mt6(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct xt_dscp_info *info = par->matchinfo;
- + u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
- +
- + return (dscp == info->dscp) ^ !!info->invert;
- +}
- +
- +static int dscp_mt_check(const struct xt_mtchk_param *par)
- +{
- + const struct xt_dscp_info *info = par->matchinfo;
- +
- + if (info->dscp > XT_DSCP_MAX) {
- + pr_info("dscp %x out of range\n", info->dscp);
- + return -EDOM;
- + }
- +
- + return 0;
- +}
- +
- +static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct xt_tos_match_info *info = par->matchinfo;
- +
- + if (par->family == NFPROTO_IPV4)
- + return ((ip_hdr(skb)->tos & info->tos_mask) ==
- + info->tos_value) ^ !!info->invert;
- + else
- + return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) ==
- + info->tos_value) ^ !!info->invert;
- +}
- +
- +static struct xt_match dscp_mt_reg[] __read_mostly = {
- + {
- + .name = "dscp",
- + .family = NFPROTO_IPV4,
- + .checkentry = dscp_mt_check,
- + .match = dscp_mt,
- + .matchsize = sizeof(struct xt_dscp_info),
- + .me = THIS_MODULE,
- + },
- + {
- + .name = "dscp",
- + .family = NFPROTO_IPV6,
- + .checkentry = dscp_mt_check,
- + .match = dscp_mt6,
- + .matchsize = sizeof(struct xt_dscp_info),
- + .me = THIS_MODULE,
- + },
- + {
- + .name = "tos",
- + .revision = 1,
- + .family = NFPROTO_IPV4,
- + .match = tos_mt,
- + .matchsize = sizeof(struct xt_tos_match_info),
- + .me = THIS_MODULE,
- + },
- + {
- + .name = "tos",
- + .revision = 1,
- + .family = NFPROTO_IPV6,
- + .match = tos_mt,
- + .matchsize = sizeof(struct xt_tos_match_info),
- + .me = THIS_MODULE,
- + },
- +};
- +
- +static int __init dscp_mt_init(void)
- +{
- + return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg));
- +}
- +
- +static void __exit dscp_mt_exit(void)
- +{
- + xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg));
- +}
- +
- +module_init(dscp_mt_init);
- +module_exit(dscp_mt_exit);
- diff -Nur a/net/netfilter/xt_hl.c b/net/netfilter/xt_hl.c
- --- a/net/netfilter/xt_hl.c 1970-01-01 02:00:00.000000000 +0200
- +++ b/net/netfilter/xt_hl.c 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,96 @@
- +/*
- + * IP tables module for matching the value of the TTL
- + * (C) 2000,2001 by Harald Welte <laforge@netfilter.org>
- + *
- + * Hop Limit matching module
- + * (C) 2001-2002 Maciej Soltysiak <solt@dns.toxicfilms.tv>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/ip.h>
- +#include <linux/ipv6.h>
- +#include <linux/module.h>
- +#include <linux/skbuff.h>
- +
- +#include <linux/netfilter/x_tables.h>
- +#include <linux/netfilter_ipv4/ipt_ttl.h>
- +#include <linux/netfilter_ipv6/ip6t_hl.h>
- +
- +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
- +MODULE_DESCRIPTION("Xtables: Hoplimit/TTL field match");
- +MODULE_LICENSE("GPL");
- +MODULE_ALIAS("ipt_ttl");
- +MODULE_ALIAS("ip6t_hl");
- +
- +static bool ttl_mt(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct ipt_ttl_info *info = par->matchinfo;
- + const u8 ttl = ip_hdr(skb)->ttl;
- +
- + switch (info->mode) {
- + case IPT_TTL_EQ:
- + return ttl == info->ttl;
- + case IPT_TTL_NE:
- + return ttl != info->ttl;
- + case IPT_TTL_LT:
- + return ttl < info->ttl;
- + case IPT_TTL_GT:
- + return ttl > info->ttl;
- + }
- +
- + return false;
- +}
- +
- +static bool hl_mt6(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct ip6t_hl_info *info = par->matchinfo;
- + const struct ipv6hdr *ip6h = ipv6_hdr(skb);
- +
- + switch (info->mode) {
- + case IP6T_HL_EQ:
- + return ip6h->hop_limit == info->hop_limit;
- + case IP6T_HL_NE:
- + return ip6h->hop_limit != info->hop_limit;
- + case IP6T_HL_LT:
- + return ip6h->hop_limit < info->hop_limit;
- + case IP6T_HL_GT:
- + return ip6h->hop_limit > info->hop_limit;
- + }
- +
- + return false;
- +}
- +
- +static struct xt_match hl_mt_reg[] __read_mostly = {
- + {
- + .name = "ttl",
- + .revision = 0,
- + .family = NFPROTO_IPV4,
- + .match = ttl_mt,
- + .matchsize = sizeof(struct ipt_ttl_info),
- + .me = THIS_MODULE,
- + },
- + {
- + .name = "hl",
- + .revision = 0,
- + .family = NFPROTO_IPV6,
- + .match = hl_mt6,
- + .matchsize = sizeof(struct ip6t_hl_info),
- + .me = THIS_MODULE,
- + },
- +};
- +
- +static int __init hl_mt_init(void)
- +{
- + return xt_register_matches(hl_mt_reg, ARRAY_SIZE(hl_mt_reg));
- +}
- +
- +static void __exit hl_mt_exit(void)
- +{
- + xt_unregister_matches(hl_mt_reg, ARRAY_SIZE(hl_mt_reg));
- +}
- +
- +module_init(hl_mt_init);
- +module_exit(hl_mt_exit);
- diff -Nur a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
- --- a/net/netfilter/xt_rateest.c 1970-01-01 02:00:00.000000000 +0200
- +++ b/net/netfilter/xt_rateest.c 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,157 @@
- +/*
- + * (C) 2007 Patrick McHardy <kaber@trash.net>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +#include <linux/module.h>
- +#include <linux/skbuff.h>
- +#include <linux/gen_stats.h>
- +
- +#include <linux/netfilter/x_tables.h>
- +#include <linux/netfilter/xt_rateest.h>
- +#include <net/netfilter/xt_rateest.h>
- +
- +
- +static bool
- +xt_rateest_mt(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct xt_rateest_match_info *info = par->matchinfo;
- + struct gnet_stats_rate_est64 *r;
- + u_int32_t bps1, bps2, pps1, pps2;
- + bool ret = true;
- +
- + spin_lock_bh(&info->est1->lock);
- + r = &info->est1->rstats;
- + if (info->flags & XT_RATEEST_MATCH_DELTA) {
- + bps1 = info->bps1 >= r->bps ? info->bps1 - r->bps : 0;
- + pps1 = info->pps1 >= r->pps ? info->pps1 - r->pps : 0;
- + } else {
- + bps1 = r->bps;
- + pps1 = r->pps;
- + }
- + spin_unlock_bh(&info->est1->lock);
- +
- + if (info->flags & XT_RATEEST_MATCH_ABS) {
- + bps2 = info->bps2;
- + pps2 = info->pps2;
- + } else {
- + spin_lock_bh(&info->est2->lock);
- + r = &info->est2->rstats;
- + if (info->flags & XT_RATEEST_MATCH_DELTA) {
- + bps2 = info->bps2 >= r->bps ? info->bps2 - r->bps : 0;
- + pps2 = info->pps2 >= r->pps ? info->pps2 - r->pps : 0;
- + } else {
- + bps2 = r->bps;
- + pps2 = r->pps;
- + }
- + spin_unlock_bh(&info->est2->lock);
- + }
- +
- + switch (info->mode) {
- + case XT_RATEEST_MATCH_LT:
- + if (info->flags & XT_RATEEST_MATCH_BPS)
- + ret &= bps1 < bps2;
- + if (info->flags & XT_RATEEST_MATCH_PPS)
- + ret &= pps1 < pps2;
- + break;
- + case XT_RATEEST_MATCH_GT:
- + if (info->flags & XT_RATEEST_MATCH_BPS)
- + ret &= bps1 > bps2;
- + if (info->flags & XT_RATEEST_MATCH_PPS)
- + ret &= pps1 > pps2;
- + break;
- + case XT_RATEEST_MATCH_EQ:
- + if (info->flags & XT_RATEEST_MATCH_BPS)
- + ret &= bps1 == bps2;
- + if (info->flags & XT_RATEEST_MATCH_PPS)
- + ret &= pps1 == pps2;
- + break;
- + }
- +
- + ret ^= info->flags & XT_RATEEST_MATCH_INVERT ? true : false;
- + return ret;
- +}
- +
- +static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
- +{
- + struct xt_rateest_match_info *info = par->matchinfo;
- + struct xt_rateest *est1, *est2;
- + int ret = -EINVAL;
- +
- + if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
- + XT_RATEEST_MATCH_REL)) != 1)
- + goto err1;
- +
- + if (!(info->flags & (XT_RATEEST_MATCH_BPS | XT_RATEEST_MATCH_PPS)))
- + goto err1;
- +
- + switch (info->mode) {
- + case XT_RATEEST_MATCH_EQ:
- + case XT_RATEEST_MATCH_LT:
- + case XT_RATEEST_MATCH_GT:
- + break;
- + default:
- + goto err1;
- + }
- +
- + ret = -ENOENT;
- + est1 = xt_rateest_lookup(info->name1);
- + if (!est1)
- + goto err1;
- +
- + est2 = NULL;
- + if (info->flags & XT_RATEEST_MATCH_REL) {
- + est2 = xt_rateest_lookup(info->name2);
- + if (!est2)
- + goto err2;
- + }
- +
- + info->est1 = est1;
- + info->est2 = est2;
- + return 0;
- +
- +err2:
- + xt_rateest_put(est1);
- +err1:
- + return ret;
- +}
- +
- +static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par)
- +{
- + struct xt_rateest_match_info *info = par->matchinfo;
- +
- + xt_rateest_put(info->est1);
- + if (info->est2)
- + xt_rateest_put(info->est2);
- +}
- +
- +static struct xt_match xt_rateest_mt_reg __read_mostly = {
- + .name = "rateest",
- + .revision = 0,
- + .family = NFPROTO_UNSPEC,
- + .match = xt_rateest_mt,
- + .checkentry = xt_rateest_mt_checkentry,
- + .destroy = xt_rateest_mt_destroy,
- + .matchsize = sizeof(struct xt_rateest_match_info),
- + .me = THIS_MODULE,
- +};
- +
- +static int __init xt_rateest_mt_init(void)
- +{
- + return xt_register_match(&xt_rateest_mt_reg);
- +}
- +
- +static void __exit xt_rateest_mt_fini(void)
- +{
- + xt_unregister_match(&xt_rateest_mt_reg);
- +}
- +
- +MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
- +MODULE_LICENSE("GPL");
- +MODULE_DESCRIPTION("xtables rate estimator match");
- +MODULE_ALIAS("ipt_rateest");
- +MODULE_ALIAS("ip6t_rateest");
- +module_init(xt_rateest_mt_init);
- +module_exit(xt_rateest_mt_fini);
- diff -Nur a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
- --- a/net/netfilter/xt_tcpmss.c 1970-01-01 02:00:00.000000000 +0200
- +++ b/net/netfilter/xt_tcpmss.c 2017-01-09 19:37:16.000000000 +0200
- @@ -0,0 +1,110 @@
- +/* Kernel module to match TCP MSS values. */
- +
- +/* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca>
- + * Portions (C) 2005 by Harald Welte <laforge@netfilter.org>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/module.h>
- +#include <linux/skbuff.h>
- +#include <net/tcp.h>
- +
- +#include <linux/netfilter/xt_tcpmss.h>
- +#include <linux/netfilter/x_tables.h>
- +
- +#include <linux/netfilter_ipv4/ip_tables.h>
- +#include <linux/netfilter_ipv6/ip6_tables.h>
- +
- +MODULE_LICENSE("GPL");
- +MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
- +MODULE_DESCRIPTION("Xtables: TCP MSS match");
- +MODULE_ALIAS("ipt_tcpmss");
- +MODULE_ALIAS("ip6t_tcpmss");
- +
- +static bool
- +tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)
- +{
- + const struct xt_tcpmss_match_info *info = par->matchinfo;
- + const struct tcphdr *th;
- + struct tcphdr _tcph;
- + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
- + const u_int8_t *op;
- + u8 _opt[15 * 4 - sizeof(_tcph)];
- + unsigned int i, optlen;
- +
- + /* If we don't have the whole header, drop packet. */
- + th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
- + if (th == NULL)
- + goto dropit;
- +
- + /* Malformed. */
- + if (th->doff*4 < sizeof(*th))
- + goto dropit;
- +
- + optlen = th->doff*4 - sizeof(*th);
- + if (!optlen)
- + goto out;
- +
- + /* Truncated options. */
- + op = skb_header_pointer(skb, par->thoff + sizeof(*th), optlen, _opt);
- + if (op == NULL)
- + goto dropit;
- +
- + for (i = 0; i < optlen; ) {
- + if (op[i] == TCPOPT_MSS
- + && (optlen - i) >= TCPOLEN_MSS
- + && op[i+1] == TCPOLEN_MSS) {
- + u_int16_t mssval;
- +
- + mssval = (op[i+2] << 8) | op[i+3];
- +
- + return (mssval >= info->mss_min &&
- + mssval <= info->mss_max) ^ info->invert;
- + }
- + if (op[i] < 2)
- + i++;
- + else
- + i += op[i+1] ? : 1;
- + }
- +out:
- + return info->invert;
- +
- +dropit:
- + par->hotdrop = true;
- + return false;
- +}
- +
- +static struct xt_match tcpmss_mt_reg[] __read_mostly = {
- + {
- + .name = "tcpmss",
- + .family = NFPROTO_IPV4,
- + .match = tcpmss_mt,
- + .matchsize = sizeof(struct xt_tcpmss_match_info),
- + .proto = IPPROTO_TCP,
- + .me = THIS_MODULE,
- + },
- + {
- + .name = "tcpmss",
- + .family = NFPROTO_IPV6,
- + .match = tcpmss_mt,
- + .matchsize = sizeof(struct xt_tcpmss_match_info),
- + .proto = IPPROTO_TCP,
- + .me = THIS_MODULE,
- + },
- +};
- +
- +static int __init tcpmss_mt_init(void)
- +{
- + return xt_register_matches(tcpmss_mt_reg, ARRAY_SIZE(tcpmss_mt_reg));
- +}
- +
- +static void __exit tcpmss_mt_exit(void)
- +{
- + xt_unregister_matches(tcpmss_mt_reg, ARRAY_SIZE(tcpmss_mt_reg));
- +}
- +
- +module_init(tcpmss_mt_init);
- +module_exit(tcpmss_mt_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement