linux協議棧pf_packet相關分析
一:名詞解釋:
1,BSD socket層:
bsd socket是Berkeley套接字應用程式介面(API)包括了一個用C語言寫成的應用程式開發庫,主要用於實現程序間通訊,在計算機網路通訊方面被廣泛使用。
Berkeley套接字介面的定義在幾個標頭檔案中。這些檔案的名字和內容與具體的實現之間有些許的不同。 大體上包括:
<sys/socket.h><netinet/in.h><sys/un.h><arpa/inet.h><netdb.h>
這個列表是一個Berkeley套接字API庫提供的函式或者方法的概要:
socket() 建立一個新的確定型別的套接字,型別用一個整型數值標識,併為它分配系統資源。
bind() 一般用於伺服器端,將一個套接字與一個套接字地址結構相關聯,比如,一個指定的本地埠和IP地址。
listen() 用於伺服器端,使一個繫結的TCP套接字進入監聽狀態。
connect() 用於客戶端,為一個套接字分配一個自由的本地埠號。 如果是TCP套接字的話,它會試圖獲得一個新的TCP連線。
accept() 用於伺服器端。 它接受一個從遠端客戶端發出的建立一個新的TCP連線的接入請求,建立一個新的套接字,與該連線相應的套接字地址相關聯。
send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用於往/從遠端套接字傳送和接受資料。
close() 用於系統釋放分配給一個套接字的資源。 如果是TCP,連線會被中斷。
gethostbyname()和gethostbyaddr() 用於解析主機名和地址.
select() 用於修整有如下情況的套接字列表: 準備讀,準備寫或者是有錯誤。
poll() 用於檢查套接字的狀態。 套接字可以被測試,看是否可以寫入、讀取或是有錯誤。
getsockopt() 用於查詢指定的套接字一個特定的套接字選項的當前值。
setsockopt() 用於為指定的套接字設定一個特定的套接字選項。
http://zh.wikipedia.org/wiki/Berkeley套接字
2,協議棧 Protocol Stack
協議族是一組協議的集合, 協議棧是協議的實現,指網路中各層協議的總和(有順序的一組協議), 協議棧的工作原理類似於棧,遵守FIFO的原則。其形象的反映了一個網路中檔案傳輸的過程:由上層協議到底層協議,再由底層協議到上層協議。使用最廣泛的是英特網協 議棧,由上到下的協議分別是:應用層(HTTP,TELNET,DNS,EMAIL等),運輸層(TCP,UDP),網路層(IP),鏈路層(WI- FI,乙太網,令牌環,FDDI等),物理層.
TCP/IP也稱”國際協議簇”, 即不僅指 TCP/IP協議本身,而且包括與其有關的協議。 TCP為傳輸控制協議,IP為網際協議,是網路層最重要的協議。採用TCP/IP協議通過網際網路傳送資訊可減少網路中的傳輸阻塞,方便大批量的資料在網上 傳輸,從而提高網路的傳輸效率。 TCP/IP協議族中包括上百個互為關聯的協議,其中有:Telnet(Remote Login):提供遠端登入功能; FTP (FileTransfer Protocol):遠端檔案傳輸協議,允許使用者將遠端主機上的檔案拷貝到自己的計算機上; SMTP (Simple Messagetransfer Protocol):簡單資訊傳輸協議,主要用於傳輸電子郵件;NFS(Network File Server):網路檔案伺服器,可使多臺計算機透明地訪問彼此的目錄 ; UDP ( User DatagramProtocol):使用者資料包協議。
3,INET socket層
BSD socket向用戶提供了一個一致性的網路程式設計介面,他的底層是INET PF_UNIX PF_IPX PF_PACKET PF_INET6 等協議棧。INET socket層是其中的IPv4網路協議的介面,相當於建立了AF_INET形式的socket,該層使用sock結構儲存介面上額外的引數,主要的檔案有net/ipv4/protocol.c、net/ipv4/af_inet.c和net/core/sock.c。
socket層支援包括TCP/IP協議在內的Internet協議族,一個協議使用另一個協議的服務。它與BSD socket層的介面要通過一系列Internet協議簇,socket操作,這一操作是在網路初始化時就已經註冊到BSD socket層的。BSD socket層從已註冊的INET proto_ops資料結構中呼叫INET層socket支援例程來為它執行工作。例如,一個地址族為INET的BSD socket建立請求,將用到下層的INET socket的建立函式。。在這些操作中,BSD socket層把用來描述BSD socket的socket 結構傳構到INET層。為了不把BSD socket與TCP/IP的特定資訊搞混,INET socket層使用它自己的資料結構 --sock,它與BSD socket結構相連。這意味著後來的INET socket呼叫能夠很容易地重新找到sock結構。sock結構的協議操作指標(sock->sk_prot)也在初始化時建立,它依賴與被請求的協議。如果請求的是TCP,那麼sock結構的協議操作指標將指向TCP連線所必需的TCP協議操作集。proto_ops(socket->ops)結構由地址族型別和一系列指向與特定地址族對應的socket操作例程的函式指標組成。
推斷:bsd socket層封裝了操作inet socket層的函式,inet socket層可以替換成其他協議層,比如pf_packet
4,TCP/UDP層,IP層;
實現傳輸層和網路層的操作,TCP/UDP層使用inet_protocol和proto結構,主要檔案有
net/ipv4/udp.c、net/ipv4/datagram.c、net/ipv4/tcp_input.c和net/ipv4/tcp_out.c。ip層使用packet_type結構表示,主要檔案包括net/ipv4資料夾下的ip_forward.c,ip_fragment.c,ip_input.c,ip_output.c。
5,驅動硬體介面層:
實現網路層操作,該層使用net_device結構表示,主要的檔案包括net/core/dev.c和driver/net目錄下的所有檔案。使用PPP,SLIP,Eethernet協議。
6,總結
本文要使用的Linux Net/4網路原始碼的,其中大部分位於目錄/usr/src/linux-2.x/net,列表如下, 插口層 BSD Socket /net/socket.c /net/protocols.c INET Socket /ipv4/protocol.c /ipv4/af_inet.c /net/ipv4/core/sock.c 協議層 TCP/UDP /net/ipv4/udp.c /net/ipv4/datagram.c /net/ipv4/tcp_input.c /net/ipv4//tcp_output.c /net/ipv4/tcp.c /net/ipv4/tcp_minisocks.c /net/ipv4/tcp_timer.c etc... IP /net/ipv4/ip_forward.c /net/ipv4/ip_fragment.c /net/ipv4/ip_input.c /net/ipv4/ip_output.c 介面層 net/core/dev.c driver/net Ethernet二:linux核心接收網路資料包處理流程
1,收包
^
|--------------bsd socket層---------
| sys_read fs/read_write.c
| sock_read net/socket.c
| sock_recvmsg net/socket.c
|--------------inet socket層(也可以是PF_pocket層)-----------
inet_create
| inet_recvmsg net/ipv4/af_inet.c
| udp_recvmsg net/ipv4/udp.c
| skb_recv_datagram net/core/datagram.c
| ------------------------------------------- 傳輸層--------
| sock_queue_rcv_skb include/net/sock.h
| udp_queue_rcv_skb net/ipv4/udp.c
| udp_rcv net/ipv4/udp.c
| ip_local_deliver_finish net/ipv4/ip_input.c
| ip_local_deliver net/ipv4/ip_input.c
| ip_recv net/ipv4/ip_input.c
| net_rx_action net/dev.c
| ----------------------------------鏈路層----------
| netif_rx net/dev.c
| el3_rx driver/net/3c309.c
| el3_interrupt driver/net/3c309.c
三:linux核心網路資料包傳送流程
如果socket(PF_INET,SOCK_DGRAM,IPPROTO_IP)
|--------------socket
| sys_write fs/read_write.c
| sock_writev net/socket.c
| sock_sendmsg net/socket.c
| inet_sendmsg net/ipv4/af_inet.c
|----------------傳輸層(協議棧)-----------
| udp_sendmsg net/ipv4/udp.c
| ip_build_xmit net/ipv4/ip_output.c
| output_maybe_reroute net/ipv4/ip_output.c
| ip_output net/ipv4/ip_output.c
| ip_finish_output net/ipv4/ip_output.c
|--------------鏈路層(網絡卡驅動)---------------
| dev_queue_xmit net/dev.c
| --------------------------------------------
| el3_start_xmit driver/net/3c309.c
V
推斷使用socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
|--------------socket
| sys_write fs/read_write.c
| sock_writev net/socket.c
| sock_sendmsg net/socket.c (sock->ops = &packet_ops_spkt;)
|----------------傳輸層(協議棧)-----------
|packet_sendmsg_spkt net/packet/af_packet.c
|--------------鏈路層(網絡卡驅動)---------------
| dev_queue_xmit net/dev.c
| --------------------------------------------
| el3_start_xmit driver/net/3c309.c
V
1,linux協議棧分析sk_buff的結構分析:
在核心中sk_buff表示一個網路資料包,它是一個雙向連結串列,而連結串列頭就是sk_buff_head,在老的核心裡面sk_buff會有一個list域直接指向sk_buff_head也就是連結串列頭,現在在2.6.32裡面這個域已經被刪除了。
http://simohayha.iteye.com/blog/556168
2,linux協議棧struct sk_buff *skb相關的操作函式
struct sk_buff * skb
skb為要引用的緩衝區
http://blog.csdn.net/jasenwan88/article/details/7365060
3,Linux.協議棧分析.AF_PACKET
當通過socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))來建立處理鏈路層資料包時,核心會首先呼叫packet_create建立套接字
http://acm.hrbeu.edu.cn/~puppy/2012/02/09/linux-協議棧分析-af_packet/
4,Linux 網絡卡驅動相關——01-02-03
http://www.cnblogs.com/zhuyp1015/archive/2012/08/04.html
5.linux核心網路棧程式碼的準備知識
6,2.4中PACKET模組程式碼分析
http://linux.chinaunix.net/techdoc/net/2006/01/18/926921.shtml