ºìÁªLinuxÃÅ»§
Linux°ïÖú

LinuxÄÚºË2.4.xµÄÍøÂç½Ó¿Ú½á¹¹£¨¶þ£©

·¢²¼Ê±¼ä:2006-09-18 10:39:44À´Ô´:ºìÁª×÷Õß:supop
¡¡¡¡ËÄ.ÍøÂç½Ó¿ÚºËÐ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ЭÒé¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 4 ÌõÆÀÂÛ

  1. 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]

    ¡¡¡¡µ½´ËΪֹ£¬ÉÏ϶¼´òͨÁË£¬¸ÃÊÇ´ó¼Ò¶ÁÔ´ÂëµÄʱºòÁË¡£

  2. 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()º¯Êý£¬°´ÕÕÕâ·ùͼ£¬¶ÁÆðÔ´ÂëÀ´¾Í¼òµ¥Á˺ܶàÁË¡£

  3. 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] ÀïÃæµÄ´¦Àíº¯ÊýÁË ¡£

  4. 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]