一, 導論
bpf(berkeley packet filter)伯克利包過濾器。 是在linux 平台下的乙個包過濾器。使用此過濾器可以在socket程式設計時非常方便的實現各種過濾規則。
首先,要確保從socket中讀取的是packet,也就是說是 mac頭+ip頭+tcp/udp頭。
關於bpf的相關介紹可以檢視英文文件:
二, bpf的使用
首先來看一段實際應用中的**:
int init_packet_capture(struct lib_cap *p)
, ,
, }; if (null == p)
// init filter settings
filter.len =4;
filter.filter = bpf_code;
//set default value
p->ifindex = -1;
p->fd = -1;
p->buffer = null;
p->buf_len = 0;
if ( (sock = socket(pf_packet, sock_raw, htons(ethertype_sadp))) < 0)
if ( setsockopt(sock, sol_socket, so_attach_filter, &filter, sizeof(filter)) < 0);
....
}
以上**首先定義並初始化了乙個bpf過濾器 filter, 然後將其 so_attach_filter 到了socket 上。
這裡用到了兩個結構體:sock_fprog和sock_filter:
sock_fprog
struct sock_fprog
sock_filter
struct sock_filter
知道以上兩個結構體後,整段**就比較清晰了, 唯一比較費解的是那一串數字!!!
struct sock_filter bpf_code = ,
, ,
};
下面將分析這一串數字是如何產生的,以及它的意義。
三, bpfcode 生成方法
在注釋中有一段提示 tcpdump -dd ether proto 0x8033。
tcpdump 是linux 中除錯網路的乙個工具, 實際上tcpdump 就是用利用bpf原理編寫的乙個工具,所以tcpdump 提供了乙個生成bpf code 的乙個命令列:
這段數字的意義就是過濾乙太網協議中型別是 0x8033的資料報(某某it公司的產品自定義的乙個資料報)。這段數字到底實現了什麼功能呢? tcpdump 提供了 -d 選項來闡述這段數字的意義:
分析這段**可知,
ldh 是高位載入, 即從幀的第12位開始載入進記憶體,第12位就是去除6位src mac 與 6位 dst mac 的資料報型別字段。
jeq: 如果型別欄位是 0x8033 的話就返回 96個位元組,如果型別字段不是 0x8033的話就返回 0個位元組。
至此就已達到過濾型別為0x8033資料報的目的。
小結:細心的朋友可能會發現,bpf_code 陣列的第三行最後一列 0x00000060 與源**中的 0x00000020 並不一樣!
這是因為tcpdump 的預設返回位元組是96個位元組, 而實際需要抓取512(0x00000200, 16*16*2)個位元組的資料。關於這點給tcpdump 指定長度欄位-s就可以了:
linux 下的 bpf 是包過濾的利器, 結合tcpdump 工具,能非常快速的實現各種個性化的包過濾需求!
過濾器(6) 過濾器的攔截
本系列部落格彙總在這裡 過濾器彙總 我們來做個測試,寫乙個過濾器,指定過濾的資源為 index.jsp,然後我們在瀏覽器中直接訪問 index.jsp,你會發現過濾器執行了!但是,當我們在 helloservlet 中使用伺服器端的跳轉request.getrequestdispathcer ind...
ethereal的抓包過濾器
抓包過濾器用來抓取感興趣的包,用在抓包過程中。抓包過濾器使用的是libcap過濾器語言,在tcpdump的手冊中有詳細的解釋,基本結構是 not primitive and or not primitive 個人觀點 如果你想抓取某些特定的資料報時,可以有以下兩種方法,你可以任選一種,個人比較偏好第...
Wireshark 抓包過濾器學習
wireshark中,分為兩種過濾器 捕獲過濾器和顯示過濾器 捕獲過濾器是指wireshark一開始在抓包時,就確定要抓取哪些型別的包 對於不需要的,不進行抓取。顯示過濾器是指wireshark對所有的包都進行抓取,當使用者分析資料報的資訊,便於篩選出需要的資料報。總結來說,捕獲過濾器是在使用者開始...