libpcap抓包分析项目(四)

在项目三中,我们完成了对“医院镜像流.pcapng”文件中一个包的解析,接下来我们要做的就是讲解析好的数据写入文件里,这样就可以还原出TS流文件,然后进行播放了。

这里比项目三多涉及的就是文件的操作了,C语言文件操作应该不难,写进去就好了。

在这份代码里面,我删掉了很多在本项目中用不到的地方,比如输出函数,并且因为文件中有一点杂音(就是不是TS流文件的数据包),我的判定条件是只有当还原出来的数据是以0x47开头的TS流文件才将数据写入文件。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "PPPoE.h"

//全局变量文件指针fp
FILE *fp;

//将TS流数据写进文件
void write_ts_file(int j,int len,const u_char *packet){
	
	while(j < len){
		if(fwrite(&packet[j],1,1,fp)!=1)
			printf("Write file error!\n");
		j++;
	}
}

//回调函数
void print_info(u_char *user,const struct pcap_pkthdr *pkthdr,const u_char *packet){
	int j,*id;
	struct ether_header *eptr;
	struct iphdr *ipptr;
	struct tcphdr *tcpptr;
	struct udphdr *udpptr;
	struct PPPoEhdr *PPPoEptr;
	
	j = 0,id = (int *)user;
	
	//获取以太网帧头部
	eptr = (struct ether_header*)packet;
	j += sizeof(struct ether_header);
	
	if(ntohs(eptr->ether_type)==0x8864){
		//获取PPPoE协议头部
		PPPoEptr = (struct PPPoEhdr *)(packet + sizeof(struct ether_header));
		j += sizeof(struct PPPoEhdr);

		j += 2;
			
		//获取IP数据包头部
		if(packet[j-2]==0x00 && packet[j-1]==0x21){
			ipptr = (struct iphdr *)(packet + sizeof(struct ether_header) + sizeof(struct PPPoEhdr) + 2);
			j += sizeof(struct iphdr);
			if(ipptr->protocol==17){
				//获取udp数据包头部
				udpptr = (struct udphdr *)(packet + sizeof(struct ether_header) + sizeof(struct PPPoEhdr) + 2 + sizeof(struct iphdr));
				j += sizeof(struct udphdr);
				if(packet[j]==0x80)
					j += 12;//去掉RDP的12个字节

				//将数据写入文件中
				write_ts_file(j,pkthdr->len,packet);
			}
		}
	}
}

//主函数
int main(){
	char errBuf[PCAP_ERRBUF_SIZE];
	pcap_t *head;
	int id;
	
	//打开离线文件
	head = pcap_open_offline("医院镜像流.pcapng",errBuf);
	if(head){
		printf("Open device success!\n");
	}else{
		printf("Open device failed. %s\n",errBuf);
		return 0;
	}
	
	//等待一个包返回
	struct pcap_pkthdr packet;
	const u_char *packetflag = pcap_next(head,&packet);
	if(packetflag){
		printf("Get a pcaket success.\n");
		if(fp = fopen("lab04.ts","a"))
			printf("Open file success\n");
		else
			printf("Open file failed\n");
		id = 0;
		pcap_loop(head,-1,print_info,(u_char *)&id);
	}else{
		printf("Get a pcaket failed. %s\n",errBuf);
		pcap_close(head);
		return 0;
	}
	
	//关闭设备,归还资源
	fclose(fp);
	pcap_close(head);
	
	return 0;
}

程序运行结果:
libpcap抓包分析项目(四)_第1张图片
在目录下找到“lab04.ts”文件。
libpcap抓包分析项目(四)_第2张图片
拖到物理机中,查看一下属性:
libpcap抓包分析项目(四)_第3张图片
然后使用VLC播放器打开,看到视频。
(这里为大家献上沙雕情头)(手动狗头)


也可以在写文件时在终端输出各层的PDU头部信息,就是结合项目三的代码,可以下载我的源代码之后查看lab04_with_print.c。

这样,我们就完成了项目四,将TS流文件提取出来并写入文件进行播放。

PS:本系列完整文章:
libpcap抓包分析项目(六):https://blog.csdn.net/NCU_CirclePlan/article/details/95624720
libpcap抓包分析项目(五):https://blog.csdn.net/NCU_CirclePlan/article/details/95601520
libpcap抓包分析项目(四):https://blog.csdn.net/NCU_CirclePlan/article/details/95500092
libpcap抓包分析项目(三):https://blog.csdn.net/NCU_CirclePlan/article/details/95451728
libpcap抓包分析项目(二):https://blog.csdn.net/NCU_CirclePlan/article/details/95353239
libpcap抓包分析项目(一):https://blog.csdn.net/NCU_CirclePlan/article/details/95351331
libpcap的安装:https://blog.csdn.net/NCU_CirclePlan/article/details/95342991

本系列相关的源文件已经上传,有需要的朋友可以自行下载:https://download.csdn.net/download/ncu_circleplan/11340737

你可能感兴趣的:(libpcap抓包分析项目)