網絡協議——TCP/IP協議
簡介:
TCP(傳輸控制協議)和 IP(網際協議)是兩個獨立且緊密結合的協議,負責管理和引導數據報文在 Internet上的傳輸。二者使用專門的報文頭定義每個報文的內容。TCP 負責和遠程主機的連接,IP負責尋址,使報文被送到其該去的地方。
TCP/IP協議模型如下圖所示:
1.網絡接口層
有時也稱為數據鏈路層或網絡接口層,通常包括操作系統中的設備驅動程序和計算機中對應的網絡接口卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理接口細節。
2.網絡層
有時也稱為互聯網層,處理分組在網絡中的活動,例如分組的選路。在T C P / I P協議族中,網絡層協議包括I P協議(網際協議),I C M P協議(I n t e r n e t互聯網控制報文協議),以及I G M P協議(I n t e r n e t組管理協議)。
3.傳輸層
主要為兩臺主機上的應用程序提供端到端的通信。在 TCP/I P協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(用戶數據報協議)
TCP為兩臺主機提供高可靠性的數據通信。它所做的工作包括把應用程序交給它的數據分成合適的小塊交給下面的網絡層,確認接收到的分組,設置發送最后確認分組的超時時鐘等。由于傳輸層提供了高可靠性的端到端的通信,因此應用層可以忽略所有這些細節。
UDP為應用層提供一種非常簡單的服務。它只是把稱為數據報的分組從一臺主機發送到另一臺主機,但并不保證該數據報能到達另一端。任何必需的可靠性必須由應用層來提供。
4.應用層
負責處理特定的應用程序細節
幾乎各種不同的 T C P / I P實現都會提供下面這些通用的應用程序:
Telnet 遠程登錄。
FTP 文件傳輸協議。
SMTP 簡單郵件傳送協議。
SNMP 簡單網絡管理協議。
5.各層主要協議
6. OSI 模型和 TCP/IP 模型的區別
6.1類似之處
均為層次結構
存在可比的傳輸層和網絡層
均有應用層,但其所提供的服務有所不同
均是一種基于協議數據單元的包交換網絡
作為概念上的模型和事實上的標準,具有同等的重要性
6.2不同之處
OSI 模型包括了 7 層,而 TCP/IP 模型只有 4 層。TCP/IP 模型將表示層與會話層包含到了應用層中去完成。另外,TCP/IP模型還將 OSI的數據鏈路層和物理層包括到了一個網絡接口層中。
OSI 參考模型在網絡層支持無連接和面向連接的兩種服務,而在傳輸層僅支持面向連接的服務。TCP/IP 模型在網絡層則只支持無連接的一種服務,但在傳輸層支持面向連接和無連接兩種服務。
TCP/IP由于有較少的層次,更為簡單
協議棧結構的說明
1、 驅動中,使用ISR/POLL/NAPI等方式從硬件收包
2、 收包接口中通過netif_receive_skb()上交協議棧
3、 在netif_receive_skb()函數中做協議解析
core/dev.c中,為報文處理的第二層,用于分離收到的以太網報文的協議類型,同我們某產品上一個叫做Packet Handler模塊一樣,逐級分發報文。
該模塊有一個list_head鏈表,鏈表上掛了很多packet_type數據結構,packet_type數據結構中包括ether_type, dev指針以及func指針等成員。
為加快對報文的分發速度,這個鏈表實現成了一個HASH表,共16way,使用ethertype作為索引。
內核中常注冊的ethertype類型:
ETH_P_IP
ETH_P_ARP
ETH_P_HDLC
ETH_P_DEC
ETH_P_PPP
PKT_TYPE_LACPDU
ETH_P_PPP_SES
ETH_P_PPP_DISC
ETH_P_BPQ
ETH_P_PARP
ETH_P_802_2
ETH_P_TR_802_2
ETH_P_X25
ETH_P_8021Q
ETH_P_ALL用于所有
其中Func是上層協議的鉤子函數,常用的有ip_rcv()和arp_rcv()等,然后iprcv()中又會解析ip上的協議,調用icmp_rcv/igmp_rcv/udp_rcv/tcp_rcv()等等。
新的協議類型可以在驅動模塊加載時,通過下面的接口增加到packet_type_list中:
void dev_add_pack()用于增加一種協議類型,將其packet_type指針加到鏈表上。
void dev_remove_pack()用于從list_head上刪除一種協議類型
4、 解析完報文協議之后,將報文放到skb_queue隊列中
skb_queue為系統底層與應用程序之間一個接口。所有接收到的同類報文都會被掛到這個隊列上,然后由協議棧上層接口來取。
5、 協議上層接口通過系統調用獲取skb。代碼位于net模塊下:
sys_recv()
sys_recvfrom()
sock_recvmsg()
__sock_recvmsg()
udp_recvmsg()或者tcp_recvmsg()
__skb_recv_datagram()
ip_cmsg_recv()
從skb接收隊列skb_queue收包
某項目中的代碼
1. 驅動driver使用NAPI方式,從硬件queue中收包
2. 調用netif_receiv_skb()函數,上交收到的報文
這個項目支持NAPT,因此會在該函數中直接調用NAPT回調做NAT,而對于非NAPT印射的報文,進行如下處理:
先遍歷ptype_all鏈表,list_for_each_entry_rcu(),最終調用packet_type.func()
編譯內核時選上BRIDGE,則會執行網橋模塊br_handle_frame_hook(skb),源文件為bridge/br.c
網橋模塊的初始化pkt_type為PACKET_HOST或者PACKET_OTHERHOST
如果編譯內核時選上了mac_VLAN模塊,則會執行macvlan_handle_frame_hook
初始化為PACKET_BROADCAST、PACKET_MULTICAST、PACKET_HOST
最后一步,判斷type==skb->protocol,會查詢鏈表,找到匹配的protocol鉤子并且調用。
3. Skb的釋放時機
如果是合法報文,放入接收隊列,在用戶系統調用取包時釋放,否則在netif_receiv_skb()函數中釋放。
802.1q協議模塊實現
帶802.1qTAG的模塊有自己單獨的協議類型,一般是0x8100。使用前面說的packet_list操作接口注冊一個新的packet_type掛到鏈表中,這樣,所有帶TAG的報文會被轉發到802.1q的接口上。
應用程序里,每調用vconfig創建一個VLAN,就會創建一個新的net device,這個虛擬擴展的net device會在原來物理的net device上面工作,將VLAN對應的報文都轉移到虛擬net device的收發接口上。
new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name,vlan_setup);