C winpcap 网络抓包 并获取IP TCP 协议的相关信息
以太网协议分析函数:
void ethernet_protocol_packet_handle (u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
说明:首先对物理帧帧作分析,看其中包含的是IP包还是ARP数据包。如果是IP包则转入到IP包处理函数。
IP包处理函数
void ip_protocol_packet_handle(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content )
说明:对IP数据包作分析,IP包的内容在原有物理帧后14字节开始。并提取出相应的字段,对其中的协议类型作分析,如果是TCP类型,则转到TCP处理函数中。
TCP协议处理函数
void tcp_protocol_packet_handle(u_char *argument,const struct pcap_pkthdr *packet_header, const u_char *packet_content )
说明:对TCP协议作分析,并提取出相应字段。TCP的内容相对物理帧起始位置后移14+20字节。
#include <stdio.h>
#include <iostream>
#define HAVE_REMOTE
#include "pcap.h"
#include "remote-ext.h" #pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "wpcap.lib") using namespace std; FILE* fp;
FILE* myFile; // 以太网协议格式的定义
typedef struct ether_header {
u_char ether_dhost[]; // 目标地址
u_char ether_shost[]; // 源地址
u_short ether_type; // 以太网类型
}ether_header; // 用户保存4字节的IP地址
typedef struct ip_address {
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address; // 用于保存IPV4的首部
typedef struct ip_header {
#ifdef WORDS_BIGENDIAN
u_char ip_version : , header_length : ;
#else
u_char header_length : , ip_version : ;
#endif u_char ver_ihl; // 版本以及首部长度,各4位
u_char tos; // 服务质量
u_short tlen; // 总长度
u_short identification; // 身份识别
u_short offset; // 分组偏移
u_char ttl; // 生命周期
u_char proto; // 协议类型
u_short checksum; // 包头测验码
ip_address saddr; // 源IP地址
ip_address daddr; // 目的IP地址
u_int op_pad; //可选 填充字段
}ip_header; // 保存TCP首部
typedef struct tcp_header {
u_short sport; //源端口
u_short dport; //目的端口
u_int sequence; // 序列码
u_int ack; // 回复码 #ifdef WORDS_BIGENDIAN
u_char offset : , reserved : ; // 偏移 预留
#else
u_char reserved : , offset : ; // 预留 偏移
#endif u_char flags; // 标志
u_short windows; // 窗口大小
u_short checksum; // 校验和
u_short urgent_pointer; // 紧急指针
}tcp_header; typedef struct udp_header {
u_int32_t sport; // 源端口
u_int32_t dport; // 目标端口
u_int8_t zero; // 保留位
u_int8_t proto; // 协议标识
u_int16_t datalen; // UDP数据长度
}udp_header; typedef struct icmp_header {
u_int8_t type; // ICMP类型
u_int8_t code; // 代码
u_int16_t checksum; // 校验和
u_int16_t identification; // 标识
u_int16_t sequence; // 序列号
u_int32_t init_time; // 发起时间戳
u_int16_t recv_time; // 接受时间戳
u_int16_t send_time; // 传输时间戳
}icmp_header; typedef struct arp_header {
u_int16_t arp_hardware_type;
u_int16_t arp_protocol_type;
u_int8_t arp_hardware_length;
u_int8_t arp_protocol_length;
u_int16_t arp_operation_code;
u_int8_t arp_source_ethernet_address[];
u_int8_t arp_source_ip_address[];
u_int8_t arp_destination_ethernet_address[];
u_int8_t arp_destination_ip_address[];
}arp_header; /*tcp函数====================================================*/ void tcp_protocol_packet_handle(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
struct tcp_header *tcp_protocol;
u_short sport;
u_short dport;
int header_length;
u_short windows;
u_short urgent_pointer;
u_int sequence;
u_int acknowledgement;
u_short checksum;
u_char flags; printf("===========TCP Protocol===========\n"); tcp_protocol = (struct tcp_header*)(packet_content + + );
sport = ntohs(tcp_protocol->sport);
dport = ntohs(tcp_protocol->dport);
header_length = tcp_protocol->offset * ;
sequence = ntohl(tcp_protocol->sequence);
acknowledgement = ntohl(tcp_protocol->ack);
windows = ntohs(tcp_protocol->windows);
urgent_pointer = ntohs(tcp_protocol->urgent_pointer);
flags = tcp_protocol->flags;
checksum = ntohs(tcp_protocol->checksum); //fprintf(myFile, "\ntcp flag %s, header %d\n",flags, header_length );
fprintf(fp, "%d0%d%d%c%d", header_length, sport, dport, flags, windows); switch(dport) {
default:
break;
} if(flags & 0x08) printf("PSH");
if(flags & 0x10) printf("ACK");
if(flags & 0x02) printf("SYN");
if(flags & 0x20) printf("URG");
if(flags & 0x01) printf("FIN");
if(flags & 0x04) printf("RST");
printf("\n");
} void udp_protocol_packet_handle(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
struct udp_header* udp_protocol;
u_short sport;
u_short dport;
u_short datalen; udp_protocol = (struct udp_header*)(packet_content + + );
sport = ntohs(udp_protocol->sport);
dport = ntohs(udp_protocol->dport);
datalen = ntohs(udp_protocol->datalen); fprintf(fp, "0%d%d%d",datalen, sport, dport);
} void arp_protocol_packet_handle(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
struct arp_header *arp_protocol;
u_short protocol_type;
u_short hardware_type;
u_short operation_code;
u_char hardware_length;
u_char protocol_length; struct tm* ltime;
char timestr[];
time_t local_tv_sec;
local_tv_sec = packet_header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime); printf("-------- ARP协议 --------\n");
arp_protocol = (struct arp_header*)(packet_content + );
hardware_type = ntohs(arp_protocol->arp_hardware_type);
protocol_type = ntohs(arp_protocol->arp_protocol_type);
operation_code = ntohs(arp_protocol->arp_operation_code);
hardware_length = arp_protocol->arp_hardware_length;
protocol_length = arp_protocol->arp_protocol_length; fprintf(fp, "%d%s", protocol_length, timestr); switch (operation_code)
{
case :
printf("ARP请求协议\n");
break;
case :
printf("ARP应答协议\n");
break;
case :
printf("RARP请求协议\n");
break;
case :
printf("RARP应答协议\n");
break;
default:
break;
}
} void icmp_protocol_packet_handle(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
struct icmp_header *icmp_protocol;
u_short type;
u_short datalen;
u_int init_time;
u_int recv_time;
u_int send_time; icmp_protocol = (struct icmp_header*)(packet_content + + );
datalen = sizeof(icmp_protocol);
type = icmp_protocol->type;
init_time = icmp_protocol->init_time;
recv_time = icmp_protocol->recv_time;
send_time = icmp_protocol->send_time; fprintf(fp, "%d%c%d%d%d", datalen, type, init_time, recv_time, send_time); // printf("===========ICMP Protocol==========\n"); switch(icmp_protocol->type) {
case :
// 回显请求报文
break;
case :
// 回显应答报文
break;
default:
break;
}
} /*IP包处理===================================================================*/
void ip_protocol_packet_handle(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
struct ip_header *ip_protocol;
u_int header_length;
u_char tos; //服务质量
u_short checksum; //校验和 ip_address saddr;//源IP地址
ip_address daddr;//目的IP地址
u_char ttl; //生命周期
u_short tlen; //总长度
u_short identification; //身份识别
u_short offset; //分组偏移 //printf("===========IP Protocol===========\n"); ip_protocol = (struct ip_header*)(packet_content + );
header_length = ip_protocol->header_length * ;
checksum = ntohs(ip_protocol->checksum);
tos = ip_protocol->tos;
offset = ntohs(ip_protocol->offset); saddr = ip_protocol->saddr;
daddr = ip_protocol->daddr;
ttl = ip_protocol->ttl;
identification = ip_protocol->identification;
tlen = ip_protocol->tlen;
offset = ip_protocol->offset;
/*printf("版本号:%d\n", ip_protocol->ip_version);
printf("首部长度:%d\n",header_length);
printf("服务质量:%d\n",tos);
printf("总长度:%d\n",ntohs(tlen));
printf("标识:%d\n",ntohs(ip_protocol->identification));
printf("偏移:%d\n",(offset & 0x1fff) * 8);
printf("生存时间:%d\n",ttl);
printf("协议类型:%d\n",ip_protocol->proto); */
//fprintf(myFile,"\n**IP\n");
fprintf(fp, "%d%d%c%d%d%d", saddr, daddr, ttl, identification, tlen, offset); switch(ip_protocol->proto) {
case :
//fprintf(myFile,"\n**IP version%s, headerlength %s , ptype %s \n",ip_protocol->ip_version,header_length, ip_protocol->proto);
tcp_protocol_packet_handle(argument, packet_header, packet_content);
break;
case :
udp_protocol_packet_handle(argument, packet_header, packet_content);
break;
case :
icmp_protocol_packet_handle(argument, packet_header, packet_content);
break;
default:
break;
}
} /*以太网包处理===============================================================*/
void ethernet_protocol_packet_handle (
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content
) {
u_short ethernet_type; // 以太网类型
struct ether_header *ethernet_protocol; // 以太网协议变量
u_char *mac_string; // 以太网地址 ethernet_protocol = (struct ether_header*)packet_content; // 获取以太网数据内容
//printf("Ethernet type is : \n");
ethernet_type = ntohs(ethernet_protocol->ether_type); // 获取以太网类型
//printf(" %04x\n", ethernet_type); /* switch(ethernet_type) {
case 0x0800:
//printf("The network layer is IP protocol\n");
break;
case 0x0806:
//printf("The network layer is ARP protocol\n");
break;
default:
break;
}*/ // 获取以太网源地址
// printf("MAC Source Address is : \n");
mac_string = ethernet_protocol->ether_shost; fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x",
*mac_string,
*(mac_string + ),
*(mac_string + ),
*(mac_string + ),
*(mac_string + ),
*(mac_string + )
); // 获取以太网目的地址
// printf("MAC Target Address is : \n");
mac_string = ethernet_protocol->ether_dhost;
fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x",
*mac_string,
*(mac_string + ),
*(mac_string + ),
*(mac_string + ),
*(mac_string + ),
*(mac_string + )
); fprintf(fp, "%d", sizeof(packet_content)); switch(ethernet_type) {
case 0x0800:
ip_protocol_packet_handle(argument, packet_header, packet_content);
break;
default:
break;
}
} /*MAIN=================================================================*/
int main() { //struct pcap_if {
// struct pcap_if *next;
// char *name; /* name to hand to "pcap_open_live()" */
// char *description; /* textual description of interface, or NULL */
// struct pcap_addr *addresses;
// bpf_u_int32 flags; /* PCAP_IF_ interface flags */
//}; pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
int inum;
int i = ;
u_int netmask;
char packet_filter[] = "ip and tcp";
struct bpf_program fcode;
int res;
struct pcap_pkthdr *header;
struct tm *ltime;
const u_char *pkt_data;
time_t local_tv_sec;
char timestr[];
ip_header *ih; // 获得设备列表 pcap_findalldevs_ex() if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -) {
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit();
} for(d = alldevs; d; d = d->next) {
printf("devices ----%d. %s\n", ++i, d->name);
if(d->description) {
printf("(%s)\n", d->description);
}
else {
printf("No description available\n");
}
} if( == i) {
printf("\nNo interface found!Make sure WinPcap is installed\n");
return -;
} //由于我只有一个网络设备 所以输入1
printf("Enter the interface number(1-%d):", i);
scanf("%d", &inum);
if(inum < || inum > i) {
printf("\nInterface number out of range.\n");
pcap_freealldevs(alldevs); /* 释放设备列表 */
return -;
} for(d = alldevs, i = ; i < inum-; d=d->next, i++);
// 跳转到该设备,打开适配器 // 设备名,要捕捉的数据包的部分(
//65536保证能捕获到不同数据链路层上的每个数据包的全部内容),
// 真值1表示混杂模式,
//读取超时时间,
//错误缓冲池
if((adhandle = pcap_open_live(d->name, , , , errbuf)) == NULL) {
fprintf(stderr, "\nUnable to open the adapter.%s is not supported by WinPcap\n", errbuf);
pcap_freealldevs(alldevs);
return -;
}
// 检查数据链路层(只考虑了以太网)
if(pcap_datalink(adhandle) != DLT_EN10MB) {
fprintf(stderr, "\nThis program works only on Ethernet networks.\n");
pcap_freealldevs(alldevs);
return -;
} if(d->addresses != NULL) {
// 获得接口的第一个地址的掩码
netmask = ((struct sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;
}
else {
netmask = 0xffffff;
} /* // 编译过滤器
if(pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0) {
fprintf(stderr, "\nUnable to compile the packet filter.Check the syntax\n");
pcap_freealldevs(alldevs);
return -1;
} // 设置过滤器 if(pcap_setfilter(adhandle, &fcode) < 0) {
fprintf(stderr, "\nError setting the filter.\n");
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistenting on %s...\n", d->description);
*/
fp = freopen("in.txt", "w", stdin);
myFile = freopen("1234.txt", "w", stdin);
int count=; //pcap_next_ex() 和 pcap_loop() 比较接近
//目的是捕获下一个数据包
//返回值为int 1表示成功 -1表示错误 -2为最后一个报文
while((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= ) {
/* if(count++>500)
{
break;
}*/
// 请求超时
if( == res) {
continue;
} // 分析数据包
//以太网数据包 包含IP包 // IP包中有包含 TCP UDP 等高层协议信息
ethernet_protocol_packet_handle(NULL, header, pkt_data); // 将时间戳转换成可识别的格式
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);
ih = (ip_header *)(pkt_data + ); //以太网头部长度 // 输出时间和IP信息
//printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len); /*printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4);*/
} //获取报文发生错误
if(- == res) {
printf("Error reading the packet:%s\n", pcap_geterr(adhandle));
return -;
}
pcap_freealldevs(alldevs); fclose(fp);
fclose(stdin);
char c[];
gets(c);
return ;
}
C winpcap 网络抓包 并获取IP TCP 协议的相关信息的更多相关文章
- 网络抓包wireshark(转)
转自 网络抓包wireshark 抓包应该是每个技术人员掌握的基础知识,无论是技术支持运维人员或者是研发,多少都会遇到要抓包的情况,用过的抓包工具有fiddle.wireshark,作为一个不是经 ...
- CatchPacket网络抓包软件
CatchPacket网络抓包软件 qq 22945088431.技术特点:基于WinPcap库,c# winform2.实现获取机器所有网卡,可任意选择监听3.可以捕获常见网络协议arp dns ...
- python编写网络抓包分析脚本
python编写网络抓包分析脚本 写网络抓包分析脚本,一个称手的sniffer工具是必不可少的,我习惯用Ethereal,简单,易用,基于winpcap的一个开源的软件 Ethereal自带许多协议的 ...
- Wireshark网络抓包(三)——网络协议
一.ARP协议 ARP(Address Resolution Protocol)地址解析协议,将IP地址解析成MAC地址. IP地址在OSI模型第三层,MAC地址在OSI第二层,彼此不直接通信: 在通 ...
- iOS安全攻防之使用 Charles 进行网络数据抓包 和 Paros 网络抓包
Charles 是 Mac 系统下常用的网路抓包工具(Paros 也不错),windows 下常用 fiddler.正版的 Charles 是收费的(PS:支持正版),天朝人民比较喜欢破解版的Char ...
- 开源网络抓包与分析框架学习-Packetbeat篇
开源简介packbeat是一个开源的实时网络抓包与分析框架,内置了很多常见的协议捕获及解析,如HTTP.MySQL.Redis等.在实际使用中,通常和Elasticsearch以及kibana联合使用 ...
- 超详细的网络抓包神器 tcpdump 使用指南
原文链接:Tcpdump 示例教程 本文主要内容翻译自<Tcpdump Examples>. tcpdump 是一款强大的网络抓包工具,它使用 libpcap 库来抓取网络数据包,这个库在 ...
- 简单谈谈网络抓包,特别是thrift 接口
按照惯例先谈谈最近情况,最近不是刚好跨年吗?看到很多人都在写年度总结,所以我也在写年度总结文章(其实之前我基本没有写过的,今年有点感触,也想记录一下),结果发现写起来有点多,之前还想着元旦前发出来,结 ...
- 网络抓包--Wireshark
Wireshark 是一款非常棒的Unix和Windows上的开源网络协议分析器.它可以实时检测网络通讯数据,也可以检测其抓取的网络通讯数据快照文件.可以通过图形界面浏览这些数据,可以查看网络通讯数据 ...
随机推荐
- loading android
drawal/loading.xml <?xml version="1.0" encoding="utf-8"?><animated-rota ...
- javaScript 工作必知(五) eval 的使用
eval eval(parse) parse :里面跟参数字符串,我们知道执行javascript 会编译执行, 改变全局变量的值: var x = 2; //定义的全局变量 alert(x); ...
- history.js 一个无刷新就可改变浏览器栏地址的插件(不依赖jquery)
示例: http://browserstate.github.io/history.js/demo/ 简介 HTML4有一些对浏览历史的前进后退API的支持如: window.hist ...
- 数据持久化------Archiving(归档,解档)
其中TRPerson为自定义的继承自NSObject的类的子类 其中有两个属性,name 和 age .h文件 #import @interface TRPerson : NSObject<& ...
- .Net平台-MVP模式再探(二)
PS: 本文与 上一遍文章 没有什么必然的联系,可以说是对于MVP的一定的加深,或许在理解上比上一篇多有点难度. 正文 一.简单讲讲MVP是什么玩意儿 如果从层次关系来讲,MVP属于P ...
- windows下安装testlink
因为项目中一直没有使用任何测试用例管理工具,如果需要的时候都是个人写在的excle里各自保存,因为没有系统的记录当时测试方法和测试用例,每次需要再次测试已有的功能时,因为时间太长,而往往记不得当时是怎 ...
- Delphi2010的RTTI增强
Delphi编译的文件体积增大了很多.很大一部分原因是因为Delphi2010默认提供了全信息的RTTI. 每一个数据类型都有全部运行时信息.例如可以在运行时获得结构体的成员以及成员类型等. 这个功能 ...
- css table 布局
使用CSS表格 CSS表格能够解决所有那些我们在使用绝对定位和浮动定位进行多列布局时所遇到的问题.例如,“display:table;”的CSS声明能够让一个HTML元素和它的子节点像table元素一 ...
- 虚拟机的静态内部 IP 地址
这是什么? 借助最新的 PowerShell 版本,您现在能够定义和配置特定的内部 IP 地址,该地址可以静态分配给部署在虚拟网络中的 IaaS 虚拟机.使用此功能,您可以直接为虚拟机配置内部 ...
- Java图形化界面设计——布局管理器之GridLayout(网格布局)
网格布局特点: l 使容器中的各组件呈M行×N列的网格状分布. l 网格每列宽度相同,等于容器的宽度除以网格的列数. l 网格每行高度相同,等于容器的高度除以网格的行数. l 各组件的排列方式 ...