BPF socket filter

以dhcpc過濾udp port 68爲例,進行一下說明
X = 表示index reg.也就是文件定位器。目前X=0,X=skb->data. skb->data指定的ip hdr.
A表示加速reg.保存臨時變量
static const struct sock_filter filter_instr[] = {
/* load 9th byte (protocol) */
BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), //報文0位置+9位置中讀出一字節放到A reg中。//BPF_LD=load. BPF_B = byte(1字節); BPF_ABS表示是絕對值=skb->data
/* jump to L1 if it is IPPROTO_UDP, else to L4 */
//A的值與IPPROTO_UDP相比,相等則jump到本行(本行爲-1)的下一行(就是0行),不相等則jump到本行的offset=6的一行。
//BPF_JMP,BPF_JEQ = if jump的意思。
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
/* 從IP頭(index=0)定位到6,並讀出(BPF_H表示)兩個字節。這是IP的分片標誌。 */
/* L1: load halfword from offset 6 (flags and frag offset) */
BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
/* jump to L4 if any bits in frag offset field are set, else to L2 */
/* */
BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
/* L2: skip IP header (load index reg with header len) */
/* 移動X,X+=*(X+k);本行中k=0; 也就是從IPhdr中讀出一字節,把此字節的數據賦值給X
BPF_MSH就是移動X的意思。*/
BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
/* load udp destination port from halfword[header_len + 2] */
/* BPF_IND從相對值X開始,加上k(2),在此位置取出一個16bit數據放到A中。 */
BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
/* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
/* A的值==68? yes,則jump 0行(本行號=-1)no 則jump (本行號-1)第一行。 */
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
/* L3: accept packet ("accept 0x7fffffff bytes") */
/* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */
BPF_STMT(BPF_RET|BPF_K, 0x7fffffff),//返回FF,表示成功。
/* L4: discard packet ("accept zero bytes") */
BPF_STMT(BPF_RET|BPF_K, 0),//返回0表示失敗。

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章