libc: Bring in getdate() from NetBSD for POSIX conformance.
[dragonfly.git] / lib / libstand / if_ether.h
1 /*      $NetBSD: if_ether.h,v 1.25 1997/01/17 17:06:06 mikel 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  * $FreeBSD: src/lib/libstand/if_ether.h,v 1.1.1.1.6.1 2000/09/20 09:49:17 jkh Exp $
34  * $DragonFly: src/lib/libstand/if_ether.h,v 1.2 2003/06/17 04:26:51 dillon Exp $
35  */
36
37 /*
38  * Ethernet address - 6 octets
39  * this is only used by the ethers(3) functions.
40  */
41 struct ether_addr {
42         u_int8_t ether_addr_octet[6];
43 };
44
45 /*
46  * Structure of a 10Mb/s Ethernet header.
47  */
48 #define ETHER_ADDR_LEN  6
49
50 struct  ether_header {
51         u_int8_t  ether_dhost[ETHER_ADDR_LEN];
52         u_int8_t  ether_shost[ETHER_ADDR_LEN];
53         u_int16_t ether_type;
54 };
55
56 #define ETHERTYPE_PUP           0x0200  /* PUP protocol */
57 #define ETHERTYPE_IP            0x0800  /* IP protocol */
58 #define ETHERTYPE_ARP           0x0806  /* address resolution protocol */
59 #define ETHERTYPE_REVARP        0x8035  /* reverse addr resolution protocol */
60
61 /*
62  * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
63  * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
64  * by an ETHER type (as given above) and then the (variable-length) header.
65  */
66 #define ETHERTYPE_TRAIL         0x1000          /* Trailer packet */
67 #define ETHERTYPE_NTRAILER      16
68
69 #define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
70
71 #define ETHERMTU        1500
72 #define ETHERMIN        (60-14)
73
74 #ifdef _KERNEL
75 /*
76  * Macro to map an IP multicast address to an Ethernet multicast address.
77  * The high-order 25 bits of the Ethernet address are statically assigned,
78  * and the low-order 23 bits are taken from the low end of the IP address.
79  */
80 #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr)                          \
81         /* struct in_addr *ipaddr; */                                   \
82         /* u_int8_t enaddr[ETHER_ADDR_LEN]; */                          \
83 {                                                                       \
84         (enaddr)[0] = 0x01;                                             \
85         (enaddr)[1] = 0x00;                                             \
86         (enaddr)[2] = 0x5e;                                             \
87         (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f;                   \
88         (enaddr)[4] = ((u_int8_t *)ipaddr)[2];                          \
89         (enaddr)[5] = ((u_int8_t *)ipaddr)[3];                          \
90 }
91 #endif
92
93 /*
94  * Ethernet Address Resolution Protocol.
95  *
96  * See RFC 826 for protocol description.  Structure below is adapted
97  * to resolving internet addresses.  Field names used correspond to 
98  * RFC 826.
99  */
100 struct  ether_arp {
101         struct   arphdr ea_hdr;                 /* fixed-size header */
102         u_int8_t arp_sha[ETHER_ADDR_LEN];       /* sender hardware address */
103         u_int8_t arp_spa[4];                    /* sender protocol address */
104         u_int8_t arp_tha[ETHER_ADDR_LEN];       /* target hardware address */
105         u_int8_t arp_tpa[4];                    /* target protocol address */
106 };
107 #define arp_hrd ea_hdr.ar_hrd
108 #define arp_pro ea_hdr.ar_pro
109 #define arp_hln ea_hdr.ar_hln
110 #define arp_pln ea_hdr.ar_pln
111 #define arp_op  ea_hdr.ar_op
112
113 /*
114  * Structure shared between the ethernet driver modules and
115  * the address resolution code.  For example, each ec_softc or il_softc
116  * begins with this structure.
117  */
118 struct  arpcom {
119         struct   ifnet ac_if;                   /* network-visible interface */
120         u_int8_t ac_enaddr[ETHER_ADDR_LEN];     /* ethernet hardware address */
121         char     ac__pad[2];                    /* be nice to m68k ports */
122         LIST_HEAD(, ether_multi) ac_multiaddrs; /* list of ether multicast addrs */
123         int      ac_multicnt;                   /* length of ac_multiaddrs list */
124 };
125
126 struct llinfo_arp {
127         LIST_ENTRY(llinfo_arp) la_list;
128         struct  rtentry *la_rt;
129         struct  mbuf *la_hold;          /* last packet until resolved/timeout */
130         long    la_asked;               /* last time we QUERIED for this addr */
131 #define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
132 };
133
134 struct sockaddr_inarp {
135         u_int8_t  sin_len;
136         u_int8_t  sin_family;
137         u_int16_t sin_port;
138         struct    in_addr sin_addr;
139         struct    in_addr sin_srcaddr;
140         u_int16_t sin_tos;
141         u_int16_t sin_other;
142 #define SIN_PROXY 1
143 };
144
145 /*
146  * IP and ethernet specific routing flags
147  */
148 #define RTF_USETRAILERS RTF_PROTO1      /* use trailers */
149 #define RTF_ANNOUNCE    RTF_PROTO2      /* announce new arp entry */
150
151 #ifdef  _KERNEL
152 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
153 u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
154 u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
155 struct  ifqueue arpintrq;
156
157 void    arpwhohas(struct arpcom *, struct in_addr *);
158 void    arpintr(void);
159 int     arpresolve(struct arpcom *,
160             struct rtentry *, struct mbuf *, struct sockaddr *, u_char *);
161 void    arp_ifinit(struct arpcom *, struct ifaddr *);
162 void    arp_rtrequest(int, struct rtentry *, struct sockaddr *);
163
164 int     ether_addmulti(struct ifreq *, struct arpcom *);
165 int     ether_delmulti(struct ifreq *, struct arpcom *);
166 #endif /* _KERNEL */
167
168 /*
169  * Ethernet multicast address structure.  There is one of these for each
170  * multicast address or range of multicast addresses that we are supposed
171  * to listen to on a particular interface.  They are kept in a linked list,
172  * rooted in the interface's arpcom structure.  (This really has nothing to
173  * do with ARP, or with the Internet address family, but this appears to be
174  * the minimally-disrupting place to put it.)
175  */
176 struct ether_multi {
177         u_int8_t enm_addrlo[ETHER_ADDR_LEN]; /* low  or only address of range */
178         u_int8_t enm_addrhi[ETHER_ADDR_LEN]; /* high or only address of range */
179         struct   arpcom *enm_ac;        /* back pointer to arpcom */
180         u_int    enm_refcount;          /* no. claims to this addr/range */
181         LIST_ENTRY(ether_multi) enm_list;
182 };
183
184 /*
185  * Structure used by macros below to remember position when stepping through
186  * all of the ether_multi records.
187  */
188 struct ether_multistep {
189         struct ether_multi  *e_enm;
190 };
191
192 /*
193  * Macro for looking up the ether_multi record for a given range of Ethernet
194  * multicast addresses connected to a given arpcom structure.  If no matching
195  * record is found, "enm" returns NULL.
196  */
197 #define ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm)                     \
198         /* u_int8_t addrlo[ETHER_ADDR_LEN]; */                          \
199         /* u_int8_t addrhi[ETHER_ADDR_LEN]; */                          \
200         /* struct arpcom *ac; */                                        \
201         /* struct ether_multi *enm; */                                  \
202 {                                                                       \
203         for ((enm) = (ac)->ac_multiaddrs.lh_first;                      \
204             (enm) != NULL &&                                            \
205             (bcmp((enm)->enm_addrlo, (addrlo), ETHER_ADDR_LEN) != 0 ||  \
206              bcmp((enm)->enm_addrhi, (addrhi), ETHER_ADDR_LEN) != 0);   \
207                 (enm) = (enm)->enm_list.le_next);                       \
208 }
209
210 /*
211  * Macro to step through all of the ether_multi records, one at a time.
212  * The current position is remembered in "step", which the caller must
213  * provide.  ETHER_FIRST_MULTI(), below, must be called to initialize "step"
214  * and get the first record.  Both macros return a NULL "enm" when there
215  * are no remaining records.
216  */
217 #define ETHER_NEXT_MULTI(step, enm) \
218         /* struct ether_multistep step; */  \
219         /* struct ether_multi *enm; */  \
220 { \
221         if (((enm) = (step).e_enm) != NULL) \
222                 (step).e_enm = (enm)->enm_list.le_next; \
223 }
224
225 #define ETHER_FIRST_MULTI(step, ac, enm) \
226         /* struct ether_multistep step; */ \
227         /* struct arpcom *ac; */ \
228         /* struct ether_multi *enm; */ \
229 { \
230         (step).e_enm = (ac)->ac_multiaddrs.lh_first; \
231         ETHER_NEXT_MULTI((step), (enm)); \
232 }
233
234 #ifdef _KERNEL
235 void arp_rtrequest(int, struct rtentry *, struct sockaddr *);
236 int arpresolve(struct arpcom *, struct rtentry *, struct mbuf *,
237                     struct sockaddr *, u_char *);
238 void arpintr(void);
239 int arpioctl(u_long, caddr_t);
240 void arp_ifinit(struct arpcom *, struct ifaddr *);
241 void revarpinput(struct mbuf *);
242 void in_revarpinput(struct mbuf *);
243 void revarprequest(struct ifnet *);
244 int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
245 int revarpwhoami(struct in_addr *, struct ifnet *);
246 int db_show_arptab(void);
247 #endif
248
249 /*
250  * Prototype ethers(3) functions.
251  */
252 #ifndef _KERNEL
253 #include <sys/cdefs.h>
254 __BEGIN_DECLS
255 char *  ether_ntoa(struct ether_addr *);
256 struct ether_addr *
257         ether_aton(char *);
258 int     ether_ntohost(char *, struct ether_addr *);
259 int     ether_hostton(char *, struct ether_addr *);
260 int     ether_line(char *, struct ether_addr *, char *);
261 __END_DECLS
262 #endif