分析內核版本:Linux 2.6.36.2。 分析網卡:DM9000
一、網絡設備驅動程序分析。
1、Linux 網絡設備驅動程序 分層:
Linux 網絡設備驅動程序從上到下可分為4層,依次為:網絡協議接口層、網絡設備接口層、提供實際功能的設備 驅動功能層、以及 網絡設備與媒介層。這4層作用如下:
1) 網絡協議接口層:網絡協議接口層想網絡協議提供統一的數據包收發接口,不論是上層ARP,還是IP,都通過dev_queue_xmit() 函數收發數據,並通過netif_rx 函數
接收數據。這一層的存在使得上層協議獨立於具體的設備。
2)網絡設備接口層:網絡設備接口層向協議層接口層提供統一的用於描述具體網絡設備屬性 和 操作的結構體 net_device,該結構體是設備驅動功能層中各函數的容器,
實際上,網絡設備接口層從宏觀上規劃了具體操作硬件的設備驅動功能層的結構。
3)設備功能層:該層的各個函數是網絡設備接口層net_device 數據結構具體成員,是驅使網絡設備硬件完成相應動作的程序,它通過har_start_xmit() 函數啟動發送操作,
並通過網絡設備上的中斷觸發接收操作。
4)網絡設備 與 媒介層: 是完成數據包發送和接收的物理實體,包括網絡適配器和具體的傳輸媒介,網絡適配器被設備驅動功能層中的函數物理上驅動,對於Linux而言,
網絡設備和媒介都是可以虛擬的。
在設計具體的網絡設備驅動程序是,我們需要完成的主要工作是編寫設備驅動功能層 的 相關函數以以填充net_device 數據結構的內容並將net_device 注冊入內核。
2、網絡協議接口層程序分析:
1) int netif_xmit (struct sk_buff *skb);// 發送一個sk_buff 數據包
int netif_rx (struct sk_buff *skb); // 接收一個數據包
以上函數定義在 net/core/dev.c 中
sk_buff 結構體定義在 include/linux/skbuff.h 文件, 它的含義為“套接字緩沖區”,用於在Linux 網絡子系統中個層之間傳遞數據,是Linux 網絡子系統數據傳遞的“中樞神經”
2) 套接字緩沖區 sk_buff 結構體
- struct sk_buff {
- /* These two members must be first. */
- struct sk_buff *next;
- struct sk_buff *prev;
-
- ktime_t tstamp;
-
- struct sock *sk;
- struct net_device *dev;
-
- /*
- * This is the control buffer. It is free to use for every
- * layer. Please put your private variables there. If you
- * want to keep them across layers you have to do a skb_clone()
- * first. This is owned by whoever has the skb queued ATM.
- */
- char cb[48] __aligned(8);
-
- unsigned long _skb_refdst;
- #ifdef CONFIG_XFRM
- struct sec_path *sp;
- #endif
- unsigned int len,
- data_len;
- __u16 mac_len,
- hdr_len;
- union {
- __wsum csum;
- struct {
- __u16 csum_start;
- __u16 csum_offset;
- };
- };
- __u32 priority;
- kmemcheck_bitfield_begin(flags1);
- __u8 local_df:1,
- cloned:1,
- ip_summed:2,
- nohdr:1,
- nfctinfo:3;
- __u8 pkt_type:3,
- fclone:2,
- ipvs_property:1,
- peeked:1,
- nf_trace:1;
- kmemcheck_bitfield_end(flags1);
- __be16 protocol;
-
- void (*destructor)(struct sk_buff *skb);
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- struct nf_conntrack *nfct;
- struct sk_buff *nfct_reasm;
- #endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- struct nf_bridge_info *nf_bridge;
- #endif
-
- int skb_iif;
- #ifdef CONFIG_NET_SCHED
- __u16 tc_index; /* traffic control index */
- #ifdef CONFIG_NET_CLS_ACT
- __u16 tc_verd; /* traffic control verdict */
- #endif
- #endif
-
- __u32 rxhash;
-
- kmemcheck_bitfield_begin(flags2);
- __u16 queue_mapping:16;
- #ifdef CONFIG_IPV6_NDISC_NODETYPE
- __u8 ndisc_nodetype:2,
- deliver_no_wcard:1;
- #else
- __u8 deliver_no_wcard:1;
- #endif
- kmemcheck_bitfield_end(flags2);
-
- /* 0/14 bit hole */
-
- #ifdef CONFIG_NET_DMA
- dma_cookie_t dma_cookie;
- #endif
- #ifdef CONFIG_NETWORK_SECMARK
- __u32 secmark;
- #endif
- union {
- __u32 mark;
- __u32 dropcount;
- };
-
- __u16 vlan_tci;
-
- sk_buff_data_t transport_header; // 傳輸層
- sk_buff_data_t network_header; // 網絡層
- sk_buff_data_t mac_header; // MAC 層
- /* These elements must be at the end, see alloc_skb() for details. */
- sk_buff_data_t tail;
- sk_buff_data_t end;
- unsigned char *head, // 緩沖區頭指針
- *data; // 有效數據頭指針
- unsigned int truesize;
- atomic_t users;
- };