2 * Definitions for IPv6 packet disassembly
4 * $Id: packet-ipv6.h,v 1.3 1999/04/06 16:24:49 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
26 #ifndef __PACKET_IPV6_H_DEFINED__
27 #define __PACKET_IPV6_H_DEFINED__
34 } u6_addr; /* 128 bit IP6 address */
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
42 #define INET6_ADDRSTRLEN 46
45 * Definition for internet protocol version 6.
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 */
56 guint8 ip6_un2_vfc; /* 4 bits version, 4 bits class */
58 struct e_in6_addr ip6_src; /* source address */
59 struct e_in6_addr ip6_dst; /* destination address */
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
69 #define IPV6_VERSION 0x60
70 #define IPV6_VERSION_MASK 0xf0
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 */
90 /* Hop-by-Hop options header */
91 /* XXX should we pad it to force alignment on an 8-byte boundary? */
93 guint8 ip6h_nxt; /* next header */
94 guint8 ip6h_len; /* length in units of 8 octets */
95 /* followed by options */
98 /* Destination options header */
99 /* XXX should we pad it to force alignment on an 8-byte boundary? */
101 guint8 ip6d_nxt; /* next header */
102 guint8 ip6d_len; /* length in units of 8 octets */
103 /* followed by options */
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
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
123 #define IP6OPT_MUTABLE 0x20
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 */
134 /* Type 0 Routing header */
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 */
145 /* Fragment header */
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 */
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 */
164 * Definition for ICMPv6.
168 #define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
169 - sizeof(struct icmp6_hdr) */
172 guint8 icmp6_type; /* type field */
173 guint8 icmp6_code; /* code field */
174 guint16 icmp6_cksum; /* checksum field */
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 */
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 */
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 */
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 */
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 */
211 #define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
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 */
219 #define ICMP6_MAXTYPE 141
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 */
227 #define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
228 #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
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 */
234 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
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 */
241 * Multicast Listener Discovery
244 struct icmp6_hdr mld6_hdr;
245 struct e_in6_addr mld6_addr; /* multicast address */
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]
258 struct nd_router_solicit { /* router solicitation */
259 struct icmp6_hdr nd_rs_hdr;
260 /* could be followed by options */
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]
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 */
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]
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 */
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]
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 */
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
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 */
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]
327 struct nd_opt_hdr { /* Neighbor discovery option header */
330 /* followed by option specific data*/
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
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;
350 #define ND_OPT_PI_FLAG_ONLINK 0x80
351 #define ND_OPT_PI_FLAG_AUTO 0x40
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 */
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;
369 /* disregard until used. We have to decide how to handle guint64 */
374 struct icmp6_namelookup {
375 struct icmp6_hdr icmp6_nl_hdr;
376 guint64 icmp6_nl_nonce;
377 guint32 icmp6_nl_ttl;
380 guint8 icmp6_nl_name[3];
382 /* could be followed by options */
387 * Router Renumbering. as router-renum-05.txt
389 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
390 struct icmp6_router_renum { /* router renumbering header */
391 struct icmp6_hdr rr_hdr;
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;
402 #elif BYTE_ORDER == LITTLE_ENDIAN
403 struct icmp6_router_renum { /* router renumbering header */
404 struct icmp6_hdr rr_hdr;
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;
415 #endif /* BYTE_ORDER */
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]
422 struct rr_pco_match { /* match prefix part */
429 guint16 rpm_reserved;
430 struct e_in6_addr rpm_prefix;
433 #define RPM_PCO_ADD 1
434 #define RPM_PCO_CHANGE 2
435 #define RPM_PCO_SETGLOBAL 3
436 #define RPM_PCO_MAX 4
438 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
439 struct rr_pco_use { /* use prefix part */
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;
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;
456 #elif BYTE_ORDER == LITTLE_ENDIAN
457 struct rr_pco_use { /* use prefix part */
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;
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;
474 #endif /* BYTE_ORDER */
476 #if BYTE_ORDER == BIG_ENDIAN /* net byte order */
477 struct rr_result { /* router renumbering result message */
479 guint8 rrr_flags_reserved : 6;
480 guint8 rrr_outofbound : 1;
481 guint8 rrr_forbidden : 1;
483 guint8 rrr_matchedlen;
485 struct e_in6_addr rrr_prefix;
487 #elif BYTE_ORDER == LITTLE_ENDIAN
488 struct rr_result { /* router renumbering result message */
490 guint8 rrr_forbidden : 1;
491 guint8 rrr_outofbound : 1;
492 guint8 rrr_flags_reserved : 6;
494 guint8 rrr_matchedlen;
496 struct e_in6_addr rrr_prefix;
498 #endif /* BYTE_ORDER */
501 gchar* ip6_to_str(struct e_in6_addr *);
503 #endif /* __PACKET_IPV6_H_DEFINED__ */