📄 if.c
字号:
#ifndef lintstatic char *sccsid = "@(#)if.c 4.5 (ULTRIX) 3/7/91";#endif lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * * Michael G. Mc Menemy 07-Mar-91 * Fixed smp lock position messup. * * Mary Walker 26-Nov-90 * Added length check to if_name matching. (ex. "l" will no * longer match "ln") * * Chran-Ham Chang - 9-Aug-90 * Added code to support SIOCEEUPDATE ioctl - FDDI EEPROM * update and SIOCIFRSET ioctl - reset the interface * * Fred Templin - 3-May-90 * Added "se/ln" compatibility lines. * * Matt Thomas - 8-Nov-89 * Add support for interfaces with units > 9 * * Ursula Sinkewicz - 8-Nov-89 * Removed lk_ifnet. * * Ursula Sinkewicz - 10-Aug-89 * Ifconf() had lk_ifnet set over a bcopy from kernel space * to user space. Fix is to copy from kernel space to a kmalloced * buffer with a lock held, then to copy out to the uarea. * * Ursula Sinkewicz - 9-June-89 * Modifications for supporting asymmetric network drivers. * * Ursula Sinkewicz - 28-Feb-89 * SMP/mips merge (Added R. Bhanukitsiri changes 2/6/89). * * JAW - 15-Feb-89 * change copyout's in ifconf to bcopy because * ioctl system call creates a stack buffer to * copy the data into. Thus copyout is not needed. * * Ursula Sinkewicz - 13-Feb-89 * Added lk_ifnet. * * * Larry Palmer - 15-Jan-88 * * Final 43bsd version * * * * Vince Wallace - Jul-23-1987 * * Add code for ioctl SIOCARPREQ - to broadcast an * * arp request packet. * * * * Marc Teitelbaum - May 5 1987 * Add suser() check in ifioctl for setting * hardware address, multicast address, zeroing counters... * * Larry Cohen - 09/16/85 * * Add 43bsd alpha tape changes for subnet routine * * * * Robin Lewis - 05/05/86 * * Added check for super user in ioctl to set flags * ************************************************************************//* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)if.c 6.7 (Berkeley) 6/8/85 */#include "../h/param.h"#include "../h/systm.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/protosw.h"#include "../h/dir.h"#include "../h/kmalloc.h"#include "../h/cpudata.h"#include "../h/user.h"#include "../h/buf.h"#include "../h/conf.h"#include "../h/proc.h"#include "../h/kernel.h"#include "../h/ioctl.h"#include "../h/errno.h"#include "../net/net/if.h"#include "../net/net/if_llc.h"#include "../net/net/af.h"#include "../h/smp_lock.h"#include "../net/netinet/in.h"#include "../net/netinet/if_ether.h"#include "../net/net/gw_screen.h"#include "ether.h"#include "fddi.h"int ifqmaxlen = IFQ_MAXLEN;char *prcrequests[] = PRC_REQLIST;/* * Network interface utility routines. * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. */ifinit(){ register struct ifnet *ifp; int saveaffinity; int s; for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_init) { CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity); (*ifp->if_init)(ifp->if_unit); RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity); s = splnet(); if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; splx(s); } if_slowtimo();}/* * Call each interface on a Unibus reset. */ifubareset(uban) int uban;{ register struct ifnet *ifp; int saveaffinity; for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_reset){ CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity); (*ifp->if_reset)(ifp->if_unit, uban); RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity); }}/* * Attach an interface to the * list of "active" interfaces. */if_attach(ifp) struct ifnet *ifp;{ register struct ifnet **p; int s; s = splnet(); smp_lock(&lk_ifnet, LK_RETRY); p = &ifnet; while (*p) p = &((*p)->if_next); *p = ifp; smp_unlock(&lk_ifnet); splx(s);}/* * Detach an interface out of the list of "active" interfaces. * Notify higher layers that this interface is gone. */if_detach(ifp) struct ifnet *ifp;{ register struct ifnet **p; int s; s = splnet(); smp_lock(&lk_ifnet, LK_RETRY); p = &ifnet; while(*p && (*p)->if_next != ifp) p = &((*p)->if_next); if(*p && (*p)->if_next) { ((*p)->if_next)->if_addr.sa_family = 0; ((*p)->if_next)->if_mtu = 0; ((*p)->if_next)->if_flags = 0; ((*p)->if_next)->if_ioctl = NULL; ((*p)->if_next)->if_output = NULL; } smp_unlock(&lk_ifnet); splx(s);}/* * Locate an interface based on a complete address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithaddr(addr) struct sockaddr *addr;{ register struct ifnet *ifp; register struct ifaddr *ifa; register struct ifaddr *lifa = 0;#define equal(a1, a2) \ (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 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(&ifa->ifa_addr, addr)) lifa = ifa; if ((ifp->if_flags & IFF_BROADCAST) && equal(&ifa->ifa_broadaddr, addr)) lifa = ifa; } if(lifa) return(lifa); return ((struct ifaddr *)0);}/* * Locate the point to point interface with a given destination address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithdstaddr(addr) 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(&ifa->ifa_dstaddr, addr)){ return (ifa); } } return ((struct ifaddr *)0);}/* * Find an interface on a specific network. If many, choice * is first found. */struct ifaddr *ifa_ifwithnet(addr) register struct sockaddr *addr;{ register struct ifnet *ifp; register struct ifaddr *ifa; register u_int af = addr->sa_family; register int (*netmatch)(); if (af >= AF_MAX) return (0); netmatch = afswitch[af].af_netmatch; 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 ((*netmatch)(&ifa->ifa_addr, addr)){ return (ifa); } } return ((struct ifaddr *)0);}#ifdef notdef/* * 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);}#endif/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -