来自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地址?
答案 0 :(得分: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).
所以" len"是数据包的总长度。但是,可能没有" len"可用数据字节;如果捕获是使用"快照长度"完成的,例如使用-s
选项使用tcpdump,dumpcap或TShark,则数据包可能已被缩短,并且" caplen&# 34;表示你实际拥有多少字节的数据。
但请注意,以太网数据包的最小长度为60个字节(不包括最后的4字节FCS,您可能无法获得捕获),包括14字节以太网接头;这意味着必须填充短数据包。 60-14 = 46,所以如果主机通过以太网发送长度小于46字节的IP数据包,它必须填充以太网数据包。
这意味着" len" field给出了 Ethernet 数据包的总长度,但是如果你从" len"中减去以太网头的l4字节,你将无法获得IP数据包的长度。为此,您需要在"总长度"中查找IP标头。领域。 (不要认为它会小于或等于" len" - 14 - 机器可能发送了无效的IP数据包。)
另外,如何将uint32_t IP地址转换为xxx.xxx.xxx.xxx格式的人类可读IP地址?
通过调用inet_ntoa()
,inet_ntoa_r()
或inet_ntop()
等例程。
答案 1 :(得分: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