summaryrefslogtreecommitdiff
path: root/sys/netinet6/in6.h
blob: ea47f255dfcc3e7d83e084725c61ce9a2d32b731 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/*
%%% copyright-nrl-95
This software is Copyright 1995-1998 by Randall Atkinson, Ronald Lee,
Daniel McDonald, Bao Phan, and Chris Winters. All Rights Reserved. All
rights under this copyright have been assigned to the US Naval Research
Laboratory (NRL). The NRL Copyright Notice and License Agreement Version
1.1 (January 17, 1995) applies to this software.
You should have received a copy of the license with this software. If you
didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.

*/

#ifndef _NETINET6_IN6_H
#define _NETINET6_IN6_H 1

#if !defined(_NETINET_IN_H) && !defined(_NETINET_IN_H_)
#error in6.h should no longer be included directly; include <netinet/in.h>
#endif /* !defined(_NETINET_IN_H) && !defined(_NETINET_IN_H_) */
#if __bsdi__ && !defined(_BSDI_VERSION)
#include <sys/param.h>
#endif /* __bsdi__ && !defined(_BSDI_VERSION) */

/* IPPROTO type macros. */

#define IS_PREFRAG(x)   ( (x)==IPPROTO_HOPOPTS || (x)==IPPROTO_ROUTING || \
			 (x) == IPPROTO_DSTOPTS)
#define IS_IPV6OPT(x)   ( (x)==IPPROTO_FRAGMENT || (x) == IPPROTO_AH || \
			 IS_PRFRAG(x) )

#if !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802)
struct in6_addr
{
  union 
    {
      uint8_t bytes[16];
      uint32_t words[4];
    } in6a_u;
#define in6a_words in6a_u.words
#define s6_addr in6a_u.bytes
};
#endif /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */

#if !defined(SIN6_LEN)
struct sockaddr_in6 {
#if __linux__
  uint16_t sin6_family;
#else /* __linux__ */
#define SIN6_LEN
  uint8_t sin6_len;
  uint8_t sin6_family;
#endif /* __linux__ */
  uint16_t sin6_port;
  uint32_t sin6_flowinfo;
  struct in6_addr sin6_addr;
};
#endif /* !defined(SIN6_LEN) */

#define CREATE_IPV6_MAPPED(v6, v4) { \
	v6.in6a_words[0] = 0; \
	v6.in6a_words[1] = 0; \
	v6.in6a_words[2] = htonl(0xffff); \
	v6.in6a_words[3] = v4; }

#if 0 /* defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) */
#define IN6_ARE_ADDR_EQUAL(x, y) memcmp((x), (y), sizeof(struct in6_addr))
#else /* defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) */
#define IN6_ARE_ADDR_EQUAL(x, y) ( \
        (x)->in6a_words[0] == (y)->in6a_words[0] && \
        (x)->in6a_words[1] == (y)->in6a_words[1] && \
        (x)->in6a_words[2] == (y)->in6a_words[2] && \
        (x)->in6a_words[3] == (y)->in6a_words[3])
#endif /* defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) */

#ifndef IN6_IS_ADDR_UNSPECIFIED
#define IN6_IS_ADDR_UNSPECIFIED(a) ( \
        ((a)->in6a_words[0] == 0) && \
        ((a)->in6a_words[1] == 0) && \
        ((a)->in6a_words[2] == 0) && \
        ((a)->in6a_words[3] == 0))

#define IN6_IS_ADDR_LOOPBACK(a) ( \
        ((a)->in6a_words[0] == 0) && \
        ((a)->in6a_words[1] == 0) && \
        ((a)->in6a_words[2] == 0) && \
        ((a)->in6a_words[3] == htonl(1)))

#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)

#define IN6_IS_ADDR_LINKLOCAL(a) \
        (((a)->in6a_words[0] & htonl(0xffc00000)) == htonl(0xfe800000))

#define IN6_IS_ADDR_SITELOCAL(a) \
        (((a)->in6a_words[0] & htonl(0xffc00000)) == htonl(0xfec00000))

#define IN6_IS_ADDR_V4MAPPED(a) ( \
        ((a)->in6a_words[0] == 0) && \
        ((a)->in6a_words[1] == 0) && \
        ((a)->in6a_words[2] == htonl(0xffff)))

#define IN6_IS_ADDR_V4COMPAT(a) ( \
        ((a)->in6a_words[0] == 0) && \
        ((a)->in6a_words[1] == 0) && \
        ((a)->in6a_words[2] == 0) && \
        ((a)->in6a_words[3] & htonl(0xfffffffe)))

