³ö×Ô£ºhttp://blue8king.blog.163.com/blog/static/8854755520087441751166/
ÐÒéÕ»¸úÍøÂçÉ豸µÄ¹ØÁªÖ÷ÒªÊÇͨ¹ýstruct net_device½á¹¹ÌåÖеÄÁù¸öÐÒéÏà¹ØµÄÖ¸Õ룺atalk_ptr£¬ip_ptr£¬dn_ptr£¬ip6_ptr£¬ec_ptr£¬ ax25_ptr¡£ÎÒÃÇÖصã¹Ø×¢µÄÊÇipv4µÄʵÏÖ£¬ËùÒÔÖ»´¦ÀíÖ¸Õëip_ptr¡£ip_ptrÖ¸ÏòµÄÊÇÒ»¸ö½á¹¹Ìåstruct in_device£¬Æä³ÉÔ±struct in_ifaddr ifa_listÊÇÒ»¸öIPµØÖ·ÁÐ±í£¬¶ÔÓÚÒ»¸ölinuxÍøÂçÉ豸À´½²£¬Ëü¿ÉÒÔÓµÓжà´ó256¸öipµØÖ·£¬Ã¿Ò»¸öIPµØÖ·ÔÚin_deviceÖеıíʾ¾ÍÊÇÒ»¸ö½á¹¹Ìåstruct in_ifaddr£¬ËùÓеÄIPµØÖ·ÒÔÒ»¸öÁ´±íµÄÐÎʽ×éÖ¯ÔÚÒ»Æð¡£ÏÂÃæÊÇstruct in_ifaddr½á¹¹ÌåµÄ¶¨Ò壺
struct in_ifaddr
{
struct in_ifaddr *ifa_next;
struct in_device *ifa_dev;
struct rcu_head rcu_head;
u32 ifa_local;
u32 ifa_address;
u32 ifa_mask;
u32 ifa_broadcast;
u32 ifa_anycast;
unsigned char ifa_scope;
unsigned char ifa_flags;
unsigned char ifa_prefixlen;
char ifa_label[IFNAMSIZ];
};
ifa_nextÊÇÁ´±íÖ¸Õ룬ifa_devÖ¸ÏòËüËùÔÚµÄin_device¡£ifa_local¸úifa_address¶¼ÊÇIPµØÖ·£¬¾ßÌåÇø±ðÄ¿Ç°»¹²»Çå³þ£¬ifa_maskÊÇ×ÓÍøÑÚÂ룬ifa_broadcastÊǹ㲥µØÖ·£¬ifa_anycastÊÇrawÐÒéÏà¹ØµÄÒ»¸öµØÖ·£¬¾ßÌå²»Ã÷¡£ ifa_scopeµÄÈ¡ÖµÈçÏ£º
enum rt_scope_t
{
RT_SCOPE_UNIVERSE=0,
/* User defined values */
RT_SCOPE_SITE=200,
RT_SCOPE_LINK=253,
RT_SCOPE_HOST=254,
RT_SCOPE_NOWHERE=255
};
ʵ¼ÊÉÏ£¬Õâ¸ö³ÉÔ±²¢·ÇÈçËüµÄ×ÖÃæÒâ˼Ëù±íʾµÄscope£¬ËüÊÇ°´µ½Ä¿µÄ¶Ë¾àÀë½øÐеÄÒ»ÖÖ·ÖÀ࣬nowhere±íʾ²»´æÔÚµÄÄ¿µÄ¶Ë£¬host±íʾĿµÄ¶ËÊDZ¾»ú£¨»Ø»·µØÖ·£©£¬linkÊÇÖ±Á¬µÄÒ»¸öÄ¿µÄ¶Ë£¬site±íʾÔÚÒ»¸ö±¾µØ·â±ÕϵͳÖеÄÄÚ²¿Â·ÓÉ£¬¶øuniverseÊdzý´ËÖ®ÍâµÄÆäËüÈκÎÇé¿ö¡£
ifa_flagsµÄÈ¡Öµ·¶Î§ÈçÏ£º
#define IFA_F_SECONDARY 0x01 //´ÓÊôÉ豸¡£
#define IFA_F_TEMPORARY IFA_F_SECONDARY //ÁÙʱÉ豸¡£
#define IFA_F_DEPRECATED 0x20
#define IFA_F_TENTATIVE 0x40
#define IFA_F_PERMANENT 0x80 //ÓÀ¾ÃÉ豸¡£
ifa_prefixlenÊÇ×ÓÍøÑÚÂëµÄÍøÂçºÅµÄ³¤¶È£¬ifa_labelÊÇÉ豸ºÍÉ豸Ãû£¬±ÈÈçeth0, eth1µÈ¡£
struct in_device *pdev_ipaddr=NULL;
pdev_ipaddr=(struct in_device *)pDev->ip_ptr;
if(pdev_ipaddr==NULL)
{
kfree(pIGMP_Leave_skb);
return IGMP_FALSE;
}
if(pdev_ipaddr->ifa_list==NULL)
{
kfree(pIGMP_Leave_skb);
return IGMP_FALSE;
}
pIpheader->saddr=pdev_ipaddr->ifa_list->ifa_local;
³ö×Ô£ºhttp://hi.baidu.com/linux_kernel/blog/item/c355c2ce7bc1ed0392457e81.html
¹ØÓÚÍøÂçÉ豸
ÔÚ»ù±¾Íê³ÉÁËÕû¸ö³õʼ»¯¹ý³ÌÒÔºó£¬ÎÒÃÇÐèÒªÔٻص½ÍøÂçÉ豸ÉÏÀ´£¬¿´¿´Õû¸öTCP/IPÐÒ龿¾¹ÊÇÈç¹û¸úÍøÂçÉ豸Ïà¹ØÁª£¬²¢×îÖÕÒ»ÆðÍê³É¸÷ÖÖ¸´ÔÓ¹¤×÷µÄ¡£
ÔÚÍø¿¨Çý¶¯Ïà¹ØµÄ·ÖÎöÖУ¬ÎÒÃÇÌáµ½£¬´ú±íÒ»¸öÍøÂçÉ豸½Ó¿ÚµÄÊÇÒ»¸ö½á¹¹Ìåstruct net_device¡£¶øÔÚmy_inetÄ£¿éµÄ³õʼ»¯¹ý³ÌÖУ¬mydevinet_initµÄ¹¤×÷ÊÇΪMY_PF_INETÓòµÄ¹¤×÷ÕÒµ½¿ÉÓõÄÍøÂçÉ豸£¬²¢½øÐбØÒªµÄ³õʼ»¯£¬ÔÚmydevinet_initÖÐÓÐÕâôһÐдúÂ룺
register_netdevice_notifier(&myip_netdev_notifier);
ËüÊÇ°ÑÒ»¸ö½á¹¹Ìåstruct notifier_block myip_netdev_notifier×¢²áµ½Ò»¸öϵͳȫ¾ÖµÄÁ´±ínetdev_chainÖУ¬½á¹¹Ìåmyip_netdev_notifierº¬ÓÐÒ»¸öÓÅÏȼ¶£¬ÔÚnetdev_chainÖУ¬Ëü¸úÆäËüµÄnotifier_block°´ÓÅÏȼ¶µÄÏȺó´ÎÐòÅÅÁУ¬Í¬Ê±ËüÓÐÒ»¸önotifier_callµÄ»Øµ÷º¯ÊýÖ¸Õ룬ÔÚËü±»×¢²áµ½netdev_chainÖкó£¬ÍøÂçÉ豸ÉÏÓÐʼþ·¢Éú£¬¸Ã»Øµ÷º¯Êý¾Í»á±»µ÷Óõ½¡£¹ØÓÚlinuxµÄnotifyµÄʵÏÖÔÀíϸ½Ú£¬ÎÒÃÇÒÔºó½øÐÐרÃŵķÖÎö¡£
¹ØÓÚÍøÂçÉ豸»á·¢³öµÄ֪ͨµÄÀàÐÍ£¬ÔÚinclude/linux/notifier.hÖÐÓÐÍêÕûµÄ¶¨Ò壺
#define NETDEV_UP 0x0001 //É豸¿ªÆô
#define NETDEV_DOWN 0x0002 //É豸¹Ø±Õ
#define NETDEV_REBOOT 0x0003 //¸æËßÐÒéÕ»Ò»¸öÍøÂç½Ó¿Ú̽²âµ½Ó²¼þ±ÀÀ£²¢ÖØÆôÁË¡£
#define NETDEV_CHANGE 0x0004 //É豸״̬¸Ä±ä
#define NETDEV_REGISTER 0x0005 //É豸ע²á
#define NETDEV_UNREGISTER 0x0006 //É豸עÏú
#define NETDEV_CHANGEMTU 0x0007 //É豸¸Ä±äMTU
#define NETDEV_CHANGEADDR 0x0008 //É豸¸Ä±äµØÖ·
#define NETDEV_GOING_DOWN 0x0009 //É豸׼±¸¹Ø±Õ
#define NETDEV_CHANGENAME 0x000A //É豸¸Ä±äÃû×Ö
#define NETDEV_FEAT_CHANGE 0x000B //... ...
µ±ÎÒÃÇ°Ñmy_inet×÷Ϊһ¸öÄ£¿éinsmodµ½ÄÚºËÖÐʱ£¬ÎÒÃÇÂíÉÏ»áÊÕµ½É豸ע²áºÍÉ豸¿ªÆôÁ½¸ö֪ͨ¡£¶ÔÓÚÿһ¸öÒÑ¿ªÆôµÄÍøÂçÉ豸£¬ myip_netdev_notifierÌṩµÄ»Øµ÷º¯Êýmyinetdev_event»á±»Á½´Îµ÷Óõ½¡£ÎÒÃÇ¿ÉÒÔÔÚÕâÀïÍê³ÉһЩÎÒÃÇÏ£Íû×öµÄ³õʼ»¯¹¤×÷¡£
ÐÒéÕ»¸úÍøÂçÉ豸µÄ¹ØÁªÖ÷ÒªÊÇͨ¹ýstruct net_device½á¹¹ÌåÖеÄÁù¸öÐÒéÏà¹ØµÄÖ¸Õ룺atalk_ptr£¬ip_ptr£¬dn_ptr£¬ip6_ptr£¬ec_ptr£¬ ax25_ptr¡£ÎÒÃÇÖصã¹Ø×¢µÄÊÇipv4µÄʵÏÖ£¬ËùÒÔÖ»´¦ÀíÖ¸Õëip_ptr¡£ip_ptrÖ¸ÏòµÄÊÇÒ»¸ö½á¹¹Ìåstruct in_device£¬Æä³ÉÔ±struct in_ifaddr ifa_listÊÇÒ»¸öIPµØÖ·ÁÐ±í£¬¶ÔÓÚÒ»¸ölinuxÍøÂçÉ豸À´½²£¬Ëü¿ÉÒÔÓµÓжà´ó256¸öipµØÖ·£¬Ã¿Ò»¸öIPµØÖ·ÔÚin_deviceÖеıíʾ¾ÍÊÇÒ»¸ö½á¹¹Ìåstruct in_ifaddr£¬ËùÓеÄIPµØÖ·ÒÔÒ»¸öÁ´±íµÄÐÎʽ×éÖ¯ÔÚÒ»Æð¡£ÏÂÃæÊÇstruct in_ifaddr½á¹¹ÌåµÄ¶¨Ò壺
struct in_ifaddr
{
struct in_ifaddr *ifa_next;
struct in_device *ifa_dev;
struct rcu_head rcu_head;
u32 ifa_local;
u32 ifa_address;
u32 ifa_mask;
u32 ifa_broadcast;
u32 ifa_anycast;
unsigned char ifa_scope;
unsigned char ifa_flags;
unsigned char ifa_prefixlen;
char ifa_label[IFNAMSIZ];
};
ifa_nextÊÇÁ´±íÖ¸Õ룬ifa_devÖ¸ÏòËüËùÔÚµÄin_device¡£ifa_local¸úifa_address¶¼ÊÇIPµØÖ·£¬¾ßÌåÇø±ðÄ¿Ç°»¹²»Çå³þ£¬ifa_maskÊÇ×ÓÍøÑÚÂ룬ifa_broadcastÊǹ㲥µØÖ·£¬ifa_anycastÊÇrawÐÒéÏà¹ØµÄÒ»¸öµØÖ·£¬¾ßÌå²»Ã÷¡£ ifa_scopeµÄÈ¡ÖµÈçÏ£º
enum rt_scope_t
{
RT_SCOPE_UNIVERSE=0,
/* User defined values */
RT_SCOPE_SITE=200,
RT_SCOPE_LINK=253,
RT_SCOPE_HOST=254,
RT_SCOPE_NOWHERE=255
};
ʵ¼ÊÉÏ£¬Õâ¸ö³ÉÔ±²¢·ÇÈçËüµÄ×ÖÃæÒâ˼Ëù±íʾµÄscope£¬ËüÊÇ°´µ½Ä¿µÄ¶Ë¾àÀë½øÐеÄÒ»ÖÖ·ÖÀ࣬nowhere±íʾ²»´æÔÚµÄÄ¿µÄ¶Ë£¬host±íʾĿµÄ¶ËÊDZ¾»ú£¨»Ø»·µØÖ·£©£¬linkÊÇÖ±Á¬µÄÒ»¸öÄ¿µÄ¶Ë£¬site±íʾÔÚÒ»¸ö±¾µØ·â±ÕϵͳÖеÄÄÚ²¿Â·ÓÉ£¬¶øuniverseÊdzý´ËÖ®ÍâµÄÆäËüÈκÎÇé¿ö¡£
ifa_flagsµÄÈ¡Öµ·¶Î§ÈçÏ£º
#define IFA_F_SECONDARY 0x01 //´ÓÊôÉ豸¡£
#define IFA_F_TEMPORARY IFA_F_SECONDARY //ÁÙʱÉ豸¡£
#define IFA_F_DEPRECATED 0x20
#define IFA_F_TENTATIVE 0x40
#define IFA_F_PERMANENT 0x80 //ÓÀ¾ÃÉ豸¡£
ifa_prefixlenÊÇ×ÓÍøÑÚÂëµÄÍøÂçºÅµÄ³¤¶È£¬ifa_labelÊÇÉ豸ºÍÉ豸Ãû£¬±ÈÈçeth0, eth1µÈ¡£