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