igmpproxy源代码学习——igmpProxyInit()

摘要:
学习igmproxy的源代码-igmpProxyInit()函数的详细说明。igmproxy的初始化需要在运行igmproxyRun()主程序之前对igmproxy进行一些配置。这些配置在igmpProxyInit()中完成。完成此功能后,虚拟网络设备所需的所有信息都保存在IfDescVc[MAX_IF]中。该信息由两部分组成:一部分是物理网络接口的配置,另一部分是配置文件中虚拟网络设备的其他描述。虚拟网络设备初始化AddVif需要在创建虚拟网络设备之前执行enableMRouter()以完成mrouter的初始化。创建套接字。
igmpproxy源代码学习——igmpProxyInit()函数详解,igmpproxy初始化

在运行igmpproxy的主程序igmpproxyRun()之前需要对igmpproxy进行一些配置,这些配置都是在igmpProxyInit()中完成的。
要进行的配置主要有:
信号处理配置
物理网络接口配置加载
配置文件的加载
虚拟网络设备初始化
路由向量表初始化
定时器初始化
信号处理配置
首先进行信号处理配置:
    sigemptyset(&sa.sa_mask);
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);


buildIfVc 物理网络接口配置加载
函数buildIfVc用于完成物理网络接口加载配置,将物理网络接口的配置保存在全局变量 IfDescVc[ MAX_IF ]中(这是目的)。
Sock = socket( AF_INET, SOCK_DGRAM, 0 )用于建立基于UDP数据包的网络套接字
ioctl( Sock, SIOCGIFCONF, &IoCtlReq )用来获取所有网络接口列表(包含接口名字,IP地址)
然后进入一个循环体,该循环体会调用将前面获取的接口名字多次使用传入ioctl来分别获得子网掩码、索引号、Flags等信息。这些信息包括IP地址都将保存在IfDescVc[ MAX_IF ]中 关于IfDescVc的类型struct IfDesc 如下所示:
struct IfDesc {
    char                Name[ sizeof( ((struct ifreq *)NULL)->ifr_name ) ];
    struct in_addr      InAdr;          /* == 0 for non IP interfaces */            
    short               Flags;
    short               state;        //状态:如upstream、downstream
    struct SubnetList*  allowednets; //一个子网链表
    unsigned int        robustness;
    unsigned char       threshold;   /* ttl limit */
    unsigned int        ratelimit; 
    unsigned int        index;
};




configureVifs配置文件中信息的加载
        在buildIfVc中,我们获取了物理网络接口的一些信息,保存在IfDescVc中,但是要创建添加虚拟网路设备,我们还有一些自己的配置(在config文件中,也就是loadConfig函数中实现的功能),这些配置我们通过loadConfig函数已经保存在vifconf中了。
        函数configuireVifs()的任务就是将配置文件中关于虚拟网络设备的诸如threshold、allowednets、ratelimit等信息加载到IfDescVc[ MAX_IF ]中。
        到这个函数完成这后,我们IfDescVc[ MAX_IF ]中才保存了虚拟网络设备所需要的所有信息——这些信息由两部分组成,一个是物理网络接口的配置,一个是配置文件中关于虚拟网络设备的一些其他的描述(config文件igmpProxy.conf中的配置)

虚拟网络设备初始化AddVif
     在创建虚拟网络设备之前需要执行   enableMRouter()完成对mrouter的初始化,创建套接口。具体如下:
    if ( (MRouterFD  = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 )//打开套接口MRouterFD
        log( LOG_ERR, errno, "IGMP socket open" );
    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT,(void *)&Va, sizeof( Va ) ) )//激活Linux内核模块mrouted服务
        return errno;
     前面通过buildIfVc()和configureVifs()我们已经将要初始化的虚拟网络设备所需要的信息都保存在IfDescVc[ MAX_IF ]中了,接下来就是通过循环读取IfDescVc[ MAX_IF ]中的信息创建VIF虚拟网络设备。
        AddVif()主要通过下面一行代码完成。
setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, (char *)&VifCtl, sizeof( VifCtl ) ) 
    从上面代码我们看到参数VifCtl,该参数保存了虚拟网络设备的一些控制信息。VifCtl的类型struct vifctl如下
struct vifctl {
	vifi_t	vifc_vifi;		/* Index of VIF */
	unsigned char vifc_flags;	/* VIFF_ flags */
	unsigned char vifc_threshold;	/* ttl limit */
	unsigned int vifc_rate_limit;	/* Rate limiter values (NI) */
	union {
		struct in_addr vifc_lcl_addr;     /* Local interface address */
		int            vifc_lcl_ifindex;  /* Local interface index   */
	};
	struct in_addr vifc_rmt_addr;	/* IPIP tunnel addr */
};


