Chinaunix首页 | 论坛 | 博客
  • 博客访问: 309912
  • 博文数量: 55
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 615
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-07 13:47
文章分类
文章存档

2011年(1)

2010年(2)

2009年(14)

2008年(38)

我的朋友

分类: LINUX

2008-05-23 23:28:56

网络传输分层
如果你考过计算机等级考试,那么你就应该已经知道了网络传输分层这个概念.在网络上
,人们为了传输数据时的方便,把网络的传输分为7 个层次.分别是:应用层,表示层,会话层
,传输层,网络层,数据链路层和物理层.分好了层以后,传输数据时,上一层如果要数据的
话,就可以直接向下一层要了,而不必要管数据传输的细节.下一层也只向它的上一层提供
数据,而不要去管其它东西了.如果你不想考试,你没有必要去记这些东西的.只要知道是
分层的,而且各层的作用不同.

IP 协议
IP 协议是在网络层的协议.它主要完成数据包的发送作用. 下面这个表是IP4 的数据包格

0 4 8 16 32
--------------------------------------------------
|版本 |首部长度|服务类型| 数据包总长 |
--------------------------------------------------
| 标识 |DF |MF| 碎片偏移 |
--------------------------------------------------
| 生存时间 | 协议 | 首部较验和 |
------------------------------------------------
| 源IP 地址 |
------------------------------------------------
| 目的IP 地址 |
-------------------------------------------------
| 选项 |
=================================================
| 数据 |
-------------------------------------------------
下面我们看一看IP 的结构定义;
struct ip
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
ip_vIP 协议的版本号,这里是4,现在IPV6 已经出来了
ip_hlIP 包首部长度,这个值以4 字节为单位.IP 协议首部的固定长度为20 个字节,如果IP 包
没有选项,那么这个值为5.
ip_tos 服务类型,说明提供的优先权.
ip_len 说明IP 数据的长度.以字节为单位.
ip_id 标识这个IP 数据包.
ip_off 碎片偏移,这和上面ID 一起用来重组碎片的.
ip_ttl 生存时间.没经过一个路由的时候减一,直到为0 时被抛弃.
ip_p 协议,表示创建这个IP 数据包的高层协议.如TCP,UDP 协议.
ip_sum 首部校验和,提供对首部数据的校验.
ip_src,ip_dst 发送者和接收者的IP 地址
关于IP 协议的详细情况,请参考 RFC791

ICMP 协议
ICMP 是消息控制协议,也处于网络层.在网络上传递IP 数据包时,如果发生了错误,那么就
会用ICMP 协议来报告错误.
ICMP 包的结构如下:
0 8 16 32
---------------------------------------------------------------------
| 类型 | 代码 | 校验和 |
--------------------------------------------------------------------
| 数据 | 数据 |
--------------------------------------------------------------------
ICMP 在;中的定义是
struct icmphdr
{
u_int8_t type; /* message type */
u_int8_t code; /* type sub-code */
u_int16_t checksum;
union
{
struct
{
u_int16_t id;
u_int16_t sequence;
} echo; /* echo datagram */
u_int32_t gateway; /* gateway address */
struct
{
u_int16_t __unused;
u_int16_t mtu;
} frag; /* path mtu discovery */
} un;
};
关于ICMP 协议的详细情况可以查看 RFC792

UDP 协议
UDP 协议是建立在IP 协议基础之上的,用在传输层的协议.UDP 和IP 协议一样是不可靠的数
据报服务.UDP 的头格式为:
0 16 32
---------------------------------------------------
| UDP 源端口 | UDP 目的端口 |
---------------------------------------------------
| UDP 数据报长度 | UDP 数据报校验 |
---------------------------------------------------
UDP 结构在;中的定义为:
struct udphdr {
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
};
关于UDP 协议的详细情况,请参考 RFC768

