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

📄 if.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: if.c,v 1.3 1998/12/28 14:13:11 nigel Exp $ *//* * Copyright (c) 1980, 1986 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	7.14 (Berkeley) 4/20/91 */#include "param.h"#include "mbuf.h"#include "systm.h"#include "socket.h"#include "socketvar.h"#include "protosw.h"#include "proc.h"#include "kernel.h"#include "ioctl.h"#include "if.h"#include "af.h"#include "if_dl.h"#include "if_types.h"#include "ether.h"#ifdef PROMconst int ifqmaxlen = IFQ_MAXLEN;#elseint	ifqmaxlen = IFQ_MAXLEN;#endif/* * Network interface utility routines. * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. */ifinit(){	register struct ifnet *ifp;	for (ifp = ifnet; ifp; ifp = ifp->if_next)		if (ifp->if_snd.ifq_maxlen == 0)			ifp->if_snd.ifq_maxlen = ifqmaxlen;	if_slowtimo();}#if defined(vax) || defined(PROM)/* * Call each interface on a Unibus/PROM reset. */ifubareset(uban)	int uban;{	register struct ifnet *ifp;	for (ifp = ifnet; ifp; ifp = ifp->if_next)		if (ifp->if_reset)			(*ifp->if_reset)(ifp->if_unit, uban);}#endifint if_index;struct ifaddr **ifnet_addrs;static char *sprint_d();/* * Attach an interface to the * list of "active" interfaces. */if_attach(ifp)	struct ifnet *ifp;{	unsigned socksize, ifasize;	int namelen, unitlen;	char workbuf[12], *unitname;	register struct ifnet **p = &ifnet;	register struct sockaddr_dl *sdl;	register struct ifaddr *ifa;#ifdef NO_DATA	static int if_indexlim;#else	static int if_indexlim = 8;#endif	extern link_rtrequest();#if NETHER > 0	extern ether_output();#endif	while (*p)		p = &((*p)->if_next);	*p = ifp;	ifp->if_index = ++if_index;#ifdef NO_DATA	if (ifnet_addrs == 0)	  if_indexlim = 8;#endif	if (ifnet_addrs == 0 || if_index >= if_indexlim) {		unsigned n = (if_indexlim <<= 1) * sizeof(ifa);		struct ifaddr **q = (struct ifaddr **)					malloc(n, M_IFADDR, M_WAITOK);		if (ifnet_addrs) {			bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);			free((caddr_t)ifnet_addrs, M_IFADDR);		}		ifnet_addrs = q;	}#if NETHER > 0	/* XXX -- Temporary fix before changing 10 ethernet drivers */	if (ifp->if_output == ether_output) {		ifp->if_type = IFT_ETHER;		ifp->if_addrlen = 6;		ifp->if_hdrlen = 14;	}#endif	/*	 * create a Link Level name for this device	 */	unitname = sprint_d((u_int)ifp->if_unit, workbuf, sizeof(workbuf));	namelen = strlen(ifp->if_name);	unitlen = strlen(unitname);#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))	socksize = _offsetof(struct sockaddr_dl, sdl_data[0]) +			       unitlen + namelen + ifp->if_addrlen;#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))	socksize = ROUNDUP(socksize);	if (socksize < sizeof(*sdl))		socksize = sizeof(*sdl);	ifasize = sizeof(*ifa) + 2 * socksize;	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);	if (ifa == 0)		return;	ifnet_addrs[if_index - 1] = ifa;	bzero((caddr_t)ifa, ifasize);	sdl = (struct sockaddr_dl *)(ifa + 1);	ifa->ifa_addr = (struct sockaddr *)sdl;	ifa->ifa_ifp = ifp;	sdl->sdl_len = socksize;	sdl->sdl_family = AF_LINK;	bcopy(ifp->if_name, sdl->sdl_data, namelen);	bcopy(unitname, namelen + (caddr_t)sdl->sdl_data, unitlen);	sdl->sdl_nlen = (namelen += unitlen);	sdl->sdl_index = ifp->if_index;	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);	ifa->ifa_netmask = (struct sockaddr *)sdl;	sdl->sdl_len = socksize - ifp->if_addrlen;	while (namelen != 0)		sdl->sdl_data[--namelen] = 0xff;	ifa->ifa_next = ifp->if_addrlist;	ifa->ifa_rtrequest = link_rtrequest;	ifp->if_addrlist = ifa;}/* * Update the link-layer address and/or type for an existing interface. * We assume that ifp->if_hdrlen is correct, and that the sockaddr_dl * created in if_attach is large enough (i.e., if_hdrlen will not increase). */voidif_newaddr(ifp, type, laddr)	register struct ifnet *ifp;	int type;	caddr_t laddr;{	register struct ifaddr *ifa;	register struct sockaddr_dl *sdl;	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&		    sdl->sdl_family == AF_LINK) {			sdl->sdl_type = type;			sdl->sdl_alen = ifp->if_addrlen;			bcopy(laddr, LLADDR(sdl), ifp->if_addrlen);			break;		}}/* * 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; ifp; ifp = ifp->if_next)	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {		if (ifa->ifa_addr->sa_family != addr->sa_family)			continue;		if (equal(addr, ifa->ifa_addr))			return (ifa);		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&		    equal(ifa->ifa_broadaddr, addr))			return (ifa);	}	return ((struct ifaddr *)0);}/* * 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; ifp; ifp = ifp->if_next) 	    if (ifp->if_flags & IFF_POINTOPOINT)		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {			if (ifa->ifa_addr->sa_family != addr->sa_family)				continue;			if (equal(addr, ifa->ifa_dstaddr))				return (ifa);	}	return ((struct ifaddr *)0);}/* * Find an interface on a specific network.  If many, choice * is first found. */struct ifaddr *ifa_ifwithnet(addr)	struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	u_int af = addr->sa_family;	if (af >= AF_MAX)		return (0);	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 - 1]);	}	for (ifp = ifnet; ifp; ifp = ifp->if_next)	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {		register char *cp, *cp2, *cp3;		register char *cplim;		if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0)			continue;		cp = addr->sa_data;		cp2 = ifa->ifa_addr->sa_data;		cp3 = ifa->ifa_netmask->sa_data;		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;		for (; cp3 < cplim; cp3++)			if ((*cp++ ^ *cp2++) & *cp3)				break;		if (cp3 == cplim)			return (ifa);	    }	return ((struct ifaddr *)0);}/* * Find an interface using a specific address family */struct ifaddr *ifa_ifwithaf(af)	register int af;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	for (ifp = ifnet; ifp; ifp = ifp->if_next)	    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if (ifa->ifa_addr->sa_family == af)			return (ifa);	return ((struct ifaddr *)0);}/* * Find an interface address specific to an interface best matching * a given address. */struct ifaddr *ifaof_ifpforaddr(addr, ifp)	struct sockaddr *addr;	register struct ifnet *ifp;{	register struct ifaddr *ifa;	register char *cp, *cp2, *cp3;	register char *cplim;	struct ifaddr *ifa_maybe = 0;	u_int af = addr->sa_family;	if (af >= AF_MAX)		return (0);	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {		if (ifa->ifa_addr->sa_family != af)			continue;		ifa_maybe = ifa;		if (ifa->ifa_netmask == 0) {			if (equal(addr, ifa->ifa_addr) ||			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))				return (ifa);			continue;		}		cp = addr->sa_data;		cp2 = ifa->ifa_addr->sa_data;		cp3 = ifa->ifa_netmask->sa_data;		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;

⌨️ 快捷键说明

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