這條if語句會進行索引判斷,對比從內核中讀取數據包使用的索引號是否和用戶通知libpcap監控網絡設備使用的索引號相同。如果索引號匹配失敗,pcap_read_packet函數會直接返回,不再調用libpcap提供的回調函數。
這段代碼是為了防止內核中可能出現的競爭情況,比如雖然已經創建了socket但還沒有來得及綁定到一個特定設備上,這種情況下AF_PACKET會在調用socket和bind中間把所有的數據包存儲到隊列中。
然而,當數據包發向作為bond設備一部分的物理設備時這個檢查會失敗。
用戶向libpcap請求對這個物理設備監控,但正如我們上面看到的,當有數據包到來時內核會用netif_receive_skb中的bond設備指針覆蓋dev結構。這樣就會造成bond設備的索引和物理設備的索引不一致。
這條if語句就是為什么發送的數據包在修改了內核以后仍然無法被類似tcpdump或者邊界流量測量器捕獲。
這個檢查在從內核讀取數據包的“新方法”中不存在,因為支持新mmap方法的內核不會產生上述代碼需要防止的競爭條件。因此,把一個更新版本的libpcap鏈接到tcpdump上(內核已經過修改)就能看到發送給bond上物理設備的數據包。
這個檢查在當前版本的libpcap上仍然存在。
總結
計算機能夠正常運行真是個奇跡。
原文轉自:http://www.anti-gravitydesign.com