原文:http://xiexiaohui.com.host2.ugocn.com/index.php/archives/34

转载请注明出处。来自 hello xiexh (xiexiaohui0921@163.com)

这是进公司写的一个练手程序,程序功能为解析由Wireshark生成的pcap文件。

实现步骤:
1)用Wireshark软件抓包得到test.pcap文件
2)程序:分析pcap文件头 -> 分析pcap_pkt头 -> 分析帧头 -> 分析ip头 -> 分析tcp头 -> 分析http信息

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<time.h>
#define BUFSIZE 10240
#define STRSIZE 1024
typedef long bpf_int32;
typedef unsigned long bpf_u_int32;
typedef unsigned short  u_short;
typedef unsigned long u_int32;
typedef unsigned short u_int16;
typedef unsigned char u_int8;
//pacp文件头结构体
struct pcap_file_header
{
bpf_u_int32 magic;       /* 0xa1b2c3d4 */
u_short version_major;   /* magjor Version 2 */
u_short version_minor;   /* magjor Version 4 */
bpf_int32 thiszone;      /* gmt to local correction */
bpf_u_int32 sigfigs;     /* accuracy of timestamps */
bpf_u_int32 snaplen;     /* max length saved portion of each pkt */
bpf_u_int32 linktype;    /* data link type (LINKTYPE_*) */
};
//时间戳
struct time_val
{
long tv_sec;         /* seconds 含义同 time_t 对象的值 */
long tv_usec;        /* and microseconds */
};
//pcap数据包头结构体
struct pcap_pkthdr
{
struct time_val ts;  /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len;    /* length this packet (off wire) */
};
//数据帧头
typedef struct FramHeader_t
{ //Pcap捕获的数据帧头
u_int8 DstMAC[6]; //目的MAC地址
u_int8 SrcMAC[6]; //源MAC地址
u_short FrameType;    //帧类型
} FramHeader_t;
//IP数据报头
typedef struct IPHeader_t
{ //IP数据报头
u_int8 Ver_HLen;       //版本+报头长度
u_int8 TOS;            //服务类型
u_int16 TotalLen;       //总长度
u_int16 ID; //标识
u_int16 Flag_Segment;   //标志+片偏移
u_int8 TTL;            //生存周期
u_int8 Protocol;       //协议类型
u_int16 Checksum;       //头部校验和
u_int32 SrcIP; //源IP地址
u_int32 DstIP; //目的IP地址
} IPHeader_t;
//TCP数据报头
typedef struct TCPHeader_t
{ //TCP数据报头
u_int16 SrcPort; //源端口
u_int16 DstPort; //目的端口
u_int32 SeqNO; //序号
u_int32 AckNO; //确认号
u_int8 HeaderLen; //数据报头的长度(4 bit) + 保留(4 bit)
u_int8 Flags; //标识TCP不同的控制消息
u_int16 Window; //窗口大小
u_int16 Checksum; //校验和
u_int16 UrgentPointer;  //紧急指针
}TCPHeader_t;
//
void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len); //查找 http 信息函数
//
int main()
{
struct pcap_file_header *file_header;
struct pcap_pkthdr *ptk_header;
IPHeader_t *ip_header;
TCPHeader_t *tcp_header;
FILE *fp, *output;
int   pkt_offset, i=0;
int ip_len, http_len, ip_proto;
int src_port, dst_port, tcp_flags;
char buf[BUFSIZE], my_time[STRSIZE];
char src_ip[STRSIZE], dst_ip[STRSIZE];
char  host[STRSIZE], uri[BUFSIZE];
//初始化
file_header = (struct pcap_file_header *)malloc(sizeof(struct pcap_file_header));
ptk_header  = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr));
ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));
tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t));
memset(buf, 0, sizeof(buf));
//
if((fp = fopen(“test.pcap”,”r”)) == NULL)
{
printf(“error: can not open pcap file\n”);
exit(0);
}
if((output = fopen(“output.txt”,”w+”)) == NULL)
{
printf(“error: can not open output file\n”);
exit(0);
}
//开始读数据包
pkt_offset = 24; //pcap文件头结构 24个字节
while(fseek(fp, pkt_offset, SEEK_SET) == 0) //遍历数据包
{
i++;
//pcap_pkt_header 16 byte
if(fread(ptk_header, 16, 1, fp) != 1) //读pcap数据包头结构
{
printf(“\nread end of pcap file\n”);
break;
}
pkt_offset += 16 + ptk_header->caplen;   //下一个数据包的偏移值
strftime(my_time, sizeof(my_time), “%Y-%m-%d %T”, localtime(&(ptk_header->ts.tv_sec))); //获取时间
// printf(“%d: %s\n”, i, my_time);
//数据帧头 14字节
fseek(fp, 14, SEEK_CUR); //忽略数据帧头
//IP数据报头 20字节
if(fread(ip_header, sizeof(IPHeader_t), 1, fp) != 1)
{
printf(“%d: can not read ip_header\n”, i);
break;
}
inet_ntop(AF_INET, (void *)&(ip_header->SrcIP), src_ip, 16);
inet_ntop(AF_INET, (void *)&(ip_header->DstIP), dst_ip, 16);
ip_proto = ip_header->Protocol;
ip_len = ip_header->TotalLen; //IP数据报总长度
// printf(“%d:  src=%s\n”, i, src_ip);
if(ip_proto != 0×06) //判断是否是 TCP 协议
{
continue;
}
//TCP头 20字节
if(fread(tcp_header, sizeof(TCPHeader_t), 1, fp) != 1)
{
printf(“%d: can not read ip_header\n”, i);
break;
}
src_port = ntohs(tcp_header->SrcPort);
dst_port = ntohs(tcp_header->DstPort);
tcp_flags = tcp_header->Flags;
// printf(“%d:  src=%x\n”, i, tcp_flags);
if(tcp_flags == 0×18) // (PSH, ACK) 3路握手成功后
{
if(dst_port == 80) // HTTP GET请求
{
http_len = ip_len – 40; //http 报文长度
match_http(fp, “Host: “, “\r\n”, host, http_len); //查找 host 值
match_http(fp, “GET “, “HTTP”, uri, http_len); //查找 uri 值
sprintf(buf, “%d:  %s  src=%s:%d  dst=%s:%d  %s%s\r\n”, i, my_time, src_ip, src_port, dst_ip, dst_port, host, uri);
//printf(“%s”, buf);
if(fwrite(buf, strlen(buf), 1, output) != 1)
{
printf(“output file can not write”);
break;
}
}
}
} // end while
fclose(fp);
fclose(output);
return 0;
}
//查找 HTTP 信息
void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len)
{
int i;
int http_offset;
int head_len, tail_len, val_len;
char head_tmp[STRSIZE], tail_tmp[STRSIZE];
//初始化
memset(head_tmp, 0, sizeof(head_tmp));
memset(tail_tmp, 0, sizeof(tail_tmp));
head_len = strlen(head_str);
tail_len = strlen(tail_str);
//查找 head_str
http_offset = ftell(fp); //记录下HTTP报文初始文件偏移
while((head_tmp[0] = fgetc(fp)) != EOF) //逐个字节遍历
{
if((ftell(fp) – http_offset) > total_len) //遍历完成
{
sprintf(buf, “can not find %s \r\n”, head_str);
exit(0);
}
if(head_tmp[0] == *head_str) //匹配到第一个字符
{
for(i=1; i<head_len; i++) //匹配 head_str 的其他字符
{
head_tmp[i]=fgetc(fp);
if(head_tmp[i] != *(head_str+i))
break;
}
if(i == head_len) //匹配 head_str 成功,停止遍历
break;
}
}
// printf(“head_tmp=%s \n”, head_tmp);
//查找 tail_str
val_len = 0;
while((tail_tmp[0] = fgetc(fp)) != EOF) //遍历
{
if((ftell(fp) – http_offset) > total_len) //遍历完成
{
sprintf(buf, “can not find %s \r\n”, tail_str);
exit(0);
}
buf[val_len++] = tail_tmp[0]; //用buf 存储 value 直到查找到 tail_str
if(tail_tmp[0] == *tail_str) //匹配到第一个字符
{
for(i=1; i<tail_len; i++) //匹配 head_str 的其他字符
{
tail_tmp[i]=fgetc(fp);
if(tail_tmp[i] != *(tail_str+i))
break;
}
if(i == tail_len) //匹配 head_str 成功,停止遍历
{
buf[val_len-1] = 0; //清除多余的一个字符
break;
}
}
}
// printf(“val=%s\n”, buf);
fseek(fp, http_offset, SEEK_SET); //将文件指针 回到初始偏移
}

