1*66570633Sbluhm /* $OpenBSD: if_ether.h,v 1.93 2025/01/01 13:44:22 bluhm Exp $ */ 26a239809Sderaadt /* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */ 3df930be7Sderaadt 4df930be7Sderaadt /* 5df930be7Sderaadt * Copyright (c) 1982, 1986, 1993 6df930be7Sderaadt * The Regents of the University of California. All rights reserved. 7df930be7Sderaadt * 8df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 9df930be7Sderaadt * modification, are permitted provided that the following conditions 10df930be7Sderaadt * are met: 11df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 12df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 13df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 14df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 15df930be7Sderaadt * documentation and/or other materials provided with the distribution. 1629295d1cSmillert * 3. Neither the name of the University nor the names of its contributors 17df930be7Sderaadt * may be used to endorse or promote products derived from this software 18df930be7Sderaadt * without specific prior written permission. 19df930be7Sderaadt * 20df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30df930be7Sderaadt * SUCH DAMAGE. 31df930be7Sderaadt * 32df930be7Sderaadt * @(#)if_ether.h 8.1 (Berkeley) 6/10/93 33df930be7Sderaadt */ 34df930be7Sderaadt 357db87fb0Sangelos #ifndef _NETINET_IF_ETHER_H_ 367db87fb0Sangelos #define _NETINET_IF_ETHER_H_ 377db87fb0Sangelos 38df930be7Sderaadt /* 39386aaa9cSbrad * Some basic Ethernet constants. 40df930be7Sderaadt */ 4180db8022Sfgsch #define ETHER_ADDR_LEN 6 /* Ethernet address length */ 4280db8022Sfgsch #define ETHER_TYPE_LEN 2 /* Ethernet type field length */ 43e4d25771Stodd #define ETHER_CRC_LEN 4 /* Ethernet CRC length */ 4480db8022Sfgsch #define ETHER_HDR_LEN ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN) 4580db8022Sfgsch #define ETHER_MIN_LEN 64 /* Minimum frame length, CRC included */ 4680db8022Sfgsch #define ETHER_MAX_LEN 1518 /* Maximum frame length, CRC included */ 47d51773cbSbrad #define ETHER_MAX_DIX_LEN 1536 /* Maximum DIX frame length */ 484412f6ecSbrad 49386aaa9cSbrad /* 50386aaa9cSbrad * Some Ethernet extensions. 51386aaa9cSbrad */ 524412f6ecSbrad #define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */ 534412f6ecSbrad 544412f6ecSbrad /* 554412f6ecSbrad * Mbuf adjust factor to force 32-bit alignment of IP header. 564412f6ecSbrad * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a 574412f6ecSbrad * receive so the upper layers get the IP header properly aligned 584412f6ecSbrad * past the 14-byte Ethernet header. 594412f6ecSbrad */ 604412f6ecSbrad #define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */ 61ba022580Schris 62ba022580Schris /* 63fc3b235fSreyk * The maximum supported Ethernet length and some space for encapsulation. 64fc3b235fSreyk */ 65fc3b235fSreyk #define ETHER_MAX_HARDMTU_LEN 65435 66fc3b235fSreyk 67fc3b235fSreyk /* 68d90fb189Schris * Ethernet address - 6 octets 69d90fb189Schris */ 70d90fb189Schris struct ether_addr { 71d90fb189Schris u_int8_t ether_addr_octet[ETHER_ADDR_LEN]; 72d90fb189Schris }; 73d90fb189Schris 74d90fb189Schris /* 75ba022580Schris * The length of the combined header. 76ba022580Schris */ 77df930be7Sderaadt struct ether_header { 78df930be7Sderaadt u_int8_t ether_dhost[ETHER_ADDR_LEN]; 79df930be7Sderaadt u_int8_t ether_shost[ETHER_ADDR_LEN]; 80df930be7Sderaadt u_int16_t ether_type; 81df930be7Sderaadt }; 82df930be7Sderaadt 836b938edbSdlg /* 846b938edbSdlg * VLAN headers. 856b938edbSdlg */ 866b938edbSdlg 876b938edbSdlg struct ether_vlan_header { 886b938edbSdlg u_char evl_dhost[ETHER_ADDR_LEN]; 896b938edbSdlg u_char evl_shost[ETHER_ADDR_LEN]; 906b938edbSdlg u_int16_t evl_encap_proto; 916b938edbSdlg u_int16_t evl_tag; 926b938edbSdlg u_int16_t evl_proto; 936b938edbSdlg }; 946b938edbSdlg 95a1d84234Sdlg #define EVL_VLID_MASK 0xFFF 96a1d84234Sdlg #define EVL_VLID_NULL 0x000 97a1d84234Sdlg /* 0x000 and 0xfff are reserved */ 98a1d84234Sdlg #define EVL_VLID_MIN 0x001 99a1d84234Sdlg #define EVL_VLID_MAX 0xFFE 1006b938edbSdlg #define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) 1016b938edbSdlg 1026b938edbSdlg #define EVL_PRIO_MAX 7 1036b938edbSdlg #define EVL_PRIO_BITS 13 1046b938edbSdlg #define EVL_PRIOFTAG(tag) (((tag) >> EVL_PRIO_BITS) & 7) 1056b938edbSdlg 1066b938edbSdlg #define EVL_ENCAPLEN 4 /* length in octets of encapsulation */ 1076b938edbSdlg 10853fa5dcfSitojun #include <net/ethertypes.h> 109df930be7Sderaadt 110df930be7Sderaadt #define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ 11178cd82e3Smpi #define ETHER_IS_BROADCAST(addr) \ 11278cd82e3Smpi (((addr)[0] & (addr)[1] & (addr)[2] & \ 11378cd82e3Smpi (addr)[3] & (addr)[4] & (addr)[5]) == 0xff) 11478cd82e3Smpi #define ETHER_IS_ANYADDR(addr) \ 11578cd82e3Smpi (((addr)[0] | (addr)[1] | (addr)[2] | \ 11678cd82e3Smpi (addr)[3] | (addr)[4] | (addr)[5]) == 0x00) 11778cd82e3Smpi #define ETHER_IS_EQ(a1, a2) (memcmp((a1), (a2), ETHER_ADDR_LEN) == 0) 118df930be7Sderaadt 119cf89a71dSdlg /* 120cf89a71dSdlg * It can be faster to work with ethernet addresses as a uint64_t. 121cf89a71dSdlg * Provide some constants and functionality centrally to better 122cf89a71dSdlg * support this. 123cf89a71dSdlg */ 124cf89a71dSdlg 125cf89a71dSdlg #define ETH64_IS_MULTICAST(_e64) ((_e64) & 0x010000000000ULL) 126cf89a71dSdlg #define ETH64_IS_BROADCAST(_e64) ((_e64) == 0xffffffffffffULL) 127cf89a71dSdlg #define ETH64_IS_ANYADDR(_e64) ((_e64) == 0x000000000000ULL) 128cf89a71dSdlg 129cf89a71dSdlg #define ETH64_8021_RSVD_PREFIX 0x0180c2000000ULL 130cf89a71dSdlg #define ETH64_8021_RSVD_MASK 0xfffffffffff0ULL 131cf89a71dSdlg #define ETH64_IS_8021_RSVD(_e64) \ 132cf89a71dSdlg (((_e64) & ETH64_8021_RSVD_MASK) == ETH64_8021_RSVD_PREFIX) 133cf89a71dSdlg 134cf89a71dSdlg /* 135cf89a71dSdlg * Ethernet MTU constants. 136cf89a71dSdlg */ 13780db8022Sfgsch #define ETHERMTU (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) 13880db8022Sfgsch #define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) 139df930be7Sderaadt 140cc403c85Snate /* 141678831beSjsg * Ethernet CRC32 polynomials (big- and little-endian versions). 142cc403c85Snate */ 143cc403c85Snate #define ETHER_CRC_POLY_LE 0xedb88320 144cc403c85Snate #define ETHER_CRC_POLY_BE 0x04c11db6 145cc403c85Snate 14696dc0726Smpi /* 14796dc0726Smpi * Ethernet Address Resolution Protocol. 14896dc0726Smpi * 14996dc0726Smpi * See RFC 826 for protocol description. Structure below is adapted 15096dc0726Smpi * to resolving internet addresses. Field names used correspond to 15196dc0726Smpi * RFC 826. 15296dc0726Smpi */ 15396dc0726Smpi struct ether_arp { 15496dc0726Smpi struct arphdr ea_hdr; /* fixed-size header */ 15596dc0726Smpi u_int8_t arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */ 15696dc0726Smpi u_int8_t arp_spa[4]; /* sender protocol address */ 15796dc0726Smpi u_int8_t arp_tha[ETHER_ADDR_LEN]; /* target hardware address */ 15896dc0726Smpi u_int8_t arp_tpa[4]; /* target protocol address */ 15996dc0726Smpi }; 16096dc0726Smpi #define arp_hrd ea_hdr.ar_hrd 16196dc0726Smpi #define arp_pro ea_hdr.ar_pro 16296dc0726Smpi #define arp_hln ea_hdr.ar_hln 16396dc0726Smpi #define arp_pln ea_hdr.ar_pln 16496dc0726Smpi #define arp_op ea_hdr.ar_op 16596dc0726Smpi 16696dc0726Smpi struct sockaddr_inarp { 16796dc0726Smpi u_int8_t sin_len; 16896dc0726Smpi u_int8_t sin_family; 16996dc0726Smpi u_int16_t sin_port; 17096dc0726Smpi struct in_addr sin_addr; 17196dc0726Smpi struct in_addr sin_srcaddr; 17296dc0726Smpi u_int16_t sin_tos; 17396dc0726Smpi u_int16_t sin_other; 17496dc0726Smpi #define SIN_PROXY 1 17596dc0726Smpi }; 17696dc0726Smpi 17796dc0726Smpi /* 17896dc0726Smpi * IP and ethernet specific routing flags 17996dc0726Smpi */ 18096dc0726Smpi #define RTF_USETRAILERS RTF_PROTO1 /* use trailers */ 18196dc0726Smpi #define RTF_PERMANENT_ARP RTF_PROTO3 /* only manual overwrite of entry */ 18296dc0726Smpi 183df930be7Sderaadt #ifdef _KERNEL 18469761fb1Skn 18569761fb1Skn #include <sys/refcnt.h> 18669761fb1Skn 187df930be7Sderaadt /* 188df930be7Sderaadt * Macro to map an IP multicast address to an Ethernet multicast address. 189df930be7Sderaadt * The high-order 25 bits of the Ethernet address are statically assigned, 190df930be7Sderaadt * and the low-order 23 bits are taken from the low end of the IP address. 191df930be7Sderaadt */ 192df930be7Sderaadt #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \ 193df930be7Sderaadt /* struct in_addr *ipaddr; */ \ 194df930be7Sderaadt /* u_int8_t enaddr[ETHER_ADDR_LEN]; */ \ 19592df2d4eSdlg do { \ 196df930be7Sderaadt (enaddr)[0] = 0x01; \ 197df930be7Sderaadt (enaddr)[1] = 0x00; \ 198df930be7Sderaadt (enaddr)[2] = 0x5e; \ 199df930be7Sderaadt (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \ 200df930be7Sderaadt (enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \ 201df930be7Sderaadt (enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \ 20292df2d4eSdlg } while (/* CONSTCOND */ 0) 203287546eaSitojun 204287546eaSitojun /* 205287546eaSitojun * Macro to map an IPv6 multicast address to an Ethernet multicast address. 206287546eaSitojun * The high-order 16 bits of the Ethernet address are statically assigned, 207287546eaSitojun * and the low-order 32 bits are taken from the low end of the IPv6 address. 208287546eaSitojun */ 209287546eaSitojun #define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \ 210287546eaSitojun /* struct in6_addr *ip6addr; */ \ 211287546eaSitojun /* u_int8_t enaddr[ETHER_ADDR_LEN]; */ \ 21292df2d4eSdlg do { \ 213287546eaSitojun (enaddr)[0] = 0x33; \ 214287546eaSitojun (enaddr)[1] = 0x33; \ 215287546eaSitojun (enaddr)[2] = ((u_int8_t *)ip6addr)[12]; \ 216287546eaSitojun (enaddr)[3] = ((u_int8_t *)ip6addr)[13]; \ 217287546eaSitojun (enaddr)[4] = ((u_int8_t *)ip6addr)[14]; \ 218287546eaSitojun (enaddr)[5] = ((u_int8_t *)ip6addr)[15]; \ 21992df2d4eSdlg } while (/* CONSTCOND */ 0) 220a7ae9819Sderaadt 2210deb6685Smpi #include <net/if_var.h> /* for "struct ifnet" */ 2220deb6685Smpi 223d79d7022Sdlg struct ether_brport { 2244e0e7160Sdlg struct mbuf *(*eb_input)(struct ifnet *, struct mbuf *, 2254e0e7160Sdlg uint64_t, void *); 226baf71576Ssashan void (*eb_port_take)(void *); 227baf71576Ssashan void (*eb_port_rele)(void *); 228d79d7022Sdlg void *eb_port; 229d79d7022Sdlg }; 230d79d7022Sdlg 231df930be7Sderaadt /* 232df930be7Sderaadt * Structure shared between the ethernet driver modules and 233df930be7Sderaadt * the address resolution code. For example, each ec_softc or il_softc 234df930be7Sderaadt * begins with this structure. 235df930be7Sderaadt */ 236df930be7Sderaadt struct arpcom { 237df930be7Sderaadt struct ifnet ac_if; /* network-visible interface */ 238df930be7Sderaadt u_int8_t ac_enaddr[ETHER_ADDR_LEN]; /* ethernet hardware address */ 239db36d367Sderaadt char ac__pad[2]; /* pad for some machines */ 2404ccfd590Sdlg LIST_HEAD(, ether_multi) ac_multiaddrs; /* list of multicast addrs */ 2414ccfd590Sdlg int ac_multicnt; /* length of ac_multiaddrs */ 2424ccfd590Sdlg int ac_multirangecnt; /* number of mcast ranges */ 2434ccfd590Sdlg 2448edbca89Sdlg void *ac_trunkport; 245d79d7022Sdlg const struct ether_brport *ac_brport; 246df930be7Sderaadt }; 247df930be7Sderaadt 2484faff50fSchris extern int arpt_keep; /* arp resolved cache expire */ 2494faff50fSchris extern int arpt_down; /* arp down cache expire */ 2504faff50fSchris 2514c366c49Smiod extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN]; 2526ff0435bSstsp extern u_int8_t etheranyaddr[ETHER_ADDR_LEN]; 2534c366c49Smiod extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN]; 2544c366c49Smiod extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN]; 255df930be7Sderaadt 256f97093e3Smpi #ifdef NFSCLIENT 257f97093e3Smpi extern unsigned int revarp_ifidx; 258f97093e3Smpi #endif /* NFSCLIENT */ 259f97093e3Smpi 2605a411d3cSmpi void revarpinput(struct ifnet *, struct mbuf *); 261f97093e3Smpi void revarprequest(struct ifnet *); 262f97093e3Smpi int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *); 263f97093e3Smpi int revarpwhoami(struct in_addr *, struct ifnet *); 264f97093e3Smpi 265632220b1Sbluhm void arpinit(void); 2665a411d3cSmpi void arpinput(struct ifnet *, struct mbuf *); 267f97093e3Smpi void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *); 268c4071fd1Smillert void arpwhohas(struct arpcom *, struct in_addr *); 269f97093e3Smpi int arpproxy(struct in_addr, unsigned int); 27096dc0726Smpi int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *, 27196dc0726Smpi struct sockaddr *, u_char *); 272dcb17c31Smpi void arp_rtrequest(struct ifnet *, int, struct rtentry *); 273df930be7Sderaadt 27496dc0726Smpi void ether_fakeaddr(struct ifnet *); 275c4071fd1Smillert int ether_addmulti(struct ifreq *, struct arpcom *); 276c4071fd1Smillert int ether_delmulti(struct ifreq *, struct arpcom *); 27704cdc2f2Spatrick int ether_multiaddr(struct sockaddr *, u_int8_t *, u_int8_t *); 278f0fcdf5cSmpi void ether_ifattach(struct ifnet *); 279f0fcdf5cSmpi void ether_ifdetach(struct ifnet *); 280f0fcdf5cSmpi int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); 28123293512Sdlg void ether_input(struct ifnet *, struct mbuf *); 28232303230Sdlg int ether_resolve(struct ifnet *, struct mbuf *, struct sockaddr *, 28332303230Sdlg struct rtentry *, struct ether_header *); 28432303230Sdlg struct mbuf * 28532303230Sdlg ether_encap(struct ifnet *, struct mbuf *, struct sockaddr *, 28632303230Sdlg struct rtentry *, int *); 28732303230Sdlg int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *, 28832303230Sdlg struct rtentry *); 289f0fcdf5cSmpi void ether_rtrequest(struct ifnet *, int, struct rtentry *); 290f0fcdf5cSmpi char *ether_sprintf(u_char *); 291f0fcdf5cSmpi 292d79d7022Sdlg int ether_brport_isset(struct ifnet *); 293d79d7022Sdlg void ether_brport_set(struct ifnet *, const struct ether_brport *); 294d79d7022Sdlg void ether_brport_clr(struct ifnet *); 295d79d7022Sdlg const struct ether_brport * 296d79d7022Sdlg ether_brport_get(struct ifnet *); 297d79d7022Sdlg const struct ether_brport * 298d79d7022Sdlg ether_brport_get_locked(struct ifnet *); 299df930be7Sderaadt 300cf89a71dSdlg uint64_t ether_addr_to_e64(const struct ether_addr *); 301cf89a71dSdlg void ether_e64_to_addr(struct ether_addr *, uint64_t); 302cf89a71dSdlg 30326fd91ceSjan struct ether_extracted { 30426fd91ceSjan struct ether_header *eh; 305d1dd6743Sjan struct ether_vlan_header *evh; 30626fd91ceSjan struct ip *ip4; 30726fd91ceSjan struct ip6_hdr *ip6; 30826fd91ceSjan struct tcphdr *tcp; 30926fd91ceSjan struct udphdr *udp; 310ac5f541aSbluhm u_int iplen; 311ac5f541aSbluhm u_int iphlen; 312e78a66e5Sbluhm u_int tcphlen; 313e78a66e5Sbluhm u_int paylen; 31426fd91ceSjan }; 31526fd91ceSjan 31626fd91ceSjan void ether_extract_headers(struct mbuf *, struct ether_extracted *); 31726fd91ceSjan 318df930be7Sderaadt /* 319df930be7Sderaadt * Ethernet multicast address structure. There is one of these for each 320df930be7Sderaadt * multicast address or range of multicast addresses that we are supposed 321df930be7Sderaadt * to listen to on a particular interface. They are kept in a linked list, 322df930be7Sderaadt * rooted in the interface's arpcom structure. (This really has nothing to 323df930be7Sderaadt * do with ARP, or with the Internet address family, but this appears to be 324df930be7Sderaadt * the minimally-disrupting place to put it.) 325df930be7Sderaadt */ 326df930be7Sderaadt struct ether_multi { 327df930be7Sderaadt u_int8_t enm_addrlo[ETHER_ADDR_LEN]; /* low or only address of range */ 328df930be7Sderaadt u_int8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */ 32969761fb1Skn struct refcnt enm_refcnt; /* no. claims to this addr/range */ 330df930be7Sderaadt LIST_ENTRY(ether_multi) enm_list; 331df930be7Sderaadt }; 332df930be7Sderaadt 333df930be7Sderaadt /* 334df930be7Sderaadt * Structure used by macros below to remember position when stepping through 335df930be7Sderaadt * all of the ether_multi records. 336df930be7Sderaadt */ 337df930be7Sderaadt struct ether_multistep { 338df930be7Sderaadt struct ether_multi *e_enm; 339df930be7Sderaadt }; 340df930be7Sderaadt 341df930be7Sderaadt /* 342df930be7Sderaadt * Macro for looking up the ether_multi record for a given range of Ethernet 343df930be7Sderaadt * multicast addresses connected to a given arpcom structure. If no matching 344df930be7Sderaadt * record is found, "enm" returns NULL. 345df930be7Sderaadt */ 346df930be7Sderaadt #define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \ 347df930be7Sderaadt /* u_int8_t addrlo[ETHER_ADDR_LEN]; */ \ 348df930be7Sderaadt /* u_int8_t addrhi[ETHER_ADDR_LEN]; */ \ 349df930be7Sderaadt /* struct arpcom *ac; */ \ 350df930be7Sderaadt /* struct ether_multi *enm; */ \ 35192df2d4eSdlg do { \ 3521573508eSmiod for ((enm) = LIST_FIRST(&(ac)->ac_multiaddrs); \ 35366c84f52Stedu (enm) != NULL && \ 354f8575965Stedu (memcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 ||\ 355f8575965Stedu memcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0); \ 3561573508eSmiod (enm) = LIST_NEXT((enm), enm_list)); \ 35792df2d4eSdlg } while (/* CONSTCOND */ 0) 358df930be7Sderaadt 359df930be7Sderaadt /* 360df930be7Sderaadt * Macro to step through all of the ether_multi records, one at a time. 361df930be7Sderaadt * The current position is remembered in "step", which the caller must 362df930be7Sderaadt * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step" 363df930be7Sderaadt * and get the first record. Both macros return a NULL "enm" when there 364df930be7Sderaadt * are no remaining records. 365df930be7Sderaadt */ 366df930be7Sderaadt #define ETHER_NEXT_MULTI(step, enm) \ 367df930be7Sderaadt /* struct ether_multistep step; */ \ 368df930be7Sderaadt /* struct ether_multi *enm; */ \ 36992df2d4eSdlg do { \ 370df930be7Sderaadt if (((enm) = (step).e_enm) != NULL) \ 3711573508eSmiod (step).e_enm = LIST_NEXT((enm), enm_list); \ 37292df2d4eSdlg } while (/* CONSTCOND */ 0) 373df930be7Sderaadt 374df930be7Sderaadt #define ETHER_FIRST_MULTI(step, ac, enm) \ 375df930be7Sderaadt /* struct ether_multistep step; */ \ 376df930be7Sderaadt /* struct arpcom *ac; */ \ 377df930be7Sderaadt /* struct ether_multi *enm; */ \ 37892df2d4eSdlg do { \ 3791573508eSmiod (step).e_enm = LIST_FIRST(&(ac)->ac_multiaddrs); \ 380df930be7Sderaadt ETHER_NEXT_MULTI((step), (enm)); \ 38192df2d4eSdlg } while (/* CONSTCOND */ 0) 382b400e158Sniklas 3830849d918Sdjm u_int32_t ether_crc32_le_update(u_int32_t crc, const u_int8_t *, size_t); 3840849d918Sdjm u_int32_t ether_crc32_be_update(u_int32_t crc, const u_int8_t *, size_t); 385cc403c85Snate u_int32_t ether_crc32_le(const u_int8_t *, size_t); 386cc403c85Snate u_int32_t ether_crc32_be(const u_int8_t *, size_t); 387cc403c85Snate 38896dc0726Smpi #else /* _KERNEL */ 389ceeee157Sderaadt 3905c86c1acSnaddy __BEGIN_DECLS 391c4071fd1Smillert char *ether_ntoa(struct ether_addr *); 3929f33d8a6Stedu struct ether_addr *ether_aton(const char *); 393c4071fd1Smillert int ether_ntohost(char *, struct ether_addr *); 3949f33d8a6Stedu int ether_hostton(const char *, struct ether_addr *); 3959f33d8a6Stedu int ether_line(const char *, struct ether_addr *, char *); 3965c86c1acSnaddy __END_DECLS 397ceeee157Sderaadt 3987db87fb0Sangelos #endif /* _KERNEL */ 3997db87fb0Sangelos #endif /* _NETINET_IF_ETHER_H_ */ 400