最近狂补基础,猛看
TCP/IP
协议。不过,书上的东西太抽象了,没有什么数据实例,
看了不
久就忘了。于是,搬来一个
sniffer
,抓了数据包来看,呵呵,结合书里面得讲解,
理解得
比较快。我就来灌点基础知识。
开始吧,先介绍
IP
协议。
IP
协议(
Internet Protocol
)是网络层协议,用在因特网上,
TCP
,
UDP
,
ICMP
,
IGMP
数据都是按照
IP
数据格式发送得。
IP
协议提供的是不可靠无连接得服务。
IP
数据包由一个
头部和一个正文部分。构成。正文主要是传输的数据,我们主要来理解头部数据,
可以从其
理解到
IP
协议。
来看看我捕获的例子吧。这是一次
FTP
的连接,呵呵,是
cuteftp
默认的
cuteftp
的
FTP
站点,
IP
地址是:
216.3.226.21
,我的
IP
地址假设为
:192.168.1.1
。下面的数据就是
TCP/IP
连接过程中的数据传输。我们可以分析
TCP/IP
协议数据格式以及
TCP/IP
连接的三次握手
(
ThreeWay-Handshake
)情况。下面的这些十六进制数据只是
TCP/IP
协议的数据,不是完
整的网络通讯数据。
第一次,我向
FTP
站点发送连接请求(我把
TCP
数据的可选部分去掉了)
192.168.1.1->216.3.226.21
IP
头部:
45 00 00 30 52 52 40 00 80 06 2c 23 c0 a8 01 01 d8 03 e2 15
TCP
头部:
0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00
来看看
IP
头部的数据是些什么。
第一字节,
“
45
”
,其中“
4
”是
IP
协议的版本(
Version
)
,说明是
IP4
。
“
5
”是
IHL
位,
表示
IP
头部的长度,是一个
4bit
字段,最大就是
1111
了,值为
12
,
IP
头部的最大长度就
是
60
字节。而这里为“
5
”
,说明是
20
字节,这是标准的
IP
头部长度,头部报文中没有发
送可选部分数据。
接下来的一个字节“
00
”是服务类型(
Type of Service
)
。这个
8bit
字段由
3bit
的优先权
子字段
(现在已经被忽略)
,
4 bit
的
TOS
子字段以及
1 bit
的未用字段
(现在为
0
)
构成
.4 bit
的
TOS
子字段包含:最小延时、最大吞吐量、最高可靠性以及最小费用构成,这四个
1bit
位最多只能有一个为
1
,本例中都为
0
,表示是一般服务。
接着的两个字节“
00 30
”是
IP
数据报文总长,包含头部以及数据,这里表示
48
字节。
这
48
字节由
20
字节的
IP
头部以及
28
字节的
TCP
头构成(本来截取的
TCP
头应该是
28
字节的,其中
8
字节为可选部分,被我省去了)
。因此目前最大的
IP
数据包长度是
65535
字
节。
再是两个字节的标志位(
Identification
)
:
“
5252
”
,转换为十进制就是
21074
。这个是让
目的主机来判断新来的分段属于哪个分组。
下一个字节
“
40
”
,
转换为二进制就是
“
0100 0000
”
,
其中第一位是
IP
协议目前没有用上的,
为
0
。接着的是两个标志
DF
和
MF
。
DF
为
1
表示不要分段,
MF
为
1
表示还有进一步的分
段
(本例为
0
)
。
然后的
“
0 0000
”
是分段便移
(
Fragment Offset
)
。
IP
包头中的
Identification
、
flags
、
ragment
offset
三个字段控制着
IP
报文的分割和重组。
TCP
报头中的
SourcePort
、
DestPort
、
TCP Sequence Number
、
Urgent pointer
、
FIN
、
PUSH
、
SYN
字段控制着
TCP
报文
的开头和结束
,
我们也可以如法完成
TCP
包
(
或特定应用
)
的重组工作。
至于
UDP
数据包
,
从其
包头可以看出
,
只要完成了
IP
包的重组
,
也就完成了
UDP
包的重组工作。
“
80
”这个字节就是
TTL
(
Time To Live
)了,表示一个
IP
数据流的生命周期,用
Ping
显示的结果,能得到
TTL
的值,很多文章就说通过
TTL
位来判别主机类型。因为一般
主机都有默认的
TTL
值,不同系统的默认值不一样。比如
WINDOWS
为
128
。不过,一般
Ping
得到的都不是默认值,
这是因为每次
IP
数据包经过一个路由器的时候
TTL
就减一,
当
减到
0
时,这个数据包就消亡了。这也是
Tracert
的原理。本例中为“
80
”
,转换为十进制就
是
128
了,我用的
WIN2000
。
继续下来的是“
06
”
,这个字节表示传输层的协议类型(
Protocol
)
。在
RFC790
中有定
义,
6
表示传输层是
TCP
协议。
“
2c 23
”这个
16bit
是头校验和(
Header Checksum
)
。
接下来“
c0 a8 01 01
”
,这个就是源地址(
Source Address
)了,也就是我的
IP
地址。
转换为十进制的
IP
地址就是:
192.168.1.1
,同样,继续下来的
32
位“
d8 03 e2 15
”是
目标地址,
216.3.226.21
好了,真累啊,终于看完基本的
20
字节的
IP
数据报头了。继续看
TCP
的头部吧,这
个是作为
IP
数据包的数据部分传输的。
TCP
头部:
0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00
一来就是一个两字节段“
0d 28
”
,
表示本地端口号,转换为十进制就是
3368
。第二个两
字节段“
00 15
”表示目标端口,因为我是连接
FTP
站点,所以,这个就是
21
啦,十六进制
当然就是“
00 15
”
。
接下来的四个字节“
50
5f
a9
06
”是顺序号(
Sequence
Number
)
,简写为
SEQ
,
SEQ=1348446470
下面的四个字节“
00 00 00 00
”是确认号(
Acknowledgment Number
)
,简
写为
ACKNUM
。
继续两个字节,
“
70 02
”
,转换为二进制吧,
“
0111 0000 0000 0010
”
。这两个字节
,
总共
16bit
,有好多东西呢。第一个
4bit
“
0111
”
,是
TCP
头长,十进制为
7
,表示
28
个字节(刚
才说了,我省略了
8
字节的
option
数据,所以你只看见了
20
字节)
。接着的
6bit
现在
TCP
协议没有用上,都为
0
。最后的
6bit
“
00 0010
”是六个重要的标志。这是两个计算机数据交
流的信息标志。接收和发送端根据这些标志来确定信息流的种类。下面是一些介绍:
URG
:
(
Urgent
Pointer
field
significant
)紧急指针。用到的时候值为
1
,用来处理避免
TCP
数据流中断
ACK
:
(
Acknowledgment fieldsignificant
)置
1
时表示确认号
(
AcknowledgmentNumber
)
为合法,为
0
的时候表示数据段不包含确认信息,确认号被忽略。
PSH
:
(
Push
Function
)
,
PUSH
标志的数据,置
1
时请求的数据段在接收方得到后就可
直接送到应用程序,而不必等到缓冲区满时才传送。
RST
:
(
Reset the connection
)用于复位因某种原因引起出现的错误连接,也用来拒绝非
法数据和请求。如果接收到
RST
位时候,通常发生了某些错误。
SYN
:
(
Synchronize sequence numbers
)
用来建立连接,
在连接请求中,
SYN=1
,
ACK=0
,
连接响应时,
SYN=1
,
ACK=1
。即,
SYN
和
ACK
来区分
Connection Request
和
Connection
Accepted
。
FIN
:
(
No more data from sender
)用来释放连接,表明发送方已经没有数据发送了。
这
6
个标志位,你们自己对号入座吧。本例中
SYN=1
,
ACK=0
,当然就是表示连接请
求了。我们可以注意下面两个过程的这两位的变换。
后面的“
40 00 c0 29 00 00
”不讲了,呵呵,偷懒了。后面两次通讯的数据,自己分开
看吧。我们看看连接的过程,一些重要地方的变化。
第二次,
FTP
站点返回一个可以连接的信号。
216.3.226.21->192.168.1.1
IP
头部:
45 00 00 2c c6 be 40 00 6a 06 cd ba d8 03 e2 15 c0 a8 01 01
TCP
头部:
00 15 0d 28 4b 4f 45 c1 50 5f a9 07 60 12 20 58 64 07 00 00
第三次,我确认连接。
TCP
连接建立起来。
192.168.1.1->216.3.226.21
IP
头部:
45 00 00 28 52 53 40 00 80 06 2c 2a c0 a8 01 01 d8 03 e2 15
TCP
头部:
0d 28 00 15 50 5f a9 07 4b 4f 45 c2 50 10 40 b0 5b 1c 00 00
好,我们看看整个
Threeway_handshake
过程。
第一步,我发出连接请求,
TCP
数据为:
SEQ=50
5f
a9 06
,
ACKNUM=00
00
00
00
,
SYN=1
,
ACK=0
。
第二步,对方确认可以连接,
TCP
数据为:
SEQ=4b 4f 45 c1
,
ACKNUM=50 5f a9 07
,
SYN=1
,
ACK=1
。
第三步,
我确认建立连接。
SEQ=50 5f a9 07
,
ACKNUM=4b 4f45c2
,
SYN=0
,
ACK=1
。
可以看出什么变化么?正式建立连接了呢,这些东西是什么值?
我接收从
216.3.226.21->192.168.1.1
的下一个数据包中:
SEQ=4b 4f 45 c2
,
ACKNUM=50 5f a9 07,SYN=0,ACK=1
这些都是很基础的东西,对于
编写
sniffer
这样的东西是必须非常熟悉的。这里只讲解了
TCP/IP
协议的一点点东西,主要
是头部数据的格式。
(T002)
来源URL:http://wenku.baidu.com/view/fa533ec658f5f61fb73666be.html