从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地址?
可变大小,我想是标题的大小。
您猜错了。
引用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()
。
否,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