BSD net源码分析(2-2)

来源:互联网 发布:中国人工智能发展大会 编辑:程序博客网 时间:2024/06/06 01:00
 二、以太网接口接收数据帧
    当接口接收到发送给该接口的单播地址和广播地址的帧,帧可用时,触发一个中断,并且内核调用驱动函数函数leintr()。
    leintr()函数内部根据硬件寄存器的值,判断是什么中断,如果是LE_RINT状态,调用lerint处理接收的数据,如果是LE_TINT,调用lexint做输出数据处理。
    其他的状态,程序会更新接口的统计,并调用lereset重设接口寄存器的值和状态。
    以太网接口接收数据中断,触发调用函数lerint(),该函数主要处理接收到的数据,并丢弃错误的数据,同时更新统计值,有效数据通过调用函数leread交到enther_input函数做后续处理。
    leread的输入参数包括数据内容buf,长度len。以太网的头部(ether_header结构存放)存放再buf的首部。
    leread获取到以太网的数据的头部,判断ether_type类型,并要区别802和以太网包的不同格式,获取数据的长度和内容。判断是否广播数据和多播数据,并置flag,如果给接口有bpf回调,同时调用。
    最后leread调用m_devget函数获取一个mbuf,并把数据放入mbuf,但以太网的首部未放入,而时通过ether_input函数的参数带入。
/******************************************************/
    /*
     * Pull packet off interface.  Off is nonzero if packet
     * has trailing header; m_devget will then force this header
     * information to be at the front, but we still have to drop
     * the type and length which are at the front of any trailer data.
     */
    m = m_devget((char *)(et + 1), len, off, &le->sc_if, 0);
    if (m == 0)
        return;
    m->m_flags |= flags;
    ether_input(&le->sc_if, et, m);
/******************************************************/
    ether_input主要完成对广播和多播包的识别以及链路层数据的分发处理。
    (1)通过以太网地址识别包的类型,并置mbuf的m_flags标记。
    (2)通过以太网头部的ether_type分发不同类型的数据包。
    对于ETHERTYPE_IP包,调用schednetisr(NETISR_IP)软中断,并选择ipintrp队列输入数据。
    对ETHERTYPE_ARP包,调用schednetisr(NETISR_ARP)软中断,并选择arpintrp队列输入数据。
    对ETHERTYPE_NS包,调用schednetisr(NETISR_NS)软中断,并选择nsintrp队列输入数据。
    对其他的包可能时ISO封装的802包做相应的处理。
    函数的最后根据选择的队列,将数据入队。
原创粉丝点击