【发布时间】:2012-02-08 19:38:20
【问题描述】:
我正在尝试从数据包中提取 tcp 有效负载,这是捕获回调的最小情况:
void capture_callback (u_char *hdr , const struct pcap_pkthdr* pkthdr , const u_char* buff)
{
struct ether_header *eptr = (struct ether_header *) buff;
buff += sizeof (ether_header); /* jump over ethernet header: 14 bytes */
if ( ntohs (eptr->ether_type) == ETHERTYPE_IP )
{
struct ip *iph;
struct tcphdr *tcp_header;
iph = (struct ip *) buff;
buff += sizeof (ip); /* jump over ip header */
if ( iph->ip_p == IPPROTO_TCP )
{
tcp_header = (struct tcphdr *) buff;
buff += sizeof (tcphdr); /* jump over tcp header */
cout << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> " << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
}
}
}
但是这里出了点问题,源IP地址和目的IP地址是一样的。
-
此外,我怎样才能打印出有效载荷?由于我不能直接将 unsigned char 数组显式转换为以 "\0" 结尾的 char 数组,因此可能会出错。
192.168.56.1:48065 --> 192.168.56.1:80
192.168.56.80:80 --> 192.168.56.80:48065
编辑
----------
感谢 Celeda,我通过分离 inet_ntoa 的调用解决了 IP 地址问题:
cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> ";
cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
现在是第二部分,我正在使用:
cout << hex << buff << endl;
对于 HTTP 协议,我没有看到类似 "GET /" 的东西,而是多个空行
编辑 2
--------------
我现在不太确定 TCP 选项,我会查看更多有关详细信息的文档, 但目前这个功能很好。
if ( iph->ip_p == IPPROTO_TCP )
{
tcp_header = (struct tcphdr *) buff;
buff += tcp_header->th_off * 4;
cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> ";
cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
for ( int i = 0 ; i < iph->ip_len - iph->ip_off * 4; i ++ )
{
if ( isascii (buff[i]) )
{
cout << buff[i];
}
}
cout << endl << "-----------" << endl;
}
【问题讨论】:
-
对于第二部分,我不确定,也许
buff没有完全指向正确的地方。我看到你这样做了buff += sizeof (tcphdr),但也许你还需要跳过一些 TCP 选项。我也不懂 C++,所以我不确定hex << buff究竟做了什么。然而我怀疑它需要一个以 NUL 结尾的字符串。我认为您需要使用一些将长度作为输入的函数,这样它就不会超出数据包的末尾。