计算机网络IP数据包解析,想问一下程序哪一部分问题了
#include<winsock2.h>
#include<ws2tcpip.h>
#include<iostream.h>
#include<stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define IO_RCVALL _WSAIOW(IOC_VENDOR,l)
#define BUFFER_SIZE 65535
//定义IP头部数据结构
typedef struct _IP_HEADER
{
union
{
BYTE Version;//版本(前4位)
BYTE HdrLen;//报头标长(后4位),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;
//逐位解析IP头中的信息,获取版本号
void getVersion(BYTE b,BYTE &version)
{
version=b>>4;
}
void getIHL(BYTE b, BYTE &result)
{
result = (b&0x0f)*4;
}
//解析服务类型
char * parseServiceType_getProcedence(BYTE b)
{
switch(b>>5)
{
case 7:
return "Network Control";
case 6:
return "Internet work Control";
case 5:
return "CRITIC/ECP";
case 4:
return "Flash Override";
case 3:
return "Flash";
case 2:
return "Immediate";
case 1:
return "Priority";
case 0:
return "Routine";
default:
return "Unknown";
}
}
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 "Unknown";
}
}
//获取禁止分片标志和分片标志
void getFlags(WORD w,BYTE &DF, BYTE &MF)
{
DF = (w>>14)&0x01;
MF = (w>>13)&0x01;
}
//获取分片偏移量
void getFragoff(WORD w,WORD &fragoff)
{
fragoff=w&0x1ffff;
}
//获取协议
char * getProtocol(BYTE Protocol)
{
switch(Protocol)
{
case 1:
return "ICMP";
case 2:
return "IGMP";
case 3:
return "GGP";
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";
case 46:
return "OSPF";
default:
return "UNKNOWN";
}
}
//解析IP数据包
void ipparse(FILE * file,char *buffer)
{
IP_HEADER ip=*(IP_HEADER *)buffer;
fseek(file,0,SEEK_END);
BYTE version;
getVersion(ip.Version,version);
fprintf(file,"版本=IPV%d\r\n",version);
BYTE headerLen;
getIHL(ip.HdrLen,headerLen);
fprintf(file,"头长度=%d(BYTE)\r\n",headerLen);
fprintf(file,"服务类型=%s,%s\r\n",
parseServiceType_getProcedence(ip.ServiceType),
parseServiceType_getTOS(ip.ServiceType));
fprintf(file,"数据报长度=%d(BYTE)\r\n", ip.TotalLen);
fprintf(file,"数据报ID=%d\r\n",ip.ID);
//DF表示禁止分片标志,MF表示分片标志
BYTE DF,MF;
getFlags(ip.Flags,DF,MF);
fprintf(file,"分段标志DF=%d,MF=%d\r\n",DF,MF);
WORD fragOff;
getFragoff(ip.FragOff,fragOff);
fprintf(file,"分段偏移值=%d\r\n", fragOff);
fprintf(file,"生存期=%d(hops)\r\n",ip.TimeToLive);
fprintf(file,"协议=%s\r\n",getProtocol(ip.Protocol));
fprintf(file,"头检验和=0x%0x\r\n",ip.HdrChksum);
fprintf(file,"源IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
fprintf(file,"目的IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
fprintf(file,"__________________\r\n");
}
//程序入口
int main(int argc, char *argv[])
{
//cmd参数
if(argc!=2)
{
printf("usage error!\n");
return -1;
}
FILE * file;
//以读写的方式建立一个文本文件logfile.txt
if((file=fopen(argv[1],"w+"))==NULL)
{
printf("fail to open file %s","logfile.txt");
return -1;
}
WSAData wsData;
//启动2.2版本的Socket,并将Socket版本信息保存到wsData中
if(WSAStartup(MAKEWORD(2,2),&wsData)!=0)
{
printf("WSA startup failed!\n");
return -1;
}
fprintf(file,"Socket初始化...\r\n");
fprintf(file,"========================\r\n");
fprintf(file,"描述:%s\r\n",wsData.szDescription);
fprintf(file,"状态:%s\r\n",wsData.szSystemStatus);
fprintf(file,"========================");
SOCKET sock;
//创建原始套接字
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
{
printf("Can not create socket!\n");
return -1;
}
BOOL flag=true;
//设置IP头操作选项
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(CHAR *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt failed!\n");
return -1;
}
char hostName[128];
//获取本地主机名
if(gethostname(hostName,100)==SOCKET_ERROR)
{
printf("gethostname failed!\n");
return -1;
}
hostent * pHostIP;
//根据主机名获取主机信息
if((pHostIP=gethostbyname(hostName))==NULL)
{
printf("gethostbyname failed!\n");
return -1;
}
printf("Hostname:%s\r\n",pHostIP->h_name);
printf("IPAddress:%s\r\n",inet_ntoa(*((struct in_addr *)pHostIP->h_addr)));
//封装IP地址信息
sockaddr_in addr_in;
addr_in.sin_addr=*(in_addr*)pHostIP->h_addr_list[0];
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(6000);//监听的端口号
//把Socket绑定到本地网卡
if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in))==SOCKET_ERROR)
{
printf("bind failed");
return -1;
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD dwBytesReturned=0;
//设置网卡为混杂模式
if(WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,
sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR)
{
printf("icotlsocket failed\n");
return -1;
}
char buffer[BUFFER_SIZE];
printf("========开始解析========\r\n");
while(true)
{
//从套接字接收IP数据报
int size=recv(sock,buffer,BUFFER_SIZE,0);
if(size>0)
{
ipparse(stdout,buffer);
ipparse(file,buffer);
}
}
//解除Socket绑定
if(WSACleanup()==SOCKET_ERROR)
{
printf("WSACleanup failed!\n");
return -1;
}
fclose(file);
return 0;
}