m_devget函数
来源:互联网 发布:mysql直接复制数据文件 编辑:程序博客网 时间:2024/05/18 13:41
当接收到一个以太网帧时,设备驱动程序调用函数m_devget来创建一个Mbuf链表,并把设备中帧复制到这个链表中。
struct mbuf *
m_devget(buf, totlen, off0, ifp, copy)
char *buf;
int totlen, off0;
struct ifnet *ifp;
void (*copy)();
{
register struct mbuf *m;
struct mbuf *top = 0, **mp = ⊤
register int off = off0, len;
register char *cp;
char *epkt;
cp = buf;
epkt = cp + totlen;
if (off) {
/*
* If parameter(参数) 'off' is non-zero(is not zero), packet is trailer-encapsulated(跟踪压缩),
* so we have to skip(跳过) the type and length fields.
*/
cp += off + 2 * sizeof(u_int16_t);
totlen -= 2 * sizeof(u_int16_t);
}
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0)
return (0);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = totlen;
m->m_len = MHLEN;
while (totlen > 0) {
if (top) {
//MGET:allocates an mbuf and initializes it to contain internal data
MGET(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m_freem(top);
return (0);
}
m->m_len = MLEN;
}
len = min(totlen, epkt - cp);
if (len >= MINCLSIZE) { //数据长度大于或等于MINCLSIZE(20
MCLGET(m, M_DONTWAIT); //分配一个簇
if (m->m_flags & M_EXT)
m->m_len = len = min(len, MCLBYTES);
else
len = m->m_len;
} else { //数据长度小于MINCLSIZE(20
/*
* Place initial small packet/header at end of mbuf.
*/
if (len < m->m_len) { //第一种情况:0<数据长度<84
if (top == 0 && len + max_linkhdr <= m->m_len)
m->m_data += max_linkhdr; //保留16个字节的空间
m->m_len = len; //len = totlen
} else
len = m->m_len;
}
if (copy)
copy(cp, mtod(m, caddr_t), (unsigned)len);
else
bcopy(cp, mtod(m, caddr_t), (unsigned)len);
cp += len;
*mp = m;
mp = &m->m_next;
totlen -= len;
if (cp == epkt)
cp = buf;
}
return (top);
}
- m_devget函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- 函数
- Lambda表达式_匿名方法_委托
- 阿里云 CentOS Java Web 项目部署
- 习题3.4 最长连续递增子序列
- 1028 排序
- 织梦DedeCMS移动端手机端站点安装搭建使用教程
- m_devget函数
- Applied.Flow.Technology.Arrow.v6.0.1100 1CD(可压缩管道流体的分析和建模工具)
- 学习python:决策树算法
- JVM中的垃圾收集策略
- 实例
- java Queue 接口
- Android 内存泄漏场景分析
- PullToRefresh
- IE报vuex requires a Promise polyfill in this browser问题解决