初始化igmp数据包 initIgmp();
初始化igmp数据包的报文格式,创建发送和接收数据包的缓冲区,为之后发送查询和接收报告做准备。
igmp数据包是实际上是在ip包首部中写入igmp相关信息,关于struct ip附上定义:
struct ip
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ip_hl:4;               /* header length */
    unsigned int ip_v:4;                /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
    unsigned int ip_v:4;                /* version */
    unsigned int ip_hl:4;               /* header length */
#endif
    u_int8_t ip_tos;                    /* type of service */
    u_short ip_len;                     /* total length */
    u_short ip_id;                      /* identification */
    u_short ip_off;                     /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
    u_int8_t ip_ttl;                    /* time to live */
    u_int8_t ip_p;                      /* protocol */
    u_short ip_sum;                     /* checksum */
    struct in_addr ip_src, ip_dst;      /* source and dest address */
  };


关于用到的全局变量的组播地址:
allhosts_group   = htonl(INADDR_ALLHOSTS_GROUP); //224.0.0.1 在本子网上的所有参加多播的主机和路由器
allrouters_group = htonl(INADDR_ALLRTRS_GROUP);  //224.0.0.2 在本子网上的所有参加多播的路由器

这两个地址在后面会用到


初始化路由表  initRouteTable();
初始化路由表,为每个下行接口加入多播组allrouters_group
joinMcGroup( getMcGroupSock(), Dp, allrouters_group );
joinMcGroup中会调用
joinleave( int Cmd, int UdpSock, struct IfDesc *IfDp, uint32 mcastaddr )
因为传入的cmd为j,表示加入组(如果传入不是j,表示离开组)
joinleave最主要的代码是:
setsockopt( UdpSock, IPPROTO_IP, 
          Cmd == 'j' ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, 
          (void *)&CtlReq, sizeof( CtlReq ) )

初始化时间表callout_init();
void callout_init() {
    queue = NULL;
}


初始化询问超时,queue=NULL


















免责声明:文章转载自《igmpproxy源代码学习——igmpProxyInit()》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux cat命令的使用给nginx指定dns服务器下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【iOS】Swift LAZY 修饰符和 LAZY 方法

延时加载或者说延时初始化是很常用的优化方法,在构建和生成新的对象的时候,内存分配会在运行时耗费不少时间,如果有一些对象的属性和内容非常复杂的话,这个时间更是不可忽略。另外,有些情况下我们并不会立即用到一个对象的所有属性,而默认情况下初始化时,那些在特定环境下不被使用的存储属性,也一样要被初始化和赋值,也是一种浪费。 在其他语言 (包括 Objectiv...

PHP是怎么运行的

这篇文章,研究一下PHP代码是如何解释和执行以及PHP脚本运行的生命周期。 概述 PHP服务的启动。严格来说,PHP的相关进程是不需要手动启动的,它是随着Apache的启动而运行的。当然,如果有需要重启PHP服务的情况下也是可以手动重启PHP服务的。比如说在有开启opcode的正式环境更新了代码之后,需要重启PHP以重新编译PHP代码。 从宏观上来看,PH...

Java的静态代码块是否会在类被加载时自动执行?

JAVA静态代码块会在类被加载时自动执行?一、先看Java静态方法,静态变量 http://www.cnblogs.com/winterfells/p/7906078.html 静态代码块 在类中,可以将某一块代码声明为静态的,这样的程序块叫静态初始化段。静态代码块的一般形式如下: static { 语句序列 } public class stat...

CS231N 数据预处理(data proprecessing)

原文链接:https://blog.csdn.net/weixin_38646522/article/details/79534677 一些数据预处理的标准方法有均值化数据和归一化数据。 零中心化的意义在上面已经详细的讲述了,这里就不在细讲。 归一化数据的意义在于让所有的特征都在相同的值域之内,并且让这些特征有相同的贡献。对于图像处理,在大部分情况下会进...

STM32H743 | FDCAN 波特率问题

STM32H743 | FDCAN 波特率问题 直奔主题,最近项目上接触了FDCAN,主控为STM32H743。在开发过程中存在疑点,特此记录。 疑点:芯片手册上,波特率的相关寄存器位标明硬件将该值解析为编程值加1,但是实际上通过STM32 HAL库的HAL_FDCAN_Init()函数来初始化FDCAN时,我们给FDCAN初始化结构体的成员变量所赋的值...

CentOS7.5 系统最小化安装与初始化配置

CentOS7.5 系统最小化安装与初始化配置 1.安装标准化的系统 1.1.系统安装期间的语言 选择:中文-简体中文,安装完成也会默认支持中文输出,便于管理 1.2.时区选择 亚洲上海,CST时区(东八区用) 1.3.分区方式 挂载路径 分区格式 分区大小 备注信息 swap分区 --- 内存的2倍 交换分区,如果是虚拟机可以不创建 /b...