对前面27中sniffer中的一个改进。这里只贴出改动地方的代码。
void get_packet(u_char * args, const pcap_pkthdr * header, const
u_char * packet){
char from_ip[24], to_ip[24];
const struct sniffer_ethernet * ethernet = (struct
sniffer_ethernet *) packet;
//packet记载了包的内容,因为是从数据链路层开始抓取,第一头部当然是以太网(当然不是绝对,但大部分局域网是以太网,如果是其它网络,就
用对应的数据结构
//前面我设置的端口是常用的WEB端口80,WEB协议是HTTP,下一层则是TCP,TCP又是构建在IP基础之上,所以这里包的分层解析就很
清楚了
const struct ip * ip_header = (struct ip *)(packet +
SIZE_ETHERNET);
//越过以太网头部,获取IP头部,struct
ip是linux中对IP头部的一个数据结构,如果是windows机器,就请使用对应的数据结构
const struct tcphdr * tcp_header = (struct tcphdr *)(packet +
SIZE_ETHERNET + sizeof(struct ip));
//越过以太网和IP头部,获取TCP头部指针,同样道理struct
tcphdr是linux下的tcp描述结构,如果是windows机器,换成对应的数据结构
inet_ntop(AF_INET, &ip_header->ip_src, from_ip,
sizeof(from_ip));
inet_ntop(AF_INET, &ip_header->ip_dst, to_ip,
sizeof(to_ip));
//从ip头部获取目的IP地址和源IP地址
printf("from %s:%d to %s:%d, ip packet len = %d\n", from_ip,
ntohs(tcp_header->source), to_ip, ntohs(tcp_header->dest),
ip_header->ip_len);
//从TCP头部可以获取目的端口和源端口
printf("tcp syn = %d, ack = %d\n", tcp_header->syn,
tcp_header->ack);
char * content = (char *)(packet + SIZE_ETHERNET + sizeof(struct
ip) + sizeof(struct tcphdr));
//这里就是TCP包所承载的内容所在,80号端口自然是HTTP内容,这里还包括HTTP头部,但HTTP是应用层协议,linux内核中集成了
TCP和UDP协议,并没有关于HTTP描述。不过HTTP比较简单,之后的运行结果可以看到HTTP内容
string content_str(content);
int loc = content_str.find("HTTP", 0);
if(loc != string::npos) { //这个判断后面运行结果会提到
cout << content_str << endl;
}
}
改动后
void get_packet(u_char * args, const pcap_pkthdr * header, const u_char * packet){
char from_ip[24], to_ip[24];
const struct sniffer_ethernet * ethernet = (struct sniffer_ethernet *) packet;
const struct ip * ip_header = (struct ip *)(packet + SIZE_ETHERNET);
const struct tcphdr * tcp_header = (struct tcphdr *)(packet + SIZE_ETHERNET + sizeof(struct ip));
inet_ntop(AF_INET, &ip_header->ip_src, from_ip, sizeof(from_ip));
inet_ntop(AF_INET, &ip_header->ip_dst, to_ip, sizeof(to_ip));
printf("from %s:%d to %s:%d, ip packet len = %d, ip head len = %d\n", from_ip, ntohs(tcp_header->source), to_ip, ntohs(tcp_header->dest), ntohs(ip_header->ip_len), ip_header->ip_hl * 4);
printf("tcp syn = %d, ack = %d, fin = %d, seq = %d, len = %d\n", tcp_header->syn, tcp_header->ack, tcp_header->fin, ntohl(tcp_header->seq), tcp_header->doff * 4);
//一般情况下tcp头部和ip头部的长度都是20个字节,但他们都是可以增加的,因此之前获取TCP承载的数据的头不指针的办法char * content = (char *)(packet + SIZE_ETHERNET + sizeof(struct
ip) + sizeof(struct tcphdr));所获取的位置不一定正确,ip头长度记录在ip_hl中,tcp头部长度记录在doff中,至于×4的原因,因为TCP和IP头部都是以4字节为基本单位来增长。
//至于判断,ip_len记录了IP包总长度,如果TCP和IP实际长度之和等于IP包总长,则说明IP包没有承载数据,(比如三路握手的起始的3个包就是不带数据的),如果大于则说明有数据,一般情况下不可能出现小于的情况。
if(ntohs(ip_header->ip_len) == ip_header->ip_hl * 4 + tcp_header->doff * 4) {
printf("no data\n");
} else {
char * content = (char *)(packet + SIZE_ETHERNET + ip_header->ip_hl * 4 + tcp_header->doff * 4);
// +的意思是向后移动
//承载的数据起始指针,应该就是头指针+以太网包头长度+ip包头长度+tcp包头长度,依次类推UDP换成UDP即可,关键是弄清楚协议所在的层次,和所使用的协议
printf("data = %s\n", content);
}
}
分享到:
相关推荐
简单的sniffer程序代码,可运行。学习网络安全课设的一个小代码,容易理解,也可作为网络编程基础实例。
用mfc编写的的sniffer小程序,可以实现简单ip地址、类型、端口等数据的收集分析,算是网络编程的一个小实验
基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序 基于winpcap的sniffer程序
修改已有的sniffer源程序,使其在屏幕上打印出捕获的数据包的协议类型及其它相关信息。如:源IP地址,目的IP地址,源端口,目的端口等信息。
模拟网络通信的一个程序
sniffer程序分析与设计 实验报告,网络课程教学开发。
linux下sniffer程序的实现.pdf
基于原始套接字编写的Sniffer程序。
使用WinPCap编写Sniffer程序
sniffer网络抓包程序 驱动级别 源代码
分布式Sniffer 解决方案对应用程序传输和网络设备状态进行全天候分析,可以使应用程序保持最高的运行效率。其中包括对部门网、校园网和主干网的集中监控、设备级别报告和故障解决。 分布式Sniffer系统 从一个单独的...
sniffer源代码,供大家研究学习!对于喜欢这方面的有帮助哦!
里面有相关问题的说明,请大家仔细阅读,并反馈问题,谢谢,里面有本人QQ。
TI的Packet Sniffer抓包软件安装程序
嗅探器原理 Winpcap介绍 Winpcap安装 Winpcap应用程序结构
支持多无线网卡的sniffer抓包驱动,内部使用。Philips,Gemtek,Linksys,Linktek,Cisco,Ralink等使用。
实现间的ip嗅探和分析功能,Sniffer,中文可以翻译为嗅探器,是一种基于被动侦听原理的网络分析方式。使用这种技术方式,可以监视网络的状态、数据流动情况以及网络上传输的信息。当信息以明文的形式在网络上传输时...
否则会提示无法启动此程序,因为计算机中丢失wpcap.dll,尝试重新安装该程序以解决此问题。ESFSoft URL Sniffer是一款用于从互联网中各种捕获多媒体文件的真实URL地址。可以查看数据的源IP端口,及目标IP端口,...