Linux网络协议栈(四)——链路层(2)
2、协议相关
2.1、第3层协议的管理
在Linux内核中,有两种不同目的的3层协议:
(1) ptype_all管理的协议主要用于分析目的,它接收所有到达第3层协议的数据包。
(2) ptype_base管理正常的3层协议,仅接收具有正确协议标志符的数据包,例如,Internet的0x0800。
注意sb_buff与net_device中几个字段的区别:
sb_buff:
unsigned short protocol
高层协议从二层设备的角度所看到的协议,典型的协议包括 IP,IPV6和 ARP,完整的列表在 include/linux/if_ether.h。
unsigned char pkt_type
帧的类型,可能的取值都在include/linux/if_packet.h 中定义.
net_device:
unsigned short type
设备类型(以太网,帧中继等)。在include/linux/if_arp.h 中有完整的类型列表。
2.2、协议处理函数注册
当协议注册时,内核会调用dev_add_pack添加一个与之对应的packet_type数据结构:
//include/linux/netdevice.h
struct packet_type {
unsigned short 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 *);
void *af_packet_priv;
struct list_head list;
};
type:协议类型,它可以取以下一些值。来看看if_ether.h中定义的协议的类型:
Code
dev:网络设备。PF_PACKET套接字通常使用它在特定的设备监听,例如,tcpdump -i eth0 通过PF_PACKET套接字创建一个packet_type实例,然后将dev指向eth0对应的net_device数据结构。
func:协议处理函数。
af_packet_priv:被PF_PACKET套接字使用。
当同一个类型的协议有多个packet_type实例时,输入的帧会被所有的协议处理函数处理。
IP协议的packet_type:
//net/ipv4/ip_output.c
static struct packet_type ip_packet_type = {
.type = __constant_htons(ETH_P_IP),
.func = ip_rcv,
}; //在inet_init中被调用
void __init ip_init(void)
{
dev_add_pack(&ip_packet_type); ip_rt_init();
inet_initpeers(); #if defined(CONFIG_IP_MULTICAST) && defined(CONFIG_PROC_FS)
igmp_mc_proc_init();
#endif
}
//net/core/dev.c
void dev_add_pack(struct packet_type *pt)
{
int hash; spin_lock_bh(&ptype_lock);
if (pt->type == htons(ETH_P_ALL)) {
netdev_nit++;
list_add_rcu(&pt->list, &ptype_all);
} else {
hash = ntohs(pt->type) & 15;
list_add_rcu(&pt->list, &ptype_base[hash]);
}
spin_unlock_bh(&ptype_lock);
}
2.3、以太网帧(Ethernet)与802.3帧
老的以太网的帧的格式与标准和802.3标准的格式分别如下:
以太网的帧头(Ethernet frame header)的定义:
//include/linux/if_ether.h
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
} __attribute__((packed));
h_proto>1536的以太网类型:
2.4、eth_type_trans函数
//net/ethernet/eth.c
unsigned short eth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct ethhdr *eth;
unsigned char *rawp;
skb->mac.raw=skb->data;
skb_pull(skb,ETH_HLEN);
//取出以太网头
eth = eth_hdr(skb);
skb->input_dev = dev;
//设置帧的类型
if(*eth->h_dest&1) //广播和多播地址
{
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
skb->pkt_type=PACKET_BROADCAST;
else
skb->pkt_type=PACKET_MULTICAST;
}
/*
* This ALLMULTI check should be redundant by 1.4
* so don't forget to remove it.
*
* Seems, you forgot to remove it. All silly devices
* seems to set IFF_PROMISC.
*/
else if(1 /*dev->flags&IFF_PROMISC*/)
{
if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
//如果帧的目标地址与网络设备的mac地址不同
skb->pkt_type=PACKET_OTHERHOST;
}
if (ntohs(eth->h_proto) >= 1536)
return eth->h_proto;
rawp = skb->data;
/*
* This is a magic hack to spot IPX packets. Older Novell breaks
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
* won't work for fault tolerant netware but does for the rest.
*/
//IPX数据包没有802.2标准的LLC层,0xFFFF为其标志位
if (*(unsigned short *)rawp == 0xFFFF)
return htons(ETH_P_802_3);
/*
* Real 802.2 LLC
*/
//802.2标准的LLC协议
return htons(ETH_P_802_2);
}
该函数主要设置数据帧的类型,返回协议的类型。
Linux网络协议栈(四)——链路层(2)的更多相关文章
- Linux网络协议栈(四)——链路层(1)
1.接收帧当网络适配器接收到数据帧时,就会触发一个中断,中断处理程序执行一些需要及时处理的任务,然后在下半部进行其它可以延迟的处理.中断处理程序主要进行以下一些操作:(1) 分配sk_buff数 ...
- linux网络协议栈(四)链路层 vlan处理
转:http://blog.csdn.net/u010246947/article/details/18224517 4.6.VLAN处理: 4.6.1.vlan原理 对于带vlan的以太网报文,其以 ...
- 理解 Linux 网络栈(1):Linux 网络协议栈简单总结
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- linux网络协议栈--路由流程分析
转:http://blog.csdn.net/hsly_support/article/details/8797976 来吧,路由 路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看 ...
- Linux 网络协议栈开发基础篇—— 网桥br0
一.桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口"连接"起来.其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去.以使得网口之间的报文能够互相转发. 交换机 ...
- (转)Linux网络协议栈(三)——网络设备(1)
网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1) 作为基于硬件的网络适配器与基于软件的协 ...
- Linux网络协议栈(三)——网络设备(1)
网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1) 作为基于硬件的网络适配器与基于软件的协 ...
- 由PPPOE看Linux网络协议栈的实现
http://www.cnblogs.com/zmkeil/archive/2013/05/01/3053545.html 这个标题起得比较纠结,之前熟知的PPPOE是作为PPP协议的底层载体,而实际 ...
- Linux网络栈下两层实现
http://www.cnblogs.com/zmkeil/archive/2013/04/18/3029339.html 1.1简介 VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linu ...
随机推荐
- 在后台根据单据标识构建单据的DynamicObject,然后调用BOS的保存服务保存单据。
var bussnessInfo = Kingdee.BOS.ServiceHelper.MetaDataServiceHelper.GetFormMetaData(this.Context, &qu ...
- wordpress优化:Gravatar头像被墙及解决方案
网站缓存现象: 打开网站是左下角出现0.gravatar.com.1.gravatar.com或2.gravatar.com字样,网站一直处于缓存状态,迟迟未能打开.很多人都会缺乏耐心地等待一个网页的 ...
- Codeforces 658B Bear and Displayed Friends【set】
题目链接: http://codeforces.com/contest/658/problem/B 题意: 给定元素编号及亲密度,每次插入一个元素,并按亲密度从大到小排序.给定若干操作,回答每次询问的 ...
- Java并发包——Atomic操作
Java并发包——Atomic操作 摘要:本文主要学习了Java并发包下的atomic包中有关原子操作的一些类. 部分内容来自以下博客: https://blog.csdn.net/qq_303796 ...
- 代理服务器squid简介
Squid 是一个高性能.开源的代理缓存服务器和 Web 缓存进程,支持 FTP.Internet Gopher.HTTPS 和 SSL 等多种协议.它通过一个非阻塞的.I/O 事件驱动的单一进程处理 ...
- 关于maven多个模块的build顺序 [INFO] Reactor Build Order
对于一个maven项目,如果有多个模块,那么它们的执行顺序是什么样的呢? 在执行mvn操作的时候,你可以看到如下信息,这个便是maven的build顺序 那么maven是如何决定顺序的呢?如下: 在多 ...
- [BLE--Physical Layer]
简述 BLE的物理层,可能做IC或板极硬件RF測试的会比較关注. 是偏硬件层面的. 频率带宽和信道分配 BLE工作于2.4 GHz ISM频段2400-2483.5 MHz,ISM频段是公用的,不须要 ...
- MySql 基本操作语句整理
数据库 DATABASE: 创建 CREATTE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [DEFAULT] CHARACTER SET [=] cha ...
- css中使input输入框与img(图片)在同一行居中对齐
input,img{vertical-align:middle;},同时设置input和img的vertical-align属性,兼容ie7
- oracle 重要函数
1)instr()函数的格式 (俗称:字符查找函数) 格式一:instr( string1, string2 ) / instr(源字符串, 目标字符串) 格式二:instr( string1, st ...