#ifndef _NETINET_IF_ETHER_H_
#define _NETINET_IF_ETHER_H_
#define ETHER_ADDR_LEN 6
#define ETHER_TYPE_LEN 2
#define ETHER_CRC_LEN 4
#define ETHER_HDR_LEN ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_MAX_DIX_LEN 1536
#define ETHER_VLAN_ENCAP_LEN 4
#define ETHER_ALIGN 2
#define ETHER_MAX_HARDMTU_LEN 65435
struct ether_addr {
u_int8_t ether_addr_octet[ETHER_ADDR_LEN];
};
struct ether_header {
u_int8_t ether_dhost[ETHER_ADDR_LEN];
u_int8_t ether_shost[ETHER_ADDR_LEN];
u_int16_t ether_type;
};
struct ether_vlan_header {
u_char evl_dhost[ETHER_ADDR_LEN];
u_char evl_shost[ETHER_ADDR_LEN];
u_int16_t evl_encap_proto;
u_int16_t evl_tag;
u_int16_t evl_proto;
};
#define EVL_VLID_MASK 0xFFF
#define EVL_VLID_NULL 0x000
#define EVL_VLID_MIN 0x001
#define EVL_VLID_MAX 0xFFE
#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
#define EVL_PRIO_MAX 7
#define EVL_PRIO_BITS 13
#define EVL_PRIOFTAG(tag) (((tag) >> EVL_PRIO_BITS) & 7)
#define EVL_ENCAPLEN 4
#include <net/ethertypes.h>
#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01)
#define ETHER_IS_BROADCAST(addr) \
(((addr)[0] & (addr)[1] & (addr)[2] & \
(addr)[3] & (addr)[4] & (addr)[5]) == 0xff)
#define ETHER_IS_ANYADDR(addr) \
(((addr)[0] | (addr)[1] | (addr)[2] | \
(addr)[3] | (addr)[4] | (addr)[5]) == 0x00)
#define ETHER_IS_EQ(a1, a2) (memcmp((a1), (a2), ETHER_ADDR_LEN) == 0)
#define ETH64_IS_MULTICAST(_e64) ((_e64) & 0x010000000000ULL)
#define ETH64_IS_BROADCAST(_e64) ((_e64) == 0xffffffffffffULL)
#define ETH64_IS_ANYADDR(_e64) ((_e64) == 0x000000000000ULL)
#define ETH64_8021_RSVD_PREFIX 0x0180c2000000ULL
#define ETH64_8021_RSVD_MASK 0xfffffffffff0ULL
#define ETH64_IS_8021_RSVD(_e64) \
(((_e64) & ETH64_8021_RSVD_MASK) == ETH64_8021_RSVD_PREFIX)
#define ETHERMTU (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
#define ETHER_CRC_POLY_LE 0xedb88320
#define ETHER_CRC_POLY_BE 0x04c11db6
struct ether_arp {
struct arphdr ea_hdr;
u_int8_t arp_sha[ETHER_ADDR_LEN];
u_int8_t arp_spa[4];
u_int8_t arp_tha[ETHER_ADDR_LEN];
u_int8_t arp_tpa[4];
};
#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
struct sockaddr_inarp {
u_int8_t sin_len;
u_int8_t sin_family;
u_int16_t sin_port;
struct in_addr sin_addr;
struct in_addr sin_srcaddr;
u_int16_t sin_tos;
u_int16_t sin_other;
#define SIN_PROXY 1
};
#define RTF_USETRAILERS RTF_PROTO1
#define RTF_PERMANENT_ARP RTF_PROTO3
#ifdef _KERNEL
#include <sys/refcnt.h>
#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
\
\
do { \
(enaddr)[0] = 0x01; \
(enaddr)[1] = 0x00; \
(enaddr)[2] = 0x5e; \
(enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \
(enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \
(enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \
} while ( 0)
#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \
\
\
do { \
(enaddr)[0] = 0x33; \
(enaddr)[1] = 0x33; \
(enaddr)[2] = ((u_int8_t *)ip6addr)[12]; \
(enaddr)[3] = ((u_int8_t *)ip6addr)[13]; \
(enaddr)[4] = ((u_int8_t *)ip6addr)[14]; \
(enaddr)[5] = ((u_int8_t *)ip6addr)[15]; \
} while ( 0)
#include <net/if_var.h>
struct ether_port {
struct mbuf *(*ep_input)(struct ifnet *, struct mbuf *,
uint64_t, void *, struct netstack *);
void *(*ep_port_take)(void *);
void (*ep_port_rele)(void *, void *);
void *ep_port;
};
struct arpcom {
struct ifnet ac_if;
u_int8_t ac_enaddr[ETHER_ADDR_LEN];
char ac__pad[2];
LIST_HEAD(, ether_multi) ac_multiaddrs;
int ac_multicnt;
int ac_multirangecnt;
const struct ether_port *ac_trport;
const struct ether_port *ac_brport;
};
extern int arpt_keep;
extern int arpt_down;
extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
extern u_int8_t etheranyaddr[ETHER_ADDR_LEN];
extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
#ifdef NFSCLIENT
extern unsigned int revarp_ifidx;
#endif
void revarpinput(struct ifnet *, struct mbuf *, struct netstack *);
void revarprequest(struct ifnet *);
int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
int revarpwhoami(struct in_addr *, struct ifnet *);
void arpinit(void);
void arpinput(struct ifnet *, struct mbuf *, struct netstack *);
void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *);
int arpproxy(struct in_addr, unsigned int);
int arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
struct sockaddr *, u_char *);
void arp_rtrequest(struct ifnet *, int, struct rtentry *);
void ether_fakeaddr(struct ifnet *);
int ether_addmulti(struct ifreq *, struct arpcom *);
int ether_delmulti(struct ifreq *, struct arpcom *);
int ether_multiaddr(struct sockaddr *, u_int8_t *, u_int8_t *);
void ether_ifattach(struct ifnet *);
void ether_ifdetach(struct ifnet *);
int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t);
void ether_input(struct ifnet *, struct mbuf *, struct netstack *);
int ether_resolve(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *, struct ether_header *);
struct mbuf *
ether_encap(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *, int *);
int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
void ether_rtrequest(struct ifnet *, int, struct rtentry *);
char *ether_sprintf(u_char *);
int ether_brport_isset(struct ifnet *);
void ether_brport_set(struct ifnet *, const struct ether_port *);
void ether_brport_clr(struct ifnet *);
const struct ether_port *
ether_brport_get(struct ifnet *);
const struct ether_port *
ether_brport_get_locked(struct ifnet *);
uint64_t ether_addr_to_e64(const struct ether_addr *);
void ether_e64_to_addr(struct ether_addr *, uint64_t);
struct ether_extracted {
struct ether_header *eh;
struct ether_vlan_header *evh;
struct ip *ip4;
struct ip6_hdr *ip6;
struct tcphdr *tcp;
struct udphdr *udp;
u_int iplen;
u_int iphlen;
u_int tcphlen;
u_int paylen;
};
void ether_extract_headers(struct mbuf *, struct ether_extracted *);
struct mbuf *ether_offload_ifcap(struct ifnet *, struct mbuf *);
struct ether_multi {
u_int8_t enm_addrlo[ETHER_ADDR_LEN];
u_int8_t enm_addrhi[ETHER_ADDR_LEN];
struct refcnt enm_refcnt;
LIST_ENTRY(ether_multi) enm_list;
};
struct ether_multistep {
struct ether_multi *e_enm;
};
#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm) \
\
\
\
\
do { \
for ((enm) = LIST_FIRST(&(ac)->ac_multiaddrs); \
(enm) != NULL && \
(memcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 ||\
memcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0); \
(enm) = LIST_NEXT((enm), enm_list)); \
} while ( 0)
#define ETHER_NEXT_MULTI(step, enm) \
\
\
do { \
if (((enm) = (step).e_enm) != NULL) \
(step).e_enm = LIST_NEXT((enm), enm_list); \
} while ( 0)
#define ETHER_FIRST_MULTI(step, ac, enm) \
\
\
\
do { \
(step).e_enm = LIST_FIRST(&(ac)->ac_multiaddrs); \
ETHER_NEXT_MULTI((step), (enm)); \
} while ( 0)
u_int32_t ether_crc32_le_update(u_int32_t crc, const u_int8_t *, size_t);
u_int32_t ether_crc32_be_update(u_int32_t crc, const u_int8_t *, size_t);
u_int32_t ether_crc32_le(const u_int8_t *, size_t);
u_int32_t ether_crc32_be(const u_int8_t *, size_t);
#else
__BEGIN_DECLS
char *ether_ntoa(const struct ether_addr *);
struct ether_addr *ether_aton(const char *);
int ether_ntohost(char *, struct ether_addr *);
int ether_hostton(const char *, struct ether_addr *);
int ether_line(const char *, struct ether_addr *, char *);
__END_DECLS
#endif
#endif