/* * © Copyright 1976, 2004 Hewlett-Packard Development Company, L.P. * * Confidential computer software. Valid license from HP and/or its * subsidiaries required for possession, use, or copying. * * Consistent with FAR 12.211 and 12.212, Commercial Computer Software, * Computer Software Documentation, and Technical Data for Commercial * Items are licensed to the U.S. Government under vendor's standard * commercial license. * * Neither HP nor any of its subsidiaries shall be liable for technical * or editorial errors or omissions contained herein. The information * in this document is provided "as is" without warranty of any kind * and is subject to change without notice. The warranties for HP * products are set forth in the express limited warranty statements * accompanying such products. Nothing herein should be construed as * constituting an additional warranty. */ /* * HISTORY */ /* * @(#)$RCSfile: if_ether.h,v $ $Revision: 4.2.34.3 $ (DEC) $Date: 2002/07/10 18:36:04 $ */ /* */ /* * (c) Copyright 1990, OPEN SOFTWARE FOUNDATION, INC. * ALL RIGHTS RESERVED */ /* * OSF/1 Release 1.0 */ /* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted provided * that: (1) source distributions retain this entire copyright notice and * comment, and (2) distributions including binaries display the following * acknowledgement: ``This product includes software developed by the * University of California, Berkeley and its contributors'' in the * documentation or other materials provided with the distribution and in * all advertising materials mentioning features or use of this software. * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Base: if_ether.h 7.4 (Berkeley) 2/17/89 * Merged: if_ether.h 7.5 (Berkeley) 6/28/90 */ #ifndef _IF_ETHER_H_ #define _IF_ETHER_H_ /* * Modification History: * * Matt Thomas 2/15/90 * Add ETHERTYPE_LAT and ETHERTYPE_DECnet for LAT and DLI. */ #include #include /* * Structure of a 10Mb/s (or for that matter 100Mb/s) Ethernet header. */ struct ether_header { u_char ether_dhost[6]; u_char ether_shost[6]; u_short ether_type; }; /* For conveniently referencing tagged data within mbuf data */ struct _ether_xtra { u_short ex_tci; /* Tag Control Information (TCI) */ u_short ex_origtype; /* ETHERTYPE_IP, ETHERTYPE_ARP, etc. */ }; /* * Ethernet 802.1Q tag header. */ struct ether_tagheader { u_char ether_dhost[6]; u_char ether_shost[6]; u_short ether_type; /* ETHERTYPE_TAG */ struct _ether_xtra ether_xtra; /* additional bytes */ }; #define ether_tci ether_xtra.ex_tci #define ether_origtype ether_xtra.ex_origtype /* * Tag Control Information (TCI) macros. * * TCI layout is defined on page 67 of 802.1Q-1998: * * octets |1 |2 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |user_|c| | * |prio |f| VID | * |rity |i| | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * bits |8 6 5 4 1|8 1| * * user_priority - 3 bit user priority * cfi - 1 bit cannonical format indicator * VID - 12 bit VLAN ID * * (Lower numbered bytes are more significant, lower numbered bits * are less significant.) * * So our in-memory copy of this is: * * octets |1 |2 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | |c|user_| | * | VID |f|prio | VID | * | MSB |i|rity | LSB | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * bits |1 4 5 6 7 8|1 8| * * The formatting macros assume that on input, we first do ntohs * before accessing the data, and on output we format the 2 bytes * then do htons. That way we're operating on 2 (little endian) bytes * with this layout: * * octets |1 |2 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | |c|user_| * | VID | VID |f|prio | * | LSB | MSB |i|rity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * bits |1 8|1 5 6 7 8| * * and the macros work for either endianism. */ #define TCI_CFI_MASK 0x1000 #define TCI_VID_MASK 0x0FFF #define TCI_PRI_SHIFT 13 #define TCI_CFI_ON(tci) ((tci) & TCI_CFI_MASK) #define TCI_VID(tci) ((tci) & TCI_VID_MASK) #define TCI_PRI(tci) ((uint_16)(tci) >> TCI_PRI_SHIFT) /* CFI bit is 0. */ #define TCI_ENCODE(vid, pri, tci) \ (tci) = htons((uint_16)((pri) << TCI_PRI_SHIFT) + (vid)) #define TCI_ENCODE_NOPRI(vid, tci) \ (tci) = htons((vid) & TCI_VID_MASK) #ifndef _KERNEL struct ether_addr { u_char ether_addr_octet[6]; }; #endif /* * Note that PUP is <= 1500 and since falls in the range of valid 802.3 * frames. Hence, PUP is not actually usuable. */ #define ETHERTYPE_PUP 0x0200 /* PUP protocol */ #define ETHERTYPE_IP 0x0800 /* IP protocol */ #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ #define ETHERTYPE_LAT 0x6004 /* Local Area Transport (LAT) */ #define ETHERTYPE_DECnet 0x6003 /* Phase IV DECnet */ #define ETHERTYPE_MOPRC 0x6002 /* MOP CCR protocol type */ #define ETHERTYPE_MOPDL 0x6001 /* MOP Downline Load protocol type */ #define ETHERTYPE_LBACK 0x9000 /* MOP loopback protocol type */ #define ETHERTYPE_IPV6 0x86DD /* IPV6 protocol */ #define ETHERTYPE_TAG 0x8100 /* 802.1Q tag header */ /* * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have * (type-ETHERTYPE_TRAIL)*512 bytes of data followed * by an ETHER type (as given above) and then the (variable-length) header. */ #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ #define ETHERTYPE_NTRAILER 16 #if 0 /* #if defined(__alpha) && defined(_KERNEL) */ /* This is needed to support networking with ADUs */ #ifndef ALPHA_ADU #include #endif extern int cpu; #define ETHERMTU ((cpu == ALPHA_ADU) ? (1500-14) : 1500) #else #define ETHERMTU 1500 #endif /* __alpha */ #define ETHERMIN (60-14) /* * Ethernet Bandwidth. */ #define ETHER_BANDWIDTH_10MB 10000000 /* Ethernet - 10Mbs */ #define ETHER_BANDWIDTH_100MB 100000000 /* Fast Ethernet - 100Mbs */ /* * Ethernet Address Resolution Protocol. * * See RFC 826 for protocol description. Structure below is adapted * to resolving internet addresses. Field names used correspond to * RFC 826. */ struct ether_arp { struct arphdr ea_hdr; /* fixed-size header */ u_char arp_sha[6]; /* sender hardware address */ u_char arp_spa[4]; /* sender protocol address */ u_char arp_tha[6]; /* target hardware address */ u_char arp_tpa[4]; /* target protocol address */ }; #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln #define arp_pln ea_hdr.ar_pln #define arp_op ea_hdr.ar_op /* * Structure shared between the ethernet driver modules and * the address resolution code. For example, each ec_softc or il_softc * begins with this structure. */ #define NISAPS 128 struct arpcom { struct ifnet ac_if; /* network-visible interface */ u_char ac_hwaddr[14]; /* hardware address (sizeof sa_data) */ u_short ac_arphrd; /* arp hardware type (net/if_arp.h) */ u_char *ac_bcastaddr; /* pointer to link broadcast or 0 */ u_int ac_flag; /* ip configured or not */ struct dli_ifnet *ac_dlif; /* pointer to the DLI data */ #ifdef __VMS u_char ac_phaddr[14]; /* physical address (sizeof sa_data) */ #endif /* __VMS */ }; #define ac_enaddr ac_hwaddr /* one size fits many */ #define AC_IPUP 0x01 /* IP addr configured */ /* * Internet to ethernet address resolution table. */ struct arptab { struct in_addr at_iaddr; /* internet address */ struct ifnet *at_if; /* interface pointer */ u_char at_hwaddr[14]; /* hardware address (len in at_if) */ u_short at_flags; /* flags (net/if_arp.h) */ short at_timer; /* ticks since last referenced */ short at_valid; /* ticks since last valid */ short at_retry; /* request send count */ short at_sent; /* at_valid at last send */ struct mbuf *at_hold; /* last packet until resolved/timeout */ }; #define at_enaddr at_hwaddr /* as for arpcom */ struct ifnet_arp_cache_head { struct radix_node_head arp_cache_head; long pad_a[3]; lock_data_t arp_cache_lock; long pad_b[2]; }; #ifdef _KERNEL #define IFNET_ARP_CACHE(ifp) &(((struct ifnet_arp_cache_head *) \ ((ifp)->if_arp_cache_head))->arp_cache_head) #define IFNET_ARP_CACHE_LOCK(ifp) (((struct ifnet_arp_cache_head *) \ ((ifp)->if_arp_cache_head))->arp_cache_lock) #define ARP_CACHE_REF(rt) ROUTE_INC_REFCNT(*(rt)) #define ARP_CACHE_UNREF(rt) if (ROUTE_DEC_REFCNT(*(rt)) <= 1) \ arp_cache_free((rt)) /* the "old" arptab entry sits off of the rtentry */ #define ARPTAB_POINTER(rt) (rt)->rt_llinfo #define ARPTAB_ENTRY(rt) (struct arptab *)(rt)->rt_llinfo #if NETSYNC_LOCK ndecl_lock_info(extern, ifnet_arp_cache_li) #define IFNET_ARP_CACHE_LOCKINIT(ifp) ulock_setup(&IFNET_ARP_CACHE_LOCK(ifp),\ ifnet_arp_cache_li, TRUE) #define IFNET_ARP_CACHE_LOCKTERMINATE(ifp) \ ulock_terminate(&IFNET_ARP_CACHE_LOCK(ifp)) #define IFNET_ARP_CACHE_READ_LOCK(ifp) ulock_read(&IFNET_ARP_CACHE_LOCK(ifp)) #define IFNET_ARP_CACHE_WRITE_LOCK(ifp) ulock_write(&IFNET_ARP_CACHE_LOCK(ifp)) #define IFNET_ARP_CACHE_UNLOCK(ifp) ulock_done(&IFNET_ARP_CACHE_LOCK(ifp)) #define IFNET_ARP_CACHE_ISLOCKED(ifp) (lockmode == 0 || \ lock_holder(&IFNET_ARP_CACHE_LOCK(ifp))) #else /* NETSYNC_LOCK */ #define IFNET_ARP_CACHE_LOCKINIT(ifp) #define IFNET_ARP_CACHE_LOCKTERMINATE(ifp) #define IFNET_ARP_CACHE_READ_LOCK(ifp) #define IFNET_ARP_CACHE_WRITE_LOCK(ifp) #define IFNET_ARP_CACHE_UNLOCK(ifp) #define IFNET_ARP_CACHE_ISLOCKED(ifp) #endif /* NETSYNC_LOCK */ #endif /* _KERNEL */ #ifdef _KERNEL /* * Macro to map an IP multicast address to an Ethernet multicast address. * The high-order 25 bits of the Ethernet address are statically assigned, * and the low-order 23 bits are taken from the low end of the IP address. */ #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \ /* struct in_addr *ipaddr; */ \ /* u_char enaddr[6]; */ \ { \ (enaddr)[0] = 0x01; \ (enaddr)[1] = 0x00; \ (enaddr)[2] = 0x5e; \ (enaddr)[3] = ((u_char *)ipaddr)[1] & 0x7f; \ (enaddr)[4] = ((u_char *)ipaddr)[2]; \ (enaddr)[5] = ((u_char *)ipaddr)[3]; \ } /* * Macro to map an IP multicast address to an Ethernet multicast address. * The high-order 25 bits of the Ethernet address are statically assigned, * and the low-order 23 bits are taken from the low end of the IP address. */ #define ETHER_MAP_IP6_MULTICAST(ip6addr, enaddr) \ /* struct in6_addr *ipaddr; */ \ /* u_char enaddr[6]; */ \ do { \ (enaddr)[0] = 0x33; \ (enaddr)[1] = 0x33; \ bcopy(&(ip6addr)->s6_laddr[3], &(enaddr)[2], 4); \ } while(0) extern CONST u_char etherbroadcastaddr[6]; #endif #endif