]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/ip6.h
MF11 r352638,r358076: correct Clang and lld version checks
[FreeBSD/FreeBSD.git] / sys / netinet / ip6.h
1 /*      $FreeBSD$       */
2 /*      $KAME: ip6.h,v 1.18 2001/03/29 05:34:30 itojun Exp $    */
3
4 /*-
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 /*-
34  * Copyright (c) 1982, 1986, 1993
35  *      The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 4. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *      @(#)ip.h        8.1 (Berkeley) 6/10/93
62  */
63
64 #ifndef _NETINET_IP6_H_
65 #define _NETINET_IP6_H_
66
67 /*
68  * Definition for internet protocol version 6.
69  * RFC 2460
70  */
71
72 struct ip6_hdr {
73         union {
74                 struct ip6_hdrctl {
75                         u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
76                         u_int16_t ip6_un1_plen; /* payload length */
77                         u_int8_t  ip6_un1_nxt;  /* next header */
78                         u_int8_t  ip6_un1_hlim; /* hop limit */
79                 } ip6_un1;
80                 u_int8_t ip6_un2_vfc;   /* 4 bits version, top 4 bits class */
81         } ip6_ctlun;
82         struct in6_addr ip6_src;        /* source address */
83         struct in6_addr ip6_dst;        /* destination address */
84 } __packed;
85
86 #define ip6_vfc         ip6_ctlun.ip6_un2_vfc
87 #define ip6_flow        ip6_ctlun.ip6_un1.ip6_un1_flow
88 #define ip6_plen        ip6_ctlun.ip6_un1.ip6_un1_plen
89 #define ip6_nxt         ip6_ctlun.ip6_un1.ip6_un1_nxt
90 #define ip6_hlim        ip6_ctlun.ip6_un1.ip6_un1_hlim
91 #define ip6_hops        ip6_ctlun.ip6_un1.ip6_un1_hlim
92
93 #define IPV6_VERSION            0x60
94 #define IPV6_VERSION_MASK       0xf0
95
96 #if BYTE_ORDER == BIG_ENDIAN
97 #define IPV6_FLOWINFO_MASK      0x0fffffff      /* flow info (28 bits) */
98 #define IPV6_FLOWLABEL_MASK     0x000fffff      /* flow label (20 bits) */
99 #else
100 #if BYTE_ORDER == LITTLE_ENDIAN
101 #define IPV6_FLOWINFO_MASK      0xffffff0f      /* flow info (28 bits) */
102 #define IPV6_FLOWLABEL_MASK     0xffff0f00      /* flow label (20 bits) */
103 #endif /* LITTLE_ENDIAN */
104 #endif
105 #define IPV6_FLOWLABEL_LEN      20
106 #if 1
107 /* ECN bits proposed by Sally Floyd */
108 #define IP6TOS_CE               0x01    /* congestion experienced */
109 #define IP6TOS_ECT              0x02    /* ECN-capable transport */
110 #endif
111
112 /*
113  * Extension Headers
114  */
115
116 struct  ip6_ext {
117         u_int8_t ip6e_nxt;
118         u_int8_t ip6e_len;
119 } __packed;
120
121 /* Hop-by-Hop options header */
122 /* XXX should we pad it to force alignment on an 8-byte boundary? */
123 struct ip6_hbh {
124         u_int8_t ip6h_nxt;      /* next header */
125         u_int8_t ip6h_len;      /* length in units of 8 octets */
126         /* followed by options */
127 } __packed;
128
129 /* Destination options header */
130 /* XXX should we pad it to force alignment on an 8-byte boundary? */
131 struct ip6_dest {
132         u_int8_t ip6d_nxt;      /* next header */
133         u_int8_t ip6d_len;      /* length in units of 8 octets */
134         /* followed by options */
135 } __packed;
136
137 /* Option types and related macros */
138 #define IP6OPT_PAD1             0x00    /* 00 0 00000 */
139 #define IP6OPT_PADN             0x01    /* 00 0 00001 */
140 #define IP6OPT_JUMBO            0xC2    /* 11 0 00010 = 194 */
141 #define IP6OPT_NSAP_ADDR        0xC3    /* 11 0 00011 */
142 #define IP6OPT_TUNNEL_LIMIT     0x04    /* 00 0 00100 */
143 #ifndef _KERNEL
144 #define IP6OPT_RTALERT          0x05    /* 00 0 00101 (KAME definition) */
145 #endif
146 #define IP6OPT_ROUTER_ALERT     0x05    /* 00 0 00101 (RFC3542, recommended) */
147
148 #define IP6OPT_RTALERT_LEN      4
149 #define IP6OPT_RTALERT_MLD      0       /* Datagram contains an MLD message */
150 #define IP6OPT_RTALERT_RSVP     1       /* Datagram contains an RSVP message */
151 #define IP6OPT_RTALERT_ACTNET   2       /* contains an Active Networks msg */
152 #define IP6OPT_MINLEN           2
153
154 #define IP6OPT_EID              0x8a    /* 10 0 01010 */
155
156 #define IP6OPT_TYPE(o)          ((o) & 0xC0)
157 #define IP6OPT_TYPE_SKIP        0x00
158 #define IP6OPT_TYPE_DISCARD     0x40
159 #define IP6OPT_TYPE_FORCEICMP   0x80
160 #define IP6OPT_TYPE_ICMP        0xC0
161
162 #define IP6OPT_MUTABLE          0x20
163
164 /* IPv6 options: common part */
165 struct ip6_opt {
166         u_int8_t ip6o_type;
167         u_int8_t ip6o_len;
168 } __packed;
169
170 /* Jumbo Payload Option */
171 struct ip6_opt_jumbo {
172         u_int8_t ip6oj_type;
173         u_int8_t ip6oj_len;
174         u_int8_t ip6oj_jumbo_len[4];
175 } __packed;
176 #define IP6OPT_JUMBO_LEN        6
177
178 /* NSAP Address Option */
179 struct ip6_opt_nsap {
180         u_int8_t ip6on_type;
181         u_int8_t ip6on_len;
182         u_int8_t ip6on_src_nsap_len;
183         u_int8_t ip6on_dst_nsap_len;
184         /* followed by source NSAP */
185         /* followed by destination NSAP */
186 } __packed;
187
188 /* Tunnel Limit Option */
189 struct ip6_opt_tunnel {
190         u_int8_t ip6ot_type;
191         u_int8_t ip6ot_len;
192         u_int8_t ip6ot_encap_limit;
193 } __packed;
194
195 /* Router Alert Option */
196 struct ip6_opt_router {
197         u_int8_t ip6or_type;
198         u_int8_t ip6or_len;
199         u_int8_t ip6or_value[2];
200 } __packed;
201 /* Router alert values (in network byte order) */
202 #if BYTE_ORDER == BIG_ENDIAN
203 #define IP6_ALERT_MLD   0x0000
204 #define IP6_ALERT_RSVP  0x0001
205 #define IP6_ALERT_AN    0x0002
206 #else
207 #if BYTE_ORDER == LITTLE_ENDIAN
208 #define IP6_ALERT_MLD   0x0000
209 #define IP6_ALERT_RSVP  0x0100
210 #define IP6_ALERT_AN    0x0200
211 #endif /* LITTLE_ENDIAN */
212 #endif
213
214 /* Routing header */
215 struct ip6_rthdr {
216         u_int8_t  ip6r_nxt;     /* next header */
217         u_int8_t  ip6r_len;     /* length in units of 8 octets */
218         u_int8_t  ip6r_type;    /* routing type */
219         u_int8_t  ip6r_segleft; /* segments left */
220         /* followed by routing type specific data */
221 } __packed;
222
223 /* Type 0 Routing header, deprecated by RFC 5095. */
224 struct ip6_rthdr0 {
225         u_int8_t  ip6r0_nxt;            /* next header */
226         u_int8_t  ip6r0_len;            /* length in units of 8 octets */
227         u_int8_t  ip6r0_type;           /* always zero */
228         u_int8_t  ip6r0_segleft;        /* segments left */
229         u_int32_t  ip6r0_reserved;      /* reserved field */
230         /* followed by up to 127 struct in6_addr */
231 } __packed;
232
233 /* Fragment header */
234 struct ip6_frag {
235         u_int8_t  ip6f_nxt;             /* next header */
236         u_int8_t  ip6f_reserved;        /* reserved field */
237         u_int16_t ip6f_offlg;           /* offset, reserved, and flag */
238         u_int32_t ip6f_ident;           /* identification */
239 } __packed;
240
241 #if BYTE_ORDER == BIG_ENDIAN
242 #define IP6F_OFF_MASK           0xfff8  /* mask out offset from _offlg */
243 #define IP6F_RESERVED_MASK      0x0006  /* reserved bits in ip6f_offlg */
244 #define IP6F_MORE_FRAG          0x0001  /* more-fragments flag */
245 #else /* BYTE_ORDER == LITTLE_ENDIAN */
246 #define IP6F_OFF_MASK           0xf8ff  /* mask out offset from _offlg */
247 #define IP6F_RESERVED_MASK      0x0600  /* reserved bits in ip6f_offlg */
248 #define IP6F_MORE_FRAG          0x0100  /* more-fragments flag */
249 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
250
251 /*
252  * Internet implementation parameters.
253  */
254 #define IPV6_MAXHLIM    255     /* maximum hoplimit */
255 #define IPV6_DEFHLIM    64      /* default hlim */
256 #define IPV6_FRAGTTL    120     /* ttl for fragment packets, in slowtimo tick */
257 #define IPV6_HLIMDEC    1       /* subtracted when forwarding */
258
259 #define IPV6_MMTU       1280    /* minimal MTU and reassembly. 1024 + 256 */
260 #define IPV6_MAXPACKET  65535   /* ip6 max packet size without Jumbo payload*/
261 #define IPV6_MAXOPTHDR  2048    /* max option header size, 256 64-bit words */
262
263 #ifdef _KERNEL
264 /*
265  * IP6_EXTHDR_CHECK ensures that region between the IP6 header and the
266  * target header (including IPv6 itself, extension headers and
267  * TCP/UDP/ICMP6 headers) are contiguous. KAME requires drivers
268  * to store incoming data into one internal mbuf or one or more external
269  * mbufs(never into two or more internal mbufs). Thus, the third case is
270  * supposed to never be matched but is prepared just in case.
271  */
272
273 #define IP6_EXTHDR_CHECK(m, off, hlen, ret)                             \
274 do {                                                                    \
275     if ((m)->m_next != NULL) {                                          \
276         if (((m)->m_flags & M_LOOP) &&                                  \
277             ((m)->m_len < (off) + (hlen)) &&                            \
278             (((m) = m_pullup((m), (off) + (hlen))) == NULL)) {          \
279                 IP6STAT_INC(ip6s_exthdrtoolong);                                \
280                 return ret;                                             \
281         } else {                                                        \
282                 if ((m)->m_len < (off) + (hlen)) {                      \
283                         IP6STAT_INC(ip6s_exthdrtoolong);                        \
284                         m_freem(m);                                     \
285                         return ret;                                     \
286                 }                                                       \
287         }                                                               \
288     } else {                                                            \
289         if ((m)->m_len < (off) + (hlen)) {                              \
290                 IP6STAT_INC(ip6s_tooshort);                             \
291                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);   \
292                 m_freem(m);                                             \
293                 return ret;                                             \
294         }                                                               \
295     }                                                                   \
296 } while (/*CONSTCOND*/ 0)
297
298 /*
299  * IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
300  * "len") is located in single mbuf, on contiguous memory region.
301  * The pointer to the region will be returned to pointer variable "val",
302  * with type "typ".
303  * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
304  * very top of mbuf.  GET0 is likely to make memory copy than GET.
305  *
306  * XXX we're now testing this, needs m_pulldown()
307  */
308 #define IP6_EXTHDR_GET(val, typ, m, off, len) \
309 do {                                                                    \
310         struct mbuf *t;                                                 \
311         int tmp;                                                        \
312         if ((m)->m_len >= (off) + (len))                                \
313                 (val) = (typ)(mtod((m), caddr_t) + (off));              \
314         else {                                                          \
315                 t = m_pulldown((m), (off), (len), &tmp);                \
316                 if (t) {                                                \
317                         if (t->m_len < tmp + (len))                     \
318                                 panic("m_pulldown malfunction");        \
319                         (val) = (typ)(mtod(t, caddr_t) + tmp);          \
320                 } else {                                                \
321                         (val) = (typ)NULL;                              \
322                         (m) = NULL;                                     \
323                 }                                                       \
324         }                                                               \
325 } while (/*CONSTCOND*/ 0)
326
327 #define IP6_EXTHDR_GET0(val, typ, m, off, len) \
328 do {                                                                    \
329         struct mbuf *t;                                                 \
330         if ((off) == 0)                                                 \
331                 (val) = (typ)mtod(m, caddr_t);                          \
332         else {                                                          \
333                 t = m_pulldown((m), (off), (len), NULL);                \
334                 if (t) {                                                \
335                         if (t->m_len < (len))                           \
336                                 panic("m_pulldown malfunction");        \
337                         (val) = (typ)mtod(t, caddr_t);                  \
338                 } else {                                                \
339                         (val) = (typ)NULL;                              \
340                         (m) = NULL;                                     \
341                 }                                                       \
342         }                                                               \
343 } while (/*CONSTCOND*/ 0)
344
345 #endif /*_KERNEL*/
346
347 #endif /* not _NETINET_IP6_H_ */