解析IP分组

#include<stdio.h>
#include<winsock2.h>
#include<ws2tcpip.h>
#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;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值