ת×Ô£ºhttp://www.yesky.com/20020207/217727_1.shtml
LinuxÄÚºË2.4.xµÄÍøÂç½Ó¿ÚÔ´ÂëµÄ½á¹¹
Ò».ǰÑÔ
¡¡¡¡LinuxµÄÔ´ÂëÀï£¬ÍøÂç½Ó¿ÚµÄʵÏÖ²¿·ÝÊǷdz£ÖµµÃÒ»¶ÁµÄ£¬Í¨¹ý¶ÁÔ´Â룬²»½ö¶ÔÍøÂçÐÒéÓиüÉîµÄÁ˽⣬ҲÓÐÖúÓÚÔÚÍøÂç±à³ÌµÄʱºò£¬¶ÔÓ¦Óú¯ÊýÓиü¾«È·µÄÁ˽âºÍ°ÑÎÕ¡£
¡¡¡¡±¾ÎİÑÖØµã·ÅÔÚÍøÂç½Ó¿Ú³ÌÐòµÄ×ÜÌå½á¹¹ÉÏ£¬Ï£ÍûÄÜ×÷Ϊ¶ÁÔ´ÂëʱһЩָµ¼ÐÔµÄÎÄ×Ö¡£
¡¡¡¡±¾ÎÄÒÔLinux2.4.16ÄÚºË×÷Ϊ½²½âµÄ¶ÔÏó£¬ÄÚºËÔ´Âë¿ÉÒÔÔÚ[http://www.kernel.org/]ÉÏÏÂÔØ¡£ÎÒ¶ÁÔ´Âëʱ²Î¿¼µÄÊÇ[lxr.linux.no]Õâ¸ö½»²î²Î¿¼µÄÍøÕ¾£¬ÎÒ¸öÈËÈÏΪÊÇÒ»¸öºÜºÃµÄ¹¤¾ß£¬Èç¹ûÓÐÌõ¼þ×îºÃÉÏÕâ¸öÍøÕ¾¡£
¶þ.ÍøÂç½Ó¿Ú³ÌÐòµÄ½á¹¹
¡¡¡¡LinuxµÄÍøÂç½Ó¿Ú·ÖΪËIJ¿·Ý£ºÍøÂçÉ豸½Ó¿Ú²¿·Ý£¬ÍøÂç½Ó¿ÚºËÐIJ¿·Ý£¬ÍøÂçÐÒé×岿·Ý£¬ÒÔ¼°ÍøÂç½Ó¿Úsocket²ã¡£
¡¡¡¡ÍøÂçÉ豸½Ó¿Ú²¿·ÝÖ÷Òª¸ºÔð´ÓÎïÀí½éÖʽÓÊպͷ¢ËÍÊý¾Ý¡£ÊµÏÖµÄÎļþÔÚlinu/driver/netĿ¼ÏÂÃæ¡£
¡¡¡¡ÍøÂç½Ó¿ÚºËÐIJ¿·ÝÊÇÕû¸öÍøÂç½Ó¿ÚµÄ¹Ø¼ü²¿Î»£¬ËüÎªÍøÂçÐÒéÌṩͳһµÄ·¢Ëͽӿڣ¬ÆÁ±Î¸÷ÖÖ¸÷ÑùµÄÎïÀí½éÖÊ£¬Í¬Ê±ÓÖ¸ºÔð°ÑÀ´×ÔϲãµÄ°üÏòºÏÊʵÄÐÒéÅäËÍ¡£ËüÊÇÍøÂç½Ó¿ÚµÄÖÐÊಿ·Ý¡£ËüµÄÖ÷ҪʵÏÖÎļþÔÚlinux/net/coreĿ¼Ï£¬ÆäÖÐlinux/net/core/dev.cΪÖ÷Òª¹ÜÀíÎļþ¡£
¡¡¡¡ÍøÂçÐÒé×岿·ÝÊǸ÷ÖÖ¾ßÌåÐÒéʵÏֵIJ¿·Ý¡£LinuxÖ§³ÖTCP/IP£¬IPX£¬X.25£¬AppleTalkµÈµÄÐÒ飬¸÷ÖÖ¾ßÌåÐÒéʵÏÖµÄÔ´ÂëÔÚlinux/net/Ŀ¼ÏÂÏàÓ¦µÄÃû³Æ¡£ÔÚÕâÀïÖ÷ÒªÌÖÂÛTCP/IP(IPv4)ÐÒ飬ʵÏÖµÄÔ´ÂëÔÚlinux/net/ipv4,ÆäÖÐlinux/net/ipv4/af_inet.cÊÇÖ÷ÒªµÄ¹ÜÀíÎļþ¡£
¡¡¡¡ÍøÂç½Ó¿ÚSocket²ãΪÓû§ÌṩµÄÍøÂç·þÎñµÄ±à³Ì½Ó¿Ú¡£Ö÷ÒªµÄÔ´ÂëÔÚlinux/net/socket.c¡£
Èý.ÍøÂçÉ豸½Ó¿Ú²¿·Ý
¡¡¡¡ÎïÀí²ãÉÏÓÐÐí¶à²»Í¬ÀàÐ͵ÄÍøÂç½Ó¿ÚÉ豸, ÔÚÎļþinclude/linux/if_arp.hµÄ28ÐÐÀﶨÒåÁËARPÄÜ´¦ÀíµÄ¸÷ÖÖÎïÀíÉ豸µÄ±êÖ¾·û¡£ÍøÂçÉ豸½Ó¿ÚÒª¸ºÔð¾ßÌåÎïÀí½éÖʵĿØÖÆ£¬´ÓÎïÀí½éÖʽÓÊÕÒÔ¼°·¢ËÍÊý¾Ý£¬²¢¶ÔÎïÀí½éÖʽøÐÐÖîÈç×î´óÊý¾Ý°üÖ®ÀàµÄ¸÷ÖÖÉèÖá£ÕâÀïÎÒÃÇÒԱȽϼòµ¥µÄ3Com3c501ÒÔÌ«Íø¿¨µÄÇý¶¯³ÌÐòΪÀý£¬´ó¸Å½²Ò»ÏÂÕâ²ãµÄ¹¤×÷ÔÀí¡£Ô´ÂëÔÚLinux/drivers/net/3c501.c¡£
¡¡¡¡ÎÒÃÇ´ÓÖ±¾õÉÏÀ´¿¼ÂÇ£¬Ò»¸öÍø¿¨µ±È»×îÖ÷ÒªµÄÊÇÍê³ÉÊý¾ÝµÄ½ÓÊպͷ¢ËÍ£¬ÔÚÕâÀïÎÒÃÇÀ´¿´¿´½ÓÊպͷ¢Ë͵Ĺý³ÌÊÇÔõôÑùµÄ¡£
¡¡¡¡·¢ËÍÏà¶ÔÀ´Ëµ±È½Ï¼òµ¥£¬ÔÚLinux/drivers/net/3c501.cµÄ475ÐпªÊ¼µÄel_start_xmit()Õâ¸öº¯Êý¾ÍÊÇʵ¼ÊÏò3Com3c501ÒÔÌ«Íø¿¨·¢ËÍÊý¾ÝµÄº¯Êý£¬¾ßÌåµÄ·¢Ë͹¤×÷²»ÍâºõÊǶÔһЩ¼Ä´æÆ÷µÄ¶Áд£¬Ô´ÂëµÄ×¢ÊͺÜÇå³þ£¬´ó¼Ò¿ÉÒÔ¿´¿´¡£
¡¡ ½ÓÊյŤ×÷Ïà¶ÔÀ´Ëµ±È½Ï¸´ÔÓ¡£Í¨³£À´Ëµ£¬Ò»¸öеİüµ½ÁË£¬»òÕßÒ»¸ö°ü·¢ËÍÍê³ÉÁË£¬¶¼»á²úÉúÒ»¸öÖжϡ£ÔÚLinux/drivers/net/3c501.cÖеÄ572ÐУ¬¿ªÊ¼µÄel_interrupt()º¯ÊýÀïÃæ£¬Ç°°ë²¿·Ý´¦ÀíµÄÊÇ·¢ËÍÍê°üÒÔºóµÄ»ã±¨£¬ºó°ë²¿·Ý´¦ÀíµÄÊÇÒ»¸öÐÂÀ´µÄ°ü£¬¾ÍÊÇ˵½ÓÊÕµ½ÁËеÄÊý¾Ý¡£el_interrupt()º¯Êý²¢Ã»ÓжÔеİü½øÐÐÌ«¶àµÄ´¦Àí£¬¾Í½»¸øÁ˽ÓÊÕ´¦Àíº¯Êýel_receive()¡£el_receive()Ê×Ïȼì²é½ÓÊյİüÊÇ·ñÕýÈ·£¬Èç¹ûÊÇÒ»¸ö¡°ºÃ¡±°ü¾Í»áΪ°ü·ÖÅäÒ»¸ö»º³å½á¹¹(dev_alloc_skb())£¬ÕâÑùÇý¶¯³ÌÐò¶Ô°üµÄ½ÓÊÕ¹¤×÷¾ÍÍê³ÉÁË£¬Í¨¹ýµ÷ÓÃÉϲãµÄº¯Êýnetif_rx()(net/core/dev.c1214ÐÐ) £¬°Ñ°ü½»¸øÉϲ㡣
¡¡ ÏÖÔÚÇý¶¯³ÌÐòÓÐÁË·¢ËͺͽÓÊÕÊý¾ÝµÄ¹¦ÄÜÁË£¬Çý¶¯³ÌÐòÔõôÑùºÍÉϲ㽨Á¢ÁªÏµÄØ£¿¾ÍÊÇ˵½ÓÊÕµ½°üÒÔºóÔõôË͸øÉϲ㣬ÒÔ¼°ÉϲãÔõôÄܵ÷ÓÃÇý¶¯³ÌÐòµÄ·¢Ëͺ¯ÊýÄØ£¿
¡¡ ÓÉÏÂÍùÉϵĹØÏµ£¬ÊÇͨ¹ýÇý¶¯³ÌÐòµ÷ÓÃÉϲãµÄnetif_rx()(net/core/dev.c 1214ÐÐ)º¯ÊýʵÏֵģ¬Çý¶¯³ÌÐòͨ¹ýÕâ¸öº¯Êý°Ñ½Óµ½µÄÊý¾Ý½»¸øÉϲ㣬Çë×¢ÒâËùÓеÄÍø¿¨Çý¶¯³ÌÐò¶¼ÐèÒªµ÷ÓÃÕâ¸öº¯ÊýµÄ£¬ÕâÊÇÍøÂç½Ó¿ÚºËÐIJãºÍÍøÂç½Ó¿ÚÉ豸ÁªÏµµÄÇÅÁº¡£
¡¡ ÓÉÉÏÍùÏµĹØÏµ¾Í¸´ÔÓµã¡£ÍøÂç½Ó¿ÚºËÐIJãÐèÒªÖªµÀÓжàÉÙÍøÂçÉ豸¿ÉÒÔÓã¬Ã¿¸öÉ豸µÄº¯ÊýµÄÈë¿ÚµØÖ·µÈ¶¼ÒªÖªµÀ¡£ÍøÂç½Ó¿ÚºËÐIJã»á´óÉùº°£¬¡°ºÙ£¬ÓжàÉÙÉ豸¿ÉÒÔ°ïÎÒ·¢ËÍÊý¾Ý°ü£¿ÄÜ·¢Ë͵ģ¬Çë¸øÎÒÅųÉÒ»¶Ó£¡¡±¡£ÕâÒ»¶Ó¾ÍÓÉdev_base¿ªÊ¼£¬Ö¸Õëstructnet_device *dev_base(Linux/include/linux/netdevice.h 436ÐÐ)¾ÍÊDZ£´æÁËÍøÂç½Ó¿ÚºËÐIJãËùÖªµÀµÄËùÓÐÉ豸¡£¶ÔÓÚÍøÂç½Ó¿ÚºËÐIJãÀ´Ëµ£¬ËùÓеÄÉ豸¶¼ÊÇÒ»¸önet_device½á¹¹£¬ËüÔÚinclude/linux/netdevice.h,line 233Àï±»¶¨Ò壬ÕâÊÇ´ÓÍøÂç½Ó¿ÚºËÐIJãµÄ½Ç¶È¿´µ½µÄÒ»¸ö³éÏóµÄÉ豸£¬ÎÒÃÇÀ´¿´¿´ÍøÂç½Ó¿ÚºËÐIJãµÄ½Ç¶È¿´µ½µÄÍøÂçÉ豸¾ßÓеŦÄÜ£º
¡¡¡¡struct net_device {
¡¡¡¡¡¡¡
¡¡¡¡open()
¡¡¡¡stop()
¡¡¡¡hard_start_xmit() £¯* ÈÃϲ㷢Êý¾Ý°ü */
¡¡¡¡hard_header()
¡¡¡¡rebuild_header()
¡¡¡¡set_mac_address()
¡¡¡¡do_ioctl()
¡¡¡¡set_config()
¡¡¡¡hard_header_cache()
¡¡¡¡header_cache_update()
¡¡¡¡change_mtu()
¡¡¡¡tx_timeout()
¡¡¡¡hard_header_parse()
¡¡¡¡neigh_setup()
¡¡¡¡accept_fastpath()
¡¡¡¡¡¡¡
¡¡¡¡}
¡¡¡¡Èç¹ûÍøÂç½Ó¿ÚºËÐIJãÐèÒªÓÉϲ㷢ËÍÊý¾ÝµÄʱºò£¬ÔÚdev_baseÕÒµ½É豸ÒԺ󣬾ÍÖ±½Óµ÷dev->hard_start_xmit()µÄÕâ¸öº¯ÊýÀ´ÈÃϲ㷢Êý¾Ý°ü¡£
¡¡¡¡Çý¶¯³ÌÐòÒªÈÃÍøÂç½Ó¿ÚºËÐIJãÖªµÀ×Ô¼ºµÄ´æÔÚ£¬µ±È»Òª¼ÓÈëdev_baseËùÖ¸ÏòµÄÖ¸ÕëÁ´£¬È»ºó°Ñ×Ô¼ºµÄº¯ÊýÒÔ¼°¸÷ÖÖ²ÎÊýºÍnet_deviceÀïµÄÏàÓ¦µÄÓò¶ÔÓ¦ÆðÀ´¡£¼ÓÈëdev_baseËùÖ¸ÏòµÄÖ¸ÕëÁ´ÊÇͨ¹ýº¯Êýregister_netdev(&dev_3c50)(linux/drivers/net/net_init.c, line 532)½¨Á¢µÄ¡£¶ø°Ñ×Ô¼ºµÄº¯ÊýÒÔºÍnet_deviceÀïµÄÏàÓ¦µÄÓò¼°¸÷ÖÖ²ÎÊý¹ØÏµµÄ½¨Á¢ÊÇÔÚel1_probe1()(Linux/drivers/net/3c501.c)Àï½øÐеģº
¡¡¡¡el1_probe1(){
¡¡¡¡¡¡¡
¡¡¡¡dev->open = &el_open;
¡¡¡¡dev->hard_start_xmit = &el_start_xmit; /* ÏÂÃæ×¢½âµÄ£¬¾ÍÊÇ´ËÓï¾ä */
¡¡¡¡dev->tx_timeout = &el_timeout;
¡¡¡¡dev->watchdog_timeo = HZ;
¡¡¡¡dev->stop = &el1_close;
¡¡¡¡dev->get_stats = &el1_get_stats;
¡¡¡¡dev->set_multicast_list = &set_multicast_list;
¡¡¡¡¡¡¡
¡¡¡¡ether_setup(dev);
¡¡¡¡¡¡¡
¡¡¡¡}
¡¡¡¡½øÒ»²½µÄ¶ÔÓ¦¹¤×÷ÔÚether_setup(dev) (drivers/net/net_init.c, line 405 )Àï½øÐС£ÎÒÃÇ×¢Òâµ½dev->hard_start_xmit =&el_start_xmit£¬ÕâÑù·¢Ëͺ¯ÊýµÄ¹ØÏµ¾Í½¨Á¢ÁË£¬ÉϲãÖ»ÖªµÀµ÷ÓÃdev->hard_start_xmitÕâ¸öÀ´·¢ËÍÊý¾Ý£¬ÉÏÃæµÄÓï¾ä¾Í°ÑÇý¶¯³ÌÐòʵ¼ÊµÄ·¢Ëͺ¯Êý¸æËßÁËÉϲ㡣
xiazhouquan ÓÚ 2009-09-07 18:21:46·¢±í:
ÏÖÔÚ¿´ÕâЩ×ÊԴͦºÃµÄ£¬Â¥Ö÷ÐÒ¿àÁË
frog ÓÚ 2006-06-09 09:20:25·¢±í:
ËÄ.ÍøÂç½Ó¿ÚºËÐIJ¿·Ö
¡¡¡¡¸Õ²Å̸ÂÛÁËÇý¶¯³ÌÐòÔõôºÍÍøÂç½Ó¿ÚºËÐIJãÏνӵġ£ÍøÂç½Ó¿ÚºËÐIJãÖªµÀÇý¶¯³ÌÐòÒÔ¼°Çý¶¯³ÌÐòµÄº¯ÊýµÄÈë¿ÚÊÇͨ¹ý*dev_baseÖ¸ÏòµÄÉ豸Á´µÄ£¬¶øÏ²ãÊÇͨ¹ýµ÷ÓÃÕâÒ»²ãµÄº¯Êýnetif_rx()(net/core/dev.c1214ÐÐ) °ÑÊý¾Ý´«µÝ¸öÕâÒ»²ãµÄ¡£
¡¡¡¡ÍøÂç½Ó¿ÚºËÐIJãµÄÉϲãÊǾßÌåµÄÍøÂçÐÒ飬ϲãÊÇÇý¶¯³ÌÐò£¬ÎÒÃÇÒѾ½â¾öÁËϲãµÄ¹ØÏµ£¬µ«ºÍÉϲãµÄ¹ØÏµÃ»Óнâ¾ö¡£ÏÈÀ´ÌÖÂÛÒ»ÏÂÍøÂç½Ó¿ÚºËÐIJãºÍÍøÂçÐÒé×岿·ÝµÄ¹ØÏµ£¬ÕâÖÖ¹ØÏµ²»ÍâºõÒ²ÊǽÓÊպͷ¢Ë͵ĹØÏµ¡£
¡¡¡¡ÍøÂçÐÒ飬ÀýÈçIP£¬ARPµÈµÄÐÒéÒª·¢ËÍÊý¾Ý°üµÄʱºò»á°ÑÊý¾Ý°ü´«µÝ¸øÕâ²ã(ÍøÂç½Ó¿ÚºËÐIJã)£¬ÄÇôÕâÖÖ´«µÝÊÇͨ¹ýʲôº¯ÊýÀ´·¢ÉúµÄÄØ£¿ÍøÂç½Ó¿ÚºËÐIJãͨ¹ýdev_queue_xmit()(net/core/dev.c,line975)Õâ¸öº¯Êý,ÏòÉϲãÌṩͳһµÄ·¢Ëͽӿڣ¬Ò²¾ÍÊÇ˵ÎÞÂÛÊÇIP£¬»¹ÊÇARPÐÒ飬ͨ¹ýÕâ¸öº¯Êý°ÑÒª·¢Ë͵ÄÊý¾Ý´«µÝ¸øÕâÒ»²ã£¬Ïë·¢ËÍÊý¾ÝµÄʱºòµ÷ÓÃÕâ¸öº¯Êý¾Í¿ÉÒÔÁË¡£dev_queue_xmit()×öµÄ¹¤×÷×îºó»áÂäʵµ½dev->hard_start_xmit()£¬¶ødev->hard_start_xmit()»áµ÷ÓÃʵ¼ÊµÄÇý¶¯³ÌÐòÀ´Íê³É·¢Ë͵ÄÈÎÎñ¡£ÀýÈçÉÏÃæµÄÀý×ÓÖУ¬µ÷ÓÃdev->hard_start_xmit()ʵ¼Ê¾ÍÊǵ÷ÓÃÁËel_start_xmit()¡£
¡¡¡¡ÏÖÔÚÌÖÂÛ½ÓÊÕµÄÇé¿ö¡£ÍøÂç½Ó¿ÚºËÐIJãͨ¹ýµÄº¯Êýnetif_rx()(net/core/dev.c 1214ÐÐ)½ÓÊÕÁËϲ㷢ËÍÀ´µÄÊý¾Ý£¬Õâʱºòµ±È»Òª°ÑÊý¾Ý°üÍùÉϲãÅÉËÍ¡£ËùÓеÄÐÒé×åµÄϲãÐÒé¶¼ÐèÒª½ÓÊÕÊý¾Ý£¬TCP/IPµÄIPÐÒéºÍARPÐÒ飬SPX/IPXµÄIPXÐÒ飬AppleTalkµÄDDPºÍAARPÐÒéµÈ¶¼ÐèÒªÖ±½Ó´ÓÍøÂç½Ó¿ÚºËÐIJã½ÓÊÕÊý¾Ý£¬ÍøÂç½Ó¿ÚºËÐIJã½ÓÊÕÊý¾ÝÊÇÈçºÎ°Ñ°ü·¢¸øÕâЩÐÒéµÄÄØ£¿ÕâʱµÄÇéÐΣ¬Óë¸Ã²ãºÍÆäϲãµÄ¹ØÏµºÜÏàËÆ£¬ÍøÂç½Ó¿ÚºËÐIJãµÄÏÂÃæ¿ÉÄÜÓÐÐí¶àµÄÍø¿¨Çý¶¯³ÌÐò£¬ÎªÁËÖªµÀÔõôÏòÕâЩÇý¶¯³ÌÐò·¢Êý¾Ý£¬Ç°ÃæÒѾ½²¹ý£¬ÊÇͨ¹ý*dev_baseÕâ¸öÖ¸ÕëÖ¸ÏòµÄÁ´½â¾öµÄ¡£ÏÖÔÚ½â¾öºÍÉϲãµÄ¹ØÏµ£¬ÊÇͨ¹ýstatic struct packet_ptype_base[16]( net/core/dev.c line 164)Õâ¸öÊý×é½â¾öµÄ¡£Õâ¸öÊý×é°üº¬ÁËÐèÒª½ÓÊÕÊý¾Ý°üµÄÐÒ飬ÒÔ¼°ËüÃǵĽÓÊÕº¯ÊýµÄÈë¿Ú¡£
¡¡¡¡´ÓÉÏÃæ¿ÉÒÔ¿´µ½£¬IPÐÒé½ÓÊÕÊý¾ÝÊÇͨ¹ýip_rcv()º¯ÊýµÄ£¬¶øARPÐÒéÊÇͨ¹ýarp_rcv()µÄ£¬ÍøÂç½Ó¿ÚºËÐIJãֻҪͨ¹ýÕâ¸öÊý×é¾Í¿ÉÒÔ°ÑÊý¾Ý½»¸øÉϲ㺯ÊýÁË¡£
¡¡¡¡Èç¹û£¬ÓÐÐÒéÏë°Ñ×Ô¼ºÌí¼Óµ½Õâ¸öÊý×飬ÊÇͨ¹ýdev_add_pack()(net/core/dev.c, line233)º¯ÊýÌí¼Ó£»´ÓÊý×éɾ³ý£¬ÔòÊÇͨ¹ýdev_remove_pack()º¯ÊýµÄ¡£Ip²ãµÄ×¢²áÊÇÔÚ³õʼ»¯º¯Êý½øÐеÄvoid __initip_init(void) (net/ipv4/ip_output.c, line 1003)
¡¡¡¡{
¡¡¡¡¡¡¡
¡¡¡¡dev_add_pack(&ip_packet_type);
¡¡¡¡¡¡¡
¡¡¡¡}
¡¡¡¡ÖØÐµ¹»ØÎÒÃǹØÓÚ½ÓÊÕµÄÌÖÂÛ£¬ÍøÂç½Óinclude¿ÚºËÐIJãͨ¹ýµÄº¯Êýnetif_rx()(net/core/dev.c 1214ÐÐ)½ÓÊÕÁËÉϲ㷢ËÍÀ´µÄÊý¾Ý£¬¿´¿´Õâ¸öº¯Êý×öÁËЩʲô¡£
¡¡¡¡ÓÉÓÚÏÖÔÚ»¹ÊÇÔÚÖжϵķþÎñÀïÃæ£¬ËùÒÔ²¢²»Äܹ»´¦ÀíÌ«¶àµÄ¶«Î÷£¬Ê£ÏµĶ«Î÷¾Íͨ¹ýcpu_raise_softirq(this_cpu, NET_RX_SOFTIRQ)½»¸øÈíÖжϴ¦Àí£¬ ´Óopen_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL)¿ÉÒÔÖªµÀNET_RX_SOFTIRQÈíÖжϵĴ¦Àíº¯ÊýÊÇnet_rx_action()(net/core/dev.c, line 1419)¡£net_rx_action()¸ù¾ÝÊý¾Ý°üµÄÐÒéÀàÐÍÔÚÊý×éptype_base[16]ÀïÕÒµ½ÏàÓ¦µÄÐÒ飬²¢´ÓÖÐÖªµÀÁ˽ÓÊյĴ¦Àíº¯Êý£¬È»ºó°ÑÊý¾Ý°ü½»¸ø´¦Àíº¯Êý£¬ÕâÑù¾Í½»¸øÁËÉϲ㴦Àí£¬Êµ¼Êµ÷Óô¦Àíº¯ÊýÊÇͨ¹ýnet_rx_action()ÀïµÄpt_prev->func()ÕâÒ»¾ä¡£ÀýÈçÈç¹ûÊý¾Ý°üÊÇIPÐÒéµÄ»°£¬ptype_base[ETH_P_IP]->func()(ip_rcv()),ÕâÑù¾Í°ÑÊý¾Ý°ü½»¸øÁËIPÐÒé¡£
Îå.ÍøÂçÐÒ鲿·Ö
¡¡¡¡ÐÒé²ãÊÇÕæÕýʵÏÖÊÇÔÚÕâÒ»²ã¡£ÔÚlinux/include/linux/socket.hÀïÃæ£¬LinuxµÄBSD Socket¶¨ÒåÁ˶àÖÁ32ÖÖÖ§³ÖµÄÐÒé×壬ÆäÖÐPF_INET¾ÍÊÇÎÒÃÇ×îÊìϤµÄTCP/IPÐÒé×å(IPv4, ÒÔÏÂûÓÐÌØ±ðÉùÃ÷¶¼Ö¸IPv4)¡£ÒÔÕâ¸öÐÒé×åΪÀý£¬¿´¿´Õâ²ãÊÇÔõô¹¤×÷µÄ¡£ÊµÏÖTCP/IPÐÒé×åµÄÖ÷ÒªÎļþÔÚLinux/net/ipv4/Ŀ¼ÏÂÃæ£¬Linux/net/ipv4/af_inet.cΪÖ÷ÒªµÄ¹ÜÀíÎļþ¡£
¡¡¡¡ÔÚLinux2.4.16ÀïÃæ£¬ÊµÏÖÁËTCP/IPÐÒé×åÀïÃæµÄµÄIGMP,TCP,UDP,ICMP,ARP,IP¡£ÎÒÃÇÏÈÌÖÂÛÒ»ÏÂÕâЩÐÒéÖ®¼äµÄ¹ØÏµ¡£IPºÍARPÐÒéÊÇÐèÒªÖ±½ÓºÍÍøÂçÉ豸½Ó¿Ú´ò½»µÀµÄÐÒ飬Ҳ¾ÍÊÇÐèÒª´ÓÍøÂçºËÐÄÄ£¿é(core)½ÓÊÕÊý¾ÝºÍ·¢ËÍÊý¾ÝµÄ¡£¶øÆäËüÐÒéTCP,UDP,IGMP,ICMPÊÇÐèÒªÖ±½ÓÀûÓÃIPÐÒéµÄ£¬ÐèÒª´ÓIPÐÒé½ÓÊÕÊý¾Ý£¬ÒÔ¼°ÀûÓÃIPÐÒé·¢ËÍÊý¾Ý£¬Í¬Ê±»¹ÒªÏòÉϲãSocket²ãÌṩֱ½ÓµÄµ÷Óýӿڡ£¿ÉÒÔ¿´µ½IP²ãÊÇÒ»¸öºËÐĵÄÐÒ飬ÏòÏÂÐèÒªºÍϲã´ò½»µÀ£¬ÓÖÒªÏòÉϲãÌṩËùÓеĴ«ÊäºÍ½ÓÊյķþÎñ¡£
¡¡¡¡ÏÈÀ´¿´¿´IPÐÒé²ã¡£ÍøÂçºËÐÄÄ£¿é(core) Èç¹û½ÓÊÕµ½IP²ãµÄÊý¾Ý£¬Í¨¹ýptype_base[ETH_P_IP] Êý×éµÄIP²ãµÄÏîÖ¸ÏòµÄIPÐÒéµÄip_packet_type->ip_rcv()º¯Êý°ÑÊý¾Ý°ü´«µÝ¸øIP²ã,Ò²¾ÍÊÇ˵IP²ãͨ¹ýÕâ¸öº¯Êýip_rcv()(linux/net/ipv4/ip_input.c)½ÓÊÕÊý¾ÝµÄ¡£ip_rcv()Õâ¸öº¯ÊýÖ»¶ÔIPÊý¾Ý°ü×öÁËһЩchecksumµÄ¼ì²é¹¤×÷£¬Èç¹û°üÊÇÕýÈ·µÄ£¬¾Í°Ñ°ü½»¸øÁËÏÂÒ»¸ö´¦Àíº¯Êýip_rcv_finish()(×¢Òâµ÷ÓÃÊÇͨ¹ýNF_HOOKÕâ¸öºêʵÏÖµÄ)¡£ÏÖÔÚ£¬ip_rcv_finish()Õâ¸öº¯ÊýÕæÕýÒªÍê³ÉһЩIP²ãµÄ¹¤×÷ÁË¡£IP²ãÒª×öµÄÖ÷Òª¹¤×÷¾ÍÊÇ·ÓÉ£¬Òª¾ö¶¨°ÑÊý¾Ý°üÍùÄÇÀïËÍ¡£Â·ÓɵŤ×÷ÊÇͨ¹ýº¯Êýip_route_input()(/linux/net/ipv4/route.c,line 1622)ʵÏֵġ£¶ÔÓÚ½øÀ´µÄ°ü¿ÉÄܵÄ·ÓÉÓÐÕâЩ£º
¡¡¡¡ÊôÓÚ±¾µØµÄÊý¾Ý(¼´ÊÇÐèÒª´«µÝ¸øTCP£¬UDP£¬IGMPÕâЩÉϲãÐÒéµÄ) £»
¡¡¡¡ÐèҪת·¢µÄÊý¾Ý°ü(Íø¹Ø»òÕßNAT·þÎñÆ÷Ö®ÀàµÄ)£»
¡¡¡¡²»¿ÉÄÜ·ÓɵÄÊý¾Ý°ü(µØÖ·ÐÅÏ¢ÓÐÎó)£»
¡¡¡¡ÎÒÃÇÏÖÔÚ¹ØÐĵÄÊÇÈç¹ûÊý¾ÝÊDZ¾µØÊý¾ÝµÄʱºòÔõô´¦Àí¡£ip_route_input()µ÷ÓÃip_route_input_slow()(net/ipv4/route.c, line 1312)£¬ÔÚip_route_input_slow()ÀïÃæ
µÄ1559ÐÐrth->u.dst.input=ip_local_deliver£¬Õâ¾ÍÊÇÅжϵ½IP°üÊDZ¾µØµÄÊý¾Ý°ü£¬²¢°Ñ±¾µØÊý¾Ý°ü´¦Àíº¯ÊýµÄµØÖ··µ»Ø¡£ºÃÁË£¬Â·Óɹ¤×÷Íê³ÉÁË£¬·µ»Øµ½ip_rcv_finish()¡£ip_rcv_finish()×îºóµ÷ÓÃÁËskb->dst->input(skb)£¬´ÓÉÏÃæ¿ÉÒÔ¿´µ½£¬ÕâÆäʵ¾ÍÊǵ÷ÓÃÁËip_local_deliver()º¯Êý£¬¶øip_local_deliver()½Óמ͵÷ÓÃÁËip_local_deliver_finish()¡£ÏÖÔÚÕæÕýµ½ÁËÍùÉϲ㴫µÝÊý¾Ý°üµÄʱºòÁË¡£
¡¡¡¡ÏÖÔÚµÄÇéÐκÍÍøÂçºËÐÄÄ£¿é²ã(core) ÍùÉϲ㴫µÝÊý¾Ý°üµÄÇéÐηdz£ÏàËÆ,Ôõô´Ó¶à¸öÐÒéÑ¡ÔñºÏÊʵÄÐÒ飬²¢ÇÒÍùÕâ¸öÐÒé´«µÝÊý¾ÝÄØ£¿ÍøÂçÍøÂçºËÐÄÄ£¿é²ã(core) ͨ¹ýÒ»¸öÊý×éptype_base[16]±£´æÁË×¢²áÁ˵ÄËùÓпÉÒÔ½ÓÊÕÊý¾ÝµÄÐÒ飬ͬÑùÍøÂçÐÒé²ãÒ²¶¨ÒåÁËÕâÑùÒ»¸öÊý×éstruct net_protocol*inet_protos[MAX_INET_PROTOS](/linux/net/ipv4/protocol.c#L102),Ëü±£´æÁËËùÓÐÐèÒª´ÓIPÐÒé²ã½ÓÊÕÊý¾ÝµÄÉϲãÐÒé(IGMP£¬TCP£¬UDP£¬ICMP)µÄ½ÓÊÕ´¦Àíº¯ÊýµÄµØÖ·¡£ÎÒÃÇÀ´¿´¿´TCPÐÒéµÄÊý¾Ý½á¹¹ÊÇÔõôÑùµÄ£º
£¯* ¡¡¡¡linux/net/ipv4/protocol.c line67 */
¡¡¡¡static struct inet_protocol tcp_protocol = {
¡¡¡¡handler: tcp_v4_rcv,// ½ÓÊÕÊý¾ÝµÄº¯Êý
¡¡¡¡err_handler: tcp_v4_err,// ³ö´í´¦ÀíµÄº¯Êý
¡¡¡¡next: IPPROTO_PREVIOUS,
¡¡¡¡protocol: IPPROTO_TCP,
¡¡¡¡name: "TCP"
¡¡¡¡};
¡¡¡¡µÚÒ»Ïî¾ÍÊÇÎÒÃÇ×î¹ØÐĵÄÁË£¬IP²ã¿ÉÒÔͨ¹ýÕâ¸öº¯Êý°ÑÊý¾Ý°üÍùTCP²ã´«µÄ¡£ÔÚlinux/net/ipv4/protocol.cµÄÉϲ¿£¬ÎÒÃÇ¿ÉÒÔ¿´µ½ÆäËüÐÒé²ãµÄ´¦Àíº¯ÊýÊÇigmp_rcv(),udp_rcv(), icmp_rcv()¡£Í¬ÑùÔÚlinux/net/ipv4/protocol.c£¬ÍùÊý×éinet_protos[MAX_INET_PROTOS] ÀïÃæÌí¼ÓÐÒéÊÇͨ¹ýº¯Êýinet_add_protocol()ʵÏֵģ¬É¾³ýÐÒéÊÇͨ¹ý inet_del_protocol()ʵÏֵġ£inet_protos[MAX_INET_PROTOS]³õʼ»¯µÄ¹ý³ÌÔÚlinux/net/ipv4/af_inet.c inet_init()³õʼ»¯º¯ÊýÀïÃæ¡£
¡¡¡¡inet_init(){
¡¡¡¡¡¡
¡¡¡¡printk(KERN_INFO "IP Protocols: ");
¡¡¡¡for (p = inet_protocol_base; p != NULL {
¡¡¡¡struct inet_protocol *tmp = (struct inet_protocol *) p->next;
¡¡¡¡inet_add_protocol(p);// Ìí¼ÓÐÒé
¡¡¡¡printk("%s%s",p->name,tmp?", ":"\n");
¡¡¡¡p = tmp;
¡¡¡¡¡¡¡
¡¡¡¡}
¡¡¡¡Èç¹ûÄãÔÚLinuxÆô¶¯µÄʱºòÓÐÁôÒâÆô¶¯µÄÐÅÏ¢, »òÕßÔÚlinuxÏ´òÃüÁîdmesg¾Í¿ÉÒÔ¿´µ½ÕâÒ»¶Î³ÌÐòÊä³öµÄÐÅÏ¢£º
¡¡¡¡IP Protocols£º ICMP£¬UDP£¬TCP£¬IGMPÒ²¾ÍÊÇ˵ÏÖÔÚÊý×éinet_protos[]ÀïÃæÓÐÁËICMP£¬UDP£¬TCP£¬IGMPËĸöÐÒéµÄinet_protocolÊý¾Ý½á¹¹£¬Êý¾Ý½á¹¹°üº¬ÁËËüÃǽÓÊÕÊý¾ÝµÄ´¦Àíº¯Êý¡£
¡¡¡¡Linux 2.4.16ÔÚlinux/include/linux/socket.hÀﶨÒåÁË32ÖÖÖ§³ÖµÄBSD socketÐÒé
£¬³£¼ûµÄÓÐTCP/IP,IPX/SPX,X.25µÈ£¬¶øÃ¿ÖÖÐÒ黹Ìṩ²»Í¬µÄ·þÎñ£¬ÀýÈçTCP/IPÐÒéͨ¹ýTCPÐÒéÖ§³ÖÁ¬½Ó·þÎñ£¬¶øÍ¨¹ýUDPÐÒéÖ§³ÖÎÞÁ¬½Ó·þÎñ£¬Ãæ¶ÔÕâô¶àµÄÐÒ飬ÏòÓû§ÌṩͳһµÄ½Ó¿ÚÊDZØÒªµÄ£¬ÕâÖÖͳһÊÇͨ¹ýsocketÀ´½øÐеġ£
¡¡¡¡ÔÚBSD socketÍøÂç±à³ÌµÄģʽÏ£¬ÀûÓÃһϵÁÐͳһµÄº¯ÊýÀ´ÀûÓÃͨÐŵķþÎñ¡£ÀýÈçÒ»¸öµäÐ͵ÄÀûÓÃTCPÐÒéͨÐųÌÐòÊÇÕâÑù£º
¡¡¡¡sock_descriptor = socket(AF_INET,SOCK_STREAM,0);
¡¡¡¡connect(sock_descriptor, µØÖ·£¬) £»
¡¡¡¡send(sock_descriptor,¡±hello world¡±);
¡¡¡¡recv(sock_descriptor,buffer,1024,0);
¡¡¡¡µÚÒ»¸öº¯ÊýÖ¸¶¨ÁËÐÒéInetÐÒ飬¼´TCP/IPÐÒ飬ͬʱÊÇÀûÓÃÃæÏòÁ¬½ÓµÄ·þÎñ£¬ÕâÑù¾Í¶ÔÓ¦µ½TCPÐÒ飬ÒÔºóµÄ²Ù×÷¾ÍÊÇÀûÓÃsocketµÄ±ê×¼º¯Êý½øÐеġ£
¡¡¡¡´ÓÉÏÃæÎÒÃÇ¿ÉÒÔ¿´µ½Á½¸öÎÊÌ⣬Ê×ÏÈsocket²ãÐèÒª¸ù¾ÝÓû§Ö¸¶¨µÄÐÒé×å(ÉÏÃæÊÇAF_INET)£¬´ÓÏÂÃæ32ÖÖÐÒéÖÐÑ¡ÔñÒ»ÖÖÐÒéÀ´Íê³ÉÓû§µÄÒªÇ󣬵±ÐÒé×åÈ·¶¨ÒԺ󣬻¹Òª°ÑÌØ¶¨µÄ·þÎñÓ³Éäµ½ÐÒé×åϵľßÌåÐÒ飬ÀýÈçµ±Óû§Ö¸¶¨µÄÊÇÃæÏòÁ¬½ÓµÄ·þÎñʱ£¬InetÐÒé×å»áÓ³Éäµ½TCPÐÒé¡£
¡¡¡¡´Ó¶à¸öÐÒéÖÐÑ¡ÔñÓû§Ö¸¶¨µÄÐÒ飬²¢°Ñ¾ßÌåµÄ³öÀí½»¸øÑ¡ÖеÄÐÒ飬ÕâºÍÍøÂçºËÐIJãÏòÉϺÍÏòÏÂÏνӵÄÎÊÌâ±¾ÖÊÉÏÊÇÒ»ÑùµÄ£¬ËùÒÔ½â¾öµÄ·½·¨Ò²ÊÇÒ»ÑùµÄ£¬Í¬Ñù»¹ÊÇͨ¹ýÊý×é¡£ÔÚLinux/net/socket.c¶¨ÒåÁËÕâ¸öÊý×éstaticstruct net_proto_family *net_families[NPROTO] ¡£Êý×éµÄÔªËØÒѾȷ¶¨ÁË£¬net_families[2] ÊÇTCP/IPÐÒ飬net_families[3]ÊÇX.25ÐÒ飬¾ßÌåÄÇÒ»Ïî¶ÔӦʲôÐÒ飬ÔÚinclude/linux/socket.hÓж¨Òå¡£µ«ÊÇÿһÏîµÄÊý¾Ý½á¹¹net_proto_familyµÄopsÊǿյģ¬Ò²¾ÍÊǾßÌåÐÒé´¦Àíº¯ÊýµÄµØÖ·ÊDz»ÖªµÀµÄ¡£ÐÒéµÄ´¦Àíº¯ÊýºÍops½¨Á¢ÁªÏµÊÇͨ¹ýsock_register()(Linux/net/socket.c)Õâ¸öº¯Êý½¨Á¢µÄ£¬ÀýÈçTCP/IPÐÒéµÄÊÇÕâÑù½¨Á¢¹ØÏµµÄ£º
¡¡¡¡int __init inet_init(void) £¯* (net/ipv4/af_inet.c) */
¡¡¡¡{
¡¡¡¡(void) sock_register(&inet_family_ops);
¡¡¡¡}
¡¡¡¡Ö»Òª¸ø³öAF_INET(ÔÚºêÀﶨÒåÊÇ2)£¬¾Í¿ÉÒÔÕÒµ½net_failies[2] ÀïÃæµÄ´¦Àíº¯ÊýÁË ¡£
¡¡¡¡ÐÒéµÄÓ³ÉäÍê³ÉÁË£¬ÏÖÔÚÒª½øÐзþÎñµÄÓ³ÉäÁË¡£Éϲ㵱Ȼ²»¿ÉÄÜÖªµÀϲãµÄʲôÐÒéÄܶÔÓ¦ÌØ¶¨µÄ·þÎñ£¬ËùÒÔÕâÖÖÓ³Éä×ÔÈ»ÓÉÐÒé×å×Ô¼ºÍê³É¡£ÔÚTCP/IPÐÒé×åÀÕâÖÖÓ³ÉäÊÇͨ¹ýstruct list_head inetsw[SOCK_MAX]( net/ipv4/af_inet.c)Õâ¸öÊý×é½øÐÐÓ³ÉäµÄ£¬ÔÚ̸ÂÛÕâ¸öÊý×é֮ǰÎÒÃÇÀ´¿´ÁíÍâÒ»¸öÊý×éinetsw_array[] (net/ipv4/af_inet.c)
¡¡¡¡static struct inet_protosw inetsw_array[] =
¡¡¡¡{
¡¡¡¡ {
¡¡¡¡ type: SOCK_STREAM,
¡¡¡¡ protocol: IPPROTO_TCP,
¡¡¡¡ prot: &tcp_prot,
¡¡¡¡ ops: &inet_stream_ops,
¡¡¡¡ capability: -1,
¡¡¡¡ no_check: 0,
¡¡¡¡ flags: INET_PROTOSW_PERMANENT,
¡¡¡¡ },
¡¡¡¡ {
¡¡¡¡ type: SOCK_DGRAM,
¡¡¡¡ protocol: IPPROTO_UDP,
¡¡¡¡ prot: &udp_prot,
¡¡¡¡ ops: &inet_dgram_ops,
¡¡¡¡ capability: -1,
¡¡¡¡ no_check: UDP_CSUM_DEFAULT,
¡¡¡¡ flags: INET_PROTOSW_PERMANENT,
¡¡¡¡ },
¡¡¡¡ {
¡¡¡¡ type: SOCK_RAW,
¡¡¡¡ protocol: IPPROTO_IP, /* wild card */
¡¡¡¡ prot: &raw_prot,
¡¡¡¡ ops: &inet_dgram_ops,
¡¡¡¡ capability: CAP_NET_RAW,
¡¡¡¡ no_check: UDP_CSUM_DEFAULT,
¡¡¡¡ flags: INET_PROTOSW_REUSE,
¡¡¡¡ }
¡¡¡¡};
¡¡¡¡ÎÒÃÇ¿´µ½£¬SOCK_STREAMÓ³Éäµ½ÁËTCPÐÒ飬SOCK_DGRAMÓ³Éäµ½ÁËUDPÐÒ飬SOCK_RA
WÓ³Éäµ½ÁËIPÐÒé¡£ÏÖÔÚÖ»Òª°Ñinetsw_arrayÀïµÄÈýÏîÌí¼Óµ½Êý×éinetsw[SOCK_MAX]¾Í¿É
ÒÔÁË£¬Ìí¼ÓÊÇͨ¹ýº¯Êýinet_register_protosw()ʵÏֵġ£ÔÚinet_init()(net/ipv4/af_inet.c) ÀïÍê³ÉÁËÕâЩ¹¤×÷¡£
¡¡¡¡»¹ÓÐÒ»¸öÐèÒªÓ³ÉäµÄ¾ÍÊÇsocketÆäËüÖîÈçaccept,send(),connect(),release(),bind()µÈµÄ²Ù×÷º¯ÊýÊÇÔõôӳÉäµÄÄØ£¿ÎÒÃÇÀ´¿´Ò»ÏÂÉÏÃæµÄÊý×éµÄTCPµÄÏî:
¡¡¡¡{
¡¡¡¡type: SOCK_STREAM,
¡¡¡¡protocol: IPPROTO_TCP,
¡¡¡¡prot: &tcp_prot,
¡¡¡¡ops: &inet_stream_ops,
¡¡¡¡capability: -1,
¡¡¡¡no_check: 0,
¡¡¡¡flags: INET_PROTOSW_PERMANENT,
¡¡¡¡},
¡¡¡¡ÎÒÃÇ¿´µ½ÕâÖÖÓ³ÉäÊÇͨ¹ýops£¬ºÍprotÀ´Ó³ÉäµÄ£¬ÎÒÃÇÔÙÀ´¿´¿´ tcp_protÕâÒ»Ï
¡¡¡¡struct proto tcp_prot = {
¡¡¡¡name: "TCP",
¡¡¡¡close: tcp_close,
¡¡¡¡connect: tcp_v4_connect,
¡¡¡¡disconnect: tcp_disconnect,
¡¡¡¡accept: tcp_accept,
¡¡¡¡ioctl: tcp_ioctl,
¡¡¡¡init: tcp_v4_init_sock,
¡¡¡¡destroy: tcp_v4_destroy_sock,
¡¡¡¡shutdown: tcp_shutdown,
¡¡¡¡setsockopt: tcp_setsockopt,
¡¡¡¡getsockopt: tcp_getsockopt,
¡¡¡¡sendmsg: tcp_sendmsg,
¡¡¡¡recvmsg: tcp_recvmsg,
¡¡¡¡backlog_rcv: tcp_v4_do_rcv,
¡¡¡¡hash: tcp_v4_hash,
¡¡¡¡unhash: tcp_unhash,
¡¡¡¡get_port: tcp_v4_get_port,
¡¡¡¡};
¡¡¡¡ËùÒÔµÄÓ³Éä¶¼ÒѾÍê³ÉÁË£¬Óû§µ÷ÓÃconnect()º¯Êý£¬Æäʵ¾ÍÊǵ÷ÓÃÁËtcp_v4_connect()º¯Êý£¬°´ÕÕÕâ·ùͼ£¬¶ÁÆðÔ´ÂëÀ´¾Í¼òµ¥Á˺ܶàÁË¡£
Áù Socket²ã
¡¡¡¡ÉÏÒ»½Ú°Ñsocket²ã´ó¶àÊýÒªÌÖÂ۵Ķ«Î÷¶¼Ì¸ÂÛÁË£¬ÏÖÔÚÖ»½²½²socket ²ãºÍÓû§µÄÏνӡ£
¡¡¡¡ÏµÍ³µ÷ÓÃsocket(),bind(),connect(),accept,send(),release()µÈÊÇÔÚLinux/net/socket.cÀïÃæÊµÏÖµÄ,ϵͳµ÷ÓÃʵÏֵĺ¯ÊýÊÇÏàÓ¦µÄº¯ÊýÃû¼ÓÉÏsys_µÄǰ׺¡£
¡¡¡¡ÏÖÔÚ¿´¿´µ±Óû§µ÷ÓÃsocket()Õâ¸öº¯Êý£¬µ½µ×ÏÂÃæ·¢ÉúÁËʲô¡£
¡¡¡¡Socket(AF_INET,SOCK_STREAM,0)µ÷ÓÃÁËsys_socket(),sys_socket()½Ó×ŵ÷ÓÃsocket_creat(),socket_creat()¾ÍÒª¸ù¾ÝÓû§ÌṩµÄÐÒé×å²ÎÊýÔÚnet_families[]ÀïѰÕÒºÏÊʵÄÐÒé×壬Èç¹ûÐÒé×åûÓб»°²×°¾ÍÒªÇëÇó°²×°¸ÃÐÒé×åµÄÄ£¿é£¬È»ºó¾Íµ÷ÓøÃÐÒé×åµÄcreate()º¯ÊýµÄ´¦Àí¾ä±ú¡£¸ù¾Ý²ÎÊýAF_INET£¬inet_creat()¾Í±»µ÷ÓÃÁË£¬ÔÚinet_creat()¸ù¾Ý·þÎñÀàÐÍÔÚinetsw[SOCK_MAX]Ñ¡ÔñºÏÊʵÄÐÒ飬²¢°ÑÐÒéµÄ²Ù×÷¼¯¸³¸øsocket¾ÍÊÇÁË£¬¸ù¾ÝSOCK_STREAM£¬TCPÐ
Ò鱻ѡÖУ¬
¡¡¡¡inet_creat(){
¡¡¡¡answer=inetsw [Óû§ÒªÇó·þÎñ] £»
¡¡¡¡sock->ops = answer->ops;
¡¡¡¡sk->prot = answer->prot
¡¡¡¡}
¡¡¡¡µ½´ËΪֹ£¬ÉÏ϶¼´òͨÁË£¬¸ÃÊÇ´ó¼Ò¶ÁÔ´ÂëµÄʱºòÁË¡£