Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1334686
  • 博文数量: 284
  • 博客积分: 3251
  • 博客等级: 中校
  • 技术积分: 3046
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-26 17:23
文章分类

全部博文(284)

文章存档

2019年(2)

2018年(5)

2015年(19)

2014年(13)

2013年(10)

2012年(235)

分类: LINUX

2012-12-21 16:34:00

  我们知道在内核中用结构体struct net_device标识一个网络设备接口,该结构体有一个成员指针ip_ptr,它是留给IPv4协议用于填充协议相关的一些数据的。IPv4协议的模 块将其指向一个结构体struct in_device,该结构体含有很多协议相关的数据,比如配置在这个网络设备接口上的所有的IPv4的地址,该网络设备接口接受的组播地址等,下面是其 完整的定义:
    struct in_device
    {
        struct net_device   *dev;
        atomic_t refcnt;
        int dead;
        struct in_ifaddr    *ifa_list;  //IP地址列表
        rwlock_t        mc_list_lock;
        struct ip_mc_list   *mc_list;   //IP组播过滤列表。
        spinlock_t      mc_tomb_lock;   //下面都是组播相关数据。
        struct ip_mc_list   *mc_tomb;
        unsigned long       mr_v1_seen;
        unsigned long       mr_v2_seen;
        unsigned long       mr_maxdelay;
        unsigned char       mr_qrv;
        unsigned char       mr_gq_running;
        unsigned char       mr_ifc_count;
        struct timer_list   mr_gq_timer;    /* general query timer */
        struct timer_list   mr_ifc_timer;   /* interface change timer */

        struct neigh_parms  *arp_parms;
        struct ipv4_devconf cnf;
        struct rcu_head     rcu_head;
    };
    我们暂时还无法完全理解这个结构体,目前只需关注的是mc_list成员,这是关于组播的一个最为关键的数据结构。mc_list是一个链表,链表的一个 结点代表一个组播地址(也就是一个多播组的组号),代表这个网络设备接口已经加入了这个组播组,需要接收来自这个组的数据报。下面是该节点的结构体定义:
    struct ip_mc_list
    {
        struct in_device    *interface;
        unsigned long       multiaddr;
        struct ip_sf_list   *sources;
        struct ip_sf_list   *tomb;
        unsigned int        sfmode;
        unsigned long       sfcount[2];
        struct ip_mc_list   *next;
        struct timer_list   timer;
        int             users;
        atomic_t        refcnt;
        spinlock_t      lock;
        char            tm_running;
        char            reporter;
        char            unsolicit_count;
        char            loaded;
        unsigned char   gsquery;
        unsigned char   crcount;
    };
    同样,我们把其中的大部分成员留待以后理解。multiaddr就是组播地址,sources和tomb是关于组播源地址的一个列表,sfmode和 sfcount是过滤参数,也就是说,该网络设备接口虽然加入了某个组播组,但对某些主机向该组发的数据报不接收,或者只接收某个主机发向该组的数据报, 这就要对组播源进行过滤。
    关于D类地址的常识,这里不再介绍,可参考相关书籍。
    下面介绍一个特殊的组播地址224.0.0.1,它标识子网中的所有主机,同一个子网内具有组播功能的主机都属于这个组。我们的my_inet模块在初始 化时,myinetdev_event函数收到网络设备接口启动(NETDEV_UP)的消息后,调用myip_mc_up启动组播功能。
    启动组播功能的第一件事便是把本机加入到这个特殊的组播组IGMP_ALL_HOSTS(即224.0.0.1),调用 myip_mc_inc_group函数完成加入动作。因为我们的my_inet模块是作为系统中的第二个IPv4模块,在系统正常运行后被加载的,所 以,网络设备接口早已完成了加入该组播组的操作。my_inet模块的加入动作是只是简单地将成员users加1,然后调用 myip_mc_add_src函数加入组播源过滤。
    IGMP_ALL_HOSTS组的sources为NULL,sfmode为MCAST_EXCLUDE(过滤掉sources中列出的所有源),所以结 果是不过滤任何组播源。myip_mc_add_src函数中,将sfcount[MCAST_EXCLUDE]的值加1,表示新增一个过滤机制。
阅读(1081) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~