📄 net_common.c
字号:
#ifndef lintstatic char *sccsid = "@(#)net_common.c 4.7 (ULTRIX) 4/4/91";#endif lint/************************************************************************ * * * Copyright (c) 1990 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 * * Modification History * * * 02-Apr-1991 - jsd * Fix FDDI packetfilter code (transmit side) * * 02-Jan-1991 - John Dustin and Matt Thomas * Move packetfilter code into pfilt.c to keep net_read() simple. * Fix PROMISC mode so it can co-exist with LAT. Restore lost * PFF_COPYALL changes from earlier release. Rework pfilt_filter() * for 20% performance improvement when in PROMISC mode. * * 20-Aug-1990 - Matt Thomas * Fix support for 802.3 frames that it will work with DLI. * This means moving some checking from DLI to here. * * 26-Mar-1990 - lp & templin * Worked in idea of generic net_output routine so that ethernet * drivers may use 802.2 encapsulation as well. Eventually all lan * drivers should use these routines to input and output * data. Action of each routine is driven by ifp->if_type * and ifp->if_flags. * * --------------------------------------------------------------------- *//* * TODO: * - Look at a way of providing trailer support for interfaces * which actually reap benefits of using it. (i.e. QNA, UNA). * * - Packet Filter with FDDI * */#include "packetfilter.h" /* NPACKETFILTER */#include "../h/param.h"#include "../h/systm.h"#include "../h/mbuf.h"#include "../h/buf.h"#include "../h/time.h"#include "../h/proc.h"#include "../h/protosw.h"#include "../h/socket.h"#include "../h/vmmac.h"#include "../h/ioctl.h"#include "../h/errno.h"#include "../h/kernel.h"#include "../h/ipc.h"#include "../net/net/if.h"#include "../net/net/netisr.h"#if NPACKETFILTER > 0#include "../net/net/pfilt.h"#endif NPACKETFILTER#include "../net/net/if_llc.h#include "../net/netinet/in.h"#include "../net/netinet/in_systm.h"#include "../net/netinet/in_var.h"#include "../net/netinet/ip.h"#include "../net/netinet/ip_var.h"#include "../net/netinet/if_ether.h"#include "../net/netinet/if_fddi.h"#include "../net/net/ether_driver.h"#ifdef vax#include "../machine/mtpr.h"#endif vaxextern struct protosw *iftype_to_proto();int net_output(), net_read();u_char broadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };u_char org_code_ether[3] = { 0x0, 0x0, 0x0 }; /* Org. Code for SNAP */u_char org_code_dec[3] = { 0x08, 0x00, 0x2b }; /* DIGITAL company code */#define ac ((struct arpcom *)ifp)extern int pfactive; /* from pfilt.c, number of currently active filters *//* * LAN output routine. * Encapsulate a packet of type family for the local net * using 802.2 "encapsulated ethernet" SNAP-SAP format * for IP and ARP in compliance with RFC1103 and RFC1042. * (Also, for any other protocols which do not perform LLC * encapsulation themselves). Assumes that ifp is actually * pointer to arpcom structure. */net_output(ifp, m0, dst) register struct ifnet *ifp; struct mbuf *m0; struct sockaddr *dst;{ short type; int s, error = 0; struct in_addr idst; u_char odst[6]; register struct ether_header *eh; register struct fddi_header *fh; register struct mbuf *m = m0; int usetrailers; /* Trailers ignored; see RFC1103 */ extern struct timeval time; struct protosw *pr, *iffamily_to_proto(); if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { error = ENETDOWN; goto bad; } switch (dst->sa_family) {#ifdef INET case AF_INET: if (nINET == 0 || ac->ac_ipaddr.s_addr == 0) { printf("net_output: %s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, dst->sa_family); error = EAFNOSUPPORT; goto bad; } idst = ((struct sockaddr_in *)dst)->sin_addr; if (!arpresolve(ac, m, &idst, (caddr_t)odst, &usetrailers)) return (0); /* if not yet resolved */ type = ETHERTYPE_IP; break;#endif#if NPACKETFILTER > 0 case AF_IMPLINK: if(ifp->if_type == IFT_ETHER) { eh = mtod(m, struct ether_header *); bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, sizeof(ac->ac_enaddr)); goto gotheader; } else if (ifp->if_type == IFT_FDDI) { fh = mtod(m, struct fddi_header *); /* * Extract Frame Control stuff and sanity-check it. * These checks probably need improvement. * We only allow 48-bit address mode. */ switch ((fh->fddi_fc) & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) { case FDDIFC_LLC_ASYNC: /* legal priorities are 0 through 7 */ if ((fh->fddi_fc & FDDIFC_Z) > 7) { error = EPROTONOSUPPORT; goto bad; } break; case FDDIFC_LLC_SYNC: /* FDDIFC_Z bits reserved, must be zero */ if (fh->fddi_fc & FDDIFC_Z) { error = EPROTONOSUPPORT; goto bad; } break; case FDDIFC_SMT: /* FDDIFC_Z bits must be non zero */ if ((fh->fddi_fc & FDDIFC_Z) == 0) { error = EPROTONOSUPPORT; goto bad; } break; default: /* anything else is too dangerous */ error = EPROTONOSUPPORT; goto bad; } /* Fill in must-be-right parts of FDDI header */ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)fh->fddi_shost, sizeof(ac->ac_enaddr)); fh->fddi_ph[0] = FDDIPH0; fh->fddi_ph[1] = FDDIPH1; fh->fddi_ph[2] = FDDIPH2; goto gotheader; } else { error = EAFNOSUPPORT; goto bad; } break;#endif NPACKETFILTER case AF_UNSPEC: /* * Constructed by ARP with ethernet header. Strip dhost and * type from ethernet header for use in MAC header and LLC * encapsulated ethernet header. BIT ORDER FOR ALL MAC HDRS * ASSUMED "CANONICAL" AS FOR ENET. (See RFC1103 and RFC1042). */ eh = (struct ether_header *)dst->sa_data; bcopy((caddr_t)eh->ether_dhost, (caddr_t)odst, sizeof(odst)); type = eh->ether_type; break; default: /* * Try to find other address families and call protocol * specific output routine. Protocols which perform LLC * encapsulation in higher layers pass a type value of * zero as an indication. */ if (pr = iffamily_to_proto(dst->sa_family)) { (*pr->pr_ifoutput)(ifp, m0, dst, &type, (char *)odst); } else { printf("net_output: %s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, dst->sa_family); error = EAFNOSUPPORT; m_freem(m0); return(error); } } /* * Grab off enough space for LLC and MAC headers */ if (m->m_off > MMAXOFF || (MMINOFF + M_NETPAD) > m->m_off) { m = m_get(M_DONTWAIT, MT_DATA); if (m == 0) { error = ENOBUFS; goto bad; } m->m_next = m0; m->m_off = MMINOFF + M_NETPAD; m->m_len = 0; } /* * Add LLC header for 802.2 media using "Encapsulated Ethernet" frame * format. */ if ((ifp->if_flags & IFF_802HDR) && (type != 0)) { register struct llc *lh; m->m_off -= sizeof (struct llc); m->m_len += sizeof (struct llc); lh = mtod(m, struct llc *); /* * Fill out encapsulated ethernet (SNAP-SAP) 802.2 header * in accordance with RFC1103 and RFC1042: * * - DSAP = SNAP = 170 (AA Hex) * - SSAP = SNAP = 170 (AA Hex) * - Control = UI = 3 * - PID contains: * - 3-Octet Organization Code = 00-00-00 * - 2-Octet Ether Type (Encapsulated Ethertype) */ type = htons((u_short)type); bcopy((caddr_t)&type, (caddr_t)&lh->llc_un.type_snap.ether_type, sizeof(u_short)); lh->llc_dsap = LLC_SNAP_LSAP; lh->llc_ssap = LLC_SNAP_LSAP; lh->llc_un.type_snap.control = LLC_UI;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -