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