TCP
TCP 协议也是建立在IP 协议之上的,不过TCP 协议是可靠的.按照顺序发送的.TCP 的数据结
构比前面的结构都要复杂.
0 4 8 10 16 24 32
-------------------------------------------------------------------
| 源端口 | 目的端口 |
-------------------------------------------------------------------
| 序列号 |
------------------------------------------------------------------
| 确认号 |
------------------------------------------------------------------
| | |U|A|P|S|F| |
|首部长度| 保留 |R|C|S|Y|I| 窗口 |
| | |G|K|H|N|N| |
-----------------------------------------------------------------
| 校验和 | 紧急指针 |
-----------------------------------------------------------------
| 选项 | 填充字节 |
-----------------------------------------------------------------
TCP 的结构在;中定义为:
struct tcphdr
{
u_int16_t source;
u_int16_t dest;
u_int32_t seq;
u_int32_t ack_seq;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int16_t res1:4;
u_int16_t doff:4;
u_int16_t fin:1;
u_int16_t syn:1;
u_int16_t rst:1;
u_int16_t psh:1;
u_int16_t ack:1;
u_int16_t urg:1;
u_int16_t res2:2;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int16_t doff:4;
u_int16_t res1:4;
u_int16_t res2:2;
u_int16_t urg:1;
u_int16_t ack:1;
u_int16_t psh:1;
u_int16_t rst:1;
u_int16_t syn:1;
u_int16_t fin:1;
#endif
u_int16_t window;
u_int16_t check;
u_int16_t urg_prt;
};
source 发送TCP 数据的源端口
dest 接受TCP 数据的目的端口
seq 标识该TCP 所包含的数据字节的开始序列号
ack_seq 确认序列号,表示接受方下一次接受的数据序列号.
doff 数据首部长度.和IP 协议一样,以4 字节为单位.一般的时候为5
urg 如果设置紧急数据指针,则该位为1
ack 如果确认号正确,那么为1
psh 如果设置为1,那么接收方收到数据后,立即交给上一层程序
rst 为1 的时候,表示请求重新连接
syn 为1 的时候,表示请求建立连接
fin 为1 的时候,表示亲戚关闭连接
window 窗口,告诉接收者可以接收的大小
check 对TCP 数据进行较核
urg_ptr 如果urg=1,那么指出紧急数据对于历史数据开始的序列号的偏移值
关于TCP 协议的详细情况,请查看 RFC793

TCP 连接的建立
TCP 协议是一种可靠的连接,为了保证连接的可靠性,TCP 的连接要分为几个步骤.我们把这
个连接过程称为"三次握手".
下面我们从一个实例来分析建立连接的过程.
第一步客户机向服务器发送一个TCP 数据包,表示请求建立连接. 为此,客户端将数据包的
SYN 位设置为1,并且设置序列号seq=1000(我们假设为1000).
第二步服务器收到了数据包,并从SYN 位为1 知道这是一个建立请求的连接.于是服务器也
向客户端发送一个TCP 数据包.因为是响应客户机的请求,于是服务器设置ACK 为1,sak_se
q=1001(1000+1)同时设置自己的序列号.seq=2000(我们假设为2000).
第三步客户机收到了服务器的TCP,并从ACK 为1 和ack_seq=1001 知道是从服务器来的确认
信息.于是客户机也向服务器发送确认信息.客户机设置ACK=1,和ack_seq=2001,seq=100
1,发送给服务器.至此客户端完成连接.
最后一步服务器受到确认信息,也完成连接.
通过上面几个步骤,一个TCP 连接就建立了.当然在建立过程中可能出现错误,不过TCP 协议
可以保证自己去处理错误的.
说一说其中的一种错误.
听说过DOS 吗?(可不是操作系统啊).今年春节的时候,美国的五大网站一起受到攻击.攻
击者用的就是DOS(拒绝式服务)方式.概括的说一下原理.
客户机先进行第一个步骤.服务器收到后,进行第二个步骤.按照正常的TCP 连接,客户机
应该进行第三个步骤.
不过攻击者实际上并不进行第三个步骤.因为客户端在进行第一个步骤的时候,修改了自
己的IP 地址,就是说将一个实际上不存在的IP 填充在自己IP 数据包的发送者的IP 一栏.这
样因为服务器发的IP 地址没有人接收,所以服务端会收不到第三个步骤的确认信号,这样
服务务端会在那边一直等待,直到超时.
这样当有大量的客户发出请求后,服务端会有大量等待,直到所有的资源被用光,而不能再
接收客户机的请求.
这样当正常的用户向服务器发出请求时,由于没有了资源而不能成功.于是就出现了春节
时所出现的情况.
----------------------------------------------------------------------------


阅读(1967) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~