原文: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\n",
        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型.

iptables 分析(三)的更多相关文章

  1. tomcat源码分析(三)一次http请求的旅行-从Socket说起

    p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...

  2. 一些有用的javascript实例分析(三)

    原文:一些有用的javascript实例分析(三) 10 输入两个数字,比较大小 window.onload = function () { var aInput = document.getElem ...

  3. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  4. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  5. Nouveau源代码分析(三):NVIDIA设备初始化之nouveau_drm_probe

    Nouveau源代码分析(三) 向DRM注冊了Nouveau驱动之后,内核中的PCI模块就会扫描全部没有相应驱动的设备,然后和nouveau_drm_pci_table对比. 对于匹配的设备,PCI模 ...

  6. Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】

    本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...

  7. [ipsec][strongswan] strongswan源码分析-- (三) xfrm与strongswan内核接口分析

    目录 strongwan sa分析(三) xfrm与strongswan内核接口分析 1. strongswan的实现 2. 交互机制 4. xfrm的消息通信的实现 strongwan sa分析(三 ...

  8. 13 数组 Java内存分析 三种初始化

    Java内存分析 三种初始化 静态初始化 //静态初始化 创建+赋值 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)}; 动态初始 ...

  9. docker 源码分析 三(基于1.8.2版本),NewDaemon启动

    本文来分析一下New Daemon的启动过程:在daemon/daemon.go文件中: func NewDaemon(config *Config, registryService *registr ...

随机推荐

  1. MySQL技术内幕读书笔记(七)——锁

    锁 ​ 锁是数据库系统区分与文件系统的一个关键特性.为了保证数据一致性,必须有锁的介入.数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性. lock与latch ​ 使用命令 ...

  2. 使用xshell+xmanager+pycharm搭建pytorch远程调试开发环境

    1. 相关软件版本 xshell: xmanager: pycharm: pycharm破解服务器:https://jetlicense.nss.im/ 2. 将相应的软件安装(pojie好) a&g ...

  3. Android 8 蓝牙 连接过程

    packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothPairingDetail.java @Override void ...

  4. GeForce GTX 1080 ti安装记录

    安装GeForce GTX 1080ti 安装GeForce GTX 1080ti,8+8pin需要全接,接4pin就开机显示器上会提示电源线没接完,将显示器线接在显卡上. 设置Win 10 pro ...

  5. SpringCloud(一)浅谈SpringCloud

    前言 现在微服务实在是太火了,所以我们必不可少的是要学习一下SpringCloud了,服务化的核心就是将传统的一站式应用 根据业务拆分成一个一个的服务,而微服务在这个基础上要更彻底地去耦合(不再共享D ...

  6. eclipse的debug模式下启动不了tomcat

    使用eclipse启动tomcat,正常模式下可以启动tomcat,却在debug模式下无法启动tomcat. 这个问题可能是由于eclipse和tomcat的交互而产生的,在以debug模式启动to ...

  7. ajax跨域,这应该是最全的解决方案了

    前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下. 个人见 ...

  8. Shell常见问题整理

    1. 使用shell进行程序设计的原因是什么? 可以快速.简单的完成编程,非常适合于编写一些执行相对简单的任务的小工具.如果有一个简单的构想,可以通过它检查自己的想法是否可行.还可以使用shell对进 ...

  9. int和Integer有什么区别

    Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper cl ...

  10. HTML中include file的用法

    语法 <!-- #include PathType = "FileName" --> 参数 PathType  路径类型 路径可为以下某种类型: 文件 该文件名是带有  ...