赞
踩
struct sk_buff {.................................... __be16 protocol;.....................................};
type = skb->protocol; list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { if (ptype->type == type && (ptype->dev == null_or_orig || ptype->dev == skb->dev || ptype->dev == orig_dev)) { if (pt_prev) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = ptype; } }static inline int deliver_skb(struct sk_buff *skb, struct packet_type *pt_prev, struct net_device *orig_dev){ atomic_inc(&skb->users); return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);}
static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
static struct list_head ptype_all __read_mostly; /* Taps */
struct packet_type { __be16 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 *, struct net_device *); struct sk_buff *(*gso_segment)(struct sk_buff *skb, int features); int (*gso_send_check)(struct sk_buff *skb); void *af_packet_priv; struct list_head list;};
static struct packet_type ip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = ip_rcv, .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment,};static int __init inet_init(void){。。。。。。。。。。。。。。。。。。。。 dev_add_pack(&ip_packet_type);.........................................}
void dev_add_pack(struct packet_type *pt){ int hash; spin_lock_bh(&ptype_lock);///判断类型是否为ETH_P_ALL if (pt->type == htons(ETH_P_ALL)) list_add_rcu(&pt->list, &ptype_all); else {///计算hash值 hash = ntohs(pt->type) & PTYPE_HASH_MASK;///插入到相应的hash表位置 list_add_rcu(&pt->list, &ptype_base[hash]); } spin_unlock_bh(&ptype_lock);}
#define PACKET_HOST 0 /* To us */#define PACKET_BROADCAST 1 /* To all */#define PACKET_MULTICAST 2 /* To group */#define PACKET_OTHERHOST 3 /* To someone else */#define PACKET_OUTGOING 4 /* Outgoing of any type */
/* * This is an Ethernet frame header. *////帧头的表示。struct ethhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_source[ETH_ALEN]; /* source ether addr */ __be16 h_proto; /* packet type ID field */} __attribute__((packed));__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev){ struct ethhdr *eth; unsigned char *rawp;///一些初始化 skb->dev = dev; skb_reset_mac_header(skb); skb_pull(skb, ETH_HLEN); eth = eth_hdr(skb); if (is_multicast_ether_addr(eth->h_dest)) {///判断是否为广播。 if (!compare_ether_addr(eth->h_dest, dev->broadcast))///数据位广播 skb->pkt_type = PACKET_BROADCAST; else///多播 skb->pkt_type = PACKET_MULTICAST; } else if (1 /*dev->flags&IFF_PROMISC */ ) {///主要用来网络的监测。 if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; }///通过上面的图我们知道大于1536为ethernet 类型的帧,因此直接返回h_proto。 if (ntohs(eth->h_proto) >= 1536) return eth->h_proto; rawp = skb->data;///取数据位来判断是否是802.3的帧。 if (*(unsigned short *)rawp == 0xFFFF) return htons(ETH_P_802_3); /* * Real 802.2 LLC */ return htons(ETH_P_802_2);}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。