在像tcpdump这样的工具中,何时捕获网络数据包?

时间:2010-09-02 14:55:33

标签: networking encryption tcp wireshark tcpdump

我使用的其中一个工具使用加密/解密来通过网络发送数据。我正在修改该工具,我需要确保数据实际上是以加密形式发送的。

Wireshark tcpdump 是否有适合此目的的正确工具?在传输过程中,它们会捕获网络数据包吗?

3 个答案:

答案 0 :(得分:12)

简答:在软件网络堆栈的最末端(例如在Linux中)窃听数据包。

在tcpdump,libpcap和linux内核3.12中搜索代码的答案很长:

Wireshark和tcpdump都使用libpcap,例如,

http://sources.debian.net/src/tcpdump/4.5.1-2/tcpdump.c#L1472

    if (pcap_setfilter(pd, &fcode) < 0)

反过来通过setfilter_op和activate_op安装数据包过滤器。这些操作有很多实现,我认为最近的Linux PF_PACKET将与pcap_activate_linux libpcap-1.5.3-2/pcap-linux.c#L1287一起使用:

/*
 * Current Linux kernels use the protocol family PF_PACKET to
 * allow direct access to all packets on the network while
 * older kernels had a special socket type SOCK_PACKET to
 * implement this feature.
 * While this old implementation is kind of obsolete we need
 * to be compatible with older kernels for a while so we are
 * trying both methods with the newer method preferred.
 */
status = activate_new(handle);

    ...
    activate_new(pcap_t *handle)
     ...
    /*
 * Open a socket with protocol family packet. If the
 * "any" device was specified, we open a SOCK_DGRAM
 * socket for the cooked interface, otherwise we first
 * try a SOCK_RAW socket for the raw interface.
 */
sock_fd = is_any_device ?
    socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
    socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

PF_PACKET在内核net/packet/af_packet.c中实现。 PF_SOCKET的初始化在packet_do_bind中使用register_prot_hook(sk)函数(如果设备处于启动状态),which calls dev_add_pack来自net/core/dev.c来注册挂钩:< / p>

 370 /**
 371 *      dev_add_pack - add packet handler
 372 *      @pt: packet type declaration
 373 *
 374 *      Add a protocol handler to the networking stack. The passed &packet_type
 375 *      is linked into kernel lists and may not be freed until it has been
 376 *      removed from the kernel lists.
 377 *
 378 *      This call does not sleep therefore it can not
 379 *      guarantee all CPU's that are in middle of receiving packets
 380 *      will see the new packet type (until the next received packet).
 381 */
 382
 383 void dev_add_pack(struct packet_type *pt)
 384 {
 385        struct list_head *head = ptype_head(pt);
 386
 387        spin_lock(&ptype_lock);
 388        list_add_rcu(&pt->list, head);
 389        spin_unlock(&ptype_lock);
 390 }

我认为,pf_packet处理程序 - tpacket_rcv(...) function - 将在ptype_all中注册。

ptype_all中注册的挂钩被调用来自dev_queue_xmit_nit的传出数据包(“支持例程。将传出帧发送到当前正在使用的任何网络点击。”)与list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func,deliver_skb调用libpcap为tpacket_rcv的函数。

dev_queue_xmit_nit从dev_hard_start_xmitLine 2539 in net/core/dev.c)调用,这是AFAIK,是Linux网络堆栈中与设备无关的数据包处理的最后一个阶段(用于传出数据包)。

相同的历史记录是传入的数据包ptype_all - 注册的挂钩是从__netif_receive_skb_core调用的,具有相同的list_for_each_entry_rcu(ptype, &ptype_all, list) {.. deliver_skb..}。在处理传入数据包的最开始时,__netif_receive_skb_core会调用__netif_receive_skb

Linux基金会对网络堆栈(http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow)有很好的描述,您可以在图例{@ 3}}上看到dev_hard_start_xmit(警告,它很大),位于图例下方的左侧。 netif_receive_skb位于最右下方(“net / core / dev.c”)内,它来自IRQ,然后是NAPI poll或netif_rx,此处唯一的退出是netif_receive_skb

图片甚至显示了两个pf_packet挂钩中的一个 - 传说中最左边的方块(“net / packet / af_packet.c”) - 用于传出数据包。

你的工具是什么?它如何连接到网络堆栈?如果您可以在http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png中找到该工具,您将得到答案。例如,Netfilter仅在NF_HOOK(传入)ip_rcv(本地传出)和ip_output(从路由传出)中挂钩(ip_forward) - 就在{{1}之后在netif_receive_skb之前。

答案 1 :(得分:5)

这两种工具都可以捕获数据,就像它通过网络传输一样。 (把它想象成输出的“tee”等同于屏幕和文件的输出;同样,数据也会输出到套接字以及tcpdump或其他任何内容。)

所以,是的,如果你的工具在发送之前正确配置加密数据,那么tcpdump或Wireshark应该在数据包捕获中反映出来。

答案 2 :(得分:1)

是的,这些是正确的工具。如果您正在使用加密,Wireshark将识别TLS和SSL数据包。您可以为Wireshark提供服务器的私钥,并在必要时解密流量(DHE和ECDHE等短暂模式除外)。