#define IN6_IS_ADDR_MC_NODELOCAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_INTRA_NODE)

#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_INTRA_LINK)

#define IN6_IS_ADDR_MC_SITELOCAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_INTRA_SITE)

#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_INTRA_ORG)

#define IN6_IS_ADDR_MC_COMMLOCAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_INTRA_COMM)

#define IN6_IS_ADDR_MC_GLOBAL(a) \
        (GET_IN6_MCASTSCOPE(*a) == IN6_GLOBAL)
#endif /* IN6_IS_ADDR_UNSPECIFIED */

/* NOTE:  IS_IN6_ALL* macros only check the 0x1 and 0x2 scoping levels.
          The IN6 ROAD document doesn't say those are good for higher
          scoping levels.
*/

#define IN6_INTRA_NODE 1  /*  intra-node scope */
#define IN6_INTRA_LINK 2  /*  intra-link scope */
/*            3  (unassigned)
            4  (unassigned)
*/
#define IN6_INTRA_SITE 5  /* intra-site scope */
/*            6  (unassigned)
            7  (unassigned)
*/
#define IN6_INTRA_ORG  8  /* intra-organization scope */
/*            9  (unassigned)
            A  (unassigned)
*/
#define IN6_INTRA_COMM 0xB/*  intra-community scope */
/*            C  (unassigned)
            D  (unassigned)
*/

#define IN6_GLOBAL   0xE  /* global scope*/
/*            F  reserved
*/

#if BYTE_ORDER ==  BIG_ENDIAN

#define SET_IN6_ALLNODES(a)  {(a).in6a_words[0]=0xff000000;(a).in6a_words[3]=1;\
                              (a).in6a_words[1]=0;(a).in6a_words[2]=0;}
#define SET_IN6_ALLROUTERS(a)  {(a).in6a_words[0]=0xff000000;(a).in6a_words[3]=2;\
                              (a).in6a_words[1]=0;(a).in6a_words[2]=0;}

#define SET_IN6_MCASTSCOPE(a,bits) {(a).in6a_words[0]&=0xfff0ffff;\
                                    (a).in6a_words[0]|=(bits<<16);}
#define GET_IN6_MCASTSCOPE(a) ( ((a).in6a_words[0] & 0x000f0000) >> 16  )

#else   /* BYTE_ORDER == LITTLE_ENDIAN */

#define SET_IN6_ALLNODES(a)  {(a).in6a_words[0]=0xff;(a).in6a_words[3]=0x01000000;\
                              (a).in6a_words[1] = 0; (a).in6a_words[2] = 0;}
#define SET_IN6_ALLROUTERS(a)  {(a).in6a_words[0]=0xff;(a).in6a_words[3]=0x02000000;\
                              (a).in6a_words[1] = 0; (a).in6a_words[2] = 0;}

#define SET_IN6_MCASTSCOPE(a,bits) {(a).in6a_words[0]&=0xfffff0ff;\
                                    (a).in6a_words[0]|=(bits<<8);}
#define GET_IN6_MCASTSCOPE(a)  ( ((a).in6a_words[0] & 0x00000f00) >>8)

#endif  /* BYTE_ORDER == {BIG,LITTLE}_ENDIAN */

/*
 * Additonal type information.
 */

#if !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802)
struct ipv6_mreq
{
  struct in6_addr ipv6mr_multiaddr;     /* Group addr. to join/leave. */
  unsigned int ipv6mr_interface;     /* Interface on which to do it. */
};
#endif /* !defined(_BSDI_VERSION) || (_BSDI_VERSION < 199802) */

/*
 * IP options for IPv6.  Note I use the IPV6_* semantics for IPv6-
 * specific options.  Another reason for the inclusion of <netinet/in.h> is
 * for the options that are common between IPv6 and IPv4.
 */

#ifdef __linux__
#define IPV6_ADDRFORM           1
#define IPV6_PKTINFO            2
#define IPV6_HOPOPTS            3
#define IPV6_DSTOPTS            4
#define IPV6_RTHDR              5
#define IPV6_PKTOPTIONS         6
#define IPV6_CHECKSUM           7
#define IPV6_HOPLIMIT           8

