网络编程:IP包解析


注:如果用的是VS打开的话,可能会提示缺少msvc**.dll文件,可以用360电脑救援搜索该文件,修复即可。


main.cpp:

#include <stdio.h>
#include"mstcpip.h"
#include<ws2tcpip.h>
#include<iostream>
#include<string>
#include <WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")
using namespace std; 

typedef struct _IP_HEADER        //定义IP头
{
	union
	{
		BYTE Version;            //版本(前4位)
		BYTE HdrLen;             //报头长度(后4位),IP头的双字长度
	};
	BYTE ServiceType;            //服务类型
	WORD TotalLen;               //IP信包字节总长度
	WORD ID;                         //IP信包标识号
//	WORD DF;
//	WORD MF;
	union
	{
		WORD Flags;             //标志位(前3位:0,DF,MF)
		WORD FragOff;           //分段偏移(后13位,以8字节为单位)
	};
	BYTE TimeToLive;            //生命期TTL值
	BYTE Protocol;                  //高层协议号(TCP:6,UDP:17,ICMP:1,IGMP:2)
	WORD HdrChksum;           //头校验和
	DWORD SrcAddr;              //源IP地址
	DWORD DstAddr;              //目的IP地址
	BYTE Options;                    //选项
} IP_HEADER;

int main()
{
	WSADATA wsaData;          //指向WinSocket信息结构的指针
	if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0)//进行WinSocket的初始化
	{
		printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1
		return -1;
	} 
	SOCKET sock;
    sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0, WSA_FLAG_OVERLAPPED); 
    BOOL flag=true;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag));
    setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(CHAR*)&flag,sizeof(flag));
	/*获取主机名*/
	char hostName[128];
	gethostname(hostName,100);
	/*获取本地IP地址*/
	hostent * pHostIP;
	pHostIP = gethostbyname(hostName);
	/*填充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);
	// 绑定套接字,将sock绑定到本机网卡上
    bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in));
	DWORD dwBufferLen[10];
    DWORD dwBufferInLen = 1;
    DWORD dwBytesReturned = 0;
    WSAIoctl(sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), 
                  &dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);

	#define BUFFER_SIZE 65535
	char buffer[BUFFER_SIZE];           //设置缓冲区
	//int err=0;
	printf("IP包内容:\n");
	for(int m=0; m<2; m++)                 //准备收2个包
	{
		int  n= recv(sock,buffer,BUFFER_SIZE,0);        //接收一个数据包 ,n为数据长度
		if(WSAGetLastError()==SOCKET_ERROR)
		{
			if(WSAGetLastError()==WSAEWOULDBLOCK) 
				continue;              //如果错误为阻塞那么将继续接受
			break;
		}
        
		/*然后是处理显示接收的IP包中的字节*/
		printf("(%d) ", m + 1);

		for(int i = 0; i < n; i++)
		{  
			printf("%02x ",(unsigned char)buffer[i]);
		}
        
		printf("\n");

		/*然后是解析接收的IP包*/
		IP_HEADER ip=*(IP_HEADER*)buffer;
		//IP包的解析
		//通过IP_HEADER解析IP头各个字段的代码:
		/*获取版本字段*/
		printf("IP包解析结果:\n");
		int version;
		version=ip.Version>>4; //取前四位
		printf("IPVersion:IPV%d\n",version);
		/*获取头部长度字段*/
		int length;
		length=ip.HdrLen & 0x0f;
		printf("头部长度:%d字节\n",length*4);
		//printf("%d",ip.HdrLen);
		/*获取服务类型字段中的优先级子域*/
		ip.ServiceType>>5;
		/*获取服务类型字段中的TOS子域*/
		(ip.ServiceType>>1)&0x0f;
		/*获取总长度字段*/
		ip.TotalLen;
		printf("总长度:%d字节\n",ip.TotalLen);
		/*获取标识字段*/
		ip.ID;
		/*解析标志字段*/
		//ip.DF = (ip.Flags>>14) & 0x01;
		//ip.MF = (ip.Flags>>13) & 0x01;
		/*获取分段偏移字段*/
		ip.FragOff & 0x1fff;
		/*获取生存时间字段*/
		ip.TimeToLive;
		printf("生存时间:%d\n",ip.TimeToLive);
		/*获取协议字段*/
		printf("上层协议:");
		if(ip.Protocol==17)
			printf("UDP\n");
		else if(ip.Protocol==6)
			printf("TCP\n");
		else if(ip.Protocol==1)
			printf("ICMP\n");
		else if(ip.Protocol==2)
			printf("IGMP\n");
		else
			printf("ERROR");
		/*获取头校验和字段*/
		ip.HdrChksum;
		/*解析源IP地址字段*/
		char *srcip,*desip;
		srcip=inet_ntoa(*(in_addr*)&ip.SrcAddr);
		printf("源地址:%s\n",srcip);
		//printf("%d%d%d%d",ip.SrcAddr);
		/*解析目的IP地址字段*/
		desip=inet_ntoa(*(in_addr*)&ip.DstAddr);
		printf("目的地址:%s\n",desip);
		//printf("%d%d%d%d",ip.SrcAddr);
	}
	closesocket(sock);
	WSACleanup();    
}

mstcpip.h:

#ifndef   _MSTCPIP_INC
#define   _MSTCPIP_INC
// Copyright (C) Microsoft Corporation, 1996-1999
#if   _MSC_VER   >   1000
#pragma   once
#endif

/* Argument structure for SIO_KEEPALIVE_VALS */
//#include <stdio.h>
#include<string>
//#include<iostream>
//#include <nldef.h>
//#include <winapifamily.h>
struct   tcp_keepalive   {
	
	_ULonglong     onoff;
	_ULonglong     keepalivetime;
	_ULonglong     keepaliveinterval;
};   

// New WSAIoctl Options

#define   SIO_RCVALL               _WSAIOW(IOC_VENDOR,1)
#define   SIO_RCVALL_MCAST         _WSAIOW(IOC_VENDOR,2)
#define   SIO_RCVALL_IGMPMCAST     _WSAIOW(IOC_VENDOR,3)
#define   SIO_KEEPALIVE_VALS       _WSAIOW(IOC_VENDOR,4)
#define   SIO_ABSORB_RTRALERT      _WSAIOW(IOC_VENDOR,5)
#define   SIO_UCAST_IF             _WSAIOW(IOC_VENDOR,6)
#define   SIO_LIMIT_BROADCASTS     _WSAIOW(IOC_VENDOR,7)
#define   SIO_INDEX_BIND           _WSAIOW(IOC_VENDOR,8)
#define   SIO_INDEX_MCASTIF        _WSAIOW(IOC_VENDOR,9)
#define   SIO_INDEX_ADD_MCAST      _WSAIOW(IOC_VENDOR,10)
#define   SIO_INDEX_DEL_MCAST      _WSAIOW(IOC_VENDOR,11)
  
#endif


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值