文档章节

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

卜星星
 卜星星
发布于 2015/03/02 11:49
字数 811
阅读 79
收藏 1
点赞 0
评论 0

        这一章说是要介绍:以太网设备驱动程序在初始化后是如何接收和传输帧的;还有配置网络通用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);
}

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

© 著作权归作者所有

共有 人打赏支持
卜星星
粉丝 25
博文 110
码字总数 68736
作品 0
海淀
程序员
《TCP/IP详解.卷1:协议》读书笔记

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

suit ⋅ 2014/10/21 ⋅ 0

网络编程懒人入门(三):快速理解TCP协议一篇就够

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

JackJiang2011 ⋅ 2017/10/12 ⋅ 0

TCP/IP详解卷一概述

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

Junin ⋅ 2012/07/31 ⋅ 0

TCP/IP详解(一)

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

红薯 ⋅ 2009/05/05 ⋅ 2

APR协议分组格式的字段解释

在看《TCP/IP详解 卷1》的第四章APR协议的时候,看到APR请求和应答分组格式里的字段如下图: 其中前两个字段和倒数第4个字段,倒数第2个字段有什么区别吗? 这本书里的解释我没有看明白,解释...

xinspace ⋅ 2013/04/10 ⋅ 1

网络编程懒人入门(四):快速理解TCP和UDP的差异

原作者:MeloDev,本文由即时通讯网重新修订发布,感谢原作者的无私分享。 1、前言 对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是...

JackJiang2011 ⋅ 2017/10/27 ⋅ 0

《TCP IP详解卷1:协议 》原书第2版下载

本书是《TCP/IP详解》第1卷的第2版,主要讲述TCP/IP协议,结合大量实例讲述TCP/IP协议族的定义原因,以及在各种不同的操作系统中的应用及工作方式。第2版在保留Stevens卓越的知识体系和写作风...

ddddd8 ⋅ 2017/12/15 ⋅ 0

TCP/IP详解(二) 

TCP/IP详解(二)  4.5 ARP举例 在本小节中,我们用tcpdump命令来看一看运行像Telnet这样的普通TCP工具软件时ARP会做些什么。附录A包含tcpdump命令的其它细节。 普通例子 为了看清楚ARP的运...

JavaGG ⋅ 2009/05/05 ⋅ 1

Linux网络编程书籍

计算机网络知识 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的《计算机网络》第五版,这本书难易适中。 目前已经是第五版,本书作者80年代就开发出MINIX,是一个用于操作系统教学的类U...

krircc ⋅ 2015/04/01 ⋅ 0

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

本文观点仅作参考,请根据自已系统的应用场景合理地选择数据传输层协议即可,无需盲目崇拜大牛言论。 1、前言 对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的...

JackJiang2011 ⋅ 2017/12/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

istio 文档

https://istio.io/docs/concepts/ https://istio.io/docs/concepts/traffic-management/handling-failures/ https://istio.io/docs/concepts/traffic-management/rules-configuration/......

xiaomin0322 ⋅ 21分钟前 ⋅ 0

编程语言的作用及与操作系统和硬件的关系

一、编程语言的作用及与操作系统和硬件的关系 作用:编程语言是计算机语言,是一种程序员与计算机之间沟通的介质,通过编程语言可以使得计算机能够根据人的指令一步一步去工作,完成某种特定...

slagga ⋅ 31分钟前 ⋅ 0

runtime实现按钮点击事件

也不能说是实现吧,,,就是有点类似于RAC里边的写法,不用给btn添加另外的点击事件,就那个add...select...这样子很不友好,来看下代码: [self.btn handleControlEvent:UIControlEventTou...

RainOrz ⋅ 32分钟前 ⋅ 0

Windows系统运维转linux系统运维的经历

开篇之前,首先介绍一下我的背景把:我是一个三线城市的甲方运维。最近,在《Linux就该这么学》书籍的影响下和朋友小A(Linux运维已经三年了,工资也比我的高很多)的影响下,决定转行。最近...

linux-tao ⋅ 32分钟前 ⋅ 0

zip压缩工具,tar打包工具

zip压缩工具 zip打包工具跟前面说到的gzip,bz2,xz 工具最大的不一样是zip可以压缩目录。如果没有安装,需要使用yum install -y zip 来安装。安装完之后就可以直接使用了,跟之前提到的压缩...

李超小牛子 ⋅ 40分钟前 ⋅ 0

使用npm发布自己的npm组件包

一、注册npm账号 官网:https://www.npmjs.com/signup 注册之后需要进行邮箱验证,否则后面进行组件包发布时候会提示403错误,让进行邮箱核准。 二、本地新建一个文件夹,cd进入后使用npm i...

灰白发 ⋅ 42分钟前 ⋅ 0

010. 深入JVM学习—垃圾收集策略概览

1. 新生代可用GC策略 1. 串行GC(Serial Copying) 算法:复制(Copying)清理算法; 操作步骤: 扫描年轻代中所有存活的对象; 使用Minor GC进行垃圾回收,同时将存活对象保存到“S0”或“S...

影狼 ⋅ 43分钟前 ⋅ 0

JVM性能调优实践——JVM篇

在遇到实际性能问题时,除了关注系统性能指标。还要结合应用程序的系统的日志、堆栈信息、GClog、threaddump等数据进行问题分析和定位。关于性能指标分析可以参考前一篇JVM性能调优实践——性...

Java小铺 ⋅ 44分钟前 ⋅ 0

误关了gitlab sign-in 功能的恢复记录

本想关sign-up的,误点了sign-in 退出后登录界面提示: No authentication methods configured 一脸懵逼.. 百度后众多方案说修改application_settings 的 signin_enabled字段; 实际上新版本字段...

铂金蛋蛋 ⋅ 44分钟前 ⋅ 0

登录后,后续请求接口没有带登录cookie可能原因

1.XMLHttpRequest.withCredentials没设置好,参考https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/withCredentials...

LM_Mike ⋅ 45分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部