#define IPV6_UNICAST_HOPS       16
#define IPV6_MULTICAST_IF       17
#define IPV6_MULTICAST_HOPS     18
#define IPV6_MULTICAST_LOOP     19
#define IPV6_ADD_MEMBERSHIP     20
#define IPV6_DROP_MEMBERSHIP    21
#else /* __linux__ */
#define	IPV6_OPTIONS		1    /* buf/ipv6_opts; set/get IP options */
#define	IPV6_HDRINCL		2    /* int; header is included with data */
#define	IPV6_TOS		3    /* int; IP type of service and preced. */
#define	IPV6_UNICAST_HOPS	4    /* int; IPv6 unicast hop limit */
#define IPV6_PKTINFO            5    /* struct in6_pktinfo: if. and addr */
#define IPV6_HOPLIMIT		6    /* int; hop limit */
#define IPV6_CHECKSUM		7    /* int: checksum offset */
#define ICMPV6_FILTER		8    /* struct icmpv6_filter: type filter */
#define	IPV6_MULTICAST_IF	9    /* u_int; set/get multicast interface */
#define	IPV6_MULTICAST_HOPS	10   /* int; set/get multicast hop limit */
#define	IPV6_MULTICAST_LOOP	11   /* u_int; set/get multicast loopback */
#define	IPV6_ADD_MEMBERSHIP	12   /* ipv6_mreq; add group membership */
#define	IPV6_DROP_MEMBERSHIP	13   /* ipv6_mreq; drop group membership */

#define IPV6_ADDRFORM         0x16   /* int; get/set form of returned addrs */
#define IPV6_HOPOPTS          0x19   /* int; receive hop-by-hop options */
#define IPV6_DSTOPTS          0x1a   /* int; receive destination options */
#define IPV6_RTHDR            0x1b   /* int; receive routing header */

#define IN6_MAX_MEMBERSHIPS 20  /* Maximum number of multicast memberships. */
#define IPV6_DEFAULT_MCAST_HOPS 1
#define IPV6_DEFAULT_MCAST_LOOP 1

/*
 * Definitions for inet6 sysctl operations.
 *
 * Third level is protocol number.
 * Fourth level is desired variable within that protocol.
 */

#define	IPV6PROTO_MAXID	(IPPROTO_ICMPV6 + 1)	/* don't list to IPPROTO_MAX. */

#define	CTL_IPV6PROTO_NAMES { \
	{ "ipv6", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ "ipv4", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ "tcp", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ "udp", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ "esp", CTLTYPE_NODE }, \
	{ "ah", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ "icmpv6", CTLTYPE_NODE }, \
}
 
/*
 * Names for IPv6 sysctl objects
 */

#define	IPV6CTL_FORWARDING	1	/* act as router */
#define	IPV6CTL_SENDREDIRECTS	2	/* may send redirects when forwarding */
#define	IPV6CTL_DEFTTL		3	/* default TTL */
#ifdef notyet
#define	IPV6CTL_DEFMTU		4	/* default MTU */
#endif
#define	IPV6CTL_STATS		5
#define	IPV6CTL_ROUTERSOLICIT	6
#define	IPV6CTL_MAXID		7

#define	IPV6CTL_NAMES { \
	{ 0, 0 }, \
	{ "forwarding", CTLTYPE_INT }, \
	{ "redirect", CTLTYPE_INT }, \
	{ "ttl", CTLTYPE_INT }, \
	{ "mtu", CTLTYPE_INT }, \
	{ "stats", CTLTYPE_STRUCT }, \
	{ "routersolicit", CTLTYPE_INT }, \
	{ 0, 0 }, \
}

#define IPV6CTL_VARS { \
	0, \
	&ipv6forwarding, \
	0, \
	&ipv6_defhoplmt, \
	0, \
	&ipv6rsolicit \
}

/* Cheesy hack for if net/route.h included... */
#ifdef RTM_VERSION 
/*
 * sizeof(struct sockaddr_in6) > sizeof(struct sockaddr), therefore, I
 * need to define... 
 */ 
struct route6
{
  struct  rtentry *ro_rt;
  struct  sockaddr_in6 ro_dst;
};
#endif RTM_VERSION 

#ifdef _KERNEL
/* Function prototypes go here. */
int in6_cksum __P((struct mbuf *,int, u_int, u_int));
#endif /* _KERNEL */
#endif /* __linux__ */

extern const struct in6_addr in6addr_any;
extern const struct in6_addr in6addr_loopback;

#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}

struct in6_pktinfo {
  struct in6_addr ipi6_addr;
  unsigned int ipi6_ifindex;
};

#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

#endif /* _NETINET6_IN6_H */