Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / net / if_ether.h @ 13

History | View | Annotate | Download (11.8 KB)

1
/*        $NetBSD: if_ether.h,v 1.64 2014/07/28 14:24:48 ozaki-r Exp $        */
2

    
3
/*
4
 * Copyright (c) 1982, 1986, 1993
5
 *        The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 * 3. Neither the name of the University nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 *
31
 *        @(#)if_ether.h        8.1 (Berkeley) 6/10/93
32
 */
33

    
34
#ifndef _NET_IF_ETHER_H_
35
#define _NET_IF_ETHER_H_
36

    
37
#ifdef _KERNEL
38
#ifdef _KERNEL_OPT
39
#include "opt_mbuftrace.h"
40
#endif
41
#include <sys/mbuf.h>
42
#endif
43

    
44
#ifndef _STANDALONE
45
#include <net/if.h>
46
#endif
47

    
48
/*
49
 * Some basic Ethernet constants.
50
 */
51
#define        ETHER_ADDR_LEN        6        /* length of an Ethernet address */
52
#define        ETHER_TYPE_LEN        2        /* length of the Ethernet type field */
53
#define        ETHER_CRC_LEN        4        /* length of the Ethernet CRC */
54
#define        ETHER_HDR_LEN        ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
55
#define        ETHER_MIN_LEN        64        /* minimum frame length, including CRC */
56
#define        ETHER_MAX_LEN        1518        /* maximum frame length, including CRC */
57
#define        ETHER_MAX_LEN_JUMBO 9018 /* maximum jumbo frame len, including CRC */
58

    
59
/*
60
 * Some Ethernet extensions.
61
 */
62
#define        ETHER_VLAN_ENCAP_LEN 4        /* length of 802.1Q VLAN encapsulation */
63
#define        ETHER_PPPOE_ENCAP_LEN 8        /* length of PPPoE encapsulation */
64

    
65
/*
66
 * Ethernet address - 6 octets
67
 * this is only used by the ethers(3) functions.
68
 */
69
struct ether_addr {
70
        uint8_t ether_addr_octet[ETHER_ADDR_LEN];
71
} __packed;
72

    
73
#if defined(__minix)
74
#define ea_addr ether_addr_octet
75
typedef struct ether_addr ether_addr_t;
76
#endif /* defined(__minix) */
77

    
78
/*
79
 * Structure of a 10Mb/s Ethernet header.
80
 */
81
struct ether_header {
82
        uint8_t  ether_dhost[ETHER_ADDR_LEN];
83
        uint8_t  ether_shost[ETHER_ADDR_LEN];
84
        uint16_t ether_type;
85
} __packed;
86

    
87
#include <net/ethertypes.h>
88

    
89
#define        ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
90
#define        ETHER_IS_LOCAL(addr) (*(addr) & 0x02) /* is address local? */
91

    
92
#define        ETHERMTU_JUMBO        (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
93
#define        ETHERMTU        (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
94
#define        ETHERMIN        (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
95

    
96
/*
97
 * Compute the maximum frame size based on ethertype (i.e. possible
98
 * encapsulation) and whether or not an FCS is present.
99
 */
100
#define        ETHER_MAX_FRAME(ifp, etype, hasfcs)                                \
101
        ((ifp)->if_mtu + ETHER_HDR_LEN +                                \
102
         ((hasfcs) ? ETHER_CRC_LEN : 0) +                                \
103
         (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0) +        \
104
         (((etype) == ETHERTYPE_PPPOE) ? ETHER_PPPOE_ENCAP_LEN : 0))
105

    
106
/*
107
 * Ethernet CRC32 polynomials (big- and little-endian verions).
108
 */
109
#define        ETHER_CRC_POLY_LE        0xedb88320
110
#define        ETHER_CRC_POLY_BE        0x04c11db6
111

    
112
#ifndef _STANDALONE
113

    
114
/*
115
 * Ethernet-specific mbuf flags.
116
 */
117
#define        M_HASFCS        M_LINK0        /* FCS included at end of frame */
118
#define        M_PROMISC        M_LINK1        /* this packet is not for us */
119

    
120
#ifdef _KERNEL
121
/*
122
 * Macro to map an IP multicast address to an Ethernet multicast address.
123
 * The high-order 25 bits of the Ethernet address are statically assigned,
124
 * and the low-order 23 bits are taken from the low end of the IP address.
125
 */
126
#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr)                                \
127
        /* const struct in_addr *ipaddr; */                                \
128
        /* uint8_t enaddr[ETHER_ADDR_LEN]; */                                \
129
do {                                                                        \
130
        (enaddr)[0] = 0x01;                                                \
131
        (enaddr)[1] = 0x00;                                                \
132
        (enaddr)[2] = 0x5e;                                                \
133
        (enaddr)[3] = ((const uint8_t *)ipaddr)[1] & 0x7f;                \
134
        (enaddr)[4] = ((const uint8_t *)ipaddr)[2];                        \
135
        (enaddr)[5] = ((const uint8_t *)ipaddr)[3];                        \
136
} while (/*CONSTCOND*/0)
137
/*
138
 * Macro to map an IP6 multicast address to an Ethernet multicast address.
139
 * The high-order 16 bits of the Ethernet address are statically assigned,
140
 * and the low-order 32 bits are taken from the low end of the IP6 address.
141
 */
