收包流程
-
數據包到達網卡NIC
-
非混雜模式的NIC校驗Mac地址
- 即目的Mac地址不是本機的數據包直接丟棄,不會處理
- 混雜模式一般適用於存在虛擬機時,虛擬機daemon會把物理網卡設置爲混雜模式
- 抓包時也需要混雜模式
-
校驗數據幀的校驗字段FCS,丟棄校驗失敗的錯誤幀
-
NIC通過DMA方式將數據幀放入提前映射好的內存區域
-
NIC等待超時或者接受區滿了後出發硬件中斷指令
-
CPU執行硬件中斷並運行網卡的驅動程序,對網卡進行輪詢收包
-
把數據包送入協議棧
-
調用netfilter(iptables對應的內核程序)的PREROUTING鏈
-
查找路由表,進行轉發或者進入本機
-
對進行本機的包調用netfilter的LOCAL_IN鏈
-
調用四層協議棧,例如tcp_v4_rcv
-
查找到對應的socket,運行TCP狀態機
-
通過epoll或者其他輪詢方式通知應用程序
-
應用程序讀取數據
發包流程
- 應用程序發送數據
- TCP協議棧爲發送的數據申請skb(內核中的數據包對象)
- 構建TCP頭部,例如src, dst的port, checksum
- 調用三層協議,構建IP頭部,調用netfilter的LOCAL_OUT鏈
- 查找路由表,判斷是發送給本機還是外部
- 如果發送給本機,就不用進行後面的步驟了
- 調用netfilter的POST_ROUTING鏈
- 對超過的MTU的報文進行分片
- 一般TCP協議在上層已經分好片了,UDP協議纔在這裏分片
- 調用二層的發包函數dev_queue_xmit
- 調用網卡驅動程序,在超時或者數據滿了後出發內核中斷
- 驅動程序把數據包映射到DMA內存
- 網卡從MDA中取出數據併發送
- 發送完畢後出發硬件中斷,釋放已經發送完的數據包的內存