`
simohayha
  • 浏览: 1401090 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

链路层到网络层的数据传递

阅读更多
我们知道在tcp/ip模型中,基本每一层都可以处理多重协议类型,那么当一个输入帧到达后,内核的每一层是如何来取得相应的处理函数呢?也就是说当我要把包传递给上层的时候,如何取得相应协议的处理函数。


我们这里先来看从二层如何把把数据传递给三层。
struct sk_buff {
....................................
	__be16			protocol;
.....................................

};


在sk_buff中的protocol字段能够表示输入帧的3层的协议,或者输入帧的mac头。在内核里面,是在函数netif_receive_skb中,通过protocol域来决定在三层的协议,以及处理函数。

如果内核没有找到protocol所对应协议的处理函数,那么这个帧将会被丢掉。而且一个packet也有可能被分发到多个handler,举个例子,当packet sniffer运行的时候,这里的protocol域有时就会为ETH_P_ALL.此时就会放所有的包进入下一层。不过使用ETH_P_ALL一般只是为了监测网络设备或者debug。比如tcpdump。

来看下netif_receive_skb的代码片段:


type = skb->protocol;
	list_for_each_entry_rcu(ptype,
			&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
		if (ptype->type == type &&
		    (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
		     ptype->dev == orig_dev)) {
			if (pt_prev)
				ret = deliver_skb(skb, pt_prev, orig_dev);
			pt_prev = ptype;
		}
	}


static inline int deliver_skb(struct sk_buff *skb,
			      struct packet_type *pt_prev,
			      struct net_device *orig_dev)
{
	atomic_inc(&skb->users);
	return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
}



我们可以看到最终会通过判断protocol来决定调用哪一个ptype,并调用相应的虚函数func,接下来我们就来看packet_type这个结构体,也就是所有的协议handler结构。

首先来看它的整体结构:





static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;

这里有一个全局的ptype_base,他是一个hash链表。它表示所有的协议handler结构。当通过dev_add_pack注册协议的时候就插入到相应的hashcode的相应链表。

static struct list_head ptype_all __read_mostly;	/* Taps */


ptype_all也是一个全局链表,可以看到他完全是和ptype_base独立的。他就表示了ETH_P_ALL协议。

接下来就来看packet_type的结构
struct packet_type {
	__be16			type;	/* This is really htons(ether_type). */
	struct net_device	*dev;	/* NULL is wildcarded here	     */
	int			(*func) (struct sk_buff *,
					 struct net_device *,
					 struct packet_type *,
					 struct net_device *);
	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
						int features);
	int			(*gso_send_check)(struct sk_buff *skb);
	void			*af_packet_priv;
	struct list_head	list;
};


type表示了协议的类型,dev表示了那个设备的协议类型,如果是NULL,则表示是所有设备,比如tcpdum就能通过指定设备名来监测某个指定设备。func对应协议的处理函数。af_pack_priv,被PF_PACKET类型的socket所使用(具体看unix网络编程). list链表(也就是hash链表中,相同的桶所处的链表). 中间的两个gso开头的函数,可以自己去看下gso的相关资料。

来看下ip协议的注册,以及初始化:

static struct packet_type ip_packet_type = {
	.type = __constant_htons(ETH_P_IP),
	.func = ip_rcv,
	.gso_send_check = inet_gso_send_check,
	.gso_segment = inet_gso_segment,
};

static int __init inet_init(void)
{
。。。。。。。。。。。。。。。。。。。。

	dev_add_pack(&ip_packet_type);
.........................................

}


可以看到在初始化函数中,调用dev_add_pack来上面定义的ip_packet_type加入到全局的hash链表中。

void dev_add_pack(struct packet_type *pt)
{
	int hash;

	spin_lock_bh(&ptype_lock);
///判断类型是否为ETH_P_ALL
	if (pt->type == htons(ETH_P_ALL))
		list_add_rcu(&pt->list, &ptype_all);
	else {
///计算hash值
		hash = ntohs(pt->type) & PTYPE_HASH_MASK;
///插入到相应的hash表位置
		list_add_rcu(&pt->list, &ptype_base[hash]);
	}
	spin_unlock_bh(&ptype_lock);
}



而链路层得到相应的输入包的协议类型是通过eth_type_trans来实现的,可以随便看一下驱动的代码,当驱动调用netif_rx之前,都会先调用这个函数来得到protocol值。

先来看下不同的帧类型的区别:




eth_type_trans有两个作用,一个是设置packet type,一个是设置协议类型。
其中packet type也就是skb->pkt_type字段,表示了链路层的数据类型,他可以为下面几种类型:


#define PACKET_HOST		0		/* To us		*/
#define PACKET_BROADCAST	1		/* To all		*/
#define PACKET_MULTICAST	2		/* To group		*/
#define PACKET_OTHERHOST	3		/* To someone else 	*/
#define PACKET_OUTGOING		4		/* Outgoing of any type */


这里要注意的是PACKET_OTHERHOST类型,它表示这个帧不属于这个接收接口,可是他并不会立即被扔掉,当传递给高层的时候。它主要用来protocol sniffer.

/*
 *	This is an Ethernet frame header.
 */
 
///帧头的表示。
struct ethhdr {
	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
	__be16		h_proto;		/* packet type ID field	*/
} __attribute__((packed));


__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
	struct ethhdr *eth;
	unsigned char *rawp;
///一些初始化
	skb->dev = dev;
	skb_reset_mac_header(skb);
	skb_pull(skb, ETH_HLEN);
	eth = eth_hdr(skb);

	if (is_multicast_ether_addr(eth->h_dest)) {
///判断是否为广播。
		if (!compare_ether_addr(eth->h_dest, dev->broadcast))
///数据位广播
			skb->pkt_type = PACKET_BROADCAST;
		else
///多播
			skb->pkt_type = PACKET_MULTICAST;
	}


	else if (1 /*dev->flags&IFF_PROMISC */ ) {
///主要用来网络的监测。
		if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr)))
			skb->pkt_type = PACKET_OTHERHOST;
	}

///通过上面的图我们知道大于1536为ethernet 类型的帧,因此直接返回h_proto。
	if (ntohs(eth->h_proto) >= 1536)
		return eth->h_proto;

	rawp = skb->data;
///取数据位来判断是否是802.3的帧。
	if (*(unsigned short *)rawp == 0xFFFF)
		return htons(ETH_P_802_3);

	/*
	 *      Real 802.2 LLC
	 */
	return htons(ETH_P_802_2);
}
  • 大小: 41.7 KB
  • 大小: 66.1 KB
分享到:
评论

相关推荐

    计算机网络数据链路层ppt

    ### 计算机网络数据链路层知识点详解 #### 数据链路层概述 计算机网络中的数据链路层是OSI七层模型中的第二层,主要负责在相邻节点之间提供可靠且透明的数据传输服务。该层的主要任务是通过一系列机制确保数据能够...

    计算机网络第7版课件-第3章-数据链路层_计算机网络数据链路层_

    数据链路层的主要任务是将网络层交下来的IP数据报封装成帧,在物理层传输的比特流基础上加上帧的起始标志、结束标志和错误检测代码,以确保数据能够正确地从源节点传输到目的节点。这个过程包含了帧的封装、传输、...

    计算机网络-物理链路层概述

    总的来说,数据链路层在物理链路层之上提供了一层逻辑控制,使得数据能够在复杂的网络环境中被正确、可靠地传递。它通过定义和执行各种协议,解决了物理层无法处理的错误和冲突,是计算机网络中不可或缺的一环。理解...

    完整报文格式大全-应用层、传输层、网络层、链路层、物理层

    在计算机网络中,数据传输的过程可以分为多个层次,这些层次共同构成了网络通信的协议栈,主要包括应用层、传输层、网络层、链路层和物理层。这些层次各自负责不同的功能,确保信息从源主机准确无误地传输到目标主机...

    计算机网络重点归纳【网络层、链路层、传输层】

    网络层不关心数据的传输质量,而是关注如何最有效地将数据包通过可能存在的多条路径传递到目的地。路由器是网络层的关键设备,它们根据路由表信息决定数据包的下一跳。 链路层则处理物理网络连接,如局域网(LAN)...

    第2部分:HART有线网络数据链路层服务定义和协议规范

    ### HART有线网络数据链路层服务定义和协议规范 #### 一、概述 HART(Highway Addressable Remote Transducer)协议是一种用于过程自动化领域中的通信协议,旨在为智能现场设备提供一种标准化的数据通信方式。HART...

    计算机硬件及网络北京邮电大学计算机网络数据链路层PPT学习教案.pptx

    在广播信道中,数据链路层面临更复杂的任务,如协调多个主机共享信道,这通常涉及到CSMA/CD(Carrier Sense Multiple Access with Collision Detection)协议。CSMA/CD是局域网,尤其是以太网中的冲突检测机制,当多...

    数据链路层的功能.docx

    数据链路层是计算机网络协议模型中的第二层,它的主要任务是为网络层提供可靠的数据传输服务。在这一层,比特流被组织成帧,并通过物理层进行传输。以下是数据链路层的关键功能: 1. **成帧与帧同步**: 数据链路...

    2.以太网链路层协议过程.pptx

    总的来说,以太网链路层是TCP/IP通信的基础,它确保了数据能够在网络中正确、高效地传输。通过ARP协议和交换机的智能转发,主机可以找到正确的路径将数据送达目的地,而交换机则在背后默默维护着网络的正常运行。...

    第5章链路层和局域网.ppt

    - **成帧**:数据链路层将来自网络层的数据报封装在帧中,添加头尾部信息,便于识别和处理。 - **链路访问**:在共享介质上,如局域网,链路层协议处理多个设备如何公平地共享信道。 - **MAC地址**:帧的头部包含...

    基于数据优先级和交通流密度的异构车联网数据链路层链路调度算法.pdf

    异构车联网数据链路层链路调度算法(Heterogeneous Vehicular Networks Link Scheduling Algorithm in LLC,HLSA)应运而生,该算法旨在根据车联网中的交通流密度、数据报文优先级和链路通信状态作为参数对链路进行...

    06-数据链路层与以太网.pdf

    在深入探讨数据链路层与以太网的相关知识点之前,我们需要了解数据链路层在整个网络架构中的作用和重要性。数据链路层位于网络的第二层,其核心功能是确保数据在相邻网络节点间的可靠传输。为了实现这一目标,数据链...

    数据链路层协议的分析与应用

    链路层位于网络模型的最底层,负责将网络层的数据包封装成帧,并通过物理介质进行传输。链路层的关键功能包括: - **封装与解封装**:将来自网络层的数据包封装成帧,并在接收端将帧解封装回数据包。 - **差错检测**...

    实验1 使用网络协议分析仪Wireshark和分析数据链路层帧结构

    Ethernet帧是数据链路层的传输单位,包含了MAC地址等关键信息。实验要求学生能够通过命令行工具(如IPconfig)查看本机MAC地址,并理解帧结构中的各个字段。例如,Frame字段提供了物理层的数据帧概述,Ethernet II...

    重要网络及链路层设备.pdf

    局域网的介质访问控制(MAC)层是OSI模型的数据链路层的一部分,负责控制同一物理介质上的多个设备如何共享通信带宽。常见的MAC层协议有: 1. **CSMA/CD (Carrier Sense Multiple Access with Collision Detection)**...

    网络协议概述:物理层、连接层、网络层、传输层、应用层详解

    **连接层**,也称为链路层,处理数据帧的传输。帧是数据在网络中传输的基本单元,包含源和目标地址,用于错误检测的校验序列,以及数据负载。以太网和Wi-Fi的连接层协议(如IEEE 802.3和802.11)确保帧正确地在...

    第3章数据链路层与局域网.ppt

    数据链路层是计算机网络协议层次中的第二层,主要负责在相邻节点间提供无差错的数据传输,确保数据帧从源节点可靠地传递到目的节点。这一层的任务包括差错检测、媒体访问控制以及在某些情况下实现可靠传输。 首先,...

    网络传输过程及各层次分析

    OSI七层模型是一个标准的网络协议栈,共有七个层次,从上到下分别是应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。每个层次都有其特定的功能和协议。 应用层是最高的一层,负责提供各种网络服务,...

    计算机网络协议分析(数据层、网络层、传输层、应用层协议分析)

    数据链路层的主要任务是为网络层提供可靠的数据传输服务,确保数据在物理链路上的正确传输。这一层的协议包括以太网、802.11无线局域网(Wi-Fi)、令牌环和PPP等。以太网是最常见的局域网标准,其帧结构包含源和目的...

Global site tag (gtag.js) - Google Analytics