igmpproxy源代码学习——igmpProxyInit()
来源:互联网 发布:手机淘宝从哪看几颗心 编辑:程序博客网 时间:2024/05/16 01:38
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_tvifc_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
0 0
- igmpproxy源代码学习——igmpProxyInit()
- igmpproxy源代码学习——配置信息加载 loadConfig
- Google开源代码学习——gtest
- TLD源码学习——cvCalcOpticalFlowPyrLK源代码
- 开源代码学习之——NoBoringActionBar
- java源代码学习——InputStream
- Sqlite3源代码学习之外篇—哈希表
- spring学习(1)——源代码工具环境配置
- Android学习之反编译——源代码可执行
- 树莓派学习笔记—— 源代码方式安装opencv
- 树莓派学习笔记—— 源代码方式安装opencv
- 树莓派学习笔记—— 源代码方式安装opencv
- 树莓派学习笔记—— 源代码方式安装opencv
- gem5学习5——源代码文件结构作用介绍
- openvSwtich学习(1)—— 源代码安装openvSwitch
- java8学习总结——Collectors类源代码分析
- Sqlite3源代码学习之外篇—哈希表 (转)
- 源代码学习
- C语言中continue的理解
- linux主机监控信息显示
- Spring Web Flow
- Maven学习 (三) 使用m2eclipse创建web项目
- 8种移动APP导航设计模式大对比
- igmpproxy源代码学习——igmpProxyInit()
- 安卓手机微信记录还能找回吗
- HDU-4296-Buildings
- Qt之QtWebKit(一)
- Dijkstra算法与实现--基础篇
- 我的人生是怎么样的?
- httpclient 无信任证书直接使用https含项目demo
- Maven学习 (四) 使用Nexus搭建Maven私服
- 关于工作量估算,你知道的和你不知道的一切