设为首页 加入收藏

TOP

TCP/IP详解2 学习笔记2---ifnet ifaddr(二)
2014-11-23 17:31:53 来源: 作者: 【 】 浏览:160
Tags:TCP/IP 详解 学习 笔记 --- ifnet ifaddr
f_snd; /* output queue */


};




对输出队列的操作函数,simple and beauty


/*


* Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)


* input routines have queues of messages stored on ifqueue structures


* (defined above). Entries are added to and deleted from these structures


* by these macros, which should be called with ipl raised to splimp().


*/


#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)


#define IF_DROP(ifq) ((ifq)->ifq_drops++)


#define IF_ENQUEUE(ifq, m) { \


(m)->m_nextpkt = 0; \


if ((ifq)->ifq_tail == 0) \


(ifq)->ifq_head = m; \


else \


(ifq)->ifq_tail->m_nextpkt = m; \


(ifq)->ifq_tail = m; \


(ifq)->ifq_len++; \


}


#define IF_PREPEND(ifq, m) { \


(m)->m_nextpkt = (ifq)->ifq_head; \


if ((ifq)->ifq_tail == 0) \


(ifq)->ifq_tail = (m); \


(ifq)->ifq_head = (m); \


(ifq)->ifq_len++; \


}


#define IF_DEQUEUE(ifq, m) { \


(m) = (ifq)->ifq_head; \


if (m) { \


if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \


(ifq)->ifq_tail = 0; \


(m)->m_nextpkt = 0; \


(ifq)->ifq_len--; \


} \


}







/*


* The ifaddr structure contains information about one address


* of an interface. They are maintained by the different address families,


* are allocated and attached when an address is set, and are linked


* together so all addresses for an interface can be located.


*/


struct ifaddr {


struct sockaddr *ifa_addr; /* address of interface */


struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */


#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */


struct sockaddr *ifa_netmask; /* used to determine subnet */


struct ifnet *ifa_ifp; /* back-pointer to interface */


struct ifaddr *ifa_next; /* next address for interface */


void (*ifa_rtrequest)(); /* check or clean routes (+ or -)'d */


u_short ifa_flags; /* mostly rt_flags for cloning */


short ifa_refcnt; /* extra to malloc for link info */


int ifa_metric; /* cost of going out this interface */


#ifdef notdef


struct rtentry *ifa_rt; /* XXXX for ROUTETOIF */


#endif


};




以loop设备为例,其初始化函数为loopattach,相当于linux下的probe函数。



81 loopattach(n)


82 int n;


83 {


有专用的ifnet,其他的设备需要申请,并初始化


84 register struct ifnet *ifp = &loif;


85


86 #ifdef lint


87 n = n; /* Highlander: there can only be one... */


88 #endif


89 ifp->if_name = "lo";


90 ifp->if_mtu = LOMTU;


91 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;


92 ifp->if_ioctl = loioctl;


93 ifp->if_output = looutput;


94 ifp->if_type = IFT_LOOP;


95 ifp->if_hdrlen = 0;


96 ifp->if_addrlen = 0;


注册给内核,相当于register_netdevice


97 if_attach(ifp);


98 #if NBPFILTER > 0


分组过滤相关,按下不表


99 bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));


100 #endif


101 }




if_attach主要就是把ifp放到一个链表里,初始化后 找到组织了



void


if_attach(ifp)


struct ifnet *ifp;


{


unsigned socksize, ifasize;


int namelen, unitlen, masklen, ether_output();


char workbuf[12], *unitname;


全局的一个结构


register struct ifnet **p = &ifnet;


register struct sockaddr_dl *sdl;


register struct ifaddr *ifa;


static int if_indexlim = 8;


extern void link_rtrequest();



这个循环很有意思,看了半天才明白


p指向的是ifnet结构中的一个成员,这个成员是ifnet*,*P指向下一个结构。所以*P==NULL,说明P所指的成员所在的结构是最后一个ifnet,所以可以直接对*P,既ifnet->if_next赋值。


while (*p)


p = &((*p)->if_next);


*p = ifp;


增加全区的if_index,如果有接口删除了,占用的if_index也不能用了


ifp->if_index = ++if_index;


动态的扩充ifnet_addr的大小,方法不错


if (ifnet_addrs == 0 || if_index >= if_indexlim) {


unsigned n = (if_indexlim <<= 1) * sizeof(ifa);


stru

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux协议栈查找算法优化随想 下一篇TCP/IP详解2 学习笔记---mbuf

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: