iptables match模块扩展 数据传递(用户空间 -> 内核空间)

大致过程:

首先,通过iptables命令将使用扩展模块的相关策略添加。例如:iptables -t mangle -A OUTPUT -p icmp -m pktsiz --size 100:200 -j DROP

其次,当接收到网络数据,内核对相关协议(IPV4)相关表(mangle)相关链(OUTPUT)..扩展模块(pktsize)进行匹配,对符合规则的进行相关的动作。

实装过程:

详见:https://blog.csdn.net/sidemap/article/details/103035483

实装内容的数据流程:

1、用户空间数据结构定义

在扩展match模块时,需要对扩展的模块进行数据结构定义。由于该数据结构是被用来封装用户的数据数据,并且在内核中被解析,因此,最好将对该数据结构定义的文件,按照内核中uapi的文件路径结构定义,以便于往内核中引用。

  6 struct
  7 ipt_pktsize_info {
  8     u_int32_t min_pktsize, max_pktsize;
  9 };

2、用户空间的数据是传入到内核中

在用空空间iptables架构中,定义了结构体struct xtables_match(include/xtables.h)的x6_parse(parse为旧版版本)回调函数,将xt_option_call中的data(per-extension kernel data block)指向的内核内存进行数据填充(ipt_packetsize_info)

struct xtables_match

225 struct xtables_match {
226     /*
227      * ABI/API version this module requires. Must be first member,
228      * as the rest of this struct may be subject to ABI changes.
229      */
230     const char *version;
231 
232     struct xtables_match *next;
233 
234     const char *name;
235     const char *real_name;
236 
237     /* Revision of match (0 by default). */
238     uint8_t revision;
239 
240     /* Extension flags */
241     uint8_t ext_flags;
242 
243     uint16_t family;
244 
245     /* Size of match data. */
246     size_t size;
247 
248     /* Size of match data relevant for userspace comparison purposes */
249     size_t userspacesize;
250 
251     /* Function which prints out usage message. */
252     void (*help)(void);
253 
254     /* Initialize the match. */
255     void (*init)(struct xt_entry_match *m);
256 
257     /* Function which parses command options; returns true if it
258            ate an option */
259     /* entry is struct ipt_entry for example */
260     int (*parse)(int c, char **argv, int invert, unsigned int *flags,
261              const void *entry,
262              struct xt_entry_match **match);
263 
264     /* Final check; exit if not ok. */
265     void (*final_check)(unsigned int flags);
266 
267     /* Prints out the match iff non-NULL: put space at end */
268     /* ip is struct ipt_ip * for example */
269     void (*print)(const void *ip,
270               const struct xt_entry_match *match, int numeric);
271 
272     /* Saves the match info in parsable form to stdout. */
273     /* ip is struct ipt_ip * for example */
274     void (*save)(const void *ip, const struct xt_entry_match *match);
275 
276     /* Print match name or alias */
277     const char *(*alias)(const struct xt_entry_match *match);
278 
279     /* Pointer to list of extra command-line options */
280     const struct option *extra_opts;
281 
282     /* New parser */
283     void (*x6_parse)(struct xt_option_call *);
284     void (*x6_fcheck)(struct xt_fcheck_call *);
285     const struct xt_option_entry *x6_options;
286 
287     /* Translate iptables to nft */
288     int (*xlate)(struct xt_xlate *xl,
289              const struct xt_xlate_mt_params *params);
290 
291     /* Size of per-extension instance extra "global" scratch space */
292     size_t udata_size;
293 
294     /* Ignore these men behind the curtain: */
295     void *udata;
296     unsigned int option_offset;
297     struct xt_entry_match *m;
298     unsigned int mflags;
299     unsigned int loaded; /* simulate loading so options are merged properly */
300 };

struct xt_option_call

