2、协议相关2.1、第3层协议的管理在Linux内核中,有两种不同目的的3层协议:(1) ptype_all管理的协议主要用于分析目的,它接收所有到达第3层协议的数据包。(2) ptype_base管理正常的3层协议,仅接收具有正确协议标志符的数据包,例如,Internet的0x0800。注意sb_buff与net_device中几个字段的区别:sb_buff:unsigned short protocol高层协议从二层设备的角度所看到的协议,典型的协议包括 IP,IPV6和 ARP,完整的列表在 include/linux/if_ether.h。 unsigned char pkt_type帧的类型,可能的取值都在include/linux/if_packet.h 中定义. net_device:unsigned short type 设备类型(以太网,帧中继等)。在include/linux/if_arp.h 中有完整的类型列表。2.2、协议处理函数注册当协议注册时,内核会调用dev_add_pack添加一个与之对应的packet_type数据结构:
// include/linux/netdevice.h struct packet_type { unsigned short type; /* This is really htons(ether_type). */ struct net_device * dev; /* NULL is wildcarded here */ int ( * func) ( struct sk_buff * , struct net_device * , struct packet_type * ); void * af_packet_priv; struct list_head list;}; type:协议类型,它可以取以下一些值。来看看if_ether.h中定义的协议的类型: Code #define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */#define ETH_P_PUP 0x0200 /* Xerox PUP packet */#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */#define ETH_P_IP 0x0800 /* Internet Protocol packet */#define ETH_P_X25 0x0805 /* CCITT X.25 */#define ETH_P_ARP 0x0806 /* Address Resolution packet */#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */#define ETH_P_DEC 0x6000 /* DEC Assigned proto */#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */#define ETH_P_LAT 0x6004 /* DEC LAT */#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */#define ETH_P_CUST 0x6006 /* DEC Customer use */#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */#define ETH_P_ATALK 0x809B /* Appletalk DDP */#define ETH_P_AARP 0x80F3 /* Appletalk AARP */#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */#define ETH_P_IPX 0x8137 /* IPX over DIX */#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol * defined in draft-wilson-wrec-wccp-v2-00.txt */#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport * over Ethernet */#define ETH_P_AOE 0x88A2 /* ATA over Ethernet *//* * Non DIX types. Won't clash for 1500 types. */ #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */#define ETH_P_802_2 0x0004 /* 802.2 frames */#define ETH_P_SNAP 0x0005 /* Internal only */#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */#define ETH_P_CONTROL 0x0016 /* Card specific control frames */#define ETH_P_IRDA 0x0017 /* Linux-IrDA */#define ETH_P_ECONET 0x0018 /* Acorn Econet */#define ETH_P_HDLC 0x0019 /* HDLC frames */#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) * dev:网络设备。PF_PACKET套接字通常使用它在特定的设备监听,例如,tcpdump -i eth0 通过PF_PACKET套接字创建一个packet_type实例,然后将dev指向eth0对应的net_device数据结构。 func:协议处理函数。 af_packet_priv:被PF_PACKET套接字使用。 当同一个类型的协议有多个packet_type实例时,输入的帧会被所有的协议处理函数处理。 IP协议的packet_type: // net/ipv4/ip_output.c static struct packet_type ip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = ip_rcv,}; // 在inet_init中被调用 void __init ip_init( void ){ dev_add_pack( & ip_packet_type); ip_rt_init(); inet_initpeers(); #if defined(CONFIG_IP_MULTICAST) && defined(CONFIG_PROC_FS) igmp_mc_proc_init(); #endif } // net/core/dev.c void dev_add_pack( struct packet_type * pt){ int hash; spin_lock_bh( & ptype_lock); if (pt -> type == htons(ETH_P_ALL)) { netdev_nit ++ ; list_add_rcu( & pt -> list, & ptype_all); } else { hash = ntohs(pt -> type) & 15 ; list_add_rcu( & pt -> list, & ptype_base[hash]); } spin_unlock_bh( & ptype_lock);} 2.3、以太网帧(Ethernet)与802.3帧 老的以太网的帧的格式与标准和802.3标准的格式分别如下: 以太网的帧头(Ethernet frame header)的定义: // include/linux/if_ether.h struct ethhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_source[ETH_ALEN]; /* source ether addr */ unsigned short h_proto; /* packet type ID field */ } __attribute__((packed)); h_proto>1536的以太网类型: 2.4、eth_type_trans函数 // net/ethernet/eth.c unsigned short eth_type_trans( struct sk_buff * skb, struct net_device * dev){ struct ethhdr * eth; unsigned char * rawp; skb -> mac.raw = skb -> data; skb_pull(skb,ETH_HLEN); // 取出以太网头 eth = eth_hdr(skb); skb -> input_dev = dev; // 设置帧的类型 if ( * eth -> h_dest & 1 ) // 广播和多播地址 { if (memcmp(eth -> h_dest,dev -> broadcast, ETH_ALEN) == 0 ) skb -> pkt_type = PACKET_BROADCAST; else skb -> pkt_type = PACKET_MULTICAST; } /* * This ALLMULTI check should be redundant by 1.4 * so don't forget to remove it. * * Seems, you forgot to remove it. All silly devices * seems to set IFF_PROMISC. */ else if ( 1 /* dev->flags&IFF_PROMISC */ ) { if (memcmp(eth -> h_dest,dev -> dev_addr, ETH_ALEN)) // 如果帧的目标地址与网络设备的mac地址不同 skb -> pkt_type = PACKET_OTHERHOST; } if (ntohs(eth -> h_proto) >= 1536 ) return eth -> h_proto; rawp = skb -> data; /* * This is a magic hack to spot IPX packets. Older Novell breaks * the protocol design and runs IPX over 802.3 without an 802.2 LLC * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This * won't work for fault tolerant netware but does for the rest. */ // IPX数据包没有802.2标准的LLC层,0xFFFF为其标志位 if ( * (unsigned short * )rawp == 0xFFFF ) return htons(ETH_P_802_3); /* * Real 802.2 LLC */ // 802.2标准的LLC协议 return htons(ETH_P_802_2);} 该函数主要设置数据帧的类型,返回协议的类型。转载于:https://www.cnblogs.com/yequan/archive/2009/12/24/1631705.html
相关资源:数据结构—成绩单生成器