1

我想使用 libpcap 来捕获数据包,但是由于以太网标头或 802.11 标头的长度可能会有所不同,IP 标头的长度也可能会有所不同,我如何确定 IP 标头和 TCP 标头的起始字节(指针),如何区分一个数据包是纯IP数据包、TCP数据包还是UDP数据包?是否有任何 API 或方法可以做到这一点?谢谢!

4

1 回答 1

2

当您使用 libpcap 时,您可以通过直接查看 pcap 文件头(对于离线捕获)pcap_file_header.linktype或(对于实时和离线捕获)从调用pcap_datalink(). 大多数时候会这样LINKTYPE_ETHERNET。为确保数据包是 IPv4,您可以转换为以太网标头并检查以确保 ethertype 为ETHERTYPE_IP(确保将其包装在ntohs().然而,更高层协议并假设您正在使用pcap_dispatch(),您可以按照以下方式编写回调:(libnet 库对于其广泛的可移植数据包结构仍然有用):

#include <libnet.h>
#include <pcap.h>

void
process_packet(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)
{
    struct libnet_ipv4_hdr *ip;
    struct libnet_udp_hdr  *tcp;
    uint16_t ip_hl, udp_hl, header_cruft;

    ip     = (struct libnet_ipv4_hdr *)(packet + LIBNET_ETH_H);
    ip_hl  = ip->ip_hl << 2;

    switch (ip->ip_p)
    {
        case IPPROTO_UDP:
            udp    = (struct libnet_udp_hdr *)(packet + LIBNET_ETH_H + ip_hl);
            udp_hl = tcp->th_off << 2;
            header_cruft = LIBNET_ETH_H + ip_hl + tcp_hl;
            break;
        case IPPROTO_TCP:
            /** you get the idea */
            break;
        default:
            break;
    }
于 2013-03-16T02:08:13.973 回答