- 论坛徽章:
- 0
|
itpables trick
以下讨论仅针对v1.3.5
1. 在同一个规则里的不同match的option不能重名
例如以下规则有问题
-m match1 --opt 1 -m match2 --opt 2
(无论match1和match2是相同的match还是不同的match)
原因:
0) 所有的-m参数都会触发merge_options操作
其主要工作是构造一个新的供getopt_long使用的选项列表
1) 扫描到-m match1,merge_options,--opt加到列表中
2) 扫描到--opt 1,match1的opt被正确的处理
3) 扫描到-m match2,merget_optpions,--opt再次被加到列表中
4) 扫描到--opt 2,依赖于getopt_long的实现,match1的参数处理函数被调用,与期望不同
2. 在同一个规则里不能有同一个match的两个实例
例如以下规则有问题
-m match --opta -m match --optb
(假设match支持opta和optb两个参数)
原因:还是跟merge_options有关
1) 两个-m对应同一个iptables_match(M),但是对应不同的ipt_entry_match(m1/m2)(类比类和对象)
2) iptables在遇到一个新的-m的时候(意味着前面的match处理完毕)不会去释放前面的match的信息
这样是为了优化iptables-restore,因为同一个match可以出现在多个规则中
3) 小小的跑一下题 
从match的角度,每个支持的option都有个编号,例如match1把opt1编号1,opt2编号2,
(用于match->parse,通常有一个关于编号的switch,不同选项不同处理),
但match2同样会把opt3编号1,opt4编号2,那如何区分不同match的相同编号呢?
merge_options通过编号偏移解决了这个问题,
把match1的opt1和opt2的编号重新定义为257和258(偏移256),
把match2的opt3和opt4的编号重新定义为513和514(偏移512),
具体偏移是多少取决于match在规则中出现的顺序,每个match有256大小的编号空间
该偏移值记在M上,调用M->parse的使用会减去偏移,
例如--opt3会被识别为514,调用match2->parse的时候会变为514-512=2,跟match2的期待相同
PS:为什么--opt3不会被match1识别
实际上,--opt3会导致所有的match的parse都会被调用,
调用match1->parse的时候,但由于match1的偏移为256,
传递的编号为514-256=258,并不满足match1的期待(只期待1或者2)
4)跑题结束... 问题的关键在于偏移被记在了M上,而不是m1和m2上
4.1) 扫描-m match, M->offset=256, opta和optb的编号为257和258
4.2) 扫描--opta,编号257, 调用M->parse(257-256=1),没有问题
4.3) 扫描-m match, M->offset=512(原有值被覆盖了),第二份opta和optb编号为513和514
4.4) 扫描--optb,编号258(getopt忽略重复的选项),调用M->parse(258-512=-254),
-254换成无符号是个很大的数,不是match所期望的选项
【未完待续】 |
|