📄 pfilt.c
字号:
#ifndef lintstatic char *sccsid = "@(#)pfilt.c 4.5 (ULTRIX) 4/11/91";#endif lint/************************************************************************ * * * Copyright (c) 1988-1991 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. * * * ************************************************************************//* --------------------------------------------------------------------- * Common code for processing received ethernet packets/********************************************************************* * Ethernet packet filter layer, * formerly: Ethernet interface driver * * - pfilt.c - ********************************************************************** * HISTORY * * 11-Apr-91 jsd * Fix several SMP lock/unlock holes; Do an untimeout when closing down * Add lock owner checking when smp_debug is enabled * * 24-Feb-91 jsd * Add COPYALL support for loopback packets * * 02-Jan-91 jsd/matt * Move PROMSIC logic to pfilt_filter from net_read() and clean up. * * $Log: pfilt.c,v $ * Revision 1.3 91/02/07 17:31:24 mogul * "generic" device names have exactly one digit * Fixed bug involving multi-interface systems where pf0 is down. * * Revision 1.2 91/01/28 15:20:37 mogul * CopyAllCount bug fix * * Revision 1.1 91/01/28 13:06:15 mogul * Initial revision * * Revision 1.3 90/06/05 13:20:00 mogul * Dynamic allocation of descriptors * * Revision 1.2 90/05/22 15:36:51 mogul * Added support for EIOCALLOWCOPYALL ioctl and ENCOPYALL mode bit. * * Revision 1.1 90/05/18 17:31:09 mogul * Initial revision * * Revision 1.5 89/08/09 11:05:02 mogul * Conditionalized method used in enetopen on GNODE_CLONING * * Revision 1.4 89/07/31 18:03:49 mogul * Moved definition of generic prefix from enet.c to enet.h * for use by outside programs. * * Revision 1.3 89/07/31 17:58:38 mogul * Made EIOCALLOWPROMISC and EIOCMAXBACKLOG in-out; if the value * of the argument is negative, then return the current setting * instead of changing it. * * EIOCSETIF accepts pseudo-names of the form pf0, pf1, etc., to * generically refer to the nth packet filter interface. * * Revision 1.2 89/07/26 19:16:09 mogul * Added several new ioctls to make this easier to use: * EIOCALLOWPROMISC * Controls whether IFF_PROMISC is set/cleared automatically * EIOCMAXBACKLOG * Sets non-super-user input queue length limit * EIOCSRTIMEOUT * EIOCGRTIMEOUT * Set/Get read timeout in units of "struct timeval" * EIOCSETIF * Rebind minor device to a different interface * * 09-Mar-89 Uttam S.N. * Combined pfilt.c and pfiltqueue.c into one file - pfilt.c * Rename enqueue, dequeue and initqueue routines to * pfiltenqueue, pfiltdequeue, pfiltinitqueue respectively. * These queueing routines were all converted to macros. * * 02-Mar-89 Uttam Shikarpur Nadig; Nashua, NH. * Changed names of en* and enet* subroutines to pfilt_*. * * Revision 1.4 88/11/23 18:05:15 mogul * Allocate per-unit structures dynamically rather than at compile * time. * * Revision 1.3 88/11/18 13:49:40 mogul * Added pfilt_newaddress(), for use when an interface address * changes in midstream. * * Revision 1.2 88/10/03 13:40:02 mogul * Port to Ultrix 3.0 * * Revision 1.19 87/07/06 12:54:03 chen * Updated for 2.0 Ultrix. Changed call to MCLGET() for new macro, * also changed some #includes for rellocation of sources from sys/vaxif * to sys/net * * Revision 1.18 87/04/09 15:22:44 mogul * Returns unwanted packets to caller instead of freeing them. This * is so we can run DECnet along with the packet filter. * * Revision 1.17 87/01/26 15:05:06 mogul * Added support for EIOCTRUNCATE ioctl for truncation of received packets. * * Revision 1.16 86/12/08 13:44:27 mogul * This now cannot be compiled for a system without the "SUN" * openi code. * * Revision 1.15 86/12/08 13:01:08 mogul * Self-profiling code. * * Revision 1.14 86/09/30 13:21:52 mogul * Minor change to extent-map creation code (probably saves a few cycles.) * * Revision 1.13 86/09/18 16:53:12 mogul * Don't transfer a partial stamp if there isn't room in the * user's buffer for a whole stamp. * Don't truncate a packet that won't fit unless it's the first * packet in a batch. * * Revision 1.12 86/09/16 17:23:34 mogul * Automatic inclusion of RCS log messages in history comments. * * * 13 July 1986 Jeff Mogul Stanford * Added Batch and TimeStamp support, with a little help * from Greg Satz. * Guarantee proper alignment between packets of a multi-packet batched * read. * Clears per-filter Drop count when input queue is flushed. * Complain about bad lengths in pfiltrmove if uio_resid is > 0. * Added ENNONEXCL mode. * Added several new literal-push actions (not sure if these help). * When scavenger removes packets from an input queue, remember * how many previously dropped packets were recorded by the newly * dropped ones. * Added EIOCIFNAME to return interface name. * Scavenger cleanup: fixed serious bug by making enScavLevel array * of shorts. Init it only once. Count packets dropped by scavenger. * Rewrote pfilt_read batch delivery loop; scavenger attack after partial * read might have blocked reader. * Count interface overflows; records unwanted packets separately from * drops. * Allow super-user to set a much higher MAXWAITING. * Mark packets according to how they were received (e.g., * promiscuous or not.) * Eliminated the call to m_pullup for each received packet. We now * build a little map indicating which mbuf holds each byte in the * packet; this should run a lot faster. I haven't yet figured * out what to do about filter operations on words that span two * mbufs; in the current code, this "shouldn't happen" for * reasonable filters. * Counts # of packets dropped because a filter had too many * packets queued. * If filter length is zero, don't execute filter because we know the * answer. * Added NOMEM debug flag. * * 7 October 1985 Jeff Mogul Stanford * Removed ENMAXOPENS limitation; available minors are now * dynamically allocated to interfaces, out of pool of NENETFILTER * minors. * Certain arrays formerly in the enState structure are now global. * Depends on modified openi() function so that pfilt_open() need * only be called once. * Remove support for "kernel access", it won't ever be used again. * Added EIOCMFREE ioctl. * * 17 October 1984 Jeff Mogul Stanford * More performance improvements: * Added ENF_CAND, ENF_COR, ENF_CNAND, and ENF_CNOR, short-circuit * operators, to make filters run faster. * All evaluate "(*sp++ == *sp++)": * ENF_CAND: returns false immediately if result is false, otherwise * continue * ENF_COR: returns true immediately if result is true, otherwise * continue * ENF_CNAND: returns true immediately if result is false, otherwise * continue * ENF_CNOR: returns false immediately if result is true, otherwise * continue * Also added ENF_NEQ to complement ENF_EQ * - Maintain count of received packets per filter, dynamically * re-organize filter queue to keep highly active filters in * front of queue (but maintaining priority order), if they are * "high priority" filters. * * 2 October 1984 Jeff Mogul Stanford * Made a few changes to pfiltdofilter() to speed it up, since profiling * shows it to be rather popular: * - precompute maximum word in packet and address of end of * filters (thereby moving this code out of "inner loop"). * - minor re-arrangement to avoid re-evaluating a * common subexpression. * - changed #ifdef DEBUG in a few routines to #ifdef INNERDEBUG, * so that code in inner loops isn't always testing the enDebug * flag; this not only costs directly, but also breaks up some * basic blocks that the optimizer could play with. * - added enOneCopy flag; if true, then never deliver more than * one copy of a packet. This is equivalent to giving everyone * a "high priority" device, and cuts down the number of superfluous * calls to pfiltdofilter(). [Temporary hack, will remove this!] * * 24 August 1984 Jeff Mogul Stanford * YA bug with sleeping in pfilt_write(); straightened out handling * of counts in pfiltkludgesleep so that they indicate the number * of sleeps in progress. Maybe I've got this right, now? * Also, don't sleep forever (since the net might be down). * * 17 July 1984 Jeff Mogul Stanford * Bug fix: in Pfilt_write(), several problems with sleeping on * IF_QFULL: * - don't do it for kernel mode writes. * - count # of procs sleeping, to avoid lost wakeups. Old * scheme would only wake up the first sleeper. * - using sleeper-count, avoid using more than one timeout * table entry per device; old scheme caused timeout table panics * - trap interrupted sleeps using setjmp, so that we can deallocate * packet header and mbufs; otherwise we lost them and panicked. * * 5 July 1984 Jeff Mogul Stanford * Bug fix: in Pfilt_write() make sure enP_RefCount is zero before * deallocating "packet". Otherwise, "packets" get lost, and * take mbufs (and ultimately, the system) with them. * * 8 December 1983 Jeffrey Mogul Stanford * Fixed bug in Pfilt_write() that eventually caused allocator * to run out of packets and panic. If Pfilt_write() returns * an error it should first deallocate any packets it has allocated. * * 10 November 1983 Jeffrey Mogul Stanford * Slight restructuring for support of 10mb ethers; * - added the EIOCDEVP ioctl * - removed the EIOCMTU ioctl (subsumed by EIOCDEVP) * This requires an additional parameter to the pfilt_attach * call so that the device driver can specify things. * * Also, cleaned up the enDebug scheme by adding symbolic * definitions for the bits. * * 25-Apr-83 Jeffrey Mogul Stanford * Began conversion to 4.2BSD. This involves removing all * references to the actual hardware. * Changed read/write interface to use uio scheme. * Changed ioctl interface to "new style"; this places a hard * limit on the size of a filter (about 128 bytes). * "Packets" now point to mbufs, not private buffers. * Filter can only access data in first mbuf (about 50 words worst case); * this is long enough for all Pup purposes. * Added EIOCMTU ioctl to get MTU (max packet size). * Added an Pfilt_select() routine and other select() support. * Other stuff is (more or less) left intact. * Most previous history comments removed. * Changed some names from enXXXX to enetXXXX to avoid confusion(?) * * 10-Aug-82 Mike Accetta (mja) at Carnegie-Mellon University * Added new EIOCMBIS and EIOCMBIC ioctl calls to set and clear * bits in mode word; added mode bit ENHOLDSIG which suppresses * the resetting of an enabled signal after it is sent (to be * used in conjunction with the SIGHOLD mechanism); changed * EIOCGETP to zero pad word for future compatibility; changed enwrite() * to enforce correct source host address on output packets (V3.05e). * (Stanford already uses long timeout value and has no pad word - JCM) * [Last change before 4.2BSD conversion starts.] * * 01-Dec-81 Mike Accetta (mja) at Carnegie-Mellon University * Fixed bug in timeout handling caused by missing "break" in the * "switch" state check within Pfilt_read(). This caused all reads * to be preceeded by a bogus timeout. In addition, fixed another * bug in signal processing by also recording process ID of * process to signal when an input packet is available. This is * necessary because it is possible for a process with an enabled * signal to fork and exit with no guarantee that the child will * reenable the signal. Thus under appropriately bizarre race * conditions, an incoming packet to the child can cause a signal * to be sent to the unsuspecting process which inherited the * process slot of the parent. Of course, if the PID's wrap around * AND the inheriting process has the same PID, well ... (V3.03d). * * 22-Feb-80 Rick Rashid (rfr) at Carnegie-Mellon University * Rewritten to provide multiple user access via user settable * filters (V1.05). * * 18-Jan-80 Mike Accetta (mja) at Carnegie-Mellon University * Created (V1.00). * ********************************************************************** */#define MAXUNITS 16 /* Maximum number of interfaces supported */#include "packetfilter.h"#if (NPACKETFILTER > 0)#include "../h/param.h"#include "../h/systm.h"#include "../h/mbuf.h"#include "../h/buf.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/ioctl.h"#include "../h/map.h"#include "../h/proc.h"#include "../h/file.h"#include "../h/tty.h"#include "../h/uio.h"#include "../h/kmalloc.h"#include "../h/protosw.h"#include "../h/socket.h"#include "../net/net/if.h"#include "../net/netinet/in.h"#include "../net/netinet/if_ether.h"#include "../net/net/ether_driver.h"#include "../h/types.h"#include "../h/time.h"#undef queue#undef dequeue#include "../net/net/pfilt.h" #include "../net/net/pfiltdefs.h"#include "../h/smp_lock.h"#undef NPACKETFILTER#define NPACKETFILTER 256 /* maximum number of minor devices *//* #define DEBUG 1 *//*#define INNERDEBUG 1*/ /* define only when debugging PfiltDoFilter() or PfiltInputDone() */#define pfiltenqueue(head, elt)\{ (elt)->F = (head);(elt)->B = (head)->B;(head)->B = (elt);((elt)->B)->F = (elt)\; };#define pfiltinitqueue(head)\ { (head)->F = (head); (head)->B = (head); };#define pfiltdequeue(head, elt)\{\struct Queue *q_tmp1, *q_tmp2;\q_tmp1 = q_tmp2 = (head)->F;\q_tmp2->B->F = q_tmp2->F;\q_tmp2->F->B = q_tmp2->B;\(elt) = (q_tmp1 == (head)) ? ((struct enPacket *)0):\(struct enPacket *)q_tmp2;\};int pfactive=0; /* number of currently active filters */#define DEBUG_ER 1#ifdef DEBUG_ERint er_debug; /* er_debug: 1=cprintf, 2=mprintf */#endif#define Pfiltprintf(flags) if (enDebug&(flags)) printf/* * Symbolic definitions for enDebug flag bits * ENDBG_TRACE should be 1 because it is the most common * use in the code, and the compiler generates faster code * for testing the low bit in a word. */#define ENDBG_TRACE 1 /* trace most operations */#define ENDBG_DESQ 2 /* trace descriptor queues */#define ENDBG_INIT 4 /* initialization info */#define ENDBG_SCAV 8 /* scavenger operation */#define ENDBG_ABNORM 16 /* abnormal events */#define ENDBG_NOMEM 32 /* could not allocate an mbuf */#define ENDBG_MISC 64 /* sleep intrs, uiomov size mismatch, etc. */#define min(a,b) ( ((a)<=(b)) ? (a) : (b) )#define splenet splimp /* used to be spl6 but I'm paranoid */#define PRINET 26 /* interruptible *//* * 'enQueueElts' is the pool of packet headers used by the driver. * 'enPackets' is the pool of packets used by the driver (these should * be allocated dynamically when this becomes possible). * 'enFreeq' is the queue of available packets * 'enStatePs' is the driver state table per logical unit number * (a vector of pointers to state records) * 'enUnit' is the physical unit number table per logical unit number; * the first "attach"ed ethernet is logical unit 0, etc. * 'enUnitMap' maps minor device numbers onto interface unit #s * 'enAllocMap' indicates if minor device is allocated or free * 'enAllDescriptors' stores OpenDescriptors, indexed by minor device # * 'enFreeqMin' is the minimum number of packets ever in the free queue * (for statistics purposes) * 'enScavenges' is the number of scavenges of the active input queues * (for statustics purposes) * 'enScavDrops' is the number of packets dropped during scavenging * (for statustics purposes) * 'enDebug' is a collection of debugging bits which enable trace and/or * diagnostic output as defined above (ENDBG_*) * 'enUnits' is the number of attached units */struct enPacket enQueueElts[ENPACKETS];struct enQueue enFreeq;struct enState *enStatePs[MAXUNITS];char enUnitMap[NPACKETFILTER];char enAllocMap[NPACKETFILTER];struct enOpenDescriptor *enAllDescriptors[NPACKETFILTER];int enFreeqMin = ENPACKETS;int enScavenges = 0;int enScavDrops = 0;int enDebug = ENDBG_ABNORM;int enUnits = 0;int enMaxMinors = NPACKETFILTER;struct lock_t lk_pfilt; /* SMP: packetfilter lock *//* * Forward declarations for subroutines which return other * than integer types. */extern boolean PfiltDoFilter();/* * Linkages to if_XXXXX.c */struct enet_info { struct ifnet *ifp; /* which ifp for output */};struct enet_info enet_info[MAXUNITS];struct sockaddr enetaf = { AF_IMPLINK };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -