资源描述
- .
课程设计报告
课程: 计算机通信与网络
题目:网络流量解析程序的实现
学号:
:
一、任务描述 3
二、windump的安装和使用 3
三、windump文件格式 3
四、程序实现 6
〔1〕算法〔〕 6
〔2〕编码中的关键问题 6
〔3〕头文件 6
〔4〕源文件 7
五、总结 10
一、 任务描述
编写一个网络流量解析程序
输入:由“Windump –W〞抓取的二进制流量文件
输出:文件中所有IP报文主要字段的信息
时间戳 源IP 目的IP 高层协议 总长度
二、 windump的安装和使用
〔一〕找到windump官方
〔二〕下载同一版本的winpcap和windump
〔三〕 先安装windump动态库
(四) Windump是个命令行程序
三、windump文件格式
数据XX 链路层数据
文件头
数据XX 链路层数据
24字节,并且前4个字节是“A1 B2 C3 D4〞或“D4 C3 B2 A1〞,用来标识数据XX中的多字节整数的读取顺序是顺着读或倒着读。
数据XX 链路层数据
数据XX 链路层数据
文件头
抓取的每个链路层帧都被附加16字节的数据XX,其中8~11是帧在文件中的存储长度或抓取长度,12~15那么是该帧的实际长度〔按照编程的习惯,从0开场数〕。由于抓取的时候可能发生截取,两个值可能不一致,使用“-s 0〞抓取的话,两个值一样。
假设第一个数据XX的8~11字节是60 00 00 00〔十六进制〕,当读取顺序为“D4 C3 B2 A1〞时,表示整数值0X00 00 00 60,即十进制数96。那么意味着从40字节开场的96个字节是第一个帧的抓取。
四、 程序实现
〔1〕算法〔〕
(2) 编码中的关键问题
如何读取二进制文件,如何输出文本文件
如何将二进制数据以十进制形式输出
(3) 头文件
#include<iostream>
#include<fstream>
(4) 源文件
#include<iostream>
#include<fstream>
using namespace std;
int read()
{ ifstream inf("f3.dat",ios::binary);
if(!inf)
{cout<<"can't open input file\n,";
exit(1);
}
char ch;
int count=0;
int c=0;
int n=0;
int p=0;
int i=0;
int s=24;
int w=0;
unsigned char m;
unsigned char b;
//inf.seekg(54,ios::beg);
ofstream out;
out.open("e:\\test.txt");
for(i=0;i<10;i++)
{
inf.seekg(s+8,ios::beg);
inf.get(ch);
b=ch;
int a=(int)b;
cout<<"数据包长度"<<endl;
out<<"数据包长度"<<' ';
cout<<a<<endl;
w=a;
inf.seekg(s+30,ios::beg);
out<<a<<' '<<endl;
//system("pause");
//inf.get(ch);b=ch;a=(int)b;cout<<a<<endl;
inf.get(ch);
b=ch;
m=b>>4;
a=(int)m;
cout<<"版本"<<a<<endl;
out<<"版本"<<a<<endl;
b=ch;
m=b&15;
a=(int)m;
cout<<"首部长度"<<a<<endl;
out<<"首部长度"<<a<<endl;
inf.get(ch);
b=ch;
a=(int)b;
cout<<"区分效劳"<<a<<endl;
out<<"区分效劳"<<a<<endl;
inf.get(ch);
b=ch;
a=(int)b*16*16;
inf.get(ch);
b=ch;
c=(int)b;
n=c+a;
cout<<"总长度"<<n<<endl;
out<<"总长度"<<n<<endl;
inf.get(ch);
b=ch;
a=(int)b*16*16;
inf.get(ch);
b=ch;
c=(int)b;
n=c+a;
cout<<"标识"<<n<<endl;
out<<"标识"<<n<<endl;
inf.get(ch);
b=ch;
m=b>>4;
a=(int)m;
cout<<"标志"<<a<<endl;
out<<"标志"<<a<<endl;
inf.get(ch);
inf.get(ch);
b=ch;
a=(int)b;
cout<<"生存时间"<<a<<endl;
out<<"生存时间"<<a<<endl;
inf.get(ch);
b=ch;
a=(int)b;
cout<<"协议"<<a<<endl;
out<<"协议"<<a<<endl;
inf.get(ch);
b=ch;
c=(int)b*16*16;
inf.get(ch);
b=ch;
a=(int)b;
n=a+c;
cout<<"首部校验和"<<n<<endl;
out<<"首部校验和"<<n<<endl;
inf.get(ch);
b=ch;
a=(int)b;
inf.get(ch);
b=ch;
c=(int)b;
inf.get(ch);
b=ch;
n=(int)b;
inf.get(ch);
b=ch;
p=(int)b;
cout<<"源地址"<<a<<'.'<<c<<'.'<<n<<'.'<<p<<endl;
out<<"源地址"<<a<<'.'<<c<<'.'<<n<<'.'<<p<<endl;
inf.get(ch);
b=ch;
a=(int)b;
inf.get(ch);
b=ch;
c=(int)b;
inf.get(ch);
b=ch;
n=(int)b;
inf.get(ch);
b=ch;
p=(int)b;
cout<<"目的地址"<<a<<'.'<<c<<'.'<<n<<'.'<<p<<endl;
out<<"目的地址"<<a<<'.'<<c<<'.'<<n<<'.'<<p<<endl<<endl<<endl<<endl<<endl;
s=s+16+w;
}
inf.close();
return 0;
}
int main()
{ cout<<"解析数据包"<<endl;
getchar();
read();
return 0;
}
五、 总结
通过这次实验对网络中的数据包有了新的认识,了解了数据链路层帧的格式,以及帧头的14个字节分别是什么和IP数据的构造。其次对windump软件的操作更加熟悉,能够根据抓来的流量进展详细的分析。在将解析好的IP数据报存入文件中时,由于存在非IP数据报使得大量的IP[]数组浪费同时也使得读出IP数据报的文件中有异常数据〔表达在空数组的初始化〕。由于是单个字节的读入二进制文件,所以程序并未实现将文件的所有容一次性都读入存而是采取认为的选定长度,而数据报的解析通样是使用人为的输入解析个数来惊喜解析,这使得程序的功能不是那么强大、完整。
- . 可修编.
展开阅读全文