igmpproxy源碼學習——igmpProxyInit()

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 ) )socket


初始化時間表callout_init();

void callout_init() {
    queue = NULL;
}


初始化詢問超時,queue=NULL
相關文章
相關標籤/搜索