BSD net源码分析(4)──环回接口
来源:互联网 发布:养老保险的算法 编辑:程序博客网 时间:2024/05/21 22:32
一、接口的初始化
环回接口的作用是直接把输出队列的分组直接发送到输入队列。
没用硬件设备,环回伪设备在main函数中通过环回接口的pdevinit结构中的pdev_attach指针直接调用loopatttach时初始化。
void
loopattach(n)
int n;
{
register struct ifnet *ifp = &loif;
#ifdef lint
n = n; /* Highlander: there can only be one... */
#endif
ifp->if_name = "lo";
ifp->if_mtu = LOMTU;
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
ifp->if_type = IFT_LOOP;
ifp->if_hdrlen = 0; /* 环回接口没有链路首部和硬件地址 */
ifp->if_addrlen = 0;
if_attach(ifp); /* 接口结构的初始化 */
#if NBPFILTER > 0
bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int)); /* 登记BPF的环回接口 */
#endif
}
二、环回接口的输入和输出
环回接口的if_output指向函数looutput,将输出分组放置到分组的目的地址指明的协议的输入队列。
int
looutput(ifp, m, dst, rt)
struct ifnet *ifp;
register struct mbuf *m;
struct sockaddr *dst;
register struct rtentry *rt;
{
int s, isr;
register struct ifqueue *ifq = 0;
if ((m->m_flags & M_PKTHDR) == 0)
panic("looutput no HDR");
ifp->if_lastchange = time;
#if NBPFILTER > 0
if (loif.if_bpf) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header
* to pacify bpf. This is safe because bpf
* will only read from the mbuf (i.e., it won't
* try to free it or keep a pointer a to it).
*/
struct mbuf m0;
u_int af = dst->sa_family;
m0.m_next = m;
m0.m_len = 4;
m0.m_data = (char *)⁡
/* 将加了目的地址的新mbuf链表传递给bpf_mtap */
bpf_mtap(loif.if_bpf, &m0);
}
#endif
/* 输出环回到输入 */
m->m_pkthdr.rcvif = ifp; /* 设置接收接口 */
/* 检查路由是否允许 */
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
m_freem(m);
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
}
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
switch (dst->sa_family) {
/* 以下根据不同的协议类型分发数据到输入队列 */
#ifdef INET
case AF_INET:
ifq = &ipintrq;
isr = NETISR_IP;
break;
#endif
#ifdef NS
case AF_NS:
ifq = &nsintrq;
isr = NETISR_NS;
break;
#endif
#ifdef ISO
case AF_ISO:
ifq = &clnlintrq;
isr = NETISR_ISO;
break;
#endif
default:
printf("lo%d: can't handle af%d/n", ifp->if_unit,
dst->sa_family);
m_freem(m);
return (EAFNOSUPPORT);
}
s = splimp();
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
m_freem(m);
splx(s);
return (ENOBUFS);
}
IF_ENQUEUE(ifq, m);
schednetisr(isr); /* 调用软中断触发 */
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
splx(s);
return (0);
}
/*****************************************************/
环回接口的处理较为简单,在这里只作简要分析。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mythfish/archive/2008/11/23/3357666.aspx
- BSD net源码分析(4)──环回接口
- BSD net源码分析(4)──环回接口
- BSD net源码分析(4)──环回接口
- BSD net源码分析(3)──SLIP接口
- BSD net源码分析(3)──SLIP接口
- BSD net源码分析(2-4)
- BSD net源码分析(2-4)
- BSD net源码分析(1)
- BSD net源码分析(2-1)
- BSD net源码分析(2-2)
- BSD net源码分析(2-3)
- BSD net源码分析(1)
- BSD net源码分析(2-1)
- BSD net源码分析(2-2)
- BSD net源码分析(2-3)
- BSD net源码分析(1)
- BSD net源码分析(2-2)
- BSD net源码分析(2-2)
- C#控制台 学生学籍管理系统
- Builder Pattern
- Windows下DNS ID欺骗的原理与实现
- Creating a Shape from a Stroked Shape
- BSD net源码分析(3)──SLIP接口
- BSD net源码分析(4)──环回接口
- BSD net源码分析(2-3)
- BSD net源码分析(2-4)
- 再谈突破TCP-IP过滤/防火墙进入内网(icmp篇)
- 80x86的指令系统(二)
- 简要描述一下SQL中的五种数据类型:字符型,文本型,数值型,逻辑型和日期型
- ARP协议的缺陷及ARP病毒(木马)欺骗的防范
- ARP协议详解
- D语言真相