解析IP数据包

 //#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;

}

你可能感兴趣的:(socket,header,File,null,buffer,byte)