免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

【iptables交流贴】iptables执行的流程分析 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-08-10 12:06 |显示全部楼层
原帖由 Godbach 于 2008-8-7 16:11 发表
也就是说带-m state的规则在存到某个表里的时候,是不是存到表的最前面了。如果是,代码哪里实现的?

个人觉得这个应该是在iptables里实现的,因为每下一条规则,都相当于把某个表取出来,更新之后,又重新下 ...



不好意思,这两天看奥运了,回复的慢了:)

我看了一些东西,先写出来,不过还没有把所有的搞清楚,先写出来一起看看。

Iptables源码中有一个Libxt_state.c,它的第一行写的是:
/* Shared library add-on to iptables to add state tracking support. */ (支持状态追踪的共享库)
它的_init函数是在注册一个state_match结构:
  1. void _init(void)
  2. {
  3.         xtables_register_match(&state_match);
  4.         xtables_register_match(&state_match6);
  5. }
复制代码

这个注册动作是将state_match注册到一个全局的xtables_matches中。具体是调find_match看看是不是有旧的相同名字的match,如果有的话就删了,然后替换掉。
  1. void xtables_register_match(struct xtables_match *me)
  2. {
  3.         struct xtables_match **i, *old;

  4.         if (strcmp(me->version, program_version) != 0) {
  5.                 fprintf(stderr, "%s: match `%s' v%s (I'm v%s).\n",
  6.                         program_name, me->name, me->version, program_version);
  7.                 exit(1);
  8.         }

  9.         /* Revision field stole a char from name. */
  10.         if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) {
  11.                 fprintf(stderr, "%s: target `%s' has invalid name\n",
  12.                         program_name, me->name);
  13.                 exit(1);
  14.         }

  15.         if (me->family >= NPROTO) {
  16.                 fprintf(stderr,
  17.                         "%s: BUG: match %s has invalid protocol family\n",
  18.                         program_name, me->name);
  19.                 exit(1);
  20.         }

  21.         /* ignore not interested match */
  22.         if (me->family != afinfo.family && me->family != AF_UNSPEC)
  23.                 return;

  24.         old = find_match(me->name, DURING_LOAD, NULL);
  25.         if (old) {
  26.                 if (old->revision == me->revision &&
  27.                     old->family == me->family) {
  28.                         fprintf(stderr,
  29.                                 "%s: match `%s' already registered.\n",
  30.                                 program_name, me->name);
  31.                         exit(1);
  32.                 }

  33.                 /* Now we have two (or more) options, check compatibility. */
  34.                 if (compatible_match_revision(old->name, old->revision)
  35.                     && old->revision > me->revision)
  36.                         return;

  37.                 /* See if new match can be used. */
  38.                 if (!compatible_match_revision(me->name, me->revision))
  39.                         return;

  40.                 /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */
  41.                 if (old->revision == me->revision && me->family == AF_UNSPEC)
  42.                         return;

  43.                 /* Delete old one. */
  44.                 for (i = &xtables_matches; *i!=old; i = &(*i)->next);
  45.                 *i = old->next;
  46.         }

  47.         if (me->size != XT_ALIGN(me->size)) {
  48.                 fprintf(stderr, "%s: match `%s' has invalid size %u.\n",
  49.                         program_name, me->name, (unsigned int)me->size);
  50.                 exit(1);
  51.         }

  52.         /* Append to list. */
  53.         for (i = &xtables_matches; *i; i = &(*i)->next);
  54.         me->next = NULL;
  55.         *i = me;

  56.         me->m = NULL;
  57.         me->mflags = 0;
  58. }
复制代码


其中 state_match是一个xtables_match结构体,具体如下里面的.parse注册一个state_parse函数指针,
  1. static struct xtables_match state_match = {
  2.         .family                = AF_INET,
  3.         .name                = "state",
  4.         .version        = XTABLES_VERSION,
  5.         .size                = XT_ALIGN(sizeof(struct xt_state_info)),
  6.         .userspacesize        = XT_ALIGN(sizeof(struct xt_state_info)),
  7.         .help                = state_help,
  8.         .parse                = state_parse,
  9.         .final_check        = state_final_check,
  10.         .print                = state_print,
  11.         .save                = state_save,
  12.         .extra_opts        = state_opts,
  13. };
复制代码

