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)的更多相关文章

  1. Linux网络协议栈(四)——链路层(1)

    1.接收帧当网络适配器接收到数据帧时,就会触发一个中断,中断处理程序执行一些需要及时处理的任务,然后在下半部进行其它可以延迟的处理.中断处理程序主要进行以下一些操作:(1)    分配sk_buff数 ...

  2. linux网络协议栈(四)链路层 vlan处理

    转:http://blog.csdn.net/u010246947/article/details/18224517 4.6.VLAN处理: 4.6.1.vlan原理 对于带vlan的以太网报文,其以 ...

  3. 理解 Linux 网络栈(1):Linux 网络协议栈简单总结

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  4. linux网络协议栈--路由流程分析

    转:http://blog.csdn.net/hsly_support/article/details/8797976 来吧,路由 路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看 ...

  5. Linux 网络协议栈开发基础篇—— 网桥br0

    一.桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口"连接"起来.其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去.以使得网口之间的报文能够互相转发. 交换机 ...

  6. (转)Linux网络协议栈(三)——网络设备(1)

    网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1)    作为基于硬件的网络适配器与基于软件的协 ...

  7. Linux网络协议栈(三)——网络设备(1)

    网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1)    作为基于硬件的网络适配器与基于软件的协 ...

  8. 由PPPOE看Linux网络协议栈的实现

    http://www.cnblogs.com/zmkeil/archive/2013/05/01/3053545.html 这个标题起得比较纠结,之前熟知的PPPOE是作为PPP协议的底层载体,而实际 ...

  9. Linux网络栈下两层实现

    http://www.cnblogs.com/zmkeil/archive/2013/04/18/3029339.html 1.1简介 VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linu ...

随机推荐

  1. centos7安装rlwrap

    http://utopia.knoware.nl/~hlub/uck/rlwrap/ 下载rlwrap-0.42.tar.gz 找到centos7 安装的iso中的 Packages的 ncurses ...

  2. POJ 2478 欧拉函数打表的运用

    http://poj.org/problem?id=2478 此题只是用简单的欧拉函数求每一个数的互质数的值会超时,因为要求很多数据的欧拉函数值,所以选用欧拉函数打表法. PS:因为最后得到的结果会很 ...

  3. RQNOJ273 马棚问题

    题目描述 每天,小明和他的马外出,然后他们一边跑一边玩耍.当他们结束的时候,必须带所有的马返回马棚,小明有K个马棚.他把他的马排成一排然后跟随它走向马棚,因为他们非常疲劳,小明不想让他的马做过多的移动 ...

  4. Codeforces Round #296 (Div. 2) D. Clique Problem [ 贪心 ]

    传送门 D. Clique Problem time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  5. msp430项目编程11

    msp430中项目---步进电机控制系统 1.步进电机工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  6. IE下IFrame引用跨域站点页面时,Session失效问题解决

    问题场景:在一个应用(集团门户)的某个page中, 通过IFrame的方式嵌入另一个应用(集团实时监管系统)的某个页面. 当两个应用的domain 不一样时, 在被嵌入的页面中Session失效.(s ...

  7. django学习之- Cookie

    cookie:客户端游览器上的一个文件,以键值对进行保存,类似字典{'k':'sfs'},与服务器端没有关系,当游览器访问服务器时候,服务器会生成一个随机字符串保存在cookie中返回给客户端,这样当 ...

  8. HDU 6395 分段矩阵快速幂 HDU 6386 建虚点+dij

    http://acm.hdu.edu.cn/showproblem.php?pid=6395 Sequence Time Limit: 4000/2000 MS (Java/Others)    Me ...

  9. Codeforces 938G(cdq分治+可撤销并查集+线性基)

    题意: 有一个无向连通图,支持三个操作: 1 x y d : 新建一条x和y的无向边,长度为d 2 x y    :删除x和y之间的无向边 3 x y    :询问x到y的所有路径中(可以绕环)最短的 ...

  10. 数据库中的DDL/DML/DCL解释(转)

    DDL is Data Definition Language statements. Some examples:数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言 1.CREATE - ...