文档章节

TCP/IP协议详解卷2 第4章 以太网

卜星星
 卜星星
发布于 2015/03/02 11:49
字数 811
阅读 87
收藏 1

        这一章说是要介绍:以太网设备驱动程序在初始化后是如何接收和传输帧的;还有配置网络通用ioctl。

在ifnet中有7个函数:

/* 这是初始化等处理函数,这些函数就是我们访问网络设备驱动程序 */ 
  int  (*if_init)   __P(( int ));
  int  (*if_output)  __P(( struct  ifnet *,  struct  mbuf *,  struct  sockaddr *,   struct  rtentry *));
  int  (*if_start)  __P(( struct  ifnet *));
  int  (*if_done)  __P(( struct  ifnet *)); 
  int  (*if_ioctl)  __P(( struct  ifnet *, u_long, caddr_t));
  int  (*if_reset)  __P(( int ));  
  int  (*if_watchdog)  __P(( int )); 

这7个函数就是用来调用驱动程序的。不同设备都有不同的驱动函数,比如这里说的以太网那个if_output就是ether_output

SNMP:简单网络管理协议信息库(SNMP MIB-II)

以太网封闭结构:目标地址(6) 源地址(6)协议类型(2) 共14字节  46~1500数据  CRC(4)

当设备接收到一个以太网帧,并且完整可用时,就产生中断,调用leintr,leintr调用leread把帧从接口弄到mbuf中,

所以以太网设备驱动程序将接收到的帧传给ether_input处理

leread函数第一个参数unit就是在ifnet中的那个if_unit同一类接口不同编号

leread(unit, buf, len)
 int unit;
 char *buf;
 int len;
{
 register struct le_softc *le = &le_softc[unit];
 register struct ether_header *et;
     struct mbuf *m;
 int off, resid, flags;
 le->sc_if.if_ipackets++;
 et = (struct ether_header *)buf;
 et->ether_type = ntohs((u_short)et->ether_type);
 /* adjust input length to account for header and CRC */
 len = len - sizeof(struct ether_header) - 4;
#define ledataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off))))
 if (et->ether_type >= ETHERTYPE_TRAIL &&
     et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
  off = (et->ether_type - ETHERTYPE_TRAIL) * 512;
  if (off >= ETHERMTU)
   return;  /* sanity */
  et->ether_type = ntohs(*ledataaddr(et, off, u_short *));
  resid = ntohs(*(ledataaddr(et, off+2, u_short *)));
  if (off + resid > len)
   return;  /* sanity */
  len = off + resid;
 } else
  off = 0;
 if (len <= 0) {
  if (ledebug)
   log(LOG_WARNING,
       "le%d: ierror(runt packet): from %s: len=%d\n",
       unit, ether_sprintf(et->ether_shost), len);
  le->sc_runt++;
  le->sc_if.if_ierrors++;
  return;
 }
 flags = 0;
 if (bcmp((caddr_t)etherbroadcastaddr,
     (caddr_t)et->ether_dhost, sizeof(etherbroadcastaddr)) == 0)
  flags |= M_BCAST;
 if (et->ether_dhost[0] & 1)
  flags |= M_MCAST;
#if NBPFILTER > 0
 /*
  * Check if there's a bpf filter listening on this interface.
  * If so, hand off the raw packet to enet.
  */
 if (le->sc_if.if_bpf) {
  bpf_tap(le->sc_if.if_bpf, buf, len + sizeof(struct ether_header));
  /*
   * Keep the packet if it's a broadcast or has our
   * physical ethernet address (or if we support
   * multicast and it's one).
   */
  if (
#ifdef MULTICAST
      (flags & (M_BCAST | M_MCAST)) == 0 &&
#else
      (flags & M_BCAST) == 0 &&
#endif
      bcmp(et->ether_dhost, le->sc_addr,
   sizeof(et->ether_dhost)) != 0)
   return;
 }
#endif
 /*
  * 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);
}
void
ether_input(ifp, eh, m)
 struct ifnet *ifp;
 register struct ether_header *eh;
 struct mbuf *m;
{
 register struct ifqueue *inq;
 register struct llc *l;
 struct arpcom *ac = (struct arpcom *)ifp;
 int s;
 if ((ifp->if_flags & IFF_UP) == 0) {
  m_freem(m);
  return;
 }
 ifp->if_lastchange = time;
 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
     sizeof(etherbroadcastaddr)) == 0)
  m->m_flags |= M_BCAST;
 else if (eh->ether_dhost[0] & 1)
  m->m_flags |= M_MCAST;
 if (m->m_flags & (M_BCAST|M_MCAST))
  ifp->if_imcasts++;
 switch (eh->ether_type) {
#ifdef INET
 case ETHERTYPE_IP:
  schednetisr(NETISR_IP);
  inq = &ipintrq;
  break;
 case ETHERTYPE_ARP:
  schednetisr(NETISR_ARP);
  inq = &arpintrq;
  break;
#endif

  default:
  if (eh->ether_type > ETHERMTU) {
    m_freem(m);
    return;
  } 
 
/* 下面很多都忽略掉了只留下了INET的 */
 }
 s = splimp();
 if (IF_QFULL(inq)) {
  IF_DROP(inq);
  m_freem(m);
 } else
  IF_ENQUEUE(inq, m);
 splx(s);
}

