我的Ubuntu虚拟机的IP地址是192.168.1.110。其他一切看起来都不错。我不知道代码有什么问题。也许我使用了错误的包头结构? 下面是我的代码和输出。我的主机IP应该是192.168.1.110,现在的端口肯定是错误的。
sudo ./sniffall 0
84.72.137.105:38055 192.168.1.105:56652
192.168.1.105:56652 174.141.213.124:28073
84.72.137.105:38055 192.168.1.105:56652
192.168.1.105:56652 174.141.213.124:28073
84.72.137.105:38055 192.168.1.105:56652
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
void getPacket(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet){
struct ip *ip;
struct tcphdr *tcp;
ip = (struct ip*)(packet+sizeof(struct ether_header));
tcp = (struct tcphdr*)(packet+sizeof(struct ether_header)+sizeof(struct ip));
char* src = inet_ntoa(ip->ip_src);
printf("%s:%d ",src,tcp->source);
char* dst = inet_ntoa(ip->ip_dst);
printf(" %s:%d\n", dst, tcp->dest);
}
int main(int argc, char *argv[]){
char errbuf[PCAP_ERRBUF_SIZE], *device;
device = argv[1];
pcap_t *handle;
handle = pcap_open_live(device, BUFSIZ, 1, 1000, errbuf);
if(!handle){
device = pcap_lookupdev(errbuf);
handle = pcap_open_live(device, BUFSIZ, 1, 1000, errbuf);
if(!handle){
printf("Couldn't open device %s: %s\n", device, errbuf);
}
}
pcap_loop(handle, 5, getPacket, NULL);
return 0;
}
答案 0 :(得分:2)
您还需要在字节顺序之间进行转换。在现在最常见的情况下,&#34;网络字节顺序&#34;与机器的字节顺序不同。要打印出端口号,您需要执行以下操作:
printf("%s:%d ",src,ntohs(tcp->source));
此外,您可能想尝试struct iphdr
而不是struct ip
。我之前看到过在标题中有多个名为ip
的结构定义的实例,但iphdr
始终适合我。
请记住,您始终可以在另一个窗口中运行tcpdump
以查看实际进入的数据包,您可能会获得比预期更多的流量。
答案 1 :(得分:0)
首先,在调用pcap_open_live()
后,在pcap_datalink()
上调用handle
,如果它没有返回DLT_EN10MB
,请退出或重写您的程序以便它可以处理它返回的值。有关pcap_datalink()
支持的值的说明,请参阅the tcpdump.org link-layer header types page。
其次, NOT 假设数据包是IPv4数据包,除非您安装了"ip"
的过滤器或检查了数据包类型(例如,以太网中的类型字段) header)确保数据包是IPv4数据包。
第三,执行 NOT 假设IPv4数据包的标头长度恰好为sizeof(struct ip)
个字节。我假设sizeof(struct ip)
将是20,这是IPv4标头的最小长度,但标头可能包含选项 - 检查IPv4标头的“标头长度”字段(在单位为4字节字,所以值为5意味着“20字节”)并将其用作标题的长度(确保它至少为5 - 如果它小于5,则数据包无效 - 然后相乘用4来得到标题的长度。)
第四,做 NOT 假设数据包是TCP数据包,除非你安装了"ip and tcp"
或"tcp"
的过滤器(后者,你将会仍然需要检查自己是否是IPv4数据包)或检查IPv4标头的“协议”字段,以确保它的值为6(对于TCP)。