linux
netfilter
kernel module
see: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/netfilter.h#L42
There are five hook point that your can hook to capture network packet.
你可以決定要在哪個點 hook PRE_ROUTING 就是進來的所有封包 LOCOL_INPUT 是指只有送給你的上層 application 的封包, 不包含 forwarded 封包 FORWARDED 就是指路過但不是給你的封包 LOCOL_OUTPUT 跟 POST_ROUTING 就不用說了吧 ztex
struct nf_hook_ops
see:
see:https://elixir.bootlin.com/linux/v4.4.180/source/include/linux/netfilter.h#L171 nf_hook_thresh - call a netfilter hook, is triggered and in charge of executing hook function.
note that netfilter mechanism has changed a lot as linux version changes. This aritcle is test under linux 4.4. 180
ztex
see my repo: https://github.com/tony2037/synonetfilter
see:
在 linux kernel 中要寫一個 netfilter, 一個方便的方式就是寫一支註冊 net hook 的 kernel module 定義 hook operations 的 structure 就是
struct nf_hook_ops
把這個結構體的 hook (hook callback function), hooknum(hook 的位置), pf(protocol family), priority 填好 然後 call nf_register_net_hook (記得 unregister, kfree) ztex
這邊有個 dump tcp payload 的小範例 (不考慮 nonlinear) https://stackoverflow.com/questions/29553990/print-tcp-packet-data
struct sk_buff
see: https://people.cs.clemson.edu/~westall/853/notes/skbuff.pdf also see: https://www.kernel.org/doc/html/v4.14/networking/kapi.html also see: https://blog.csdn.net/ds1130071727/article/details/96908564 also see: http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-2-SECT-1.html also see: http://abcdxyzk.github.io/download/kernel/sk_buff详解.pdf also see: https://eeepage.info/sk_buff-packet/ also see: http://vger.kernel.org/~davem/skb_data.html
hook function 長這個樣子
其中 struct sk_buff
是一個重要的 structure 定義在 include/linux/skbuff.h
see: http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-2-SECT-1.html
可以看到 struct sk_buff
是個 doubly linked list
這牽扯到 碎片化 (fragment)
顯示幾個重要的 pointer head 指向頭部 data 指向包括 header 的部份 tail 指向 data 尾部 end 指向整個結構體最後 要拿到 tail 可以這樣
這牽扯到, 你的 config 是不是 DATA OFFSET, see: https://elixir.bootlin.com/linux/v4.4.180/source/include/linux/skbuff.h#L1769
剛提到 data 包括 header, 那要怎麼拿 header ?
include/linux/skbuff.h
中定義的幾個重要函式我在處理 SMB2 read response 封包時遇到一個奇怪的問題是: skbuff 的 data 包含 ip header + tcp header + NETBIOS + SMB2 header, 但就是沒有看到 payload.
結果我偶然看到 https://elixir.bootlin.com/linux/latest/source/include/linux/skbuff.h#L3285
這個函式會把 fraged skb 變成 linear 的, 直接省去我們的一堆麻煩
往下面追可以看到
可以看到函式幫我們處理 skb_shinfo(skb) 的 frags (這個是拿到 skb 尾部的 shared info), 並!吃!(eat) 進 data_len
size