Capturing packets from ethereal now saves the capture in an "anonymous" buffer. That...
[metze/wireshark/wip.git] / packet-ipv6.h
1 /* packet-ipv6.h
2  * Definitions for IPv6 packet disassembly 
3  *
4  * $Id: packet-ipv6.h,v 1.3 1999/04/06 16:24:49 gram Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifndef __PACKET_IPV6_H_DEFINED__
27 #define __PACKET_IPV6_H_DEFINED__
28
29 struct e_in6_addr {
30         union {
31                 guint32  u6_addr32[4];
32                 guint16  u6_addr16[8];
33                 guint8   u6_addr8[16];
34         } u6_addr;                      /* 128 bit IP6 address */
35 };
36
37 #define s6_addr32 u6_addr.u6_addr32
38 #define s6_addr16 u6_addr.u6_addr16
39 #define s6_addr8  u6_addr.u6_addr8
40 #define s6_addr   u6_addr.u6_addr8
41
42 #define INET6_ADDRSTRLEN        46
43
44 /*
45  * Definition for internet protocol version 6.
46  * RFC 1883
47  */
48 struct ip6_hdr {
49         union {
50                 struct ip6_hdrctl {
51                         guint32 ip6_un1_flow;   /* 20 bits of flow-ID */
52                         guint16 ip6_un1_plen;   /* payload length */
53                         guint8  ip6_un1_nxt;    /* next header */
54                         guint8  ip6_un1_hlim;   /* hop limit */
55                 } ip6_un1;
56                 guint8 ip6_un2_vfc;     /* 4 bits version, 4 bits class */
57         } ip6_ctlun;
58         struct e_in6_addr ip6_src;      /* source address */
59         struct e_in6_addr ip6_dst;      /* destination address */
60 };
61
62 #define ip6_vfc         ip6_ctlun.ip6_un2_vfc
63 #define ip6_flow        ip6_ctlun.ip6_un1.ip6_un1_flow
64 #define ip6_plen        ip6_ctlun.ip6_un1.ip6_un1_plen
65 #define ip6_nxt         ip6_ctlun.ip6_un1.ip6_un1_nxt
66 #define ip6_hlim        ip6_ctlun.ip6_un1.ip6_un1_hlim
67 #define ip6_hops        ip6_ctlun.ip6_un1.ip6_un1_hlim
68
69 #define IPV6_VERSION            0x60
70 #define IPV6_VERSION_MASK       0xf0
71
72 #if BYTE_ORDER == BIG_ENDIAN
73 #define IPV6_FLOWINFO_MASK      0x0fffffff      /* flow info (28 bits) */
74 #define IPV6_FLOWLABEL_MASK     0x000fffff      /* flow label (20 bits) */
75 #endif /* BIG_ENDIAN */
76 #if BYTE_ORDER == LITTLE_ENDIAN
77 #define IPV6_FLOWINFO_MASK      0xffffff0f      /* flow info (28 bits) */
78 #define IPV6_FLOWLABEL_MASK     0xffff0f00      /* flow label (20 bits) */
79 #endif /* LITTLE_ENDIAN */
80
81 /*
82  * Extension Headers
83  */
84
85 struct  ip6_ext {
86         u_char  ip6e_nxt;
87         u_char  ip6e_len;
88 };
89
90 /* Hop-by-Hop options header */
91 /* XXX should we pad it to force alignment on an 8-byte boundary? */
92 struct ip6_hbh {
93         guint8 ip6h_nxt;        /* next header */
94         guint8 ip6h_len;        /* length in units of 8 octets */
95         /* followed by options */
96 };
97
98 /* Destination options header */
99 /* XXX should we pad it to force alignment on an 8-byte boundary? */
100 struct ip6_dest {
101         guint8 ip6d_nxt;        /* next header */
102         guint8 ip6d_len;        /* length in units of 8 octets */
103         /* followed by options */
104 };
105
106 /* Option types and related macros */
107 #define IP6OPT_PAD1             0x00    /* 00 0 00000 */
108 #define IP6OPT_PADN             0x01    /* 00 0 00001 */
109 #define IP6OPT_JUMBO            0xC2    /* 11 0 00010 = 194 */
110 #define IP6OPT_JUMBO_LEN        6
111 #define IP6OPT_RTALERT          0x05    /* 00 0 00101 */
112 #define IP6OPT_RTALERT_LEN      4
113 #define IP6OPT_RTALERT_MLD      0       /* Datagram contains MLD message */
114 #define IP6OPT_RTALERT_RSVP     1       /* Datagram contains RSVP message */
115 #define IP6OPT_MINLEN           2
116
117 #define IP6OPT_TYPE(o)          ((o) & 0xC0)
118 #define IP6OPT_TYPE_SKIP        0x00
119 #define IP6OPT_TYPE_DISCARD     0x40
120 #define IP6OPT_TYPE_FORCEICMP   0x80
121 #define IP6OPT_TYPE_ICMP        0xC0
122
123 #define IP6OPT_MUTABLE          0x20
124
125 /* Routing header */
126 struct ip6_rthdr {
127         guint8  ip6r_nxt;       /* next header */
128         guint8  ip6r_len;       /* length in units of 8 octets */
129         guint8  ip6r_type;      /* routing type */
130         guint8  ip6r_segleft;   /* segments left */
131         /* followed by routing type specific data */
132 };
133
134 /* Type 0 Routing header */
135 struct ip6_rthdr0 {
136         guint8  ip6r0_nxt;              /* next header */
137         guint8  ip6r0_len;              /* length in units of 8 octets */
138         guint8  ip6r0_type;             /* always zero */
139         guint8  ip6r0_segleft;  /* segments left */
140         guint8  ip6r0_reserved; /* reserved field */
141         guint8  ip6r0_slmap[3]; /* strict/loose bit map */
142         struct e_in6_addr  ip6r0_addr[1];       /* up to 23 addresses */
143 };
144
145 /* Fragment header */
146 struct ip6_frag {
147         guint8  ip6f_nxt;               /* next header */
148         guint8  ip6f_reserved;  /* reserved field */
149         guint16 ip6f_offlg;             /* offset, reserved, and flag */
150         guint32 ip6f_ident;             /* identification */
151 };
152
153 #if BYTE_ORDER == BIG_ENDIAN
154 #define IP6F_OFF_MASK           0xfff8  /* mask out offset from _offlg */
155 #define IP6F_RESERVED_MASK      0x0006  /* reserved bits in ip6f_offlg */
156 #define IP6F_MORE_FRAG          0x0001  /* more-fragments flag */
157 #else /* BYTE_ORDER == LITTLE_ENDIAN */
158 #define IP6F_OFF_MASK           0xf8ff  /* mask out offset from _offlg */
159 #define IP6F_RESERVED_MASK      0x0600  /* reserved bits in ip6f_offlg */
160 #define IP6F_MORE_FRAG          0x0100  /* more-fragments flag */
161 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
162
163 /*
164  * Definition for ICMPv6.
165  * RFC 1885
166  */
167
168 #define ICMPV6_PLD_MAXLEN       1232    /* IPV6_MMTU - sizeof(struct ip6_hdr)
169                                            - sizeof(struct icmp6_hdr) */
170
171 struct icmp6_hdr {
172         guint8  icmp6_type;     /* type field */
173         guint8  icmp6_code;     /* code field */
174         guint16 icmp6_cksum;    /* checksum field */
175         union {
176                 guint32 icmp6_un_data32[1]; /* type-specific field */
177                 guint16 icmp6_un_data16[2]; /* type-specific field */
178                 guint8  icmp6_un_data8[4];  /* type-specific field */
179         } icmp6_dataun;
180 };
181
182 #define icmp6_data32    icmp6_dataun.icmp6_un_data32
183 #define icmp6_data16    icmp6_dataun.icmp6_un_data16
184 #define icmp6_data8     icmp6_dataun.icmp6_un_data8
185 #define icmp6_pptr      icmp6_data32[0]         /* parameter prob */
186 #define icmp6_mtu       icmp6_data32[0]         /* packet too big */
187 #define icmp6_id        icmp6_data16[0]         /* echo request/reply */
188 #define icmp6_seq       icmp6_data16[1]         /* echo request/reply */
189 #define icmp6_maxdelay  icmp6_data16[0]         /* mcast group membership */
190
191 #define ICMP6_DST_UNREACH               1       /* dest unreachable, codes: */
192 #define ICMP6_PACKET_TOO_BIG            2       /* packet too big */
193 #define ICMP6_TIME_EXCEEDED             3       /* time exceeded, code: */
194 #define ICMP6_PARAM_PROB                4       /* ip6 header bad */
195
196 #define ICMP6_ECHO_REQUEST              128     /* echo service */
197 #define ICMP6_ECHO_REPLY                129     /* echo reply */
198 #define ICMP6_MEMBERSHIP_QUERY          130     /* group membership query */
199 #define MLD6_LISTENER_QUERY             130     /* multicast listener query */
200 #define ICMP6_MEMBERSHIP_REPORT         131     /* group membership report */
201 #define MLD6_LISTENER_REPORT            131     /* multicast listener report */
202 #define ICMP6_MEMBERSHIP_REDUCTION      132     /* group membership termination */
203 #define MLD6_LISTENER_DONE              132     /* multicast listener done */
204
205 #define ND_ROUTER_SOLICIT               133     /* router solicitation */
206 #define ND_ROUTER_ADVERT                134     /* router advertisment */
207 #define ND_NEIGHBOR_SOLICIT             135     /* neighbor solicitation */
208 #define ND_NEIGHBOR_ADVERT              136     /* neighbor advertisment */
209 #define ND_REDIRECT                     137     /* redirect */
210
211 #define ICMP6_ROUTER_RENUMBERING        138     /* router renumbering */
212
213 /* xxx: actually not assigned yet */
214 #define ICMP6_WRUREQUEST                140     /* who are you request */
215 #define ICMP6_WRUREPLY                  141     /* who are you reply */
216 #define ICMP6_FQDN_QUERY                140     /* FQDN query */
217 #define ICMP6_FQDN_REPLY                141     /* FQDN reply */
218
219 #define ICMP6_MAXTYPE                   141
220
221 #define ICMP6_DST_UNREACH_NOROUTE       0       /* no route to destination */
222 #define ICMP6_DST_UNREACH_ADMIN         1       /* administratively prohibited */
223 #define ICMP6_DST_UNREACH_NOTNEIGHBOR   2       /* not a neighbor */
224 #define ICMP6_DST_UNREACH_ADDR          3       /* address unreachable */
225 #define ICMP6_DST_UNREACH_NOPORT        4       /* port unreachable */
226
227 #define ICMP6_TIME_EXCEED_TRANSIT       0       /* ttl==0 in transit */
228 #define ICMP6_TIME_EXCEED_REASSEMBLY    1       /* ttl==0 in reass */
229
230 #define ICMP6_PARAMPROB_HEADER          0       /* erroneous header field */
231 #define ICMP6_PARAMPROB_NEXTHEADER      1       /* unrecognized next header */
232 #define ICMP6_PARAMPROB_OPTION          2       /* unrecognized option */
233
234 #define ICMP6_INFOMSG_MASK              0x80    /* all informational messages */
235
236 #define ICMP6_ROUTER_RENUMBERING_COMMAND  0     /* rr command */
237 #define ICMP6_ROUTER_RENUMBERING_RESULT   1     /* rr result */
238 #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255     /* rr seq num reset */
239
240 /*
241  * Multicast Listener Discovery
242  */
243 struct mld6_hdr {
244         struct icmp6_hdr        mld6_hdr;
245         struct e_in6_addr               mld6_addr; /* multicast address */
246 };
247
248 #define mld6_type       mld6_hdr.icmp6_type
249 #define mld6_code       mld6_hdr.icmp6_code
250 #define mld6_cksum      mld6_hdr.icmp6_cksum
251 #define mld6_maxdelay   mld6_hdr.icmp6_data16[0]
252 #define mld6_reserved   mld6_hdr.icmp6_data16[1]
253
254 /*
255  * Neighbor Discovery
256  */
257
258 struct nd_router_solicit {      /* router solicitation */
259         struct icmp6_hdr        nd_rs_hdr;
260         /* could be followed by options */
261 };
262
263 #define nd_rs_type      nd_rs_hdr.icmp6_type
264 #define nd_rs_code      nd_rs_hdr.icmp6_code
265 #define nd_rs_cksum     nd_rs_hdr.icmp6_cksum
266 #define nd_rs_reserved  nd_rs_hdr.icmp6_data32[0]
267
268 struct nd_router_advert {       /* router advertisement */
269         struct icmp6_hdr        nd_ra_hdr;
270         guint32         nd_ra_reachable;        /* reachable time */
271         guint32         nd_ra_retransmit;       /* retransmit timer */
272         /* could be followed by options */
273 };
274
275 #define nd_ra_type              nd_ra_hdr.icmp6_type
276 #define nd_ra_code              nd_ra_hdr.icmp6_code
277 #define nd_ra_cksum             nd_ra_hdr.icmp6_cksum
278 #define nd_ra_curhoplimit       nd_ra_hdr.icmp6_data8[0]
279 #define nd_ra_flags_reserved    nd_ra_hdr.icmp6_data8[1]
280 #define ND_RA_FLAG_MANAGED      0x80
281 #define ND_RA_FLAG_OTHER        0x40
282 #define nd_ra_router_lifetime   nd_ra_hdr.icmp6_data16[1]
283
284 struct nd_neighbor_solicit {    /* neighbor solicitation */
285         struct icmp6_hdr        nd_ns_hdr;
286         struct e_in6_addr               nd_ns_target;   /*target address */
287         /* could be followed by options */
288 };
289
290 #define nd_ns_type              nd_ns_hdr.icmp6_type
291 #define nd_ns_code              nd_ns_hdr.icmp6_code
292 #define nd_ns_cksum             nd_ns_hdr.icmp6_cksum
293 #define nd_ns_reserved          nd_ns_hdr.icmp6_data32[0]
294
295 struct nd_neighbor_advert {     /* neighbor advertisement */
296         struct icmp6_hdr        nd_na_hdr;
297         struct e_in6_addr               nd_na_target;   /* target address */
298         /* could be followed by options */
299 };
300
301 #define nd_na_type              nd_na_hdr.icmp6_type
302 #define nd_na_code              nd_na_hdr.icmp6_code
303 #define nd_na_cksum             nd_na_hdr.icmp6_cksum
304 #define nd_na_flags_reserved    nd_na_hdr.icmp6_data32[0]
305 #if BYTE_ORDER == BIG_ENDIAN
306 #define ND_NA_FLAG_ROUTER               0x80000000
307 #define ND_NA_FLAG_SOLICITED            0x40000000
308 #define ND_NA_FLAG_OVERRIDE             0x20000000
309 #elif BYTE_ORDER == LITTLE_ENDIAN
310 #define ND_NA_FLAG_ROUTER               0x80
311 #define ND_NA_FLAG_SOLICITED            0x40
312 #define ND_NA_FLAG_OVERRIDE             0x20
313 #endif
314
315 struct nd_redirect {            /* redirect */
316         struct icmp6_hdr        nd_rd_hdr;
317         struct e_in6_addr               nd_rd_target;   /* target address */
318         struct e_in6_addr               nd_rd_dst;      /* destination address */
319         /* could be followed by options */
320 };
321
322 #define nd_rd_type              nd_rd_hdr.icmp6_type
323 #define nd_rd_code              nd_rd_hdr.icmp6_code
324 #define nd_rd_cksum             nd_rd_hdr.icmp6_cksum
325 #define nd_rd_reserved          nd_rd_hdr.icmp6_data32[0]
326
327 struct nd_opt_hdr {             /* Neighbor discovery option header */
328         guint8  nd_opt_type;
329         guint8  nd_opt_len;
330         /* followed by option specific data*/
331 };
332
333 #define ND_OPT_SOURCE_LINKADDR          1
334 #define ND_OPT_TARGET_LINKADDR          2
335 #define ND_OPT_PREFIX_INFORMATION       3
336 #define ND_OPT_REDIRECTED_HEADER        4
337 #define ND_OPT_MTU                      5
338
339 struct nd_opt_prefix_info {     /* prefix information */
340         guint8  nd_opt_pi_type;
341         guint8  nd_opt_pi_len;
342         guint8  nd_opt_pi_prefix_len;
343         guint8  nd_opt_pi_flags_reserved;
344         guint32 nd_opt_pi_valid_time;
345         guint32 nd_opt_pi_preferred_time;
346         guint32 nd_opt_pi_reserved2;
347         struct e_in6_addr       nd_opt_pi_prefix;
348 };
349
350 #define ND_OPT_PI_FLAG_ONLINK           0x80
351 #define ND_OPT_PI_FLAG_AUTO             0x40
352
353 struct nd_opt_rd_hdr {         /* redirected header */
354         guint8  nd_opt_rh_type;
355         guint8  nd_opt_rh_len;
356         guint16 nd_opt_rh_reserved1;
357         guint32 nd_opt_rh_reserved2;
358         /* followed by IP header and data */
359 };
360
361 struct nd_opt_mtu {             /* MTU option */
362         guint8  nd_opt_mtu_type;
363         guint8  nd_opt_mtu_len;
364         guint16 nd_opt_mtu_reserved;
365         guint32 nd_opt_mtu_mtu;
366 };
367
368 #if 0
369 /* disregard until used. We have to decide how to handle guint64 */ 
370 /*
371  * icmp6 namelookup
372  */
373
374 struct icmp6_namelookup {
375         struct icmp6_hdr        icmp6_nl_hdr;
376         guint64 icmp6_nl_nonce;
377         guint32 icmp6_nl_ttl;
378 #if 0
379         guint8  icmp6_nl_len;
380         guint8  icmp6_nl_name[3];
381 #endif
382         /* could be followed by options */
383 };
384 #endif
385
386 /*
387  * Router Renumbering. as router-renum-05.txt
388  */
389 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
390 struct icmp6_router_renum {     /* router renumbering header */
391         struct icmp6_hdr        rr_hdr;
392         guint8          rr_segnum;
393         guint8          rr_test : 1;
394         guint8          rr_reqresult : 1;
395         guint8          rr_forceapply : 1;
396         guint8          rr_specsite : 1;
397         guint8          rr_prevdone : 1;
398         guint8          rr_flags_reserved : 3;
399         guint16         rr_maxdelay;
400         guint32         rr_reserved;
401 };
402 #elif BYTE_ORDER == LITTLE_ENDIAN
403 struct icmp6_router_renum {     /* router renumbering header */
404         struct icmp6_hdr        rr_hdr;
405         guint8          rr_segnum;
406         guint8          rr_flags_reserved : 3;
407         guint8          rr_prevdone : 1;
408         guint8          rr_specsite : 1;
409         guint8          rr_forceapply : 1;
410         guint8          rr_reqresult : 1;
411         guint8          rr_test : 1;
412         guint16         rr_maxdelay;
413         guint32         rr_reserved;
414 };
415 #endif /* BYTE_ORDER */
416
417 #define rr_type                 rr_hdr.icmp6_type
418 #define rr_code                 rr_hdr.icmp6_code
419 #define rr_cksum                rr_hdr.icmp6_cksum
420 #define rr_seqnum               rr_hdr.icmp6_data32[0]
421
422 struct rr_pco_match {           /* match prefix part */
423         guint8  rpm_code;
424         guint8  rpm_len;
425         guint8  rpm_ordinal;
426         guint8  rpm_matchlen;
427         guint8  rpm_minlen;
428         guint8  rpm_maxlen;
429         guint16 rpm_reserved;
430         struct e_in6_addr       rpm_prefix;
431 };
432
433 #define RPM_PCO_ADD             1
434 #define RPM_PCO_CHANGE          2
435 #define RPM_PCO_SETGLOBAL       3
436 #define RPM_PCO_MAX             4
437
438 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
439 struct rr_pco_use {             /* use prefix part */
440         guint8  rpu_uselen;
441         guint8  rpu_keeplen;
442         guint8  rpu_mask_onlink : 1;
443         guint8  rpu_mask_autonomous : 1;
444         guint8  rpu_mask_reserved : 6;
445         guint8  rpu_onlink : 1;
446         guint8  rpu_autonomous : 1;
447         guint8  rpu_raflags_reserved : 6;
448         guint32 rpu_vltime;
449         guint32 rpu_pltime;
450         guint32 rpu_decr_vltime : 1;
451         guint32 rpu_decr_pltime : 1;
452         guint32 rpu_flags_reserved : 6;
453         guint32 rpu_reserved : 24;
454         struct e_in6_addr rpu_prefix;
455 };
456 #elif BYTE_ORDER == LITTLE_ENDIAN
457 struct rr_pco_use {             /* use prefix part */
458         guint8  rpu_uselen;
459         guint8  rpu_keeplen;
460         guint8  rpu_mask_reserved : 6;
461         guint8  rpu_mask_autonomous : 1;
462         guint8  rpu_mask_onlink : 1;
463         guint8  rpu_raflags_reserved : 6;
464         guint8  rpu_autonomous : 1;
465         guint8  rpu_onlink : 1;
466         guint32 rpu_vltime;
467         guint32 rpu_pltime;
468         guint32 rpu_flags_reserved : 6;
469         guint32 rpu_decr_pltime : 1;
470         guint32 rpu_decr_vltime : 1;
471         guint32 rpu_reserved : 24;
472         struct e_in6_addr rpu_prefix;
473 };
474 #endif /* BYTE_ORDER */
475
476 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
477 struct rr_result {              /* router renumbering result message */
478         guint8  rrr_reserved;
479         guint8  rrr_flags_reserved : 6;
480         guint8  rrr_outofbound : 1;
481         guint8  rrr_forbidden : 1;
482         guint8  rrr_ordinal;
483         guint8  rrr_matchedlen;
484         guint32 rrr_ifid;
485         struct e_in6_addr rrr_prefix;
486 };
487 #elif BYTE_ORDER == LITTLE_ENDIAN
488 struct rr_result {              /* router renumbering result message */
489         guint8  rrr_reserved;
490         guint8  rrr_forbidden : 1;
491         guint8  rrr_outofbound : 1;
492         guint8  rrr_flags_reserved : 6;
493         guint8  rrr_ordinal;
494         guint8  rrr_matchedlen;
495         guint32 rrr_ifid;
496         struct e_in6_addr rrr_prefix;
497 };
498 #endif /* BYTE_ORDER */
499
500 struct e_in6_addr;
501 gchar*     ip6_to_str(struct e_in6_addr *);
502
503 #endif /* __PACKET_IPV6_H_DEFINED__ */