杨老师之Blog
杨老师的茅屋
导航
VC知识库BLOG
首页
新随笔
联系
聚合
登录
<
2006年11月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
随笔分类
COM (22)
(rss)
VC (13)
(rss)
Math (7)
(rss)
文章 (1)
(rss)
随笔档案
2008年4月 (1)
2007年11月 (1)
2007年10月 (1)
2007年4月 (1)
2006年11月 (2)
2006年10月 (1)
2006年9月 (1)
2006年4月 (1)
2005年12月 (1)
2005年9月 (4)
2005年8月 (4)
2005年7月 (6)
2005年6月 (3)
2005年4月 (1)
2005年2月 (2)
2005年1月 (3)
2004年12月 (1)
2004年11月 (2)
2004年6月 (6)
2004年5月 (2)
文章档案
相册
(0)
简单图片 (23)
小巧玲珑的网络抓包
#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
&