最近维护一个抓包程序,发现需要用到IP分组,搜索到的代码,还没测试,先收藏吧。
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
//定义IP头部结构
typedef struct _IP_HEADER
{
union
{
BYTE Version; //版本(前4位)
BYTE HdrLen; //IP头部长度(后4位)
};
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;
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define BUFFER_SIZE 65535
//解析IP包的版本信息
void getVersion(BYTE b,BYTE &version)
{
version=b>>4;
}
//解析IP包的头部长度
void getIHL(BYTE b,BYTE &length)
{
length=(b&0x0f)*4;
}
//解析IP包的服务类型
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";
}
}
//解析IP包的服务级别
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";
}
}
//解析IP包的标志位
void getFlags(WORD w,BYTE &DF,BYTE &MF)
{
DF=(w>>14)&0x01;
MF=(w>>13)&0x01;
}
//解析IP包的分段偏移
void getFragoff(WORD w,WORD &fragoff)
{
fragoff=w&0x1fff;
}
//解析IP包的协议类型
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 "UNKNOWN";
}
}
void ipparse(FILE* file,char* buffer)
{
IP_HEADER ip=*(IP_HEADER*)buffer;
fseek(file,0,SEEK_END);
fprintf(file,"--------------------------------------------\n");
//解析IP包的版本信息
BYTE version;
getVersion(ip.Version,version);
fprintf(file,"Version: %d\n",version);
//解析IP包的头部长度
BYTE headerLen;
getIHL(ip.HdrLen,headerLen);
fprintf(file,"HdrLen: %d(Bytes)\n",headerLen);
//解析IP包的服务类型与等级
fprintf(file,"ServiceType: %s,%s\n",parseServiceType_getProcedence(ip.ServiceType), parseServiceType_getTOS(ip.ServiceType));
//解析IP包的总长度
fprintf(file,"TotalLen: %d(Bytes)\n",ip.TotalLen);
//解析IP包的标识符
fprintf(file,"ID: %d\n",ip.ID);
//解析IP包的标志位
BYTE DF,MF;
getFlags(ip.Flags,DF,MF);
fprintf(file,"Flags: DF=%d,MF=%d\n",DF,MF);
//解析IP包的分段偏移
WORD fragoff;
getFragoff(ip.Fragoff,fragoff);
fprintf(file,"Fragoff: %d\n",fragoff);
//解析IP包的生存期
fprintf(file,"TimeToLive: %d(Hops)\n",ip.TimeToLive);
//解析IP包的协议类型
fprintf(file,"Protocol: %s\n",getProtocol(ip.Protocol));
//解析IP包的头部校验和
fprintf(file,"HdrChksum: 0x%0x\n",ip.HdrChksum);
//解析IP包的源IP地址
fprintf(file,"SrcAddr: %d\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
//解析IP包的目的IP地址
fprintf(file,"DstAddr: %d\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
}
void main(int argc,char* argv[])
{
if(argc!=2)
{
printf("Please input command: ParseArp output_file");
return;
}
//打开输出日志文件
FILE* file;
if((file=fopen(argv[1],"wb+"))==NULL)
{
printf("Fail to open file %s",argv[1]);
return;
}
//初始化Socket环境
WSADATA wsData;
if(WSAStartup(MAKEWORD(2,2),&wsData)!=0)
{
printf("WSAStartup failed!");
return;
}
//建立原始Socket
SOCKET sock;
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
{
printf("Create socket failed!");
return;
}
//设置IP头部操作选项,flag设置为TRUE
BOOL flag=true;
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("Setsockopt failed!");
return;
}
//获取本地主机名
char hostName[128];
if(gethostname(hostName,100)==SOCKET_ERROR)
{
printf("Gethostname failed!");
return;
}
//获取本地主机IP地址
hostent* pHostIP;
if((pHostIP=gethostbyname(hostName))==NULL)
{
printf("Gethostbyname failed!");
return;
}
//填充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;
}
//设置SOCK_RAW为SIO_RCVALL,接收所有的IP包
DWORD dwValue=1;
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD dwBytesReturned=0;
if(WSAIoctl(sock,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR)
{
printf("Ioctlsocket failed!");
return;
}
//监听经过本机的IP包
char buffer[BUFFER_SIZE];
printf("Listening on local host...\n");
while(true)
{
int size=recv(sock,buffer,BUFFER_SIZE,0);
if(size>0)
{
ipparse(stdout,buffer);
ipparse(file,buffer);
}
}
fclose(file);
return;
}