//#include "stdafx.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "iostream.h"
#include "stdio.h"
typedef struct _IP_HEADER
{
union
{
BYTE Version;//版本
BYTE HdrLen;//IHL
};
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";
break;
case 6:
return "Internet work Control";
break;
case 5:
return "CRITIC/ECP";
break;
case 4:
return "Flash Override";
break;
case 3:
return "Flash";
break;
case 2:
return "Immediate";
break;
case 1:
return "Priority";
break;
case 0:
return "Routine";
break;
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&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 "BGP";
case 17:
return "UDP";
case 41:
return "RSVP";
case 89:
return "OSPF";
default:
return "UNKNOWN";
}
}
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,"版本=%d/r/n",version);
//解析IP长度
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);
//解析数据包ID
fprintf(file,"数据报ID=%d/r/n",ip.ID);
//解析标志位
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/r/n",ip.TimeToLive);
//解析协议
fprintf(file,"协议=%s/r/n",getProtocol(ip.Protocol));
//解析头校验和
fprintf(file,"头校验和=0x%0x/r/n",ip.HdrChksum);
//解析IP地址
fprintf(file,"源IP地址=%s/r/n",inet_ntoa(*(in_addr *)&ip.DstAddr));
//解析目的IP地址
fprintf(file,"目的IP地址=%s/r/n",inet_ntoa(*(in_addr *)&ip.DstAddr));
fprintf(file,"--------------------------------------------------/r/n");
}
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("usage error!/n");
return -1;
}
FILE *file;
if((file=fopen(argv[1],"wb+"))==NULL)
{
printf("fail to open file %s",argv[1]);
return -1;
}
WSADATA wsData;
//初始化失败,程序退出
if(WSAStartup(MAKEWORD( 2, 2 ),&wsData)!=0)
{
printf("WSAStartup failed/n");
return -1;
}
SOCKET sock;//建立原始socket
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET )
{
printf("create socket failed!/n");
return -1;
}
BOOL flag=TRUE;
//设置IP头操作选项,其中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;
}
//获取本地IP地址
hostent *pHostIP;
if((pHostIP=gethostbyname(hostName))==NULL)
{
printf("gethostbyname failed/n");
return -1;
}
//地充SOCKADDR_IN结构
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 dwValue=1;
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
#define IO_RCVALL _WSAIOW(IOC_VENDOR,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("ioctlsocket failed/n");
cout<<GetLastError()<<endl;
return -1;
}
//设置接收数据包的缓冲区长度
#define BUFFER_SIZE 65535
char buffer[BUFFER_SIZE];
//监听网卡
printf("开始解析经过本机的IP数据包/n/n");
while(true)
{
int size=recv(sock,buffer,BUFFER_SIZE,0);
if(size>0)
{
ipparse(stdout,buffer);
ipparse(file,buffer);
}
}
fclose(file);
return 0;
}