📄 ipparse.cpp
字号:
/* 解析IP数据包 */
#include <WINSOCK2.H>
#include <WS2TCPIP.H>
#include <iostream.h>
#include <stdio.h>
//#include "stdafx.h"
typedef struct _IP_HEADER /*定义IP头*/
{
union
{
BYTE Version; /*版本(前4位)*/
BYTE HdrLen; /*IHL(后4位),IP头的长度*/
};
BYTE ServiceType; /*服务类型*/
WORD TotalLen; /*总长*/
WORD ID; /*标识*/
union
{
WORD Flags; /*标志(前3位)*/
WORD FragOff; /*分段偏移(后13位)*/
};
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";
break;
case 2:
return "IGMP";
break;
case 4:
return "IP in IP";
break;
case 6:
return "TCP";
break;
case 8:
return "EGP";
break;
case 17:
return "UDP";
break;
case 41:
return "IPV6";
break;
case 46:
return "RSVP";
break;
case 89:
return "OSPF";
break;
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(hops)\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.SrcAddr));
/*解析目的IP地址*/
fprintf(file,"目的IP地址 = %s\r\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
}
int main(int argc,char* argv[])
{
if (argc!=2)
{
printf("usage error !\n");
}
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*/
SOCKET sock;
if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP)) == INVALID_SOCKET)
{
printf("Create socket failed !\n");
return -1;
}
BOOL flag= TRUE;
/*设置IP头操作选项,其中flag设置为真,用户可以亲自对IP头进行处理 */
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)) == SOCKET_ERROR)
{
printf("setsocket 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 \n");
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");
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);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -