zoukankan      html  css  js  c++  java
  • iptables 分析(三)

    原文:http://blog.chinaunix.net/uid-24207747-id-2622902.html

    find_target查到目标并加载成功,返回一个xtables_target型对象保存在target,分配空间,拷贝目标,初始化target对象。

    if (target) { //成功

                    size_t size;
                    size = IPT_ALIGN(sizeof(struct ipt_entry_target))
                        + target->size;

                    target->t = fw_calloc(1, size);
                    target->t->u.target_size = size;//空间大小
                    strcpy(target->t->u.user.name, jumpto); //保存目标名到xptables_targets

                    set_revision(target->t->u.user.name,
                         target->revision); //设置版本

                    if (target->init != NULL)
                        target->init(target->t); //初始化xptables_targets                    

                    opts = merge_options(opts,
                             target->extra_opts,
                             &target->option_offset);//将target 的参数选项与旧的参数选项连接在一起由opts 返回,这样下一个循环可以分析target 的参数选项,一般在“default:”中进行分析

                    if (opts == NULL)
                        exit_error(OTHER_PROBLEM,
                             "can't alloc memory!");
                }

    接下来看个比较重要的函数iptc_init来从内核获取表的规则信息,tables就是是-t保存的表名

     /*为了用户能够对内核态的规则进行操作,需要将内核态的规则信息读取到用户空间,对用户空间的规则进行修改后,再根据用户态的规则信息设置内核态的规则信息*/
        if (!*handle)
            *handle = iptc_init(*table); //调用 iptc_init获取表的规则信息,调用list_entries函数显示规则


        /* 加载此模块再获取 */
        if (!*handle && load_xtables_ko(modprobe_program, 0) != -1)
            *handle = iptc_init(*table);

        if (!*handle)
            exit_error(VERSION_PROBLEM,
                 "can't initialize iptables table `%s': %s",
                 *table, iptc_strerror(errno));

    进入iptc_init:

    iptc_handle_t iptc_init(const char *tablename);
    #define TC_INIT        iptc_init //宏定义
    TC_HANDLE_T  TC_INIT(const char *tablename) //获取表信息

    {
        TC_HANDLE_T h;
        STRUCT_GETINFO info;
        unsigned int tmp;
        socklen_t s;

        iptc_fn = TC_INIT;

        if (strlen(tablename) >= TABLE_MAXNAMELEN) {
            errno = EINVAL;
            return NULL;
        }

     /*为获取信息打开一个套接字接口*/
        if (sockfd_use == 0) {
            sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
            if (sockfd < 0)
                return NULL;
        }
        sockfd_use++;
    retry:
        s = sizeof(info);

        strcpy(info.name, tablename);
    /*获取表基本信息,保存在info*/    
        if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
            if (--sockfd_use == 0) {
                close(sockfd);
                sockfd = -1;
            }
            return NULL;
        }

        DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u ",
            info.valid_hooks, info.num_entries, info.size);

        if ((h = alloc_handle(info.name, info.size, info.num_entries))
         == NULL) {
            if (--sockfd_use == 0) {
                close(sockfd);
                sockfd = -1;
            }
            return NULL;
        }

        /* Initialize current state */
        h->info = info;

        h->entries->size = h->info.size;

        tmp = sizeof(STRUCT_GET_ENTRIES) + h->info.size;

        if (getsockopt(sockfd, TC_IPPROTO, SO_GET_ENTRIES, h->entries,
             &tmp) < 0)//最后规则信息存入h->entries
            goto error;

    #ifdef IPTC_DEBUG2
        {
            int fd = open("/tmp/libiptc-so_get_entries.blob", 
                    O_CREAT|O_WRONLY);
            if (fd >= 0) {
                write(fd, h->entries, tmp);
                close(fd);
            }
        }
    #endif

        if (parse_table(h) < 0)
            goto error;

        CHECK(h);
        return h;
    error:
        TC_FREE(&h);
        /* A different process changed the ruleset size, retry */
        if (errno == EAGAIN)
            goto retry;
        return NULL;
    }

    iptables与内核的交互,都是使用setsockopt函数(设置与某个套接字关联的选 项)来实现的,创建socket,通过getsockopt函数是获取与对应的套接字关联的选项,其标志位是SO_GET_INFO,获取保存在STRUCT_GETINFO类型info里,STRUCT_GETINFO结构也就是#define STRUCT_GETINFO struct ipt_getinfo,最后getsockopt返回规则信息是ipt_getinfo型而TC_INIT函数返回一个具体的规则表信息iptc_handle型.

  • 相关阅读:
    【模板】多项式开根(加强版)
    【模板】多项式幂函数 (加强版)
    Codeforces Round #628 (Div. 2) 总结
    [TJOI2017] 不勤劳的图书管理员
    [HNOI2015] 接水果
    [USACO3.4] Raucous Rockers
    [CF1268B] Domino for Young
    Linux提权小结
    weblogic漏洞练习
    SSL/TLS 安全测试
  • 原文地址:https://www.cnblogs.com/wangliangblog/p/9799528.html
Copyright © 2011-2022 走看看