湖南第一师范学院 实验报告
课程名称:通信软件基础 成绩评定: 实验项目名称:基于C++ 的IP数据包解析程序设计 指导教师: 王建军 学生姓名: 学号: 专业班级: 14通信1班 实验项目类型:综合性 实验地点:实A602 实验时间:2016年 11 月11 日
一、实验目的与要求:
1.熟悉C++文件操作;
2.熟悉SOCKET编程; 3.熟悉IP包结构。
二、实验环境:(硬件环境、软件环境)
1.windows 7操作系统;
2.VC++编译器 。
三、实验过程:(内容、操作步骤、结果等)
#include \"winsock2.h\"
#include \"ws2tcpip.h\" #include \"iostream.h\" #include \"stdio.h\"
#pragma comment(lib,\"ws2_32.lib\")
/*定义IP头部数据结构*/ typedef struct _IP_HEADER {
union {
BYTE Version; //版本(前四位) BYTE HdrLen; //报头标长(后四位),IP头长度 };
BYTE ServiceType; //服务类型 WORD TotalLen; //总长度 WORD ID; //标志 union {
WORD Flags; WORD FragOff; };
BYTE TimeToLive; //生存时间 BYTE Protocol; //协议
WORD HdrChksum; //首部检验和 DWORD SrcAddr; //源地址 DWORD DstAddr; //目的地址 BYTE Options; }IP_HEADER;
void getVersion(BYTE b, BYTE & version) /*逐位解析IP头中的信息,获取版本号*/ {
version=b>>4; }
void getIHL(BYTE b,BYTE & result) {
1
result=(b&0x0f)*4; }
char * parseServiceType_getProcedence(BYTE b) /*解析服务类型*/ {
switch(b>>5) {
case 7: return \"Network Control\"; break; case 6:
return \"Internet work Control\"; break; case 5:
return \"CRITIC/ECP\";break; case 4:
return \"Flash Override\";break; case 3:
return \"Flsah\"; break; case 2:
return \"Immediate\";break; case 1:
return \"Priority\"; break; case 0:
return \"Routine\";break; default:
return \"Unknow\";break; } }
char * parseServiceType_getTOS(BYTE b) {
b=(b>>1)&0x0f;
switch(b) { case 0:
return \"Normal service\";break; case 1:
return \"Minimize monetary cost\";break; case 2:
return \"Maximize reliability\";break; case 4:
return \"Maximize throughput\"; break; case 8:
return \"Minimize delay\";break; case 15:
return \"Maximize security\";break; default:
return \"Unknow\"; } }
/* 获取禁止分片标志和分片标志 */
void getFlags(WORD w,BYTE & DF,BYTE & MF) {
DF=(w>>14)&0x01; MF=(w>>13)&0x01; }
void getFragOff(WORD w,WORD & fragOff) /* 获取分片偏移量 */
2
{
fragOff=w&0x1fff; }
char * getProtocol(BYTE Protocol) /*获取协议*/ {
switch(Protocol) { case 1:
return \"ICMP\"; case 2:
return \"IGMP\"; case 4:
return \"IP in IP\"; case 6:
return \"TCP\"; case 8:
return \"EGP\"; case 17:
return \"UDP\"; case 41:
return \"IPv6\"; case 46:
return \"RSVP\"; case 89:
return \"OSPF\"; default:
return \"UNKNOW\"; } }
void ipparse(FILE* file,char* buffer) /* 解析IP数据包 */ {
IP_HEADER ip=*(IP_HEADER*)buffer; fseek(file,0,SEEK_END); BYTE version;
getVersion(ip.Version,version);
fprintf(file,\"版本号=%d\\r\\n\ BYTE headerLen;
getIHL(ip.HdrLen,headerLen);
fprintf(file,\"报头标长=%d(BYTE)\\r\\n\ fprintf(file,\"服务类型=%s,%s\\r\\n\
parseServiceType_getProcedence(ip.ServiceType), parseServiceType_getTOS(ip.ServiceType));
fprintf(file,\"总长度=%d(BYTE)\\r\\n\ fprintf(file,\"标识=%d\\r\\n\ BYTE DF,MF;
getFlags(ip.Flags,DF,MF);
fprintf(file,\"标志 DF=%d,MF=%d\\r\\n\ WORD fragOff;
getFragOff(ip.FragOff,fragOff);
fprintf(file,\"分段偏移值=%d\\r\\n\
fprintf(file,\"生存期=%d(hopes)\\r\\n\ fprintf(file,\"协议=%s\\r\\n\ fprintf(file,\"头校验和=0x%0x\\r\\n\
fprintf(file,\"源IP地址=%s\\r\\n\
3
fprintf(file,\"目的IP地址=%s\\r\\n\ fprintf(file,\"---------------------------------------------\\r\\n\"); }
main() {
int nRetCode = 0; {
FILE * file;
if((file=fopen(\"logfile.txt\ {
printf(\"fail to open file %s\"); return -1; }
WSADATA wsData;/* 启动2.2版本的Socket,并将Socket版本信息保存到wsData中 */ WSAStartup(MAKEWORD(2,2),&wsData); SOCKET sock;/* 创建原始套接字 */
sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP); BOOL flag=TRUE;/* 设置IP头操作选项 */
setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)); char hostName[128];/* 获取本地主机名 */ gethostname(hostName,100);
hostent * pHostIP;/* 根据主机名获取主机信息 */ pHostIP=gethostbyname(hostName);
sockaddr_in addr_in; /* 封装IP地址信息 */
addr_in.sin_addr=*(in_addr*)pHostIP->h_addr_list[0]; addr_in.sin_family=AF_INET; addr_in.sin_port=htons(6000);
bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in)); DWORD dwValue=1;
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1) DWORD dwBufferLen[10]; DWORD dwBufferInLen=1; DWORD dwBytesReturned=0;
WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
#define BUFFER_SIZE 65535 char buffer[BUFFER_SIZE];
printf(\"开始解析经过本机的IP数据包:\\n\"); while(true) {
int size=recv(sock,buffer,BUFFER_SIZE,0); /* 从套接字接收IP数据报 */ if (size>0) {
ipparse(stdout,buffer); ipparse(file,buffer); } }
fclose(file); /* 关闭文件 */ return 0; }
return nRetCode; }
四、实验体会(感想,实验中碰到的问题及解决方法等)
4
因篇幅问题不能全部显示,请点此查看更多更全内容