由于我其实也不知道究竟要看什么,哪些是有用的,哪些没有用,所以只能从头看下去,争取能看完一遍,之后再回来总结一下。

© 著作权归作者所有

共有 人打赏支持
卜星星
粉丝 27
博文 111
码字总数 68736
作品 0
海淀
程序员
私信 提问
《TCP/IP详解 卷1:协议》第3章 IP:网际协议

3.1 引言 IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输(见图1-4)。许多刚开始接触TCP/IP的人对IP提供不可靠、无连接的数据报传送服务感到很奇怪...

开元中国2015
11/14
0
0
《TCP/IP详解 卷1:协议》系列分享专栏

《TCP/IP详解卷1:协议》是一本详细的TCP/IP协议指南,计算机网络历久不衰的经典著作之一。 作者理论联系实际,使读者可以轻松掌握TCP/IP的知识。阅读对象为计算机专业学生、教师以及研究网络...

开元中国2015
11/15
0
0
《TCP/IP详解.卷1:协议》读书笔记

从大学的时候就听余老师介绍过stevens这三卷书,还听说最后一卷没写完作者就去世了,工作后也一直听人谈起, 但还是没去真正读它。最近因为工作上很多涉及到网络,捉包,各种tcpdump的使用,...

suit
2014/10/21
0
0
网络编程懒人入门(三):快速理解TCP协议一篇就够

原作者:阮一峰(ruanyifeng.com),本文由即时通讯网重新整理发布,感谢原作者的无私分享。 1、前言 本系列文章的前两篇《网络编程懒人入门(一):快速理解网络通信协议(上篇)》、《网络编程...

JackJiang2011
2017/10/12
0
0
TCP/IP详解卷一概述

第1章 概述 1.1 引言 很多不同的厂家生产各种型号的计算机,它们运行完全不同的操作系统,但TCP/IP协议族允许它们互相进行通信。这一点很让人感到吃惊,因为它的作用已远远超出了起初的设想。...

Junin
2012/07/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
17
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
昨天
27
0
"errcode": 41001, "errmsg": "access_token missing hint: [w.ILza05728877!]"

Postman获取微信小程序码的时候报错, errcode: 41001, errmsg: access_token missing hint 查看小程序开发api指南,原来access_token是直接当作parameter的(写在url之后),scene参数一定要...

两广总督bogang
昨天
31
0
MYSQL索引

索引的作用 索引类似书籍目录,查找数据,先查找目录,定位页码 性能影响 索引能大大减少查询数据时需要扫描的数据量,提高查询速度, 避免排序和使用临时表 将随机I/O变顺序I/O 降低写速度,占用磁...

关元
昨天
15
0
撬动世界的支点——《引爆点》读书笔记2900字优秀范文

撬动世界的支点——《引爆点》读书笔记2900字优秀范文: 作者:挽弓如月。因为加入火种协会的读书活动,最近我连续阅读了两本论述流行的大作,格拉德威尔的《引爆点》和乔纳伯杰的《疯传》。...

原创小博客
昨天
35
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部