igmpproxy原始碼學習——igmpProxyInit()

來源:互聯網
上載者:User

標籤:igmp   多播   路由器   組播   igmpproxy   

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 )用於建立套介面,開啟RAM
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中,我們擷取了物理網路介面的一些資訊,但是要建立添加虛擬網路裝置,僅有這些資訊還不夠,有些資訊需要從設定檔中擷取。在載入設定檔一文中,我們已經知道,設定檔中的有關虛擬網路裝置的資訊都被儲存在vifconf中。        函數configuireVifs()的任務就是講設定檔中關於虛擬網路裝置的諸如robustness、allowednets、ratelimit等資訊載入到IfDescVc[ MAX_IF ]中。        也就是說到這個函數完成這裡,我們IfDescVc[ MAX_IF ]中儲存了虛擬網路裝置所需要的資訊,這些資訊由兩部分組成,一個是物理網路介面的配置,一個是設定檔中關於虛擬網路裝置的一些其他的描述
虛擬網路裝置初始化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

















igmpproxy原始碼學習——igmpProxyInit()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.