¡¡¡¡ËÄ.ÍøÂç½Ó¿ÚºËÐ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²ãµÄ×¢²áÊÇÔÚ³õʼ»¯º¯Êý½øÐеÄ
[code]void __initip_init(void) (net/ipv4/ip_output.c, line 1003)
{
¡¡¡
dev_add_pack(&ip_packet_type);
¡¡¡
}[/code]
¡¡¡¡ÖØе¹»ØÎÒÃǹØÓÚ½ÓÊÕµÄÌÖÂÛ£¬ÍøÂç½Ó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ÐÒé¡£
supop ÓÚ 2006-09-18 10:43:46·¢±í:
¡¡¡¡Áù 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ÐÒ鱻ѡÖУ¬
[code]inet_creat(){
¡¡¡¡answer=inetsw [Óû§ÒªÇó·þÎñ] £»
¡¡¡¡sock->ops = answer->ops;
¡¡¡¡sk->prot = answer->prot
¡¡¡¡}[/code]
¡¡¡¡µ½´ËΪֹ£¬ÉÏ϶¼´òͨÁË£¬¸ÃÊÇ´ó¼Ò¶ÁÔ´ÂëµÄʱºòÁË¡£
supop ÓÚ 2006-09-18 10:43:05·¢±í:
¡¡¡¡ÐÒéµÄÓ³ÉäÍê³ÉÁË£¬ÏÖÔÚÒª½øÐзþÎñµÄÓ³ÉäÁË¡£Éϲ㵱Ȼ²»¿ÉÄÜÖªµÀϲãµÄʲôÐÒéÄܶÔÓ¦Ìض¨µÄ·þÎñ£¬ËùÒÔÕâÖÖÓ³Éä×ÔÈ»ÓÉÐÒé×å×Ô¼ºÍê³É¡£ÔÚTCP/IPÐÒé×åÀÕâÖÖÓ³ÉäÊÇͨ¹ýstruct list_head inetsw[SOCK_MAX]( net/ipv4/af_inet.c)Õâ¸öÊý×é½øÐÐÓ³ÉäµÄ£¬ÔÚ̸ÂÛÕâ¸öÊý×é֮ǰÎÒÃÇÀ´¿´ÁíÍâÒ»¸öÊý×飺
[code]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,
¡¡¡¡ }
¡¡¡¡};[/code]
¡¡¡¡ÎÒÃÇ¿´µ½£¬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µÄÏî:
[code]{
¡¡¡¡type: SOCK_STREAM,
¡¡¡¡protocol: IPPROTO_TCP,
¡¡¡¡prot: &tcp_prot,
¡¡¡¡ops: &inet_stream_ops,
¡¡¡¡capability: -1,
¡¡¡¡no_check: 0,
¡¡¡¡flags: INET_PROTOSW_PERMANENT,
¡¡¡¡},[/code]
¡¡¡¡ÎÒÃÇ¿´µ½ÕâÖÖÓ³ÉäÊÇͨ¹ýops£¬ºÍprotÀ´Ó³ÉäµÄ£¬ÎÒÃÇÔÙÀ´¿´¿´ tcp_protÕâÒ»Ï
[code]¡¡¡¡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,
¡¡¡¡};[/code]
¡¡¡¡ËùÒÔµÄÓ³É䶼ÒѾÍê³ÉÁË£¬Óû§µ÷ÓÃconnect()º¯Êý£¬Æäʵ¾ÍÊǵ÷ÓÃÁËtcp_v4_connect()º¯Êý£¬°´ÕÕÕâ·ùͼ£¬¶ÁÆðÔ´ÂëÀ´¾Í¼òµ¥Á˺ܶàÁË¡£
supop ÓÚ 2006-09-18 10:41:57·¢±í:
¡¡¡¡Èç¹ûÄãÔÚ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ÐÒéͨÐųÌÐòÊÇÕâÑù£º
[code]sock_descriptor = socket(AF_INET,SOCK_STREAM,0);
¡¡¡¡connect(sock_descriptor, µØÖ·£¬) £»
¡¡¡¡send(sock_descriptor,¡±hello world¡±);
¡¡¡¡recv(sock_descriptor,buffer,1024,0);[/code]
¡¡¡¡µÚÒ»¸öº¯ÊýÖ¸¶¨ÁËÐÒé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ÐÒéµÄÊÇÕâÑù½¨Á¢¹ØϵµÄ£º
[code]int __init inet_init(void) £¯* (net/ipv4/af_inet.c) */
¡¡¡¡{
¡¡¡¡(void) sock_register(&inet_family_ops);
¡¡¡¡}[/code]
¡¡¡¡Ö»Òª¸ø³öAF_INET(ÔÚºêÀﶨÒåÊÇ2)£¬¾Í¿ÉÒÔÕÒµ½net_failies[2] ÀïÃæµÄ´¦Àíº¯ÊýÁË ¡£
supop ÓÚ 2006-09-18 10:40:39·¢±í:
¡¡¡¡Îå.ÍøÂçÐÒ鲿·Ö
¡¡¡¡ÐÒé²ãÊÇÕæÕýʵÏÖÊÇÔÚÕâÒ»²ã¡£ÔÚ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ÐÒéµÄÊý¾Ý½á¹¹ÊÇÔõôÑùµÄ£º
[code]£¯* ¡¡¡¡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"
¡¡¡¡};[/code]
¡¡¡¡µÚÒ»Ïî¾ÍÊÇÎÒÃÇ×î¹ØÐĵÄÁË£¬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()³õʼ»¯º¯ÊýÀïÃæ¡£
[code]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;
¡¡¡¡¡¡¡
¡¡¡¡}[/code]