博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
igmpproxy源码学习——igmpProxyInit()
阅读量:5339 次
发布时间:2019-06-15

本文共 4441 字,大约阅读时间需要 14 分钟。

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

转载于:https://www.cnblogs.com/zfyouxi/p/5253706.html

你可能感兴趣的文章
mysql操作命令梳理(4)-中文乱码问题
查看>>
Python环境搭建(安装、验证与卸载)
查看>>
一个.NET通用JSON解析/构建类的实现(c#)
查看>>
Windows Phone开发(5):室内装修 转:http://blog.csdn.net/tcjiaan/article/details/7269014
查看>>
详谈js面向对象 javascript oop,持续更新
查看>>
关于这次软件以及pda终端的培训
查看>>
jQuery上传插件Uploadify 3.2在.NET下的详细例子
查看>>
如何辨别一个程序员的水平高低?是靠发量吗?
查看>>
新手村之循环!循环!循环!
查看>>
正则表达式的用法
查看>>
线程安全问题
查看>>
SSM集成activiti6.0错误集锦(一)
查看>>
下拉刷新
查看>>
linux的子进程调用exec( )系列函数
查看>>
MSChart的研究
查看>>
C# 索引器
查看>>
MySQLdb & pymsql
查看>>
zju 2744 回文字符 hdu 1544
查看>>
delphi 内嵌汇编例子
查看>>
【luogu P2298 Mzc和男家丁的游戏】 题解
查看>>