135 /**
136  * @arg:    input from command line
137  * @ext_name:   name of extension currently being processed
138  * @entry:  current option being processed
139  * @data:   per-extension kernel data block
140  * @xflags: options of the extension that have been used
141  * @invert: whether option was used with !
142  * @nvals:  number of results in uXX_multi
143  * @val:    parsed result
144  * @udata:  per-extension private scratch area
145  *      (cf. xtables_{match,target}->udata_size)
146  */
147 struct xt_option_call {
148     const char *arg, *ext_name;
149     const struct xt_option_entry *entry;
150     void *data;
151     unsigned int xflags;
152     bool invert;
153     uint8_t nvals;
154     union {
155         uint8_t u8, u8_range[2], syslog_level, protocol;
156         uint16_t u16, u16_range[2], port, port_range[2];
157         uint32_t u32, u32_range[2];
158         uint64_t u64, u64_range[2];
159         double dbl;
160         struct {
161             union nf_inet_addr haddr, hmask;
162             uint8_t hlen;
163         };
164         struct {
165             uint8_t tos_value, tos_mask;
166         };
167         struct {
168             uint32_t mark, mask;
169         };
170         uint8_t ethermac[6];
171     } val;
172     /* Wished for a world where the ones below were gone: */
173     union {
174         struct xt_entry_match **match;
175         struct xt_entry_target **target;
176     };
177     void *xt_entry;
178     void *udata;
179 };

3、在内核中接收到iptables发送的数据

在内核中net/ipv4/netfilter/构建module处理扩展模块,构建module使用的数据结构xt_match,构建该对象之后,通过xt_register_match向系统进行注册。

 30 static struct xt_match pktsize_match = {
 31     .name        = "pktsize",
 32     .family      = NFPROTO_IPV4,
 33     .match       = match,
 34     .matchsize   = sizeof(struct ipt_pktsize_info),
 35     .destroy     = NULL,
 36     .me          = THIS_MODULE,
 37 };

xt_match实现(include/linux/netfilter/x_tables.h):

109 struct xt_match {
110     struct list_head list;
111 
112     const char name[XT_EXTENSION_MAXNAMELEN];
113     u_int8_t revision;
114 
115     /* Return true or false: return FALSE and set *hotdrop = 1 to
116            force immediate packet drop. */
117     /* Arguments changed since 2.6.9, as this must now handle
118        non-linear skb, using skb_header_pointer and
119        skb_ip_make_writable. */
120     bool (*match)(const struct sk_buff *skb,
121               struct xt_action_param *);
122 
123     /* Called when user tries to insert an entry of this type. */
124     int (*checkentry)(const struct xt_mtchk_param *);
125 
126     /* Called when entry of this type deleted. */
127     void (*destroy)(const struct xt_mtdtor_param *);
128 #ifdef CONFIG_COMPAT
129     /* Called when userspace align differs from kernel space one */
130     void (*compat_from_user)(void *dst, const void *src);
131     int (*compat_to_user)(void __user *dst, const void *src);
132 #endif
133     /* Set this to THIS_MODULE if you are a module, otherwise NULL */
134     struct module *me;
135 
136     const char *table;
137     unsigned int matchsize;
138 #ifdef CONFIG_COMPAT
139     unsigned int compatsize;
140 #endif
141     unsigned int hooks;
142     unsigned short proto;
143 
144     unsigned short family;
145 };

在其中的match函数xt_action_param会得到到通过用户空间iptables设置的数据(ipt_packetsize_info  100:200),其中 xt_action_param定义(也在include/linux/netfilt/x_table.h):

  9 /**
 10  * struct xt_action_param - parameters for matches/targets
 11  *
 12  * @match:  the match extension
 13  * @target: the target extension
 14  * @matchinfo:  per-match data
 15  * @targetinfo: per-target data
 16  * @net     network namespace through which the action was invoked
 17  * @in:     input netdevice
 18  * @out:    output netdevice
 19  * @fragoff:    packet is a fragment, this is the data offset
 20  * @thoff:  position of transport header relative to skb->data
 21  * @hook:   hook number given packet came from
 22  * @family: Actual NFPROTO_* through which the function is invoked
 23  *      (helpful when match->family == NFPROTO_UNSPEC)
 24  *
 25  * Fields written to by extensions:
 26  *
 27  * @hotdrop:    drop packet if we had inspection problems
 28  */
 29 struct xt_action_param {
 30     union {
 31         const struct xt_match *match;
 32         const struct xt_target *target;
 33     };
 34     union {
 35         const void *matchinfo, *targinfo;
 36     };
 37     struct net *net;
 38     const struct net_device *in, *out;
 39     int fragoff;
 40     unsigned int thoff;
 41     unsigned int hooknum;
 42     u_int8_t family;
 43     bool hotdrop;
 44 };

对于扩展match,设置的信息(ipt_pktsize_info)位于matchinfo中。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值