我正在使用Linux(ubuntu 14.04)。我想要一些关于linux内核编程的典型信息。
在TCP通信中,当linux内核通过封装标头创建数据包时,我希望在从网络层到以太网层(而不是通过wireshark)时捕获数据包。
封装:
我认为内核模块的每一步都是专用的(我不确定)。如果是这样我想知道哪个模块正在执行第3步,哪个模块正在将该数据包传输到第4步,即以太网层。
我有一个内核源代码,即linux-3.13.0。
我想获取NAT防火墙代码。
答案 0 :(得分:0)
分析源代码有两种方法。
在静态代码分析中,您没有正在运行的系统:
我知道函数dev_queue_xmit(struct sk_buff*)
负责通过网络发送数据包。让我们说通过我提出的两种方法收集它的初步知识。让我们深入研究struct sk_buff*
以寻找相应的设备级处理程序:
struct sk_buff {
...
struct sock *sk;
struct net_device *dev;
...
因此,让我们使用SystemTap捕获struct net_device背后的一些信息:
# stap -e 'probe kernel.function("dev_queue_xmit") {
printf("symname: %s\n",
symname($skb->dev->netdev_ops->ndo_start_xmit));
print_backtrace(); }' --all-modules
...
symname: tg3_start_xmit
0xffffffff813277b8 : dev_queue_xmit+0x0/0x7 [kernel]
0xffffffffa02482e2 : br_dev_queue_push_xmit+0x163/0x169 [bridge]
0xffffffffa024672a : br_dev_xmit+0x1be/0x1db [bridge]
0xffffffff8132726f : dev_hard_start_xmit+0x23b/0x315 [kernel]
0xffffffff813276b6 : __dev_queue_xmit+0x36d/0x46a [kernel]
0xffffffff81353690 : ip_finish_output2+0x226/0x29a [kernel]
0xffffffff81354dcd : ip_queue_xmit+0x270/0x29b [kernel]
0xffffffff81366d6c : tcp_transmit_skb+0x6f9/0x72a [kernel]
0xffffffff81367cd1 : tcp_write_xmit+0x802/0xa20 [kernel]
0xffffffff81367f3f : __tcp_push_pending_frames+0x24/0x50 [kernel]
0xffffffff8135de79 : tcp_sendmsg+0x6af/0x7c9 [kernel]
0xffffffff813121df : sock_write_iter+0x7c/0xa1 [kernel]
0xffffffff81138510 : new_sync_write+0x6a/0x8e [kernel]
0xffffffff811392aa : vfs_write+0x9c/0x11e [kernel]
0xffffffff811394f4 : sys_write+0x51/0x85 [kernel]
0xffffffff813e6449 : system_call_fastpath+0x12/0x17 [kernel]
现在你有了负责传输数据包的函数名称,如果你想要更深入,即tcp_write_xmit
是一个TCP层函数,ip_finish_output2
是一个IP层函数,{{1 } br_dev_queue_push_xmit
是设备级函数。
如果您希望捕获数据包的数据,您可以绑定到其中一个函数并从tg3_start_xmit
中提取数据(即请参见此处:Extracting data from struct sk_buff)
另请注意,大多数函数都有sk_buff
后缀,这意味着没有单独的模块负责它们。这是因为Linux中的模块术语相当广泛:如果将CONFIG选项作为值[kernel]
进行相关而不是大多数Linux子系统可能与vmlinux
(“主模块”)静态链接y
。