第二十四章:L4协议和Raw IP的处理

本章描述L3和L4协议间的接口。L3协议只考虑IP。L4协议如TCP,UDP,ICMP,这几个协议是静态编译至内核中的。还有其他L4协议编译成模块。

L4协议的注册:

L4协议由net_protocol数据结构定义,其中三个字段如下:

    int (*handler)(struct sk_buff *skb):由协议来注册的处理函数,用来处理送进来的封包。

    void (*err_handler)(struct sk_buff *skb,u32 info):由ICMP协议处理函数所用的函数,用于通知L4协议有关收到ICMP  UNREACHABLE消息的事情。

    int no_policy:此字段在网络协议栈中的某些关键点被查询,用于使协议免于IPsec策略检查。

协议会以inet_add_protocol函数自行注册,当协议实现成模块时,以inet_del_protocol自行除名。所有和内核注册的L4协议的你、inet_protocol结构会插入到名为inet_protos的表内,如下图,是一个数组,数组索引就是协议编号:

对于每个L4协议而言,内核只能有一个处理函数,但是用户空间可用有多个处理函数。

L3到L4的传递:ip_local_deliver_finish:

ip_local_deliver_finish的主要工作是根据IP封包报头的协议字段找出正确的协议处理函数,然后把封包交给协议处理函数。同时,ip_local_deliver_finish还要处理raw IP以及IPsec(如果有配置的话)。

如果没有找到相关的协议处理函数,且没有raw套接字对该封包感兴趣,则会丢弃封包并发送icmp报文给来源地。也就是说,无论是否注册有相关的协议处理函数,ip_local_deliver_finish总是会检查是否有应用程序设立了一个raw 套接字要处理该协议,如果有,拷贝一个封包的副本,将其交给应用程序。

如下图所示,无论封包是由已注册L4协议或Raw IP处理,其他协议可能还是得被启用,例如IPsec 集组里的协议。

Raw套接字和Raw IP:

并非所有的L4协议都是在内核空间中实现的。例如,tcp和udp完全在内核实现,ospf协议在用户空间实现,icmp部分在内核,部分在用户空间实现。下图分别显示了这三种情况:

上图a:网页浏览器和web服务器通信,浏览器和服务器只传递TCP有效载荷给内核,而内核会处理TCP和IP报头。

上图b:两台执行OSPF常驻程序的路由器彼此对话,OSPF协议是在用户空间实现的,而且会把L4报头(ospf的头,不是tcp和udp)和有效载荷传给内核(这是使用raw 套接字的实例之一,参见第十三章了解raw套接字和协议栈如何搭配)。事实上,多数ospf实现也会传递ip头。就像图d一样。

上图c:一台主机ping另一台主机,请求组件是在用户空间实现的,ping程序产生icmp封包,然后传给L3,内核不会去碰icmp头部。然而,回复组件在内核空间实现,进行接收的主机会在内核处理ICMP_ECHO_REQUEST然后进行回复。

上图d:一台执行traceroute的主机执行网络除错工作。L3和L4头部由应用程序处理。应用程序将它的L4协议指定为RAW IP,然后对套接字设定IP_HDRINCL选项(包含报头)。(参见二十一章有关IP如何处理Raw IP)

把Raw输入数据段传递给进行接收的应用程序:

当应用程序打开一个套接字时,必须指定家族,套接字类型以及协议标识符。套接字和协议类型都可以是raw。socket系统调用的原型如下:

    socket(int family,int type,int protocol)

其中,family是地址家族(TCP/IP所有值为AF_INET),type是套接字类型,protocol是L4协议标识符。当你打开一个SOCK_RAW类型的套接字(所选协议号码是整数P),你的应用程序会接收到所有满足下列规则的入口封包:

    IP报头中的L4协议标识符是P

    当套接字绑定至目的IP地址时,封包中源IP地址必须吻合

    当套接字绑定至本地IP地址时,封包中目的IP地址必须吻合

不是只有一个套接字可以满足这些规则,所以一个Raw IP封包可以传递给多个应用程序。

当套i额类型时SOCK_RAW而协议为RAW IP(255)时,应用程序需要处理L4和L3报头。这一点和图24-6b不同,因为协议是raw IP而不是ospf。图24-6d所显示的是RAW IP的情况。这类应该程序会对套接字设定IP_HDRINCL来告知内核应该程序会处理ip头。当协议是RAW IP时,IP_HDRINCL选项是默认打开的。

用于存储raw处理函数的表(raw_v4_htable)和用于存储协议处理函数的表(inet_protos)具有相同的尺寸。raw封包会传给raw_v4_input,该函数会拷贝封包然后交给主要处理函数raw_rcv。

IPsec:

ip_local_deliver_finish把封包传给正确的协议处理函数之前,必须先以IPsec检查该封包是否准许处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值