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