142
#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr)                        \
143
        /* struct in6_addr *ip6addr; */                                        \
144
        /* uint8_t enaddr[ETHER_ADDR_LEN]; */                                \
145
{                                                                       \
146
        (enaddr)[0] = 0x33;                                                \
147
        (enaddr)[1] = 0x33;                                                \
148
        (enaddr)[2] = ((const uint8_t *)ip6addr)[12];                        \
149
        (enaddr)[3] = ((const uint8_t *)ip6addr)[13];                        \
150
        (enaddr)[4] = ((const uint8_t *)ip6addr)[14];                        \
151
        (enaddr)[5] = ((const uint8_t *)ip6addr)[15];                        \
152
}
153
#endif
154

    
155
struct mii_data;
156

    
157
struct ethercom;
158

    
159
typedef int (*ether_cb_t)(struct ethercom *);
160

    
161
/*
162
 * Structure shared between the ethernet driver modules and
163
 * the multicast list code.  For example, each ec_softc or il_softc
164
 * begins with this structure.
165
 */
166
struct ethercom {
167
        struct        ifnet ec_if;                        /* network-visible interface */
168
        LIST_HEAD(, ether_multi) ec_multiaddrs;        /* list of ether multicast
169
                                                   addrs */
170
        int        ec_multicnt;                        /* length of ec_multiaddrs
171
                                                   list */
172
        int        ec_capabilities;                /* capabilities, provided by
173
                                                   driver */
174
        int        ec_capenable;                        /* tells hardware which
175
                                                   capabilities to enable */
176

    
177
        int        ec_nvlans;                        /* # VLANs on this interface */
178
        /* The device handle for the MII bus child device. */
179
        struct mii_data                                *ec_mii;
180
        /* Called after a change to ec_if.if_flags.  Returns
181
         * ENETRESET if the device should be reinitialized with
182
         * ec_if.if_init, 0 on success, not 0 on failure.
183
         */
184
        ether_cb_t                                ec_ifflags_cb;
185
#ifdef MBUFTRACE
186
        struct        mowner ec_rx_mowner;                /* mbufs received */
187
        struct        mowner ec_tx_mowner;                /* mbufs transmitted */
188
#endif
189
};
190

    
191
#define        ETHERCAP_VLAN_MTU        0x00000001        /* VLAN-compatible MTU */
192
#define        ETHERCAP_VLAN_HWTAGGING        0x00000002        /* hardware VLAN tag support */
193
#define        ETHERCAP_JUMBO_MTU        0x00000004        /* 9000 byte MTU supported */
194
#define        ETHERCAP_MASK                0x00000007
195

    
196
#define        ECCAPBITS                \
197
        "\020"                        \
198
        "\1VLAN_MTU"                \
199
        "\2VLAN_HWTAGGING"        \
200
        "\3JUMBO_MTU"
201

    
202
/* ioctl() for Ethernet capabilities */
203
struct eccapreq {
204
        char                eccr_name[IFNAMSIZ];        /* if name, e.g. "en0" */
205
        int                eccr_capabilities;        /* supported capabiliites */
206
        int                eccr_capenable;                /* capabilities enabled */
207
};
208

    
209
#ifdef        _KERNEL
210
extern const uint8_t etherbroadcastaddr[ETHER_ADDR_LEN];
211
extern const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN];
212
extern const uint8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
213
extern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
214

    
215
void        ether_set_ifflags_cb(struct ethercom *, ether_cb_t);
216
int        ether_ioctl(struct ifnet *, u_long, void *);
217
int        ether_addmulti(const struct sockaddr *, struct ethercom *);
218
int        ether_delmulti(const struct sockaddr *, struct ethercom *);
219
int        ether_multiaddr(const struct sockaddr *, uint8_t[], uint8_t[]);
220
void    ether_input(struct ifnet *, struct mbuf *);
221
#endif /* _KERNEL */
222

    
223
/*
224
 * Ethernet multicast address structure.  There is one of these for each
225
 * multicast address or range of multicast addresses that we are supposed
226
 * to listen to on a particular interface.  They are kept in a linked list,
227
 * rooted in the interface's ethercom structure.
228
 */
229
struct ether_multi {
230
        uint8_t enm_addrlo[ETHER_ADDR_LEN]; /* low  or only address of range */
231
        uint8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */
232
        u_int         enm_refcount;                /* no. claims to this addr/range */
233
        LIST_ENTRY(ether_multi) enm_list;
234
};
235

    
236
struct ether_multi_sysctl {
237
        u_int   enm_refcount;
238
        uint8_t enm_addrlo[ETHER_ADDR_LEN];
239
        uint8_t enm_addrhi[ETHER_ADDR_LEN];
240
};
241

    
242
/*
243
 * Structure used by macros below to remember position when stepping through
244
 * all of the ether_multi records.
245
 */
