#include
<
Winsock2.h
>
#include
<
mstcpip.h
>

#pragma comment(lib,
"
WS2_32.lib
"
)

typedef
struct
_iphdr

{
unsigned char h_lenver; //4位首部长度+4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}
IP_HEADER;

typedef
struct
_tcphdr
//
定义TCP首部

{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_lenres;//4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}
TCP_HEADER;

typedef
struct
_udphdr
//
定义UDP首部

{
unsigned short uh_sport;
unsigned short uh_dport;
unsigned short uh_len;
unsigned short uh_sum;
}
UDP_HEADER;

typedef
struct
_icmphdr
//
定义ICMP首部

{
BYTE i_type; //8位类型
BYTE i_code; //8位代码
USHORT i_cksum; //16位校验和
USHORT i_id; //识别号(一般用进程号作为识别号)
USHORT i_seq; //报文序列号
ULONG timestamp; //时间戳
}
ICMP_HEADER;

bool
DecodeIpPack(
const
char
*
,
int
);
//
IP 解包
bool
DecodeTcpPack(
const
char
*
);
//
TCP 解包
bool
DecodeUdpPack(
const
char
*
);
//
UDP 解包
bool
DecodeIcmpPack(
const
char
*
);
//
ICMP 解包
const
char
*
CheckProtocol(
int
);
//
查询协议
int
_tmain(
int
argc, _TCHAR
*
argv[])

{
// 初始化SOCKET
WSADATA wsaData;
int iErrorCode = ::WSAStartup( MAKEWORD(2,1), &wsaData );
if( SOCKET_ERROR == iErrorCode )

{
printf( "WSAStartup() error. " );
return -1;
}
SOCKET sock = ::socket( AF_INET, SOCK_RAW, IPPROTO_IP );
if( INVALID_SOCKET == sock )

{
printf( "socket() error. " );
return -1;
}

//获取本机IP地址
char szHostName[200];
iErrorCode = ::gethostname( szHostName, sizeof(szHostName) );
if( SOCKET_ERROR == iErrorCode )

{
printf( "gethostname() error. " );
return -1;
}

PHOSTENT pHostent = ::gethostbyname( szHostName );
if( NULL == pHostent )

{
printf( "gethostbyname() error. " );
return -1;
}

SOCKADDR_IN sa;
sa.sin_family = AF_INET;
memcpy( &sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length );
sa.sin_port = htons( 60000 );

iErrorCode = ::bind( sock, (PSOCKADDR)&sa, sizeof(sa) );
if( SOCKET_ERROR == iErrorCode )

{
printf( "bind() error. " );
return -1;
}

// 设置 SOCK_RAW 为 SIO_RCVALL,接收所有的 IP 包
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
iErrorCode = ::WSAIoctl( sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen,
sizeof( dwBufferLen ), &dwBytesReturned, NULL, NULL );
if( SOCKET_ERROR == iErrorCode )

{
printf( "Ioctl() error. " );
return -1;
}

//侦听IP报文
while( 1 )

{

char package[8 * 1024] =
{ 0 }; // 数据缓冲区
iErrorCode = ::recv( sock, package, sizeof(package), 0 );
if( SOCKET_ERROR == iErrorCode )
printf( "recv() error. " );
else if( !DecodeIpPack( package, iErrorCode ) ) // 解析 IP 包
printf( "DecodeIpPack() error. " );
}

// ::Closesocket( sock );
// ::WSACleanup();
return 0;
}

//
解析 IP 包
bool
DecodeIpPack(
const
char
*
buf,
int
iBufSize)

{
IP_HEADER *pIpheader;
int iProtocol, iTTL;
char szProtocol[12];
char szSourceIP[16];
char szDestIP[16];
SOCKADDR_IN saSource, saDest;
pIpheader = (IP_HEADER *)buf;

//Check Proto
iProtocol = pIpheader->proto;
::strcpy( szProtocol, CheckProtocol(iProtocol) );

//Check Source IP
saSource.sin_addr.s_addr = pIpheader->sourceIP;
::strcpy( szSourceIP, inet_ntoa(saSource.sin_addr) );

//Check Dest IP
saDest.sin_addr.s_addr = pIpheader->destIP;
::strcpy( szDestIP, inet_ntoa(saDest.sin_addr) );
iTTL = pIpheader->ttl;

//Output
printf( "%s ", szProtocol );
printf( "%s->%s ", szSourceIP, szDestIP );
printf( "bytes=%d TTL=%d ",iBufSize,iTTL );

//Calculate IP Header Length
int iIphLen = sizeof(unsigned long) * ( pIpheader->h_lenver & 0x0f );

//Decode Sub Protocol:TCP, UDP, ICMP, etc
switch( iProtocol )

{
case IPPROTO_TCP: DecodeTcpPack( buf + iIphLen ); break;
case IPPROTO_UDP: DecodeUdpPack( buf + iIphLen ); break;
case IPPROTO_ICMP: DecodeIcmpPack( buf + iIphLen ); break;
default: break;
}
printf( " " );

int col = 0;
char ascii[17];
for( int i=0; i<iBufSize; i++ )

{
printf( "%02X ", (unsigned char)buf[i] );

ascii[ col++ ] = ( unsigned char )buf[i] < 0x20 ? '.' : buf[i];

if( 15 == i%16 )

{
ascii[ col ] = 0;
printf( "%s ", ascii );
col = 0;
}
else if( 7 == i%8 ) printf( "- " );
}
if( col )

{
for( int i=col; i<16; i++ )

{
printf( " " );
if( 15 == i%16 )

{
ascii[ col ] = 0;
printf( "%s ", ascii );
}
else if( 7 == i%8 ) printf( "- " );
}
}

return true;
}

//
协议识别程序
const
char
*
CheckProtocol(
int
iProtocol)

{
typedef struct _protomap //定义子协议映射表

{
int ProtoNum;
char ProtoText[12];
}PROTOMAP;


static PROTOMAP ProtoMap[]=
{ //为子协议映射表赋值

{ IPPROTO_IP, "IP" },

{ IPPROTO_ICMP, "ICMP" },

{ IPPROTO_IGMP, "IGMP" },

{ IPPROTO_GGP, "GGP" },

{ IPPROTO_IPV4, "IPV4" },

{ IPPROTO_TCP, "TCP" },

{ IPPROTO_PUP, "PUP" },

{ IPPROTO_UDP, "UDP" },

{ IPPROTO_IDP, "IDP" },

{ IPPROTO_IPV6, "IPV6" },

{ IPPROTO_ROUTING, "ROUTING" },

{ IPPROTO_FRAGMENT, "FRAGMENT" },

{ IPPROTO_ESP, "ESP" },

{ IPPROTO_AH, "AH" },

{ IPPROTO_ICMPV6, "ICMPV6" },

{ IPPROTO_NONE, "NONE" },

{ IPPROTO_DSTOPTS, "DSTOPTS" },

{ IPPROTO_ND, "ND" },

{ IPPROTO_ICLFXBM, "ICLFXBM" },

{ IPPROTO_RAW, "RAW" },

{ IPPROTO_MAX, "MAX" },
};
const int nProtoCount = sizeof(ProtoMap)/sizeof(PROTOMAP);

for(int i=0; i<nProtoCount; i++)

{
if(ProtoMap[i].ProtoNum==iProtocol)
return ProtoMap[i].ProtoText;
}
return "";
}

//
TCP解包程序
bool
DecodeTcpPack(
const
char
*
TcpBuf)

{
TCP_HEADER * pTcpHeader;
int i;
pTcpHeader = (TCP_HEADER * )TcpBuf;
printf("Port:%d->%d ", ntohs(pTcpHeader->th_sport),ntohs(pTcpHeader->th_dport));
unsigned char FlagMask = 1;
for( i=0; i<6; i++ )

{
static char * TcpFlag = "FSRPAU"; //定义TCP标志位
if( ( pTcpHeader->th_flag ) & FlagMask )
printf( "%c", TcpFlag[i] );
else printf( "-" );

FlagMask = FlagMask << 1;
}
return true;
}

//
UDP解包程序
bool
DecodeUdpPack(
const
char
*
UdpBuf)

{
UDP_HEADER *pUdpHeader;
pUdpHeader = (UDP_HEADER * )UdpBuf;
printf("Port:%d->%d ", ntohs(pUdpHeader->uh_sport), ntohs(pUdpHeader->uh_dport));
printf("Len=%d", ntohs(pUdpHeader->uh_len));
return true;
}

//
ICMP解包程序
bool
DecodeIcmpPack(
const
char
*
IcmpBuf)

{
ICMP_HEADER *pIcmpHeader;
pIcmpHeader = (ICMP_HEADER * )IcmpBuf;
printf("Type:%d,%d ", pIcmpHeader->i_type,pIcmpHeader->i_code);
printf("ID=%d SEQ=%d", pIcmpHeader->i_id, pIcmpHeader->i_seq);
return true;
}































































































































































































































































































































































































