我如何在libpcap中获取数据包长度和IP地址

问题描述 投票:0回答:2

this示例

void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer)
{
    int size = header->len;

    //Get the IP Header part of this packet , excluding the ethernet header
    struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
    ++total;
    switch (iph->protocol) //Check the Protocol and do accordingly...
    {
        case 1:  //ICMP Protocol
            ++icmp;
            print_icmp_packet( buffer , size);
            break;

        case 2:  //IGMP Protocol
            ++igmp;
            break;

        case 6:  //TCP Protocol
            ++tcp;
            print_tcp_packet(buffer , size);
            break;

        case 17: //UDP Protocol
            ++udp;
            print_udp_packet(buffer , size);
            break;

        default: //Some Other Protocol like ARP etc.
            ++others;
            break;
    }
    printf("TCP : %d   UDP : %d   ICMP : %d   IGMP : %d   Others : %d   Total : %d\r", tcp , udp , icmp , igmp , others , total);
}

可变大小,我想是标题的大小。如何获得整个数据包的大小?

而且,如何将uint32_t IP地址转换为xxx.xxx.xxx.xxx形式的可读IP地址?

linux tcp udp libpcap
2个回答
1
投票

可变大小,我想是标题的大小。

您猜错了。

引用pcap手册页:

   Packets  are  read  with  pcap_dispatch()  or  pcap_loop(),  which
   process one or more packets, calling a callback routine  for  each
   packet,  or  with  pcap_next() or pcap_next_ex(), which return the
   next packet.  The callback for pcap_dispatch() and pcap_loop()  is
   supplied  a  pointer  to  a struct pcap_pkthdr, which includes the
   following members:

          ts     a struct timeval containing the time when the packet
                 was captured

          caplen a  bpf_u_int32  giving  the  number  of bytes of the
                 packet that are available from the capture

          len    a bpf_u_int32 giving the length of  the  packet,  in
                 bytes  (which might be more than the number of bytes
                 available from the capture, if  the  length  of  the
                 packet is larger than the maximum number of bytes to
                 capture).

so“ len是数据包的total长度。但是,可能没有可用的“ len”个字节的数据。如果使用“快照长度”完成捕获,例如使用-s选项使用tcpdump,dumpcap或TShark完成捕获,则该数据包可能已被剪短,并且“ caplen”将指示您实际拥有多少字节数据。

但是请注意,以太网数据包的最小长度为60字节(不算最后的4字节FCS,您可能不会在捕获中得到),包括14字节的以太网报头;这意味着必须填充短数据包。 60-14 = 46,因此,如果主机通过以太网发送的IP数据包长度不足46个字节,则它必须填充以太网数据包。

这意味着“ len”字段给出Ethernet数据包的总长度,但是如果您从“ len”中减去以太网报头的14个字节,则不会获得IP数据包的长度。为此,您需要在IP标头中的“总长度”字段中查找。 (不要假设它小于或等于“ len”的值-14-机器可能发送了无效的IP数据包。)

而且,如何将uint32_t IP地址转换为xxx.xxx.xxx.xxx形式的可读IP地址?

通过调用例程,例如inet_ntoa()inet_ntoa_r()inet_ntop()


0
投票

否,header->len是此数据包的长度,正是您想要的长度。

请参见头文件pcap.h

struct pcap_pkthdr {
    struct timeval ts;      /* time stamp */
    bpf_u_int32 caplen;     /* length of portion present */
    bpf_u_int32 len;        /* length this packet (off wire) */
};

您可以使用sprintf()uint32_t ip字段转换为xxx.xxx.xxx.xxx

© www.soinside.com 2019 - 2024. All rights reserved.