📄 if.c
字号:
/* if.c - network interface utility routines *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/* $NetBSD: if.c,v 1.18 1994/10/30 21:48:46 cgd Exp $ *//* * 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 *//*modification history--------------------01u,25apr02,vvv removed unused ifAttachChange (SPR #74391)01t,06mar02,vvv clean up multicast memberships when interface is detached (SPR #72486)01s,29oct01,wap ifconf() fails with unit numbers greater than 9 (SPR #31752)01r,26oct01,vvv fixed memory leak in if_dettach (SPR #71081) 01q,12oct01,rae merge from truestack ver 01w base 01m SPR #69112, Windview events, etc.01p,30mar01,rae allow m2 stuff to be excluded (SPR# 65428)01o,24oct00,niq Merging in RFC2233 changes from tor2_0.open_stack-f1 branch.01n,17oct00,spm merged from version 01j of tor2_0_x branch (base version 01h): updated if_attach to report memory allocation failures01m,29apr99,pul Upgraded NPT phase3 code to tor2.0.001l,25mar99,sj removed logMsg within SIOCSIFASYNCFLAGS ioctl 01k,24mar99,ead Added a call to m2SetIfLastChange() in ifioctl() when the interfaces operational status changes. (SPR #23290)01j,19mar99,sj SIOCSIFASYNCFLAGS ioctl recvd only when we didn't change flags01i,18mar99,sj added SIOCSIFASYNCFLAGS for async flag change report from END01h,16jul98,n_s fixed ifioctl to pass correct flags to driver Ioctl. SPR 21124 01g,16dec97,vin fixed if_dettach SPR 9970.01f,10dec97,vin added spl protection to ifreset, if_dettach, if_attach, ifIndexToIfp SPR 9987.01e,05oct97,vin fixed if_dettach, for changes in multicast code.01d,12aug97,rjc made if_index global to support non ip interfaces (SPR 9060).01c,02jul97,vin fixed warnings. added _rtIfaceMsgHook for scaling out routing sockets.01b,05dec96,vin moved ifafree() from route.c(), added ifIndexToIfp(), deleted ifnet_addrs in ifattach(), made if_index static. made ifqmaxlen static, replaced calloc with MALLOC, replaced free(..) with FREE(..)01a,03mar96,vin created from BSD4.4 stuff,integrated with 02t of if.c. rewrote if_dettach(), added in_ifaddr_remove in if_dettach*//*DESCRIPTION*/#include "vxWorks.h"#include "sys/socket.h"#include "net/socketvar.h"#include "net/protosw.h"/* #include "net/route.h" */#include "routeEnhLib.h"#include "net/if_dl.h"#include "net/if_subr.h"#include "sys/ioctl.h"#include "errno.h"#include "ifIndexLib.h"#include "net/if.h"#include "wdLib.h"#include "net/systm.h"#include "net/mbuf.h"#ifdef INET#include "netinet/in_var.h"#endif /* INET */#include "m2Lib.h"#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET#include "wvNetLib.h"#endif /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endif#include "logLib.h"IMPORT STATUS netJobAdd (FUNCPTR, int, int, int, int, int);extern void pfctlinput(int cmd, struct sockaddr * sa);extern int sysClkRateGet();extern void in_ifaddr_remove ();extern int arpioctl (int cmd, caddr_t data); extern int splnet2 (int timeout);/* XXX temporary fix should be removed after updating all drivers */extern void ether_ifattach(struct ifnet * ifp);extern int ether_output (); #ifndef VIRTUAL_STACKIMPORT struct inpcbhead udb;#endif#ifndef VIRTUAL_STACKstruct ifnet *ifnet; /* head of linked list of interfaces */LOCAL WDOG_ID ifslowtimoWd; /* watchdog timer for slowtimo routine */#endif /* VIRTUAL_STACK *//* locals */static int ifqmaxlen = IFQ_MAXLEN;static char * sprint_d(unsigned int, char *, int);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* Set common fields of event identifiers for this module. */LOCAL UCHAR wvNetModuleId = WV_NET_IF_MODULE; /* Value for if.c */LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE; /* Available event filter */LOCAL ULONG wvNetEventId; /* Event identifier: see wvNetLib.h */#endif /* INCLUDE_WVNET */#endif/* forward declarations */LOCAL void ifMultiDelete (struct ifnet *);/* globals */FUNCPTR _m2SetIfLastChange;FUNCPTR _m2IfTableUpdate;/* * Network interface utility routines. * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. */void ifinit() { register struct ifnet *ifp;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 0, 8, WV_NETEVENT_IFINIT_START)#endif /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK if (_ifnet != NULL)#else if (ifnet != NULL)#endif {#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; } /* XXX using watchdogs good idea? -gae */ ifslowtimoWd = wdCreate ();#ifdef VIRTUAL_STACK if_slowtimo (myStackNum);#else if_slowtimo ();#endif }/* * Actuall interface reset invocation. */void ifreset2 () { register struct ifnet *ifp; register struct ifnet *ifpnext;#ifdef VIRTUAL_STACK ifp = _ifnet;#else ifp = ifnet;#endif while (ifp) { ifpnext = ifp->if_next; if (ifp->if_reset) (*ifp->if_reset)(ifp->if_unit); ifp = ifpnext; } }/* * Call each interface on a reset. */void ifreset () { int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 1, 9, WV_NETEVENT_IFRESET_START)#endif /* INCLUDE_WVNET */#endif s = splnet (); ifreset2(); splx (s); }/* * For rebootHook use only - Immediate i/f reset * * WARNING: Calling this routine that does not wait spl semaphore * is a violation of mutual exclusion and will cause problems in a * running system. * This routine should only be used if the system is being rebooted * (i.e. when called from a reboot hook) or if the application has * very specific knowledge of the state of all ENDs in the system. */void ifresetImmediate () { int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 1, 9, WV_NETEVENT_IFRESET_START)#endif /* INCLUDE_WVNET */#endif s = splnet2 (0); /* don't wait spl semaphore */ ifreset2(); splx(s); }/* * Attach an interface to the list of "active" interfaces. */STATUS if_attach(ifp) struct ifnet *ifp; { unsigned socksize, ifasize; int namelen, unitlen, masklen; char workbuf[12], *unitname;#ifdef VIRTUAL_STACK register struct ifnet **p = &_ifnet;#else register struct ifnet **p = &ifnet;#endif register struct sockaddr_dl *sdl; register struct ifaddr *ifa; extern void link_rtrequest(); int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 2, 10, WV_NETEVENT_IFATTACH_START, ifp)#endif /* INCLUDE_WVNET */#endif /* make interface not use trailer protocol by default */ ifp->if_flags |= IFF_NOTRAILERS; /* make send queue maxlen be default if none specified; * this relaxes the requirement that all interfaces be attached * before calling ifinit */ if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; /* * 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)) masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + unitlen + namelen; socksize = masklen + 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; MALLOC (ifa, struct ifaddr *, ifasize, MT_IFADDR, M_WAIT); if (ifa == 0) return (ERROR); /* Make interface globally visible after all memory is allocated. */ s = splnet (); while (*p) p = &((*p)->if_next); splx (s); *p = ifp; ifp->if_index = ifIndexAlloc(); bzero((caddr_t)ifa, ifasize); sdl = (struct sockaddr_dl *)(ifa + 1); 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->sdl_type = ifp->if_type; ifa->ifa_ifp = ifp; ifa->ifa_next = ifp->if_addrlist; ifa->ifa_rtrequest = link_rtrequest; ifp->if_addrlist = ifa; 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; if (_m2IfTableUpdate) _m2IfTableUpdate(ifp, M2_IF_TABLE_INSERT, 0, 0); /* XXX Temporary fix before changing ethernet drivers */ s = splnet (); if (ifp->if_output == ether_output) ether_ifattach (ifp); splx (s); return (OK); }/***************************************************************************** if_dettach - dettaches an interface from the linked list of interfaces** if_dettach is used to dettach an interface from the linked list of* all available interfaces. This function needs to be used with* if_down () when shutting down a network interface.*/void if_dettach (ifp) struct ifnet *ifp; /* inteface pointer */ { FAST struct ifnet ** pPtrIfp; FAST struct ifaddr * pIfAddr; FAST struct ifaddr ** pPtrIfAddr; int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 3, 11, WV_NETEVENT_IFDETACH_START, ifp)#endif /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK pPtrIfp = &_ifnet;#else pPtrIfp = &ifnet;#endif s = splnet (); while (*pPtrIfp != NULL) { if (*pPtrIfp == ifp) { pPtrIfAddr = &(*pPtrIfp)->if_addrlist; while (*pPtrIfAddr != NULL) { pIfAddr = *pPtrIfAddr; *pPtrIfAddr = (*pPtrIfAddr)->ifa_next; #ifdef INET if (pIfAddr->ifa_addr->sa_family == AF_INET) in_ifaddr_remove (pIfAddr); else#endif IFAFREE (pIfAddr); }#ifdef INET if ((*pPtrIfp)->pInmMblk != NULL) in_delmulti ((*pPtrIfp)->pInmMblk, NULL); if (ifp->if_flags & IFF_MULTICAST) ifMultiDelete (ifp);#endif /* INET */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -