跟踪数据包通过内核(linux)

我有两台机器设置为使用Ip-Security和机器A(让我们称之为A和B)有一个套接字,它绑定到本地机器上的特定UDP端口,并经常轮询它以查看是否有任何接收在上面。

当我禁用Ip-security时,两台机器之间的数据运行良好,我发送和接收数据包很好。 但是当启用Ip-Security时,数据包不会到达机器B发送的机器A上的那个套接字。

我在这两台机器上都做了一个tcpdump ,我可以看到(加密的)数据包从机器B发出并在机器A上接收。但是之后,数据包进入内核,在某个地方要么解密数据包,要么在某个其他阶段,数据包被丢弃。

我希望能够在数据包通过内核时跟踪数据包并查看它被丢弃的位置。 是否有一些/proc可以用于此目的? 我能想到的另一种方法是在整个内核中插入调试语句并重新编译它,然后再次尝试发送数据包并进行调试。

感谢和抱歉长信息,但这是必要的。

请参阅名为SystemTap的项目。 它允许您插入用户友好的脚本挂钩到任何内核代码,而无需重新编译内核。 例如:

 probe function("ip_rcv").call { printf("%d: ->ip_rcv()\n", gettimeofday_ms()) } 

它将为网络层中的每个接收数据包发出内核打印。 当然,您需要从更深入的网络堆栈中读取要遵循的源。

SystemTap非常强大,并且已经记录了可以插入的各种钩子。

是的,正如Dan所说,SystemTap很有用。 但我最喜欢的是ftrace。

以供参考:

linux内核中UDP包的路径

因此,为了跟踪网络流量,请将以下内容放在bash shell中并以root身份运行:

 mkdir /debug mount -t debugfs nodev /debug mount -t debugfs nodev /sys/kernel/debug echo '*' >/debug/tracing/set_ftrace_filter echo function_graph >/debug/tracing/current_tracer echo 1 >/debug/tracing/tracing_on sleep 20 echo 0 >/debug/tracing/tracing_on cat /debug/tracing/trace > /tmp/tracing.out$$ 

等接收入口路径:

  5) | tcp_recvmsg() { 5) | lock_sock_nested() { 5) 0.042 us | _cond_resched(); 5) | _raw_spin_lock_bh() { 5) 0.040 us | local_bh_disable(); 5) 0.414 us | } 5) 0.040 us | _raw_spin_unlock(); 5) 0.040 us | local_bh_enable(); 5) 1.814 us | } 5) | skb_copy_datagram_iovec() { 5) 0.042 us | _cond_resched(); 5) 0.588 us | } 5) 0.042 us | tcp_rcv_space_adjust(); 5) | __kfree_skb() { 5) | skb_release_all() { 5) | skb_release_head_state() { 5) 0.044 us | sock_rfree(); 5) 0.670 us | } 5) | skb_release_data() { 5) | put_page() { 5) 0.049 us | put_compound_page(); 5) 0.449 us | } 

还有这个:

Netlink处理:

  6) | rtnetlink_rcv() { 6) | mutex_lock() { 6) 0.090 us | _cond_resched(); 6) 1.455 us | } 6) | netlink_rcv_skb() { 6) | rtnetlink_rcv_msg() { 6) 0.150 us | mutex_unlock(); 6) | __netlink_dump_start() { 6) | netlink_lookup() { 6) 0.091 us | _raw_read_lock(); 6) 0.100 us | netlink_compare(); 6) 1.791 us | } 6) | mutex_lock() { 6) 0.095 us | _cond_resched(); 6) 0.913 us | } 6) 0.100 us | try_module_get(); 6) 0.090 us | mutex_unlock(); 

这也是入口:

  3) | tcp_v4_rcv() { 3) | sk_filter() { 3) | security_sock_rcv_skb() { 3) 0.076 us | cap_socket_sock_rcv_skb(); 3) 0.867 us | } 3) 1.630 us | } 3) 0.076 us | _raw_spin_lock(); 3) 0.477 us | tcp_prequeue(); 3) | tcp_v4_do_rcv() { 3) 0.088 us | tcp_md5_do_lookup(); 3) 0.109 us | tcp_parse_md5sig_option(); 3) 0.072 us | ipv4_dst_check(); 3) | tcp_rcv_established() { 3) 0.076 us | tcp_parse_aligned_timestamp.part.34(); 3) | tcp_queue_rcv() { 3) | tcp_try_coalesce.part.41() { 3) 0.835 us | skb_try_coalesce(); 3) 1.722 us | } 3) 2.637 us | } 

这是出口(从系统调用“sendmsg()”开始):

  5) | SyS_sendmsg() { 5) | __sys_sendmsg() { 5) | sockfd_lookup_light() { 5) 0.080 us | fget_light(); 5) 0.502 us | } 5) | ___sys_sendmsg() { 5) 0.117 us | copy_msghdr_from_user(); 5) 0.101 us | verify_iovec(); 5) | sock_sendmsg() { 5) | security_socket_sendmsg() { 5) | apparmor_socket_sendmsg() { 5) 0.092 us | aa_revalidate_sk(); 5) 0.580 us | } 5) 1.044 us | } 5) | unix_stream_sendmsg() { 5) 0.113 us | wait_for_unix_gc(); 5) | security_socket_getpeersec_dgram() { 5) 0.044 us | apparmor_socket_getpeersec_dgram(); 5) 0.479 us | } 5) | sock_alloc_send_pskb() { 5) | __alloc_skb() { 5) | kmem_cache_alloc_node() { 5) 0.042 us | _cond_resched(); 5) 0.648 us | } 5) | __kmalloc_reserve.isra.27() { 5) | __kmalloc_node_track_caller() { 5) 0.074 us | kmalloc_slab(); 5) 0.040 us | _cond_resched(); 5) 0.504 us | __slab_alloc(); 5) 1.878 us | } 5) 2.276 us | } 5) 0.175 us | ksize(); 5) 4.217 us | } 

希望你喜欢….