转载于:https://www.cnblogs.com/hnrainll/archive/2012/06/17/2553000.html

C语言解析pcap文件得到HTTP信息实例(原创,附源码)相关推荐

  1. c语言编程题报文解析,C语言解析pcap文件得到HTTP信息实例

    程序功能为解析由Wireshark生成的pcap文件. 实现步骤: 1)用Wireshark软件抓包得到test.pcap文件 2)程序:分析pcap文件头 -> 分析pcap_pkt头 -&g ...

  2. JAVA计算机毕业设计美容院信息管理系统(附源码、数据库)

    JAVA计算机毕业设计美容院信息管理系统(附源码.数据库) 目运行 环境项配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe ...

  3. Java毕设项目家政服务公司管理信息计算机(附源码+系统+数据库+LW)

    Java毕设项目家政服务公司管理信息计算机(附源码+系统+数据库+LW) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ ...

  4. JAVA文件上传详解(附源码)

    文章目录 JAVA文件上传详解(附源码) 1.准备工作 2.使用类介绍 FileItem类 ServletFileUpload类 3.代码编写 JAVA文件上传详解(附源码) 在web应用中,文件上传 ...

  5. (增删查改+排序+文件存储)通讯录实现(附源码)

    本通讯录具体实现以下功能: 实现结果如下 其中排序分为姓名排序和年龄排序 附源码: 测试部分-- void menu() {printf("************************* ...

  6. 如何使用mp4v2解析mp4文件,抽取音视频数据帧【源码】【mp4】【NVR】

    前言: mp4文件目前已经成为了流媒体音视频行业的通用标准文件格式,它是基于mov格式基础上演变来的,特别适合多平台播放,录制一次,多个平台都可使用.但是,由于mp4格式相对比较复杂,直到mp4v2这 ...

  7. C语言初学者如何做出美观的图形界面(附源码及完整文件)

    主要面向想做出图形界面的C语言初学者 C语言初学者开始都是在黑白控制台上开发一些小程序,实现一些小功能,因为基础的C语言可视化效果比较差,所展示的都是黑白的字符和数字,比较单调乏味.一些大学的计算机类 ...

  8. C语言制作个人通讯录管理系统—超详解(附源码)

    之前利用C语言完成了一个关于个人通讯录管理系统的课题,主要是关于联系人的添加.查找.删除.修改.输出以及文件的写入与读出,还有一个甜点功能-模拟通话,它的实现原理也很容易理解,文章末尾会介绍到. 主框 ...

  9. 火车售票排队系统 c语言,【C语言】实现12306火车售票系统!【附源码】

    程序设计要求用C语言写一个简单的火车售票系统,主要实现的功能为: ● 录入班次信息 ● 浏览班次信息 ● 按班次号查询 ● 按终点站查询 ● 按余票数量排序保存 ● 售票 ● 退票 ● 更新班次信息 ...

最新文章

  1. SLAM常用函数总结,如刚体变换、时间戳对齐等。
  2. springboot+shiro+cas实现单点登录之shiro端搭建
  3. 大数据流通与交易技术国家工程实验室成立大会在京举行
  4. 有sql漏洞的php脚本,DedeCms V57 plus/search.php 文件SQL注射0day漏洞脚本安全 -电脑资料...
  5. Hudson-ci/Installing Hudson Windows Service---官方文档
  6. ASP实现隐藏下载地址和防盗
  7. react.js app_如何创建Next.js入门程序以轻松引导新的React App
  8. 【CodeForces - 546C 】Soldier and Cards (模拟)
  9. 第二次作业+105032014098
  10. 信息学奥赛一本通C++语言——1122:计算鞍点
  11. Mybatis(10)properties标签的使用及细节,typeAliases和package标签
  12. Eclipse安装UML 插件
  13. A股开盘:深证区块链50指数跌0.32%,118只概念股下跌
  14. vue+webpack项目调试
  15. centos7下安装oracle11gR2
  16. rxjava 观察者模式_RxJava可观察对象和观察者
  17. 嵌入式系统——软件知识产权
  18. 汉代以前,鸳鸯是形容兄弟感情的,后来演变为男女感情
  19. 【MySQL】多表查询事务权限管理
  20. 华为路由模拟器3.0参考实验7----直连路由无法ping通解决办法

热门文章

  1. 2022-2028年中国康养地产行业市场需求前景及投资战略分析报告
  2. 2022-2028年中国氢化丁腈橡胶行业市场深度分析及投资规模预测报告
  3. 2022-2028年中国NFT行业市场研究及前瞻分析报告
  4. 并发 IO多路复用 select 非asyncio
  5. python pycharm 包 安装问题
  6. NLP --- 条件随机场CRF详解 重点 特征函数 转移矩阵
  7. 命名实体识别视频51cto
  8. LLVM Clang前端编译与调试
  9. PyTorch全连接ReLU网络
  10. CodeGen融合核心关系循环扩展