使用libpcab抓包&处理包
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <pcap.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> /* 默认捕获长度 (每个包捕获的最大长度) */
#define SNAP_LEN 1518 /* 以太网头部14个字节 */
#define SIZE_ETHERNET 14 /* 以太网地址6个字节 */
#define ETHER_ADDR_LEN 6 #define NUM_PACKET 5
#define PACKETS_NUM 2000
#define TCP_FLAG 0
#define UDP_FLAG 1
#define MYIP "192.168.1.106"
/* UDP header */
struct sniff_udp {
uint16_t sport; /* source port */
uint16_t dport; /* destination port */
uint16_t udp_length;
uint16_t udp_sum; /* checksum 检验和 */
}; /* Ethernet header */
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
}; /* IP header */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */
typedef unsigned long tcp_seq;
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
}; int tcp_num_count;
int udp_num_count;
int fin, syn, rst, push, ack, urg, ece, cwr; void callback(unsigned char*, const struct pcap_pkthdr*, const unsigned char*); int main()
{
char errBuf[PCAP_ERRBUF_SIZE];
char *dev = NULL; // dev应设置为网卡
/* 获取网络设备接口,即网络设备名 */
dev = pcap_lookupdev(errBuf); // dev应设置为网卡
/* 显示捕获设备信息
* printf("Device: %s\n", dev);
*/
if (dev == NULL) {
printf("%s\n", errBuf);
exit(1);
}
// netp为ip地址, bpf_u_int32为32位无符号整型
bpf_u_int32 netp = 0, maskp = 0;
int ret = 0;
/* 获取网络号和掩码,成功返回0 */
ret = pcap_lookupnet(dev, &netp, &maskp, errBuf);
if (ret == -1) {
printf("%s\n", errBuf);
exit(1);
}
// printf("ip = %d\n", netp); 应转化为点二进制形式 // 打开网络接口
// 参数分别为接口名, 捕获数据包的长度不能超过65535字节
// 混杂模式, 等待的ms数(超过该时间函数立即返回,0表示一直等待)
pcap_t* pcap_handle = pcap_open_live(dev, SNAP_LEN, 1, 0, errBuf);
//实例 pcap_t *pcap_handle = pcap_open_live("eth0", 1024, 1, 0, errBuf);
if (pcap_handle == NULL) {
printf("%s\n", errBuf);
exit(1);
} /* pcap_datalink();
* 返回数据链路层类型,例如DLT_EN10MB;
* 确保我们对以太网设备捕获
*/
if (pcap_datalink(pcap_handle) != DLT_EN10MB) {
fprintf(stderr, "%s is not an Ethernet\n", dev);
exit(EXIT_FAILURE);
} // 捕获单个数据包 const u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h);
// 参数分别为:打开网络接口返回的指针 捕获的数据包头
/*
const unsigned char *packet_addr = NULL; // 捕获的包的地址
struct pcap_pkthdr packet_header; // 抓到的时间 实际长度 原来长度
packet_addr = pcap_next(pcap_handle, &packet_header);
printf("Packet's length is:%d\n", packet_header.len); // 原来长度
printf("Packet's true length is:%d\n", packet_header.caplen);
*/ // 捕获多个数据包 int pcap_loop(pcap_t *p,int cnt,pcap_handler callback,u_char *user);
// 每捕获一个就调用callback指定的回调函数,可在回调函数中处理数据包
// 参数分别为:同pcap_next 指定捕获数据包的个数(设为-1将一直捕获)
// 参数分别为:回调函数(名字自取) 向回调函数中传递的参数 // 回调函数说明 void callback(u_char *userarg,const struct pcap_pkthdr *pkthdr,const u_char *packet)
// 参数:pcap_loop的最后一个参数 捕获的数据包的头(同pcap_next第二个参数)
// 参数:捕获的的数据包数据 /* 设置回掉函数并开始捕获包 */
if (pcap_loop(pcap_handle, NUM_PACKET, callback, NULL) < 0) {
perror("pcap_loop finish!\n");
} // 捕获多个数据包 int pcap_dispatch(pcap_t *p,int cnt,pcap_handler callback,u_char *user);
// 说明:和pcap_loop类似,只是超过x毫秒后返回(x是pcap_open_live的第四个参数) // 关闭网络接口
pcap_close(pcap_handle);
} //void func(unsigned char *argument, const struct pcap_pkthdr *packet_header, const unsigned char *packet_data)
//{
// printf("使用pcap_loop的回调函数,该包长度为%d\n", packet_header->len);
//} void callback(unsigned char *args, const struct pcap_pkthdr *header, const unsigned char *packet) {
static int count = 1; /* 包计数器,记录捕获多少包 */
/* 显示包总数
* printf("\nPacket number %d:\n", count);
* count++;
*/
/* declare pointers to packet headers */
struct sniff_ethernet *ethernet; /* 以太网头部 */
struct sniff_ip *ip; /* IP 头部 */
struct sniff_tcp *tcp; /* TCP 头部 */
struct sniff_udp *udp; /* UDP 头部 */
unsigned char *payload; /* Packet payload */
int size_ip;
int size_tcp;
int size_udp;
int size_payload; int proto_flag = 2; // 0=TCP_FLAG; 1=UDP_FLAG
//==== /* 定义以太网头部 */
ethernet = (struct sniff_ethernet*)(packet);
/* 定义/计算 IP 头部偏移 */
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4; // ip头部长度
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
/* 显示源IP和目的IP print source and destination IP addresses */
// only print internet->me information
if(strcmp(inet_ntoa(ip->ip_src), MYIP) == 0)
return;
/* 确定协议 determine protocol */
switch(ip->ip_p) {
case IPPROTO_TCP: //useful
// printf(" Protocol: TCP\n");
proto_flag=0;
break;
case IPPROTO_UDP: //useful
// printf(" Protocol: UDP\n");
proto_flag=1;
break;
case IPPROTO_ICMP: //useless
// printf(" Protocol: ICMP\n");
return;
case IPPROTO_IP: //useless
// printf(" Protocol: IP\n");
return;
default:
// printf(" Protocol: unknown\n");
return;
}
/*
* This packet is TCP.
*/
if (proto_flag == 0) {
/* 定义/计算 TCP 头部偏移 */
tcp = (struct sniff_tcp *) (packet + SIZE_ETHERNET + size_ip);
/* 计算TCP头部长度 */
size_tcp = TH_OFF(tcp) * 4;
if (size_tcp < 20) {
printf (" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
// printf(" From: %s\n", inet_ntoa(ip->ip_src));
// printf(" To: %s\n", inet_ntoa(ip->ip_dst));
printf (" Src port : %d\n", ntohs (tcp->th_sport));
printf (" Dst port : %d\n", ntohs (tcp->th_dport));
printf (" Seq number: %d\n", ntohl (tcp->th_seq));
int fin=0;
if(tcp->th_flags & TH_FIN)
fin=1;
printf (" FIN : %d\n", fin); /* define/compute tcp payload (segment) offset */
payload = (unsigned char *) (packet + SIZE_ETHERNET + size_ip + size_tcp); /* compute tcp payload (segment) size , 即TCP报文数据部分字节数 */
size_payload = ntohs (ip->ip_len) - (size_ip + size_tcp);
printf (" TCP size_payload: %d\n", size_payload);
printf (" Payload (%d bytes):\n", size_payload);
/*
if (size_payload > 0) {
//printf (" Payload (%d bytes):\n", size_payload);
// insert_tcp_hex_mysql(0, inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst), ntohs (tcp->th_sport), ntohs (tcp->th_dport), payload, ntohl (tcp->th_seq), size_payload,fin );
}
*/
} //end tcp
//=====================================================================================
/*
* This packet is UDP.
*/
else if (proto_flag == 1) {
/* define/compute udp header offset */
udp = (struct sniff_udp *) (packet + SIZE_ETHERNET + size_ip);
// printf(" From: %s\n", inet_ntoa(ip->ip_src));
// printf(" To: %s\n", inet_ntoa(ip->ip_dst));
printf (" Src port: %d\n", ntohs (udp->sport));
printf (" Dst port: %d\n", ntohs (udp->dport));
printf ("udp length:%d\n", ntohs (udp->udp_length));
// printf ("udp sum:%d\n", ntohs (udp->udp_sum)); /* define/compute udp payload (segment) offset */
payload = (unsigned char *) (packet + SIZE_ETHERNET + size_ip + 8);
size_payload = ntohs (ip->ip_len) - (size_ip + 8);
printf (" UDP size_payload: %d\n", size_payload);
}//end udp
return;
}
使用libpcab抓包&处理包的更多相关文章
- tcpdump抓取HTTP包
tcpdump抓取HTTP包 tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 0x4745为"GET&quo ...
- 使用Chrome或Fiddler抓取WebSocket包
首先,HTTP是建立在TCP协议基础上的,而WebSocket通常也是建立在TCP上,所以说为什么有些网页游戏抓不到包而有些又可以,这仅是因为你使用的抓包工具是针对了HTTP的通信协议. 我先从抽象的 ...
- wireshark设置抓服务器的包
wireshark设置抓服务器的包:
- 利用Fiddler抓取websocket包
一.利用fiddler抓取websockt包 打开Fiddler,点开菜单栏的Rules,选择Customize Rules... 这时会打开CustomRules.js文件,在class Handl ...
- 使用wireshark抓取TCP包分析1
使用wireshark抓取TCP包分析1 前言 介绍 目的 准备工作 传输 创建连接 握手 生成密钥 发送数据 断开连接 结论 前言 介绍 本篇文章是使用wireshrak对某个https请求的tcp ...
- libnids关于计算校验和引起的抓不到包的现象的解决方法
libnids关于计算校验和引起的抓不到包的现象的解决方法: nids.h中有这么一段: struct nids_chksum_ctl { u_int netaddr; u_int mask; u_i ...
- 用wiershark抓dns数据包
wireshark是非常好的抓包工具,捕获工具也很强大.比如说我只要抓dns数据包,其他数据包全部丢弃. 步骤如下: 选择菜单->捕获-捕获接口-输入-所选择接口的捕获过滤器:port 53 1 ...
- 手机通过Charles抓取https包
因为fiddler不能在mac上使用,而Charles是跨平台的,可以在mac上使用,所以需要了解一下Charles的使用 安装破解版Charles 下载破解版包,先启动一次未破解版的Ch ...
- Android移动网络如何抓取数据包
1)下载tcpdump工具 tcpdump(dump the traffic on a network)是Linux中强大的网络数据采集分析工具之一,可以将网络中传送的数据包头完全截获下来提供分析.它 ...
随机推荐
- .Net core使用Quartz.Net 实现定时任务
很多情况下,我们需要完成一些定时执行的功能,用很多定时工具,像:hangfire,TimeJob,以及Quartz.net,不过quartz.net 比较精确一些,功能也比较强大,所以我选择了Quar ...
- 单文件版本的netframework的net core 2.1
如果你还在用net4.5,如果你还在用netframework,又想使用netcore2.1的库或者功能,又觉得nuget动不动就好大,可以试试下面的这个. https://pan.baidu.com ...
- linux 学习第八天
一.特殊权限 1.SUID 让命令的执行者临时获取到了所有者权限(rws) 2.SGID 让目录中新的文件的所有组,归属上级目录 3.SBIT 粘滞位 让目录内的文件只能被文件所有者删除 4.修改文件 ...
- [异常笔记]启动DFS报错:Cannot find configuration directory: /etc/hadoop
[hadoop@master ~]$ start-dfs.sh Incorrect configuration: namenode address dfs.namenode.servicerpc-ad ...
- Vagrant 总结
引言 本文将讨论Vagrant基础应用,高级应用,基于Vagrant 的虚拟机优化,Vagrant的优势及区别等四部分 参考资料: [阿里云教程中心]Docker学习总结之Docker与Vag ...
- SHOPEX快递物流单号查询插件
本SHOPEX快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅急送快递.德邦物流.百世快递.汇通快递.中通快递.天天快递等知 ...
- Js 手指事件
1.Touch事件简介 pc上的web页面鼠标会产生onmousedown.onmouseup.onmouseout.onmouseover.onmousemove的事件,但是在移动终端如ipho ...
- ggplot2画简单的heatmap
gg_heatmap gg_heatmap PeRl ggplot2 heatmap 偶然的机会,发现ggplot2画的heatmap也挺好看的,除了不能画出聚类树来(手动滑稽). 随意新建了两个矩阵 ...
- Git Status 中文乱码解决
现象: jb@H39:~/doc$ git statusOn branch masterYour branch is up-to-date with 'origin/master'. Untracke ...
- BZOJ1303_中位数图_KEY
题目传送门 较水,开两个桶即可. 题目可以理解为,将大于B的数看为1,小于B的数看为-1,将以B这个数为中位数的序列左右分为两半,加起来为0. code: #include <cstdio> ...