From 6cf86998dfa72f3b03cc8a61a0db337beda82193 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Tue, 10 Dec 2013 19:34:19 +0100 Subject: [PATCH] Change-Id: I7425aae72ab43e3fcec8373f7c589273d36f7fcb --- commands/dhcpd/dhcpd.h | 1 + include/net/gen/eth_hdr.h | 2 + include/net/gen/eth_io.h | 2 + include/net/gen/ether.h | 5 - include/net/gen/if_ether.h | 19 +-- sys/net/if_ether.h | 237 ++++++++++++++++++++++++++++++++++++- 6 files changed, 242 insertions(+), 24 deletions(-) diff --git a/commands/dhcpd/dhcpd.h b/commands/dhcpd/dhcpd.h index 4ec65b19f..35d729d3e 100644 --- a/commands/dhcpd/dhcpd.h +++ b/commands/dhcpd/dhcpd.h @@ -6,6 +6,7 @@ #define nil ((void*)0) #include +#include /* Paths to files. */ #define PATH_DHCPCONF _PATH_DHCPCONF diff --git a/include/net/gen/eth_hdr.h b/include/net/gen/eth_hdr.h index 7b7bb9cbb..3d882f7e8 100644 --- a/include/net/gen/eth_hdr.h +++ b/include/net/gen/eth_hdr.h @@ -5,6 +5,8 @@ server/ip/gen/eth_hdr.h #ifndef __SERVER__IP__GEN__ETH_HDR_H__ #define __SERVER__IP__GEN__ETH_HDR_H__ +#include + typedef struct eth_hdr { ether_addr_t eh_dst; diff --git a/include/net/gen/eth_io.h b/include/net/gen/eth_io.h index 9358f71c3..bcc320514 100644 --- a/include/net/gen/eth_io.h +++ b/include/net/gen/eth_io.h @@ -5,6 +5,8 @@ server/gen/ip/eth_io.h #ifndef __SERVER__IP__GEN__ETH_IO_H__ #define __SERVER__IP__GEN__ETH_IO_H__ +#include + typedef struct nwio_ethopt { u32_t nweo_flags; diff --git a/include/net/gen/ether.h b/include/net/gen/ether.h index 0cb00dea6..24cd231f2 100644 --- a/include/net/gen/ether.h +++ b/include/net/gen/ether.h @@ -11,11 +11,6 @@ server/ip/gen/ether.h #define ETH_HDR_SIZE 14 #define ETH_CRC_SIZE 4 -typedef struct ether_addr -{ - u8_t ea_addr[6]; -} ether_addr_t; - typedef u16_t ether_type_t; #define ETH_ARP_PROTO 0x806 diff --git a/include/net/gen/if_ether.h b/include/net/gen/if_ether.h index a94d899e0..d1df1ee22 100644 --- a/include/net/gen/if_ether.h +++ b/include/net/gen/if_ether.h @@ -1,18 +1 @@ -/* -server/ip/gen/if_ether.h -*/ - -#ifndef __SERVER__IP__GEN__IF_ETHER_H__ -#define __SERVER__IP__GEN__IF_ETHER_H__ - -struct ether_addr; - -#define _PATH_ETHERS "/etc/ethers" - -char *ether_ntoa( struct ether_addr *e ); -struct ether_addr *ether_aton( const char *s ); -int ether_ntohost( char *hostname, struct ether_addr *e ); -int ether_hostton( char *hostname, struct ether_addr *e ); -int ether_line( char *l, struct ether_addr *e, char *hostname ); - -#endif /* __SERVER__IP__GEN__IF_ETHER_H__ */ +#include diff --git a/sys/net/if_ether.h b/sys/net/if_ether.h index 3cc90642a..ce146ad3b 100644 --- a/sys/net/if_ether.h +++ b/sys/net/if_ether.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_ether.h,v 1.58 2010/05/19 20:41:59 christos Exp $ */ +/* $NetBSD: if_ether.h,v 1.59 2012/09/30 05:08:08 dholland Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -34,6 +34,17 @@ #ifndef _NET_IF_ETHER_H_ #define _NET_IF_ETHER_H_ +#ifdef _KERNEL +#ifdef _KERNEL_OPT +#include "opt_mbuftrace.h" +#endif +#include +#endif + +#ifndef _STANDALONE +#include +#endif + /* * Some basic Ethernet constants. */ @@ -59,6 +70,11 @@ struct ether_addr { uint8_t ether_addr_octet[ETHER_ADDR_LEN]; } __packed; +#ifdef __minix +#define ea_addr ether_addr_octet +typedef struct ether_addr ether_addr_t; +#endif + /* * Structure of a 10Mb/s Ethernet header. */ @@ -93,6 +109,222 @@ struct ether_header { #define ETHER_CRC_POLY_LE 0xedb88320 #define ETHER_CRC_POLY_BE 0x04c11db6 +#ifndef _STANDALONE + +/* + * Ethernet-specific mbuf flags. + */ +#define M_HASFCS M_LINK0 /* FCS included at end of frame */ +#define M_PROMISC M_LINK1 /* this packet is not for us */ + +#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) \ + /* const struct in_addr *ipaddr; */ \ + /* uint8_t enaddr[ETHER_ADDR_LEN]; */ \ +do { \ + (enaddr)[0] = 0x01; \ + (enaddr)[1] = 0x00; \ + (enaddr)[2] = 0x5e; \ + (enaddr)[3] = ((const uint8_t *)ipaddr)[1] & 0x7f; \ + (enaddr)[4] = ((const uint8_t *)ipaddr)[2]; \ + (enaddr)[5] = ((const uint8_t *)ipaddr)[3]; \ +} while (/*CONSTCOND*/0) +/* + * Macro to map an IP6 multicast address to an Ethernet multicast address. + * The high-order 16 bits of the Ethernet address are statically assigned, + * and the low-order 32 bits are taken from the low end of the IP6 address. + */ +#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \ + /* struct in6_addr *ip6addr; */ \ + /* uint8_t enaddr[ETHER_ADDR_LEN]; */ \ +{ \ + (enaddr)[0] = 0x33; \ + (enaddr)[1] = 0x33; \ + (enaddr)[2] = ((const uint8_t *)ip6addr)[12]; \ + (enaddr)[3] = ((const uint8_t *)ip6addr)[13]; \ + (enaddr)[4] = ((const uint8_t *)ip6addr)[14]; \ + (enaddr)[5] = ((const uint8_t *)ip6addr)[15]; \ +} +#endif + +struct mii_data; + +struct ethercom; + +typedef int (*ether_cb_t)(struct ethercom *); + +#ifndef __minix +/* + * Structure shared between the ethernet driver modules and + * the multicast list code. For example, each ec_softc or il_softc + * begins with this structure. + */ +struct ethercom { + struct ifnet ec_if; /* network-visible interface */ + LIST_HEAD(, ether_multi) ec_multiaddrs; /* list of ether multicast + addrs */ + int ec_multicnt; /* length of ec_multiaddrs + list */ + int ec_capabilities; /* capabilities, provided by + driver */ + int ec_capenable; /* tells hardware which + capabilities to enable */ + + int ec_nvlans; /* # VLANs on this interface */ + /* The device handle for the MII bus child device. */ + struct mii_data *ec_mii; + /* Called after a change to ec_if.if_flags. Returns + * ENETRESET if the device should be reinitialized with + * ec_if.if_init, 0 on success, not 0 on failure. + */ + ether_cb_t ec_ifflags_cb; +#ifdef MBUFTRACE + struct mowner ec_rx_mowner; /* mbufs received */ + struct mowner ec_tx_mowner; /* mbufs transmitted */ +#endif +}; +#endif + +#define ETHERCAP_VLAN_MTU 0x00000001 /* VLAN-compatible MTU */ +#define ETHERCAP_VLAN_HWTAGGING 0x00000002 /* hardware VLAN tag support */ +#define ETHERCAP_JUMBO_MTU 0x00000004 /* 9000 byte MTU supported */ + +#ifdef _KERNEL +extern const uint8_t etherbroadcastaddr[ETHER_ADDR_LEN]; +extern const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN]; +extern const uint8_t ether_ipmulticast_min[ETHER_ADDR_LEN]; +extern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN]; + +void ether_set_ifflags_cb(struct ethercom *, ether_cb_t); +int ether_ioctl(struct ifnet *, u_long, void *); +int ether_addmulti(const struct sockaddr *, struct ethercom *); +int ether_delmulti(const struct sockaddr *, struct ethercom *); +int ether_multiaddr(const struct sockaddr *, uint8_t[], uint8_t[]); +#endif /* _KERNEL */ + +#ifndef __minix +/* + * Ethernet multicast address structure. There is one of these for each + * multicast address or range of multicast addresses that we are supposed + * to listen to on a particular interface. They are kept in a linked list, + * rooted in the interface's ethercom structure. + */ +struct ether_multi { + uint8_t enm_addrlo[ETHER_ADDR_LEN]; /* low or only address of range */ + uint8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */ + u_int enm_refcount; /* no. claims to this addr/range */ + LIST_ENTRY(ether_multi) enm_list; +}; +#endif + +/* + * Structure used by macros below to remember position when stepping through + * all of the ether_multi records. + */ +struct ether_multistep { + struct ether_multi *e_enm; +}; + +/* + * Macro for looking up the ether_multi record for a given range of Ethernet + * multicast addresses connected to a given ethercom structure. If no matching + * record is found, "enm" returns NULL. + */ +#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm) \ + /* uint8_t addrlo[ETHER_ADDR_LEN]; */ \ + /* uint8_t addrhi[ETHER_ADDR_LEN]; */ \ + /* struct ethercom *ec; */ \ + /* struct ether_multi *enm; */ \ +{ \ + for ((enm) = LIST_FIRST(&(ec)->ec_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)); \ +} + +/* + * Macro to step through all of the ether_multi records, one at a time. + * The current position is remembered in "step", which the caller must + * provide. ETHER_FIRST_MULTI(), below, must be called to initialize "step" + * and get the first record. Both macros return a NULL "enm" when there + * are no remaining records. + */ +#define ETHER_NEXT_MULTI(step, enm) \ + /* struct ether_multistep step; */ \ + /* struct ether_multi *enm; */ \ +{ \ + if (((enm) = (step).e_enm) != NULL) \ + (step).e_enm = LIST_NEXT((enm), enm_list); \ +} + +#define ETHER_FIRST_MULTI(step, ec, enm) \ + /* struct ether_multistep step; */ \ + /* struct ethercom *ec; */ \ + /* struct ether_multi *enm; */ \ +{ \ + (step).e_enm = LIST_FIRST(&(ec)->ec_multiaddrs); \ + ETHER_NEXT_MULTI((step), (enm)); \ +} + +#ifdef _KERNEL + +/* + * Ethernet 802.1Q VLAN structures. + */ + +/* add VLAN tag to input/received packet */ +static inline int vlan_input_tag(struct ifnet *, struct mbuf *, u_int); +static inline int +vlan_input_tag(struct ifnet *ifp, struct mbuf *m, u_int vlanid) +{ + struct m_tag *mtag; + mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), M_NOWAIT); + if (mtag == NULL) { + ifp->if_ierrors++; + printf("%s: unable to allocate VLAN tag\n", ifp->if_xname); + m_freem(m); + return 1; + } + *(u_int *)(mtag + 1) = vlanid; + m_tag_prepend(m, mtag); + return 0; +} + +#define VLAN_INPUT_TAG(ifp, m, vlanid, _errcase) \ + if (vlan_input_tag(ifp, m, vlanid) != 0) { \ + _errcase; \ + } + +/* extract VLAN tag from output/trasmit packet */ +#define VLAN_OUTPUT_TAG(ec, m0) \ + (VLAN_ATTACHED(ec) ? m_tag_find((m0), PACKET_TAG_VLAN, NULL) : NULL) + +/* extract VLAN ID value from a VLAN tag */ +#define VLAN_TAG_VALUE(mtag) \ + ((*(u_int *)(mtag + 1)) & 4095) + +/* test if any VLAN is configured for this interface */ +#define VLAN_ATTACHED(ec) ((ec)->ec_nvlans > 0) + +void ether_ifattach(struct ifnet *, const uint8_t *); +void ether_ifdetach(struct ifnet *); +int ether_mediachange(struct ifnet *); +void ether_mediastatus(struct ifnet *, struct ifmediareq *); + +char *ether_sprintf(const uint8_t *); +char *ether_snprintf(char *, size_t, const uint8_t *); + +uint32_t ether_crc32_le(const uint8_t *, size_t); +uint32_t ether_crc32_be(const uint8_t *, size_t); + +int ether_aton_r(u_char *, size_t, const char *); +#else /* * Prototype ethers(3) functions. */ @@ -105,5 +337,8 @@ int ether_ntohost(char *, const struct ether_addr *); int ether_hostton(const char *, struct ether_addr *); int ether_line(const char *, struct ether_addr *, char *); __END_DECLS +#endif + +#endif /* _STANDALONE */ #endif /* !_NET_IF_ETHER_H_ */