iptables 流程分析

iptables 流程分析(ip6tables同理)

  iptables 作为接口开机并不启动在执行命令才开始启动,所以在系统进程看不到此进程。

https://wiki.archlinuxcn.org/wiki/Iptables?rdfrom=https%3A%2F%2Fwiki.archlinux.org%2Findex.php%3Ftitle%3DIptables_%28%25E7%25AE%2580%25E4%25BD%2593%25E4%25B8%25AD%25E6%2596%2587%29%26redirect%3Dno

一. iptables 入口函数:

1. BIN 文件入口:

文件:iptables/xtables-multi.c

static const struct subcommand multi_subcommands[] = {
    #ifdef ENABLE_IPV4
        {"iptables",            iptables_main},
        {"main4",               iptables_main},
        {"iptables-save",       iptables_save_main},
        {"save4",               iptables_save_main},
        {"iptables-restore",    iptables_restore_main},
        {"restore4",            iptables_restore_main},
    #endif
    ......
}
    
int main(int argc, char **argv)
{
	return subcmd_main(argc, argv, multi_subcommands);
}
2. 命令入口:

文件:iptables/iptables-standalone.c

int iptables_main(int argc, char *argv[])
{
	return xtables_main(NFPROTO_IPV4, "iptables", argc, argv);
}

​ 调用xtables_main过滤执行命令,在进入到xtables_main中会先加载规则,然后过滤输入参数,若参数无误则设置到netfilter中处理,xtables_main方法如下:

int iptables_main(int argc, char *argv[]) {
	int ret;
	char *table = "filter";
	struct xtc_handle *handle = NULL;
    signal(SIGPIPE, SIG_IGN);
	iptables_globals.program_name = "iptables";
	ret = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
    if (ret < 0) {
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",iptables_globals.program_name,iptables_globals.program_version);
		exit(1);
	}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
	init_extensions();
	init_extensions4();
#endif
    ret = do_command4(argc, argv, &table, &handle, false);
	if (ret) {
		ret = iptc_commit(handle);
		iptc_free(handle);
	}
    if (!ret) {
    	if (errno == EINVAL) {
         	fprintf(stderr, "iptables: %s. ""Run `dmesg' for more information.\n",iptc_strerror(errno));
         } else {
         	fprintf(stderr, "iptables: %s.\n",iptc_strerror(errno));
         }
         if (errno == EAGAIN) {
			exit(RESOURCE_PROBLEM);
		}
	}
	exit(!ret);
}

二. 命令解析

1. 过滤参数do_commandx

文件:iptables/iptables.c
方法:do_command4 ,使用getopt_long方法解析输入参数。getopt_long方法参考:https://blog.csdn.net/ljl113/article/details/131398079

while ((cs.c = getopt_long(argc, argv,"-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46",opts, NULL)) != -1) {
 switch (cs.c) {
			/*
			 * Command selection
			 */
		case 'A':
			add_command(&command, CMD_APPEND, CMD_NONE,cs.invert);
			chain = optarg;
			break;
			......
 }

测试如下:

iptables -A OUTPUT -m owner --pid-owner 78

param 0 : iptables
param 1 : -A
iptables param 2 : OUTPUT
iptables param 3 : -m
iptables param 4 : owner
iptables param 5 : --pid-owner
iptables param 6 : 78

do_command4 拆解参数后执行命令iptc_commit命令

//执行如下
ret = iptc_commit(handle);
iptc_free(handle);
//解析xt参数 如:iptables -A OUTPUT  -m owner --uid-owner 1000 -j ACCEPT 中的“ -uid-owner 1000”
//查找解析对象 xtables_match
//文件:libxtables/xtables.c
xtables_find_match(const char *name, enum xtables_tryload tryload,struct xtables_rule_match **matches)

iptc_commit方法

//文件:libiptc/libip4tc.c
#define TC_COMMIT      iptc_commit
//libiptc/libiptc.c
int TC_COMMIT(struct xtc_handle *handle)

add_command
大写字母: 视为命令 调用add_command函数将其加入command 变量中
小写字母: 视为OPtion, 调用set_option函数将其加入options变量中, 并更新 &fw.ip.invflags 变量, 表明是否是一个反转option

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值