246
struct ether_multistep {
247
        struct ether_multi  *e_enm;
248
};
249

    
250
/*
251
 * Macro for looking up the ether_multi record for a given range of Ethernet
252
 * multicast addresses connected to a given ethercom structure.  If no matching
253
 * record is found, "enm" returns NULL.
254
 */
255
#define ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm)                        \
256
        /* uint8_t addrlo[ETHER_ADDR_LEN]; */                                \
257
        /* uint8_t addrhi[ETHER_ADDR_LEN]; */                                \
258
        /* struct ethercom *ec; */                                        \
259
        /* struct ether_multi *enm; */                                        \
260
{                                                                        \
261
        for ((enm) = LIST_FIRST(&(ec)->ec_multiaddrs);                        \
262
            (enm) != NULL &&                                                \
263
            (memcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 ||        \
264
             memcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0);        \
265
                (enm) = LIST_NEXT((enm), enm_list));                        \
266
}
267

    
268
/*
269
 * Macro to step through all of the ether_multi records, one at a time.
270
 * The current position is remembered in "step", which the caller must
271
 * provide.  ETHER_FIRST_MULTI(), below, must be called to initialize "step"
272
 * and get the first record.  Both macros return a NULL "enm" when there
273
 * are no remaining records.
274
 */
275
#define ETHER_NEXT_MULTI(step, enm) \
276
        /* struct ether_multistep step; */  \
277
        /* struct ether_multi *enm; */  \
278
{ \
279
        if (((enm) = (step).e_enm) != NULL) \
280
                (step).e_enm = LIST_NEXT((enm), enm_list); \
281
}
282

    
283
#define ETHER_FIRST_MULTI(step, ec, enm) \
284
        /* struct ether_multistep step; */ \
285
        /* struct ethercom *ec; */ \
286
        /* struct ether_multi *enm; */ \
287
{ \
288
        (step).e_enm = LIST_FIRST(&(ec)->ec_multiaddrs); \
289
        ETHER_NEXT_MULTI((step), (enm)); \
290
}
291

    
292
#ifdef _KERNEL
293

    
294
/*
295
 * Ethernet 802.1Q VLAN structures.
296
 */
297

    
298
/* add VLAN tag to input/received packet */
299
static inline int vlan_input_tag(struct ifnet *, struct mbuf *, u_int);
300
static inline int
301
vlan_input_tag(struct ifnet *ifp, struct mbuf *m, u_int vlanid)
302
{
303
        struct m_tag *mtag;
304
        mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), M_NOWAIT);
305
        if (mtag == NULL) {
306
                ifp->if_ierrors++;
307
                printf("%s: unable to allocate VLAN tag\n", ifp->if_xname);
308
                m_freem(m);
309
                return 1;
310
        }
311
        *(u_int *)(mtag + 1) = vlanid;
312
        m_tag_prepend(m, mtag);
313
        return 0;
314
}
315

    
316
#define VLAN_INPUT_TAG(ifp, m, vlanid, _errcase)                \
317
    if (vlan_input_tag(ifp, m, vlanid) != 0) {                         \
318
        _errcase;                                                \
319
    }
320

    
321
/* extract VLAN tag from output/trasmit packet */
322
#define VLAN_OUTPUT_TAG(ec, m0)                        \
323
        (VLAN_ATTACHED(ec) ? m_tag_find((m0), PACKET_TAG_VLAN, NULL) : NULL)
324

    
325
/* extract VLAN ID value from a VLAN tag */
326
#define VLAN_TAG_VALUE(mtag)        \
327
        ((*(u_int *)(mtag + 1)) & 4095)
328

    
329
/* test if any VLAN is configured for this interface */
330
#define VLAN_ATTACHED(ec)        ((ec)->ec_nvlans > 0)
331

    
332
void        etherinit(void);
333
void        ether_ifattach(struct ifnet *, const uint8_t *);
334
void        ether_ifdetach(struct ifnet *);
335
int        ether_mediachange(struct ifnet *);
336
void        ether_mediastatus(struct ifnet *, struct ifmediareq *);
337

    
338
char        *ether_sprintf(const uint8_t *);
339
char        *ether_snprintf(char *, size_t, const uint8_t *);
340

    
341
uint32_t ether_crc32_le(const uint8_t *, size_t);
342
uint32_t ether_crc32_be(const uint8_t *, size_t);
343

    
344
int        ether_aton_r(u_char *, size_t, const char *);
345
#else
346
/*
347
 * Prototype ethers(3) functions.
348
 */
349
#include <sys/cdefs.h>
350
__BEGIN_DECLS
351
char *        ether_ntoa(const struct ether_addr *);
352
struct ether_addr *
353
        ether_aton(const char *);
354
int        ether_ntohost(char *, const struct ether_addr *);
355
int        ether_hostton(const char *, struct ether_addr *);
356
int        ether_line(const char *, struct ether_addr *, char *);
357
__END_DECLS
358
#endif
359

    
360
#endif /* _STANDALONE */
361

    
362
#endif /* !_NET_IF_ETHER_H_ */