而parse_state函数就是来根据判断state字符串来设置相应位的:
  1. static int
  2. parse_state(const char *state, size_t len, struct xt_conntrack_info *sinfo)
  3. {
  4.         if (strncasecmp(state, "INVALID", len) == 0)
  5.                 sinfo->statemask |= XT_CONNTRACK_STATE_INVALID;
  6.         else if (strncasecmp(state, "NEW", len) == 0)
  7.                 sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_NEW);
  8.         else if (strncasecmp(state, "ESTABLISHED", len) == 0)
  9.                 sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED);
  10.         else if (strncasecmp(state, "RELATED", len) == 0)
  11.                 sinfo->statemask |= XT_CONNTRACK_STATE_BIT(IP_CT_RELATED);
  12.         else if (strncasecmp(state, "UNTRACKED", len) == 0)
  13.                 sinfo->statemask |= XT_CONNTRACK_STATE_UNTRACKED;
  14.         else if (strncasecmp(state, "SNAT", len) == 0)
  15.                 sinfo->statemask |= XT_CONNTRACK_STATE_SNAT;
  16.         else if (strncasecmp(state, "DNAT", len) == 0)
  17.                 sinfo->statemask |= XT_CONNTRACK_STATE_DNAT;
  18.         else
  19.                 return 0;
  20.         return 1;
  21. }
复制代码


以上操作即实现了在添加这个共享库的时候全局的xtables_matches中已经有了可以实现解析state的match了。

现在重新回到那个do_command函数中,在解析到 -m 选项的时候,调用:
  1.                 case 'm': {
  2.                         size_t size;

  3.                         if (invert)
  4.                                 exit_error(PARAMETER_PROBLEM,
  5.                                            "unexpected ! flag before --match");

  6.                         m = find_match(optarg, LOAD_MUST_SUCCEED, &matches);
  7.                         size = IPT_ALIGN(sizeof(struct ipt_entry_match))
  8.                                          + m->size;
  9.                         m->m = fw_calloc(1, size);
  10.                         m->m->u.match_size = size;
  11.                         strcpy(m->m->u.user.name, m->name);
  12.                         set_revision(m->m->u.user.name, m->revision);
  13.                         if (m->init != NULL)
  14.                                 m->init(m->m);
  15.                         if (m != m->next) {
  16.                                 /* Merge options for non-cloned matches */
  17.                                 opts = merge_options(opts,
  18.                                                      m->extra_opts,
  19.                                                      &m->option_offset);
  20.                                 if (opts == NULL)
  21.                                         exit_error(OTHER_PROBLEM,
  22.                                                    "can't alloc memory!");
  23.                         }
  24.                 }
复制代码

它调用find_match函数根据optarg找相应名字的match(但是我的souceinsight始终找不到这个optarg在哪儿,到底是什么---郁闷!)
###################中间我也不知道怎么回事。。。####################这个{case "m"}函数段中的那个变量m(xtables_match类型的),一直没找到它是后来是用来干嘛的。。。。同志们也看看吧。
然后是do_command函数后面调用,e = generate_entry(&fw, matches, target->t);
然后就是append_entry往内核里添加了。。。

综上所述,实际上我只找到了parse state的函数,没找到它到底是加在一个chain的头部还是尾部了。。。。。我觉得就是由match的parse函数去设置要添加的entry追踪状态位。

还有就是,我有个想法,其实Iptables里的match,就是那个全局变量xtables_matches,跟netfilter里match根本不是一回事。前者是实现了对命令行解析的match,后者是对数据包的match。

我看了这些,还会继续看下去,如果哪里错了还望大家及时纠正

[ 本帖最后由 jaycu 于 2008-8-10 12:08 编辑 ]

论坛徽章:
0
12 [报告]
发表于 2008-08-11 15:07 |显示全部楼层
原帖由 sunorr 于 2008-8-11 09:21 发表


解析命令行参数用的吧。

man 3 getopt



o .原来如此。。。C功底太差了。。。

论坛徽章:
0
13 [报告]
发表于 2008-08-11 15:10 |显示全部楼层
原帖由 Godbach 于 2008-8-10 21:42 发表


LS的看的细啊。偶感觉到把握住核心的流程,就是do_command(),完成之后就是iptc_commit()。
这个里面并没看出对state的特殊处理。

后来flw版主提示了一下,说其实还是在于添加规则时使用iptables -A 还是 ...

收到!!多谢:)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP