⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      sys/net/if.c////     ////==========================================================================//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD or other sources,// and are covered by the appropriate copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    gthomas// Contributors: gthomas// Date:         2000-01-10// Purpose:      // Description:  //              ////####DESCRIPTIONEND####////==========================================================================/*	$OpenBSD: if.c,v 1.25 1999/12/08 06:50:17 itojun Exp $	*//*	$NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $	*//* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * Copyright (c) 1980, 1986, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)if.c	8.3 (Berkeley) 1/4/94 */#ifdef __ECOS#include <pkgconf/net.h>#else#include "bpfilter.h"#include "bridge.h"#endif#include <sys/param.h>#include <sys/mbuf.h>#ifndef __ECOS#include <sys/systm.h>#include <sys/proc.h>#endif#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/protosw.h>#include <sys/kernel.h>#include <sys/ioctl.h>#include <net/if.h>#include <net/if_dl.h>#include <net/if_types.h>#include <net/radix.h>#include <net/route.h>#ifdef INET#include <netinet/in.h>#include <netinet/in_var.h>#include <netinet/if_ether.h>#include <netinet/igmp.h>#ifdef MROUTING#include <netinet/ip_mroute.h>#endif#endif#ifdef INET6#ifndef INET#include <netinet/in.h>#endif#endif#ifdef IPFILTER#include <netinet/ip_fil_compat.h>#include <netinet/ip_fil.h>#include <netinet/ip_nat.h>#endif#if NBPFILTER > 0#include <net/bpf.h>#endif#if NBRIDGE > 0#include <net/if_bridge.h>#endifvoid	if_attachsetup __P((struct ifnet *));int	if_detach_rtdelete __P((struct radix_node *, void *));int	ifqmaxlen = IFQ_MAXLEN;void	if_slowtimo __P((void *arg));#ifdef INET6/* * XXX: declare here to avoid to include many inet6 related files.. * should be more generalized? */extern void nd6_setmtu __P((struct ifnet *));#endif /* * Network interface utility routines. * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. */voidifinit(){	register struct ifnet *ifp;	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)		if (ifp->if_snd.ifq_maxlen == 0)			ifp->if_snd.ifq_maxlen = ifqmaxlen;	if_slowtimo(NULL);}int if_index = 0;struct ifaddr **ifnet_addrs = NULL;struct ifnet **ifindex2ifnet = NULL;/* * Attach an interface to the * list of "active" interfaces. */voidif_attachsetup(ifp)	struct ifnet *ifp;{	unsigned int socksize, ifasize;	int namelen, masklen;	register struct sockaddr_dl *sdl;	register struct ifaddr *ifa;	static int if_indexlim = 8;	ifp->if_index = ++if_index;	/*	 * We have some arrays that should be indexed by if_index.	 * since if_index will grow dynamically, they should grow too.	 *	struct ifadd **ifnet_addrs	 *	struct ifnet **ifindex2ifnet	 */	if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {		size_t n;		caddr_t q;				while (if_index >= if_indexlim)			if_indexlim <<= 1;		/* grow ifnet_addrs */		n = if_indexlim * sizeof(ifa);		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);		bzero(q, n);		if (ifnet_addrs) {			bcopy((caddr_t)ifnet_addrs, q, n/2);			free((caddr_t)ifnet_addrs, M_IFADDR);		}		ifnet_addrs = (struct ifaddr **)q;		/* grow ifindex2ifnet */		n = if_indexlim * sizeof(struct ifnet *);		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);		bzero(q, n);		if (ifindex2ifnet) {			bcopy((caddr_t)ifindex2ifnet, q, n/2);			free((caddr_t)ifindex2ifnet, M_IFADDR);		}		ifindex2ifnet = (struct ifnet **)q;	}	ifindex2ifnet[if_index] = ifp;	/*	 * create a Link Level name for this device	 */	namelen = strlen(ifp->if_xname);#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))	masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;	socksize = masklen + ifp->if_addrlen;#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))	if (socksize < sizeof(*sdl))		socksize = sizeof(*sdl);	socksize = ROUNDUP(socksize);	ifasize = sizeof(*ifa) + 2 * socksize;	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);	bzero((caddr_t)ifa, ifasize);	sdl = (struct sockaddr_dl *)(ifa + 1);	sdl->sdl_len = socksize;	sdl->sdl_family = AF_LINK;	bcopy(ifp->if_xname, sdl->sdl_data, namelen);	sdl->sdl_nlen = namelen;	sdl->sdl_index = ifp->if_index;	sdl->sdl_type = ifp->if_type;	ifnet_addrs[if_index] = ifa;	ifa->ifa_ifp = ifp;	ifa->ifa_rtrequest = link_rtrequest;	TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);	ifa->ifa_addr = (struct sockaddr *)sdl;	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);	ifa->ifa_netmask = (struct sockaddr *)sdl;	sdl->sdl_len = masklen;	while (namelen != 0)		sdl->sdl_data[--namelen] = 0xff;}voidif_attachhead(ifp)	struct ifnet *ifp;{	if (if_index == 0)		TAILQ_INIT(&ifnet);	TAILQ_INIT(&ifp->if_addrlist);	TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);	if_attachsetup(ifp);}voidif_attach(ifp)	struct ifnet *ifp;{// Initialize queue - moved here to support "late" attaches    if (ifp->if_snd.ifq_maxlen == 0)        ifp->if_snd.ifq_maxlen = ifqmaxlen;//	if (if_index == 0)		TAILQ_INIT(&ifnet);	TAILQ_INIT(&ifp->if_addrlist);	TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);	if_attachsetup(ifp);}/* * Delete a route if it has a specific interface for output. * This function complies to the rn_walktree callback API. */intif_detach_rtdelete(rn, vifp)	struct radix_node *rn;	void *vifp;{	struct ifnet *ifp = vifp;	struct rtentry *rt = (struct rtentry *)rn;	if (rt->rt_ifp == ifp)		rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),		    0, NULL);	/*	 * XXX There should be no need to check for rt_ifa belonging to this	 * interface, because then rt_ifp is set, right?	 */	return (0);}/* * Detach an interface from everything in the kernel.  Also deallocate * private resources. * XXX So far only the INET protocol family has been looked over * wrt resource usage that needs to be decoupled. */voidif_detach(ifp)	struct ifnet *ifp;{	struct ifaddr *ifa;	int i, s = splimp();	struct radix_node_head *rnh;#if NBRIDGE > 0	/* Remove the interface from any bridge it is part of.  */	if (ifp->if_bridge)		bridge_ifdetach(ifp);#endif#if NBPFILTER > 0	/* If there is a bpf device attached, detach from it.  */	if (ifp->if_bpf)		bpfdetach(ifp);#endif	/*	 * Find and remove all routes which is using this interface.	 * XXX Factor out into a route.c function?	 */	for (i = 1; i <= AF_MAX; i++) {		rnh = rt_tables[i];		if (rnh)			(*rnh->rnh_walktree)(rnh, if_detach_rtdelete, ifp);	}#ifdef INET	rti_delete(ifp);	myip_ifp = NULL;#ifdef MROUTING	vif_delete(ifp);#endif#endif	/*	 * XXX transient ifp refs?  inpcb.ip_moptions.imo_multicast_ifp?	 * Other network stacks than INET?	 */	/* Remove the interface from the list of all interfaces.  */	TAILQ_REMOVE(&ifnet, ifp, if_list);#ifdef IPFILTER	/* XXX More ipf & ipnat cleanup needed.  */	nat_ifdetach(ifp);#endif	/* Deallocate private resources.  */	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa;	    ifa = TAILQ_FIRST(&ifp->if_addrlist)) {		TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);#ifdef INET		if (ifa->ifa_addr->sa_family == AF_INET)			TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa,			    ia_list);#endif		free(ifa, M_IFADDR);	}	splx(s);}/* * Locate an interface based on a complete address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithaddr(addr)	register struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;#define	equal(a1, a2) \  (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)	    for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {		if (ifa->ifa_addr->sa_family != addr->sa_family)			continue;		if (ifa->ifa_dstaddr == NULL)			continue;		if (equal(addr, ifa->ifa_addr))			return (ifa);		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&		    /* IP6 doesn't have broadcast */		    ifa->ifa_broadaddr->sa_len != 0 &&		    equal(ifa->ifa_broadaddr, addr))			return (ifa);	}	return (NULL);}/* * Locate the point to point interface with a given destination address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithdstaddr(addr)	register struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)	    if (ifp->if_flags & IFF_POINTOPOINT)		for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {			if (ifa->ifa_addr->sa_family != addr->sa_family ||			    ifa->ifa_dstaddr == NULL)				continue;			if (equal(addr, ifa->ifa_dstaddr))				return (ifa);	}	return (NULL);}/* * Find an interface on a specific network.  If many, choice * is most specific found. */struct ifaddr *ifa_ifwithnet(addr)	struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	struct ifaddr *ifa_maybe = 0;	u_int af = addr->sa_family;	char *addr_data = addr->sa_data, *cplim;	if (af == AF_LINK) {	    register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;	    if (sdl->sdl_index && sdl->sdl_index <= if_index)		return (ifnet_addrs[sdl->sdl_index]);	}	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)		for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {			register char *cp, *cp2, *cp3;			if (ifa->ifa_addr->sa_family != af ||			    ifa->ifa_netmask == 0)				next: continue;			cp = addr_data;			cp2 = ifa->ifa_addr->sa_data;			cp3 = ifa->ifa_netmask->sa_data;			cplim = (char *)ifa->ifa_netmask +				ifa->ifa_netmask->sa_len;			while (cp3 < cplim)				if ((*cp++ ^ *cp2++) & *cp3++)				    /* want to continue for() loop */					goto next;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -