2 * Routines for IPv6 packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
12 * MobileIPv6 support added by Tomislav Borosa <tomislav.borosa@siemens.hr>
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include <epan/expert.h>
35 #include <epan/ip_opts.h>
36 #include <epan/addr_resolv.h>
37 #include <epan/prefs.h>
38 #include <epan/reassemble.h>
39 #include <epan/ipproto.h>
40 #include <epan/ipv6-utils.h>
41 #include <epan/etypes.h>
42 #include <epan/ppptypes.h>
43 #include <epan/aftypes.h>
44 #include <epan/nlpid.h>
45 #include <epan/arcnet_pids.h>
46 #include <epan/in_cksum.h>
47 #include <epan/expert.h>
48 #include <epan/wmem/wmem.h>
50 #include "packet-ipsec.h"
51 #include "packet-ipv6.h"
52 #include "packet-ip.h"
56 #include <epan/geoip_db.h>
57 #endif /* HAVE_GEOIP_V6 */
59 /* Option types and related macros */
60 #define IP6OPT_PAD1 0x00 /* 00 0 00000 */
61 #define IP6OPT_PADN 0x01 /* 00 0 00001 */
62 #define IP6OPT_TEL 0x04 /* 00 0 00100 */
63 #define IP6OPT_RTALERT 0x05 /* 00 0 00101 */
64 #define IP6OPT_CALIPSO 0x07 /* 00 0 00111 */
65 #define IP6OPT_QUICKSTART 0x26 /* 00 1 00110 */
66 #define IP6OPT_ENDI 0x8A /* 10 0 01010 */
67 #define IP6OPT_EXP_1E 0x1E /* 00 0 11110 */
68 #define IP6OPT_EXP_3E 0x3E /* 00 1 11110 */
69 #define IP6OPT_EXP_5E 0x5E /* 01 0 11110 */
70 #define IP6OPT_RPL 0x63 /* 01 1 00011 */
71 #define IP6OPT_EXP_7E 0x7E /* 01 1 11110 */
72 #define IP6OPT_EXP_9E 0x9E /* 10 0 11110 */
73 #define IP6OPT_EXP_BE 0xBE /* 10 1 11110 */
74 #define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
75 #define IP6OPT_HOME_ADDRESS 0xC9 /* 11 0 01001 */
76 #define IP6OPT_EXP_DE 0xDE /* 11 0 11110 */
77 #define IP6OPT_EXP_FE 0xFE /* 11 1 11110 */
79 #define IP6OPT_RTALERT_MLD 0 /* Datagram contains MLD msg */
80 #define IP6OPT_RTALERT_RSVP 1 /* Datagram contains RSVP msg */
81 #define IP6OPT_RTALERT_ACTNET 2 /* Datagram contains ACTNET msg */
83 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
84 #define IPDSFIELD_DSCP_MASK 0xFC
85 #define IPDSFIELD_ECN_MASK 0x03
86 #define IPDSFIELD_DSCP_SHIFT 2
87 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
88 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
89 #define IPDSFIELD_DSCP_DEFAULT 0x00
90 #define IPDSFIELD_DSCP_CS1 0x08
91 #define IPDSFIELD_DSCP_CS2 0x10
92 #define IPDSFIELD_DSCP_CS3 0x18
93 #define IPDSFIELD_DSCP_CS4 0x20
94 #define IPDSFIELD_DSCP_CS5 0x28
95 #define IPDSFIELD_DSCP_CS6 0x30
96 #define IPDSFIELD_DSCP_CS7 0x38
97 #define IPDSFIELD_DSCP_AF11 0x0A
98 #define IPDSFIELD_DSCP_AF12 0x0C
99 #define IPDSFIELD_DSCP_AF13 0x0E
100 #define IPDSFIELD_DSCP_AF21 0x12
101 #define IPDSFIELD_DSCP_AF22 0x14
102 #define IPDSFIELD_DSCP_AF23 0x16
103 #define IPDSFIELD_DSCP_AF31 0x1A
104 #define IPDSFIELD_DSCP_AF32 0x1C
105 #define IPDSFIELD_DSCP_AF33 0x1E
106 #define IPDSFIELD_DSCP_AF41 0x22
107 #define IPDSFIELD_DSCP_AF42 0x24
108 #define IPDSFIELD_DSCP_AF43 0x26
109 #define IPDSFIELD_DSCP_EF 0x2E
110 #define IPDSFIELD_ECT_MASK 0x02
111 #define IPDSFIELD_CE_MASK 0x01
113 /* RPL Routing header */
114 #define IP6RRPL_BITMASK_CMPRI 0xF0000000
115 #define IP6RRPL_BITMASK_CMPRE 0x0F000000
116 #define IP6RRPL_BITMASK_PAD 0x00F00000
117 #define IP6RRPL_BITMASK_RESERVED 0x000FFFFF
119 static int ipv6_tap
= -1;
121 static int proto_ipv6
= -1;
122 static int hf_ipv6_version
= -1;
123 static int hf_ip_version
= -1;
124 static int hf_ipv6_class
= -1;
125 static int hf_ipv6_flow
= -1;
126 static int hf_ipv6_plen
= -1;
127 static int hf_ipv6_nxt
= -1;
128 static int hf_ipv6_hlim
= -1;
129 static int hf_ipv6_src
= -1;
130 static int hf_ipv6_src_host
= -1;
131 static int hf_ipv6_src_sa_mac
= -1;
132 static int hf_ipv6_src_isatap_ipv4
= -1;
133 static int hf_ipv6_src_6to4_gateway_ipv4
= -1;
134 static int hf_ipv6_src_6to4_sla_id
= -1;
135 static int hf_ipv6_src_teredo_server_ipv4
= -1;
136 static int hf_ipv6_src_teredo_port
= -1;
137 static int hf_ipv6_src_teredo_client_ipv4
= -1;
138 static int hf_ipv6_dst
= -1;
139 static int hf_ipv6_dst_host
= -1;
140 static int hf_ipv6_dst_sa_mac
= -1;
141 static int hf_ipv6_dst_isatap_ipv4
= -1;
142 static int hf_ipv6_dst_6to4_gateway_ipv4
= -1;
143 static int hf_ipv6_dst_6to4_sla_id
= -1;
144 static int hf_ipv6_dst_teredo_server_ipv4
= -1;
145 static int hf_ipv6_dst_teredo_port
= -1;
146 static int hf_ipv6_dst_teredo_client_ipv4
= -1;
147 static int hf_ipv6_addr
= -1;
148 static int hf_ipv6_host
= -1;
149 static int hf_ipv6_sa_mac
= -1;
150 static int hf_ipv6_isatap_ipv4
= -1;
151 static int hf_ipv6_6to4_gateway_ipv4
= -1;
152 static int hf_ipv6_6to4_sla_id
= -1;
153 static int hf_ipv6_teredo_server_ipv4
= -1;
154 static int hf_ipv6_teredo_port
= -1;
155 static int hf_ipv6_teredo_client_ipv4
= -1;
156 static int hf_ipv6_opt
= -1;
157 static int hf_ipv6_opt_type
= -1;
158 static int hf_ipv6_opt_length
= -1;
159 static int hf_ipv6_opt_pad1
= -1;
160 static int hf_ipv6_opt_padn
= -1;
161 static int hf_ipv6_opt_tel
= -1;
162 static int hf_ipv6_opt_rtalert
= -1;
163 static int hf_ipv6_opt_jumbo
= -1;
164 static int hf_ipv6_opt_calipso_doi
= -1;
165 static int hf_ipv6_opt_calipso_cmpt_length
= -1;
166 static int hf_ipv6_opt_calipso_sens_level
= -1;
167 static int hf_ipv6_opt_calipso_checksum
= -1;
168 static int hf_ipv6_opt_calipso_cmpt_bitmap
= -1;
169 static int hf_ipv6_opt_qs_func
= -1;
170 static int hf_ipv6_opt_qs_rate
= -1;
171 static int hf_ipv6_opt_qs_ttl
= -1;
172 static int hf_ipv6_opt_qs_ttl_diff
= -1;
173 static int hf_ipv6_opt_qs_unused
= -1;
174 static int hf_ipv6_opt_qs_nonce
= -1;
175 static int hf_ipv6_opt_qs_reserved
= -1;
176 static int hf_ipv6_opt_rpl_flag
= -1;
177 static int hf_ipv6_opt_rpl_flag_o
= -1;
178 static int hf_ipv6_opt_rpl_flag_r
= -1;
179 static int hf_ipv6_opt_rpl_flag_f
= -1;
180 static int hf_ipv6_opt_rpl_flag_rsv
= -1;
181 static int hf_ipv6_opt_rpl_instance_id
= -1;
182 static int hf_ipv6_opt_rpl_senderrank
= -1;
183 static int hf_ipv6_opt_experimental
= -1;
184 static int hf_ipv6_opt_unknown
= -1;
185 static int hf_ipv6_dst_opt
= -1;
186 static int hf_ipv6_hop_opt
= -1;
187 static int hf_ipv6_unk_hdr
= -1;
188 static int hf_ipv6_routing_hdr_opt
= -1;
189 static int hf_ipv6_routing_hdr_type
= -1;
190 static int hf_ipv6_routing_hdr_left
= -1;
191 static int hf_ipv6_routing_hdr_addr
= -1;
192 static int hf_ipv6_frag_nxt
= -1;
193 static int hf_ipv6_frag_reserved
= -1;
194 static int hf_ipv6_frag_offset
= -1;
195 static int hf_ipv6_frag_reserved_bits
= -1;
196 static int hf_ipv6_frag_more
= -1;
197 static int hf_ipv6_frag_id
= -1;
198 static int hf_ipv6_fragments
= -1;
199 static int hf_ipv6_fragment
= -1;
200 static int hf_ipv6_fragment_overlap
= -1;
201 static int hf_ipv6_fragment_overlap_conflict
= -1;
202 static int hf_ipv6_fragment_multiple_tails
= -1;
203 static int hf_ipv6_fragment_too_long_fragment
= -1;
204 static int hf_ipv6_fragment_error
= -1;
205 static int hf_ipv6_fragment_count
= -1;
206 static int hf_ipv6_reassembled_in
= -1;
207 static int hf_ipv6_reassembled_length
= -1;
208 static int hf_ipv6_reassembled_data
= -1;
210 static int hf_ipv6_mipv6_home_address
= -1;
212 static int hf_ipv6_routing_hdr_rpl_cmprI
= -1;
213 static int hf_ipv6_routing_hdr_rpl_cmprE
= -1;
214 static int hf_ipv6_routing_hdr_rpl_pad
= -1;
215 static int hf_ipv6_routing_hdr_rpl_reserved
= -1;
216 static int hf_ipv6_routing_hdr_rpl_segments
= -1;
217 static int hf_ipv6_routing_hdr_rpl_addr
= -1;
218 static int hf_ipv6_routing_hdr_rpl_fulladdr
= -1;
220 static int hf_ipv6_shim6
= -1;
221 static int hf_ipv6_shim6_nxt
= -1;
222 static int hf_ipv6_shim6_len
= -1;
223 static int hf_ipv6_shim6_p
= -1;
224 /* context tag is 49 bits, cannot be used for filter yet */
225 static int hf_ipv6_shim6_ct
= -1;
226 static int hf_ipv6_shim6_type
= -1;
227 static int hf_ipv6_shim6_proto
= -1;
228 static int hf_ipv6_shim6_checksum
= -1;
229 static int hf_ipv6_shim6_checksum_bad
= -1;
230 static int hf_ipv6_shim6_checksum_good
= -1;
231 static int hf_ipv6_shim6_inonce
= -1; /* also for request nonce */
232 static int hf_ipv6_shim6_rnonce
= -1;
233 static int hf_ipv6_shim6_precvd
= -1;
234 static int hf_ipv6_shim6_psent
= -1;
235 static int hf_ipv6_shim6_psrc
= -1;
236 static int hf_ipv6_shim6_pdst
= -1;
237 static int hf_ipv6_shim6_pnonce
= -1;
238 static int hf_ipv6_shim6_pdata
= -1;
239 static int hf_ipv6_shim6_sulid
= -1;
240 static int hf_ipv6_shim6_rulid
= -1;
241 static int hf_ipv6_shim6_reap
= -1;
242 static int hf_ipv6_shim6_opt_type
= -1;
243 static int hf_ipv6_shim6_opt_len
= -1;
244 static int hf_ipv6_shim6_opt_total_len
= -1;
245 static int hf_ipv6_shim6_opt_loc_verif_methods
= -1;
246 static int hf_ipv6_shim6_opt_critical
= -1;
247 static int hf_ipv6_shim6_opt_loclist
= -1;
248 static int hf_ipv6_shim6_locator
= -1;
249 static int hf_ipv6_shim6_loc_flag
= -1;
250 static int hf_ipv6_shim6_loc_prio
= -1;
251 static int hf_ipv6_shim6_loc_weight
= -1;
252 static int hf_ipv6_shim6_opt_locnum
= -1;
253 static int hf_ipv6_shim6_opt_elemlen
= -1;
254 static int hf_ipv6_shim6_opt_fii
= -1;
255 static int hf_ipv6_traffic_class_dscp
= -1;
256 static int hf_ipv6_traffic_class_ect
= -1;
257 static int hf_ipv6_traffic_class_ce
= -1;
260 static int hf_geoip_country
= -1;
261 static int hf_geoip_city
= -1;
262 static int hf_geoip_org
= -1;
263 static int hf_geoip_isp
= -1;
264 static int hf_geoip_asnum
= -1;
265 static int hf_geoip_lat
= -1;
266 static int hf_geoip_lon
= -1;
267 static int hf_geoip_src_country
= -1;
268 static int hf_geoip_src_city
= -1;
269 static int hf_geoip_src_org
= -1;
270 static int hf_geoip_src_isp
= -1;
271 static int hf_geoip_src_asnum
= -1;
272 static int hf_geoip_src_lat
= -1;
273 static int hf_geoip_src_lon
= -1;
274 static int hf_geoip_dst_country
= -1;
275 static int hf_geoip_dst_city
= -1;
276 static int hf_geoip_dst_org
= -1;
277 static int hf_geoip_dst_isp
= -1;
278 static int hf_geoip_dst_asnum
= -1;
279 static int hf_geoip_dst_lat
= -1;
280 static int hf_geoip_dst_lon
= -1;
281 #endif /* HAVE_GEOIP_V6 */
283 static gint ett_ipv6
= -1;
284 static gint ett_ipv6_opt
= -1;
285 static gint ett_ipv6_opt_flag
= -1;
286 static gint ett_ipv6_version
= -1;
287 static gint ett_ipv6_shim6
= -1;
288 static gint ett_ipv6_shim6_option
= -1;
289 static gint ett_ipv6_shim6_locators
= -1;
290 static gint ett_ipv6_shim6_verif_methods
= -1;
291 static gint ett_ipv6_shim6_loc_pref
= -1;
292 static gint ett_ipv6_shim6_probes_sent
= -1;
293 static gint ett_ipv6_shim6_probe_sent
= -1;
294 static gint ett_ipv6_shim6_probes_rcvd
= -1;
295 static gint ett_ipv6_shim6_probe_rcvd
= -1;
296 static gint ett_ipv6_shim6_cksum
= -1;
297 static gint ett_ipv6_fragments
= -1;
298 static gint ett_ipv6_fragment
= -1;
299 static gint ett_ipv6_traffic_class
= -1;
302 static gint ett_geoip_info
= -1;
303 #endif /* HAVE_GEOIP_V6 */
305 static expert_field ei_ipv6_dst_addr_not_multicast
= EI_INIT
;
306 static expert_field ei_ipv6_src_route_list_mult_inst_same_addr
= EI_INIT
;
307 static expert_field ei_ipv6_src_route_list_src_addr
= EI_INIT
;
308 static expert_field ei_ipv6_src_route_list_dst_addr
= EI_INIT
;
309 static expert_field ei_ipv6_src_route_list_multicast_addr
= EI_INIT
;
310 static expert_field ei_ipv6_cmpri_cmpre_pad
= EI_INIT
;
311 static expert_field ei_ipv6_routing_hdr_rpl_reserved
= EI_INIT
;
312 static expert_field ei_ipv6_opt_tel_invalid_len
= EI_INIT
;
313 static expert_field ei_ipv6_opt_jumbo_invalid_len
= EI_INIT
;
314 static expert_field ei_ipv6_opt_rtalert_invalid_len
= EI_INIT
;
315 static expert_field ei_ipv6_mipv6_home_address_invalid_len
= EI_INIT
;
316 static expert_field ei_ipv6_shim6_opt_elemlen_invalid
= EI_INIT
;
317 static expert_field ei_ipv6_shim6_checksum_bad
= EI_INIT
;
318 static expert_field ei_ipv6_routing_hdr_rpl_segments_ge0
= EI_INIT
;
320 static const fragment_items ipv6_frag_items
= {
325 &hf_ipv6_fragment_overlap
,
326 &hf_ipv6_fragment_overlap_conflict
,
327 &hf_ipv6_fragment_multiple_tails
,
328 &hf_ipv6_fragment_too_long_fragment
,
329 &hf_ipv6_fragment_error
,
330 &hf_ipv6_fragment_count
,
331 &hf_ipv6_reassembled_in
,
332 &hf_ipv6_reassembled_length
,
333 &hf_ipv6_reassembled_data
,
337 static dissector_handle_t data_handle
;
339 static dissector_table_t ip_dissector_table
;
341 /* Reassemble fragmented datagrams */
342 static gboolean ipv6_reassemble
= TRUE
;
344 /* Place IPv6 summary in proto tree */
345 static gboolean ipv6_summary_in_tree
= TRUE
;
348 /* Look up addresses in GeoIP */
349 static gboolean ipv6_use_geoip
= TRUE
;
350 #endif /* HAVE_GEOIP_V6 */
352 /* Perform strict RFC adherence checking */
353 static gboolean g_ipv6_rpl_srh_strict_rfc_checking
= FALSE
;
356 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
360 * defragmentation of IPv6
362 static reassembly_table ipv6_reassembly_table
;
364 /* http://www.iana.org/assignments/icmpv6-parameters (last updated 2012-12-22) */
365 static const value_string ipv6_opt_vals
[] = {
366 { IP6OPT_PAD1
, "Pad1" },
367 { IP6OPT_PADN
, "PadN" },
368 { IP6OPT_TEL
, "Tunnel Encapsulation Limit" },
369 { IP6OPT_RTALERT
, "Router Alert" },
370 { IP6OPT_CALIPSO
, "Calipso" },
371 { IP6OPT_QUICKSTART
, "Quick Start" },
372 { IP6OPT_ENDI
, "Endpoint Identification" },
373 { IP6OPT_EXP_1E
, "Experimental (0x1E)" },
374 { IP6OPT_EXP_3E
, "Experimental (0x3E)" },
375 { IP6OPT_EXP_5E
, "Experimental (0x5E)" },
376 { IP6OPT_RPL
, "RPL Option" },
377 { IP6OPT_EXP_7E
, "Experimental (0x7E)" },
378 { IP6OPT_EXP_9E
, "Experimental (0x9E)" },
379 { IP6OPT_EXP_BE
, "Experimental (0xBE)" },
380 { IP6OPT_JUMBO
, "Jumbo" },
381 { IP6OPT_HOME_ADDRESS
, "Home Address" },
382 { IP6OPT_EXP_DE
, "Experimental (0xDE)" },
383 { IP6OPT_EXP_FE
, "Experimental (0xFE)" },
389 capture_ipv6(const guchar
*pd
, int offset
, int len
, packet_counts
*ld
)
394 if (!BYTES_ARE_IN_FRAME(offset
, len
, 4+4+16+16)) {
398 nxt
= pd
[offset
+6]; /* get the "next header" value */
399 offset
+= 4+4+16+16; /* skip past the IPv6 header */
403 case IP_PROTO_HOPOPTS
:
404 case IP_PROTO_ROUTING
:
405 case IP_PROTO_DSTOPTS
:
406 if (!BYTES_ARE_IN_FRAME(offset
, len
, 2)) {
411 advance
= (pd
[offset
+1] + 1) << 3;
412 if (!BYTES_ARE_IN_FRAME(offset
, len
, advance
)) {
418 case IP_PROTO_FRAGMENT
:
419 if (!BYTES_ARE_IN_FRAME(offset
, len
, 2)) {
425 if (!BYTES_ARE_IN_FRAME(offset
, len
, advance
)) {
432 if (!BYTES_ARE_IN_FRAME(offset
, len
, 2)) {
437 advance
= 8 + ((pd
[offset
+1] - 1) << 2);
438 if (!BYTES_ARE_IN_FRAME(offset
, len
, advance
)) {
445 case IP_PROTO_SHIM6_OLD
:
446 if (!BYTES_ARE_IN_FRAME(offset
, len
, 2)) {
451 advance
= (pd
[offset
+1] + 1) << 3;
452 if (!BYTES_ARE_IN_FRAME(offset
, len
, advance
)) {
468 case IP_PROTO_UDPLITE
:
472 case IP_PROTO_ICMPV6
: /* XXX - separate counters? */
491 * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
493 /* XXX Currently unused
494 static inline gboolean in6_is_addr_link_local(struct e_in6_addr *a) {
495 if ((a->bytes[0] == 0xfe) && ((a->bytes[1] & 0xc0) == 0x80)) {
501 static inline gboolean in6_is_addr_sitelocal(struct e_in6_addr *a) {
502 if ((a->bytes[0] == 0xfe) && ((a->bytes[1] & 0xc0) == 0xc0)) {
512 static inline gboolean
in6_is_addr_multicast(struct e_in6_addr
*a
) {
513 if (a
->bytes
[0] == 0xff) {
521 add_geoip_info_entry(proto_tree
*geoip_info_item
, tvbuff_t
*tvb
, gint offset
, const struct e_in6_addr
*ip
, int isdst
)
523 proto_tree
*geoip_info_tree
;
525 guint num_dbs
= geoip_db_num_dbs();
529 geoip_info_tree
= proto_item_add_subtree(geoip_info_item
, ett_geoip_info
);
531 for (dbnum
= 0; dbnum
< num_dbs
; dbnum
++) {
532 const char *geoip_str
= geoip_db_lookup_ipv6(dbnum
, *ip
, NULL
);
533 int db_type
= geoip_db_type(dbnum
);
535 int geoip_hf
, geoip_local_hf
;
538 case GEOIP_COUNTRY_EDITION_V6
:
539 geoip_hf
= hf_geoip_country
;
540 geoip_local_hf
= (isdst
) ? hf_geoip_dst_country
: hf_geoip_src_country
;
542 #if NUM_DB_TYPES > 31
543 case GEOIP_CITY_EDITION_REV0_V6
:
544 case GEOIP_CITY_EDITION_REV1_V6
:
545 geoip_hf
= hf_geoip_city
;
546 geoip_local_hf
= (isdst
) ? hf_geoip_dst_city
: hf_geoip_src_city
;
548 case GEOIP_ORG_EDITION_V6
:
549 geoip_hf
= hf_geoip_org
;
550 geoip_local_hf
= (isdst
) ? hf_geoip_dst_org
: hf_geoip_src_org
;
552 case GEOIP_ISP_EDITION_V6
:
553 geoip_hf
= hf_geoip_isp
;
554 geoip_local_hf
= (isdst
) ? hf_geoip_dst_isp
: hf_geoip_src_isp
;
556 case GEOIP_ASNUM_EDITION_V6
:
557 geoip_hf
= hf_geoip_asnum
;
558 geoip_local_hf
= (isdst
) ? hf_geoip_dst_asnum
: hf_geoip_src_asnum
;
560 #endif /* DB_NUM_TYPES */
561 case WS_LAT_FAKE_EDITION
:
562 geoip_hf
= hf_geoip_lat
;
563 geoip_local_hf
= (isdst
) ? hf_geoip_dst_lat
: hf_geoip_src_lat
;
565 case WS_LON_FAKE_EDITION
:
566 geoip_hf
= hf_geoip_lon
;
567 geoip_local_hf
= (isdst
) ? hf_geoip_dst_lon
: hf_geoip_src_lon
;
576 if (db_type
== WS_LAT_FAKE_EDITION
|| db_type
== WS_LON_FAKE_EDITION
) {
577 /* Convert latitude, longitude to double. Fix bug #5077 */
578 item
= proto_tree_add_double_format_value(geoip_info_tree
, geoip_local_hf
, tvb
,
579 offset
, 16, g_ascii_strtod(geoip_str
, NULL
), "%s", geoip_str
);
580 PROTO_ITEM_SET_GENERATED(item
);
581 item
= proto_tree_add_double_format_value(geoip_info_tree
, geoip_hf
, tvb
,
582 offset
, 16, g_ascii_strtod(geoip_str
, NULL
), "%s", geoip_str
);
583 PROTO_ITEM_SET_GENERATED(item
);
584 PROTO_ITEM_SET_HIDDEN(item
);
586 item
= proto_tree_add_unicode_string(geoip_info_tree
, geoip_local_hf
, tvb
,
587 offset
, 16, geoip_str
);
588 PROTO_ITEM_SET_GENERATED(item
);
589 item
= proto_tree_add_unicode_string(geoip_info_tree
, geoip_hf
, tvb
,
590 offset
, 16, geoip_str
);
591 PROTO_ITEM_SET_GENERATED(item
);
592 PROTO_ITEM_SET_HIDDEN(item
);
596 proto_item_append_text(geoip_info_item
, "%s%s", plurality(item_cnt
, "", ", "), geoip_str
);
601 proto_item_append_text(geoip_info_item
, "Unknown");
605 add_geoip_info(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
, const struct e_in6_addr
*src
, const struct e_in6_addr
*dst
)
608 proto_item
*geoip_info_item
;
610 num_dbs
= geoip_db_num_dbs();
614 geoip_info_item
= proto_tree_add_text(tree
, tvb
, offset
+ IP6H_SRC
, 16, "Source GeoIP: ");
615 PROTO_ITEM_SET_GENERATED(geoip_info_item
);
616 add_geoip_info_entry(geoip_info_item
, tvb
, offset
+ IP6H_SRC
, src
, 0);
618 geoip_info_item
= proto_tree_add_text(tree
, tvb
, offset
+ IP6H_DST
, 16, "Destination GeoIP: ");
619 PROTO_ITEM_SET_GENERATED(geoip_info_item
);
620 add_geoip_info_entry(geoip_info_item
, tvb
, offset
+ IP6H_DST
, dst
, 1);
622 #endif /* HAVE_GEOIP_V6 */
625 ipv6_reassemble_init(void)
627 reassembly_table_init(&ipv6_reassembly_table
,
628 &addresses_reassembly_table_functions
);
632 IPv6_RT_HEADER_SOURCE_ROUTING
=0,
633 IPv6_RT_HEADER_NIMROD
,
634 IPv6_RT_HEADER_MobileIP
,
638 /* Routing Header Types */
639 static const value_string routing_header_type
[] = {
640 { IPv6_RT_HEADER_SOURCE_ROUTING
, "IPv6 Source Routing" },
641 { IPv6_RT_HEADER_NIMROD
, "Nimrod" },
642 { IPv6_RT_HEADER_MobileIP
, "Mobile IP" },
643 { IPv6_RT_HEADER_RPL
, "RPL" },
648 dissect_routing6(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
*pinfo
) {
651 proto_tree
*rthdr_tree
;
653 guint8 buf
[sizeof(struct ip6_rthdr0
) + sizeof(struct e_in6_addr
) * 23];
655 tvb_memcpy(tvb
, (guint8
*)&rt
, offset
, sizeof(rt
));
656 len
= (rt
.ip6r_len
+ 1) << 3;
658 /* Assigning seg_left and the if (seg_left) {} blocks of code that follow,
659 * along with any expert_add_info() calls, all need to execute when
660 * appropriate, regardless of whether the tree is NULL or not. */
662 /* !!! specify length */
663 ti
= proto_tree_add_uint_format(tree
, hf_ipv6_routing_hdr_opt
, tvb
,
664 offset
, len
, rt
.ip6r_type
,
665 "Routing Header, Type : %s (%u)",
666 val_to_str_const(rt
.ip6r_type
, routing_header_type
, "Unknown"),
668 rthdr_tree
= proto_item_add_subtree(ti
, ett_ipv6
);
670 proto_tree_add_text(rthdr_tree
, tvb
,
671 offset
+ (int)offsetof(struct ip6_rthdr
, ip6r_nxt
), 1,
672 "Next header: %s (%u)", ipprotostr(rt
.ip6r_nxt
), rt
.ip6r_nxt
);
674 proto_tree_add_text(rthdr_tree
, tvb
,
675 offset
+ (int)offsetof(struct ip6_rthdr
, ip6r_len
), 1,
676 "Length: %u (%d bytes)", rt
.ip6r_len
, len
);
678 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_type
, tvb
,
679 offset
+ (int)offsetof(struct ip6_rthdr
, ip6r_type
), 1, ENC_BIG_ENDIAN
);
681 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_left
, tvb
,
682 offset
+ (int)offsetof(struct ip6_rthdr
, ip6r_segleft
), 1, ENC_BIG_ENDIAN
);
684 seg_left
= tvb_get_guint8(tvb
, offset
+ (int)offsetof(struct ip6_rthdr
, ip6r_segleft
));
686 if (rt
.ip6r_type
== IPv6_RT_HEADER_SOURCE_ROUTING
&& len
<= sizeof(buf
)) {
687 struct e_in6_addr
*a
;
689 struct ip6_rthdr0
*rt0
;
691 tvb_memcpy(tvb
, buf
, offset
, len
);
692 rt0
= (struct ip6_rthdr0
*)buf
;
694 for (a
= rt0
->ip6r0_addr
, n
= 0;
695 a
< (struct e_in6_addr
*)(buf
+ len
); a
++, n
++) {
697 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_addr
, tvb
,
698 offset
+ (int)(offsetof(struct ip6_rthdr0
, ip6r0_addr
)
699 + n
* sizeof(struct e_in6_addr
)),
700 (int)sizeof(struct e_in6_addr
), ENC_NA
);
702 TVB_SET_ADDRESS(&pinfo
->dst
, AT_IPv6
, tvb
,
703 offset
+ (int)offsetof(struct ip6_rthdr0
, ip6r0_addr
) + n
* (int)sizeof(struct e_in6_addr
), 16);
706 if (rt
.ip6r_type
== IPv6_RT_HEADER_MobileIP
) {
707 proto_tree_add_item(rthdr_tree
, hf_ipv6_mipv6_home_address
, tvb
,
708 offset
+ 8, 16, ENC_NA
);
710 TVB_SET_ADDRESS(&pinfo
->dst
, AT_IPv6
, tvb
, offset
+ 8, 16);
712 if (rt
.ip6r_type
== IPv6_RT_HEADER_RPL
) {
719 /* IPv6 destination address used for elided bytes */
720 struct e_in6_addr dstAddr
;
721 /* IPv6 source address used for strict checking */
722 struct e_in6_addr srcAddr
;
724 memcpy((guint8
*)&dstAddr
, (guint8
*)pinfo
->dst
.data
, pinfo
->dst
.len
);
725 memcpy((guint8
*)&srcAddr
, (guint8
*)pinfo
->src
.data
, pinfo
->src
.len
);
727 /* from RFC6554: Multicast addresses MUST NOT appear in the IPv6 Destination Address field */
728 if(g_ipv6_rpl_srh_strict_rfc_checking
&& in6_is_addr_multicast(&dstAddr
)){
729 expert_add_info(pinfo
, ti
, &ei_ipv6_dst_addr_not_multicast
);
732 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_cmprI
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
733 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_cmprE
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
734 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_pad
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
736 cmprI
= tvb_get_guint8(tvb
, offset
) & 0xF0;
737 cmprE
= tvb_get_guint8(tvb
, offset
) & 0x0F;
738 pad
= tvb_get_guint8(tvb
, offset
+ 1) & 0xF0;
740 /* Shift bytes over */
744 /* from RFC6554: when CmprI and CmprE are both 0, Pad MUST carry a value of 0 */
745 if(g_ipv6_rpl_srh_strict_rfc_checking
&& (cmprI
== 0 && cmprE
== 0 && pad
!= 0)){
746 expert_add_info_format(pinfo
, ti
, &ei_ipv6_cmpri_cmpre_pad
, "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was %d", pad
);
749 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_reserved
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
750 reserved
= tvb_get_bits32(tvb
, ((offset
+ 1) * 8) + 4, 20, ENC_BIG_ENDIAN
);
752 if(g_ipv6_rpl_srh_strict_rfc_checking
&& reserved
!= 0){
753 expert_add_info_format(pinfo
, ti
, &ei_ipv6_routing_hdr_rpl_reserved
, "Reserved field must equal 0 but instead was %d", reserved
);
757 n = (((Hdr Ext Len * 8) - Pad - (16 - CmprE)) / (16 - CmprI)) + 1 */
758 segments
= (((rt
.ip6r_len
* 8) - pad
- (16 - cmprE
)) / (16 - cmprI
)) + 1;
759 ti
= proto_tree_add_int(rthdr_tree
, hf_ipv6_routing_hdr_rpl_segments
, tvb
, offset
, 2, segments
);
760 PROTO_ITEM_SET_GENERATED(ti
);
763 /* This error should always be reported */
764 expert_add_info_format(pinfo
, ti
, &ei_ipv6_routing_hdr_rpl_segments_ge0
, "Calculated total segments must be greater than or equal to 0, instead was %d", segments
);
769 /* We use cmprI for internal (e.g.: not last) address for how many bytes to elide, so actual bytes present = 16-CmprI */
770 while(segments
> 1) {
771 struct e_in6_addr addr
;
773 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_addr
, tvb
, offset
, (16-cmprI
), ENC_NA
);
774 /* Display Full Address */
775 memcpy((guint8
*)&addr
, (guint8
*)&dstAddr
, sizeof(dstAddr
));
776 tvb_memcpy(tvb
, (guint8
*)&addr
+ cmprI
, offset
, (16-cmprI
));
777 ti
= proto_tree_add_ipv6(rthdr_tree
, hf_ipv6_routing_hdr_rpl_fulladdr
, tvb
, offset
, (16-cmprI
), (guint8
*)&addr
);
778 PROTO_ITEM_SET_GENERATED(ti
);
779 offset
+= (16-cmprI
);
782 if(g_ipv6_rpl_srh_strict_rfc_checking
){
784 /* The SRH MUST NOT specify a path that visits a node more than once. */
785 /* To do this, we will just check the current 'addr' against the next addresses */
788 tempSegments
= segments
; /* Has already been decremented above */
789 tempOffset
= offset
; /* Has already been moved */
790 while(tempSegments
> 1) {
791 struct e_in6_addr tempAddr
;
792 memcpy((guint8
*)&tempAddr
, (guint8
*)&dstAddr
, sizeof(dstAddr
));
793 tvb_memcpy(tvb
, (guint8
*)&tempAddr
+ cmprI
, tempOffset
, (16-cmprI
));
794 /* Compare the addresses */
795 if (memcmp(addr
.bytes
, tempAddr
.bytes
, 16) == 0) {
796 /* Found a later address that is the same */
797 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_mult_inst_same_addr
);
800 tempOffset
+= (16-cmprI
);
803 if (tempSegments
== 1) {
804 struct e_in6_addr tempAddr
;
806 memcpy((guint8
*)&tempAddr
, (guint8
*)&dstAddr
, sizeof(dstAddr
));
807 tvb_memcpy(tvb
, (guint8
*)&tempAddr
+ cmprE
, tempOffset
, (16-cmprE
));
808 /* Compare the addresses */
809 if (memcmp(addr
.bytes
, tempAddr
.bytes
, 16) == 0) {
810 /* Found a later address that is the same */
811 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_mult_inst_same_addr
);
814 /* IPv6 Source and Destination addresses of the encapsulating datagram (MUST) not appear in the SRH*/
815 if (memcmp(addr
.bytes
, srcAddr
.bytes
, 16) == 0) {
816 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_src_addr
);
819 if (memcmp(addr
.bytes
, dstAddr
.bytes
, 16) == 0) {
820 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_dst_addr
);
823 /* Multicast addresses MUST NOT appear in the in SRH */
824 if(in6_is_addr_multicast(&addr
)){
825 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_multicast_addr
);
830 /* We use cmprE for last address for how many bytes to elide, so actual bytes present = 16-CmprE */
832 struct e_in6_addr addr
;
834 proto_tree_add_item(rthdr_tree
, hf_ipv6_routing_hdr_rpl_addr
, tvb
, offset
, (16-cmprI
), ENC_NA
);
835 /* Display Full Address */
836 memcpy((guint8
*)&addr
, (guint8
*)&dstAddr
, sizeof(dstAddr
));
837 tvb_memcpy(tvb
, (guint8
*)&addr
+ cmprE
, offset
, (16-cmprE
));
838 ti
= proto_tree_add_ipv6(rthdr_tree
, hf_ipv6_routing_hdr_rpl_fulladdr
, tvb
, offset
, (16-cmprE
), (guint8
*)&addr
);
839 PROTO_ITEM_SET_GENERATED(ti
);
840 /* offset += (16-cmprE); */
842 if(g_ipv6_rpl_srh_strict_rfc_checking
){
843 /* IPv6 Source and Destination addresses of the encapsulating datagram (MUST) not appear in the SRH*/
844 if (memcmp(addr
.bytes
, srcAddr
.bytes
, 16) == 0) {
845 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_src_addr
);
848 if (memcmp(addr
.bytes
, dstAddr
.bytes
, 16) == 0) {
849 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_dst_addr
);
852 /* Multicast addresses MUST NOT appear in the in SRH */
853 if(in6_is_addr_multicast(&addr
)){
854 expert_add_info(pinfo
, ti
, &ei_ipv6_src_route_list_multicast_addr
);
866 dissect_frag6(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
,
867 guint16
*offlg
, guint32
*ident
) {
868 struct ip6_frag frag
;
871 proto_tree
*rthdr_tree
;
873 tvb_memcpy(tvb
, (guint8
*)&frag
, offset
, sizeof(frag
));
875 frag
.ip6f_offlg
= g_ntohs(frag
.ip6f_offlg
);
876 frag
.ip6f_ident
= g_ntohl(frag
.ip6f_ident
);
877 *offlg
= frag
.ip6f_offlg
;
878 *ident
= frag
.ip6f_ident
;
879 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
880 "IPv6 fragment (nxt=%s (%u) off=%u id=0x%x)",
881 ipprotostr(frag
.ip6f_nxt
), frag
.ip6f_nxt
,
882 (frag
.ip6f_offlg
& IP6F_OFF_MASK
) >> IP6F_OFF_SHIFT
, frag
.ip6f_ident
);
885 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
,
886 "Fragmentation Header");
887 rthdr_tree
= proto_item_add_subtree(ti
, ett_ipv6
);
889 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_nxt
, tvb
,
890 offset
+ (int)offsetof(struct ip6_frag
, ip6f_nxt
), 1,
893 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_reserved
, tvb
,
894 offset
+ (int)offsetof(struct ip6_frag
, ip6f_reserved
), 1,
897 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_offset
, tvb
,
898 offset
+ (int)offsetof(struct ip6_frag
, ip6f_offlg
), 2, ENC_BIG_ENDIAN
);
899 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_reserved_bits
, tvb
,
900 offset
+ (int)offsetof(struct ip6_frag
, ip6f_offlg
), 2, ENC_BIG_ENDIAN
);
901 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_more
, tvb
,
902 offset
+ (int)offsetof(struct ip6_frag
, ip6f_offlg
), 2, ENC_BIG_ENDIAN
);
903 proto_tree_add_item(rthdr_tree
, hf_ipv6_frag_id
, tvb
,
904 offset
+ (int)offsetof(struct ip6_frag
, ip6f_ident
), 4, ENC_BIG_ENDIAN
);
909 static const value_string rtalertvals
[] = {
910 { IP6OPT_RTALERT_MLD
, "MLD" },
911 { IP6OPT_RTALERT_RSVP
, "RSVP" },
912 { IP6OPT_RTALERT_ACTNET
, "Active Network" },
917 dissect_unknown_option(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
920 proto_tree
*unkopt_tree
;
921 proto_item
*ti
, *ti_len
;
923 len
= (tvb_get_guint8(tvb
, offset
+ 1) + 1) << 3;
926 /* !!! specify length */
927 ti
= proto_tree_add_item(tree
, hf_ipv6_unk_hdr
, tvb
, offset
, len
, ENC_NA
);
929 unkopt_tree
= proto_item_add_subtree(ti
, ett_ipv6
);
931 proto_tree_add_item(unkopt_tree
, hf_ipv6_nxt
, tvb
, offset
, 1, ENC_NA
);
934 ti_len
= proto_tree_add_item(unkopt_tree
, hf_ipv6_opt_length
, tvb
, offset
, 1, ENC_NA
);
935 proto_item_append_text(ti_len
, " (%d byte%s)", len
, plurality(len
, "", "s"));
942 dissect_opts(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
* pinfo
, const int hf_option_item
)
946 proto_tree
*dstopt_tree
, *opt_tree
;
947 proto_item
*ti
, *ti_len
, *ti_opt
, *ti_opt_len
;
948 guint8 opt_len
, opt_type
;
950 len
= (tvb_get_guint8(tvb
, offset
+ 1) + 1) << 3;
951 offset_end
= offset
+ len
;
954 /* !!! specify length */
955 ti
= proto_tree_add_item(tree
, hf_option_item
, tvb
, offset
, len
, ENC_NA
);
957 dstopt_tree
= proto_item_add_subtree(ti
, ett_ipv6
);
959 proto_tree_add_item(dstopt_tree
, hf_ipv6_nxt
, tvb
, offset
, 1, ENC_NA
);
962 ti_len
= proto_tree_add_item(dstopt_tree
, hf_ipv6_opt_length
, tvb
, offset
, 1, ENC_NA
);
963 proto_item_append_text(ti_len
, " (%d byte%s)", len
, plurality(len
, "", "s"));
966 while (offset_end
> offset
) {
967 /* there are more options */
970 ti_opt
= proto_tree_add_item(dstopt_tree
, hf_ipv6_opt
, tvb
, offset
, 1, ENC_NA
);
971 opt_tree
= proto_item_add_subtree(ti_opt
, ett_ipv6_opt
);
974 proto_tree_add_item(opt_tree
, hf_ipv6_opt_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
975 opt_type
= tvb_get_guint8(tvb
, offset
);
977 /* Add option name to option root label */
978 proto_item_append_text(ti_opt
, " (%s", val_to_str(opt_type
, ipv6_opt_vals
, "Unknown %d"));
980 /* The Pad1 option is a special case, and contains no data. */
981 if (opt_type
== IP6OPT_PAD1
) {
982 proto_tree_add_item(opt_tree
, hf_ipv6_opt_pad1
, tvb
, offset
, 1, ENC_NA
);
984 proto_item_append_text(ti_opt
, ")");
990 ti_opt_len
= proto_tree_add_item(opt_tree
, hf_ipv6_opt_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
991 opt_len
= tvb_get_guint8(tvb
, offset
);
992 proto_item_set_len(ti_opt
, opt_len
+ 2);
998 * "The PadN option is used to insert two or more octets of
999 * padding into the Options area of a header. For N octets of
1000 * padding, the Opt Data Len field contains the value N-2, and
1001 * the Option Data consists of N-2 zero-valued octets."
1003 proto_tree_add_item(opt_tree
, hf_ipv6_opt_padn
, tvb
,
1004 offset
, opt_len
, ENC_NA
);
1009 expert_add_info_format(pinfo
, ti_opt_len
, &ei_ipv6_opt_tel_invalid_len
,
1010 "Tunnel Encapsulation Limit: Invalid length (%u bytes)", opt_len
);
1012 proto_tree_add_item(opt_tree
, hf_ipv6_opt_tel
, tvb
,
1013 offset
, 1, ENC_BIG_ENDIAN
);
1018 expert_add_info_format(pinfo
, ti_opt_len
, &ei_ipv6_opt_jumbo_invalid_len
,
1019 "Jumbo payload: Invalid length (%u bytes)", opt_len
);
1021 proto_tree_add_item(opt_tree
, hf_ipv6_opt_jumbo
, tvb
,
1022 offset
, 4, ENC_BIG_ENDIAN
);
1025 case IP6OPT_RTALERT
:
1028 expert_add_info_format(pinfo
, ti_opt_len
, &ei_ipv6_opt_rtalert_invalid_len
,
1029 "Router alert: Invalid Length (%u bytes)",
1032 proto_tree_add_item(opt_tree
, hf_ipv6_opt_rtalert
, tvb
,
1033 offset
, 2, ENC_BIG_ENDIAN
);
1037 case IP6OPT_HOME_ADDRESS
:
1038 if (opt_len
!= 16) {
1039 expert_add_info_format(pinfo
, ti_opt_len
, &ei_ipv6_mipv6_home_address_invalid_len
,
1040 "Home Address: Invalid length (%u bytes)", opt_len
);
1042 proto_tree_add_item(opt_tree
, hf_ipv6_mipv6_home_address
, tvb
,
1043 offset
, 16, ENC_NA
);
1044 TVB_SET_ADDRESS(&pinfo
->src
, AT_IPv6
, tvb
, offset
, 16);
1047 case IP6OPT_CALIPSO
:
1050 proto_tree_add_item(opt_tree
, hf_ipv6_opt_calipso_doi
, tvb
,
1051 offset
, 4, ENC_BIG_ENDIAN
);
1053 proto_tree_add_item(opt_tree
, hf_ipv6_opt_calipso_cmpt_length
, tvb
,
1054 offset
, 1, ENC_BIG_ENDIAN
);
1055 cmpt_length
= tvb_get_guint8(tvb
, offset
);
1057 proto_tree_add_item(opt_tree
, hf_ipv6_opt_calipso_sens_level
, tvb
,
1058 offset
, 1, ENC_BIG_ENDIAN
);
1060 /* Need to add Check Checksum..*/
1061 proto_tree_add_item(opt_tree
, hf_ipv6_opt_calipso_checksum
, tvb
,
1062 offset
, 2, ENC_BIG_ENDIAN
);
1064 proto_tree_add_item(opt_tree
, hf_ipv6_opt_calipso_cmpt_bitmap
, tvb
,
1065 offset
, cmpt_length
, ENC_NA
);
1066 offset
+= cmpt_length
;
1069 case IP6OPT_QUICKSTART
:
1072 guint8 command
= tvb_get_guint8(tvb
, offset
);
1073 guint8 function
= command
>> 4;
1074 guint8 rate
= command
& QS_RATE_MASK
;
1077 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_func
, tvb
, offset
, 1, ENC_NA
);
1079 if (function
== QS_RATE_REQUEST
) {
1080 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_rate
, tvb
, offset
, 1, ENC_NA
);
1082 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_ttl
, tvb
, offset
, 1, ENC_NA
);
1083 ttl_diff
= (pinfo
->ip_ttl
- tvb_get_guint8(tvb
, offset
) % 256);
1085 ti
= proto_tree_add_uint_format_value(opt_tree
, hf_ipv6_opt_qs_ttl_diff
,
1086 tvb
, offset
, 1, ttl_diff
,
1088 PROTO_ITEM_SET_GENERATED(ti
);
1089 proto_item_append_text(ti_opt
, ", %s, QS TTL %u, QS TTL diff %u",
1090 val_to_str_ext(rate
, &qs_rate_vals_ext
, "Unknown (%u)"),
1091 tvb_get_guint8(tvb
, offset
), ttl_diff
);
1093 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_nonce
, tvb
, offset
, 4, ENC_NA
);
1094 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_reserved
, tvb
, offset
, 4, ENC_NA
);
1096 } else if (function
== QS_RATE_REPORT
) {
1097 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_rate
, tvb
, offset
, 1, ENC_NA
);
1099 proto_item_append_text(ti_opt
, ", %s",
1100 val_to_str_ext(rate
, &qs_rate_vals_ext
, "Unknown (%u)"));
1101 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_unused
, tvb
, offset
, 1, ENC_NA
);
1103 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_nonce
, tvb
, offset
, 4, ENC_NA
);
1104 proto_tree_add_item(opt_tree
, hf_ipv6_opt_qs_reserved
, tvb
, offset
, 4, ENC_NA
);
1112 proto_tree
*flag_tree
;
1113 proto_item
*ti_flag
;
1115 ti_flag
= proto_tree_add_item(opt_tree
, hf_ipv6_opt_rpl_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1116 flag_tree
= proto_item_add_subtree(ti_flag
, ett_ipv6_opt_flag
);
1117 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_flag_o
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1118 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_flag_r
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1119 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_flag_f
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1120 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_flag_rsv
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1123 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_instance_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1126 proto_tree_add_item(flag_tree
, hf_ipv6_opt_rpl_senderrank
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1129 /* TODO: Add dissector of sub TLV */
1140 proto_tree_add_item(opt_tree
, hf_ipv6_opt_experimental
, tvb
,
1141 offset
, opt_len
, ENC_NA
);
1145 proto_tree_add_item(opt_tree
, hf_ipv6_opt_unknown
, tvb
,
1146 offset
, opt_len
, ENC_NA
);
1150 /* Close the ) to option root label */
1151 proto_item_append_text(ti_opt
, ")");
1159 dissect_hopopts(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
* pinfo
)
1161 return dissect_opts(tvb
, offset
, tree
, pinfo
, hf_ipv6_hop_opt
);
1165 dissect_dstopts(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
* pinfo
)
1167 return dissect_opts(tvb
, offset
, tree
, pinfo
, hf_ipv6_dst_opt
);
1170 /* START SHIM6 PART */
1171 static guint16
shim_checksum(const guint8
*ptr
, int len
)
1175 cksum_vec
[0].ptr
= ptr
;
1176 cksum_vec
[0].len
= len
;
1177 return in_cksum(&cksum_vec
[0], 1);
1181 dissect_shim_hex(tvbuff_t
*tvb
, int offset
, int len
, const char *itemname
, guint8 bitmask
, proto_tree
*tree
)
1189 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
, "%s", itemname
);
1191 proto_item_append_text(ti
, " 0x%02x", tvb_get_guint8(tvb
, p
) & bitmask
);
1192 for (count
=1; count
<len
; count
++)
1193 proto_item_append_text(ti
, "%02x", tvb_get_guint8(tvb
, p
+count
));
1198 static const value_string shimoptvals
[] = {
1199 { SHIM6_OPT_RESPVAL
, "Responder Validator Option" },
1200 { SHIM6_OPT_LOCLIST
, "Locator List Option" },
1201 { SHIM6_OPT_LOCPREF
, "Locator Preferences Option" },
1202 { SHIM6_OPT_CGAPDM
, "CGA Parameter Data Structure Option" },
1203 { SHIM6_OPT_CGASIG
, "CGA Signature Option" },
1204 { SHIM6_OPT_ULIDPAIR
, "ULID Pair Option" },
1205 { SHIM6_OPT_FII
, "Forked Instance Identifier Option" },
1209 static const value_string shimverifmethods
[] = {
1210 { SHIM6_VERIF_HBA
, "HBA" },
1211 { SHIM6_VERIF_CGA
, "CGA" },
1215 static const value_string shimflags
[] _U_
= {
1216 { SHIM6_FLAG_BROKEN
, "BROKEN" },
1217 { SHIM6_FLAG_TEMPORARY
, "TEMPORARY" },
1221 static const value_string shimreapstates
[] = {
1222 { SHIM6_REAP_OPERATIONAL
, "Operational" },
1223 { SHIM6_REAP_EXPLORING
, "Exploring" },
1224 { SHIM6_REAP_INBOUNDOK
, "InboundOK" },
1228 static const value_string shim6_protocol
[] = {
1236 dissect_shim6_opt_loclist(proto_tree
* opt_tree
, tvbuff_t
* tvb
, gint
*offset
)
1239 proto_tree
* subtree
;
1244 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_loclist
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1247 optlen
= tvb_get_guint8(tvb
, p
);
1248 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_locnum
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
1251 /* Verification Methods */
1252 it
= proto_tree_add_text(opt_tree
, tvb
, p
, optlen
,
1253 "Locator Verification Methods");
1254 subtree
= proto_item_add_subtree(it
, ett_ipv6_shim6_verif_methods
);
1256 for (count
=0; count
< optlen
; count
++)
1257 proto_tree_add_item(subtree
, hf_ipv6_shim6_opt_loc_verif_methods
, tvb
,
1258 p
+count
, 1, ENC_BIG_ENDIAN
);
1261 /* Padding, included in length field */
1262 if ((7 - optlen
% 8) > 0) {
1263 proto_tree_add_text(opt_tree
, tvb
, p
, (7 - optlen
% 8), "Padding");
1264 p
+= (7 - optlen
% 8);
1268 it
= proto_tree_add_text(opt_tree
, tvb
, p
, 16 * optlen
, "Locators");
1269 subtree
= proto_item_add_subtree(it
, ett_ipv6_shim6_locators
);
1271 for (count
=0; count
< optlen
; count
++) {
1272 proto_tree_add_item(subtree
, hf_ipv6_shim6_locator
, tvb
, p
, 16, ENC_NA
);
1279 dissect_shim6_opt_loc_pref(proto_tree
* opt_tree
, tvbuff_t
* tvb
, gint
*offset
, gint len
, packet_info
*pinfo
)
1281 proto_tree
* subtree
;
1290 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_loclist
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1293 optlen
= tvb_get_guint8(tvb
, p
);
1294 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_elemlen
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
1296 if (optlen
< 1 || optlen
> 3) {
1297 proto_tree_add_expert_format(opt_tree
, pinfo
, &ei_ipv6_shim6_opt_elemlen_invalid
, tvb
, p
, 1,
1298 "Invalid element length: %u", optlen
);
1304 /* Locator Preferences */
1307 it
= proto_tree_add_text(opt_tree
, tvb
, p
, optlen
, "Locator Preferences %u", count
);
1308 subtree
= proto_item_add_subtree(it
, ett_ipv6_shim6_loc_pref
);
1312 proto_tree_add_item(subtree
, hf_ipv6_shim6_loc_flag
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
1315 proto_tree_add_item(subtree
, hf_ipv6_shim6_loc_prio
, tvb
, p
+1, 1, ENC_BIG_ENDIAN
);
1318 proto_tree_add_item(subtree
, hf_ipv6_shim6_loc_weight
, tvb
, p
+2, 1, ENC_BIG_ENDIAN
);
1320 * Shim6 Draft 08 doesn't specify the format when the Element length is
1321 * more than three, except that any such formats MUST be defined so that
1322 * the first three octets are the same as in the above case, that is, a
1323 * of a 1 octet flags field followed by a 1 octet priority field, and a
1324 * 1 octet weight field.
1334 dissect_shimopts(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
*pinfo
)
1339 proto_tree
*opt_tree
;
1348 len
= tvb_get_ntohs(tvb
, offset
+2);
1349 padding
= 7 - ((len
+ 3) % 8);
1350 total_len
= 4 + len
+ padding
;
1355 ctype
= val_to_str_const( (tvb_get_ntohs(tvb
, offset
) & SHIM6_BITMASK_OPT_TYPE
) >> 1, shimoptvals
, "Unknown Option Type");
1356 ti
= proto_tree_add_text(tree
, tvb
, offset
, total_len
, "%s", ctype
);
1357 opt_tree
= proto_item_add_subtree(ti
, ett_ipv6_shim6_option
);
1359 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1362 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_critical
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
1364 /* Content Length */
1365 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_len
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
1366 ti
= proto_tree_add_uint(opt_tree
, hf_ipv6_shim6_opt_total_len
, tvb
, offset
+2, 2, total_len
);
1367 PROTO_ITEM_SET_GENERATED(ti
);
1369 /* Option Type Specific */
1370 switch (tvb_get_ntohs(tvb
, offset
) >> 1)
1372 case SHIM6_OPT_RESPVAL
:
1373 p
+= dissect_shim_hex(tvb
, p
, len
, "Validator:", 0xff, opt_tree
);
1374 if (total_len
-(len
+4) > 0)
1375 proto_tree_add_text(opt_tree
, tvb
, p
, total_len
-(len
+4), "Padding");
1377 case SHIM6_OPT_LOCLIST
:
1378 dissect_shim6_opt_loclist(opt_tree
, tvb
, &p
);
1380 case SHIM6_OPT_LOCPREF
:
1381 dissect_shim6_opt_loc_pref(opt_tree
, tvb
, &p
, offset
+len
+4, pinfo
);
1382 if (total_len
-(len
+4) > 0)
1383 proto_tree_add_text(opt_tree
, tvb
, p
, total_len
-(len
+4), "Padding");
1385 case SHIM6_OPT_CGAPDM
:
1386 p
+= dissect_shim_hex(tvb
, p
, len
, "CGA Parameter Data Structure:", 0xff, opt_tree
);
1387 if (total_len
-(len
+4) > 0)
1388 proto_tree_add_text(opt_tree
, tvb
, p
, total_len
-(len
+4), "Padding");
1390 case SHIM6_OPT_CGASIG
:
1391 p
+= dissect_shim_hex(tvb
, p
, len
, "CGA Signature:", 0xff, opt_tree
);
1392 if (total_len
-(len
+4) > 0)
1393 proto_tree_add_text(opt_tree
, tvb
, p
, total_len
-(len
+4), "Padding");
1395 case SHIM6_OPT_ULIDPAIR
:
1396 proto_tree_add_text(opt_tree
, tvb
, p
, 4, "Reserved");
1398 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_sulid
, tvb
, p
, 16, ENC_NA
);
1400 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_rulid
, tvb
, p
, 16, ENC_NA
);
1404 proto_tree_add_item(opt_tree
, hf_ipv6_shim6_opt_fii
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1415 dissect_shim6_ct(proto_tree
* shim_tree
, gint hf_item
, tvbuff_t
* tvb
, gint offset
, const guchar
* label
)
1420 tmp
[0] = tvb_get_guint8(tvb
, offset
++);
1421 tmp
[1] = tvb_get_guint8(tvb
, offset
++);
1422 tmp
[2] = tvb_get_guint8(tvb
, offset
++);
1423 tmp
[3] = tvb_get_guint8(tvb
, offset
++);
1424 tmp
[4] = tvb_get_guint8(tvb
, offset
++);
1425 tmp
[5] = tvb_get_guint8(tvb
, offset
++);
1427 ct_str
= wmem_strdup_printf(wmem_packet_scope(),
1428 "%s: %02X %02X %02X %02X %02X %02X", label
,
1429 tmp
[0] & SHIM6_BITMASK_CT
, tmp
[1], tmp
[2],
1430 tmp
[3], tmp
[4], tmp
[5]
1432 proto_tree_add_none_format(shim_tree
, hf_item
, tvb
, offset
- 6, 6, "%s", ct_str
);
1436 dissect_shim6_probes(proto_tree
* shim_tree
, tvbuff_t
* tvb
, gint offset
,
1437 const guchar
* label
, guint nbr_probe
,
1438 gboolean probes_rcvd
)
1440 proto_tree
* probes_tree
;
1441 proto_tree
* probe_tree
;
1448 ett_probes
= ett_ipv6_shim6_probes_rcvd
;
1449 ett_probe
= ett_ipv6_shim6_probe_rcvd
;
1451 ett_probes
= ett_ipv6_shim6_probes_sent
;
1452 ett_probe
= ett_ipv6_shim6_probe_sent
;
1454 it
= proto_tree_add_text(shim_tree
, tvb
, offset
, 40 * nbr_probe
, "%s", label
);
1455 probes_tree
= proto_item_add_subtree(it
, ett_probes
);
1457 for (count
=0; count
< nbr_probe
; count
++) {
1458 it
= proto_tree_add_text(probes_tree
, tvb
, offset
, 40, "Probe %u", count
+1);
1459 probe_tree
= proto_item_add_subtree(it
, ett_probe
);
1461 proto_tree_add_item(probe_tree
, hf_ipv6_shim6_psrc
, tvb
, offset
, 16, ENC_NA
);
1463 proto_tree_add_item(probe_tree
, hf_ipv6_shim6_pdst
, tvb
, offset
, 16, ENC_NA
);
1466 proto_tree_add_item(probe_tree
, hf_ipv6_shim6_pnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1469 proto_tree_add_item(probe_tree
, hf_ipv6_shim6_pdata
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1474 /* Dissect SHIM6 data: control messages */
1476 dissect_shimctrl(tvbuff_t
*tvb
, gint offset
, guint type
, proto_tree
*shim_tree
)
1489 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Initiator Context Tag");
1491 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_inonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1495 proto_tree_add_text(shim_tree
, tvb
, p
, 2, "Reserved2");
1497 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_inonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1499 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_rnonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1503 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Initiator Context Tag");
1505 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_inonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1507 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_rnonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1509 proto_tree_add_text(shim_tree
, tvb
, p
, 4, "Reserved2");
1513 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Responder Context Tag");
1515 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_inonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1518 case SHIM6_TYPE_R1BIS
:
1519 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Packet Context Tag");
1521 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_rnonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1524 case SHIM6_TYPE_I2BIS
:
1525 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Initiator Context Tag");
1527 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_inonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1529 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_rnonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1531 proto_tree_add_text(shim_tree
, tvb
, p
, 6, "Reserved2");
1533 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Initiator Context Tag");
1536 case SHIM6_TYPE_UPD_REQ
:
1537 case SHIM6_TYPE_UPD_ACK
:
1538 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Receiver Context Tag");
1540 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_rnonce
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
1543 case SHIM6_TYPE_KEEPALIVE
:
1544 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Receiver Context Tag");
1546 proto_tree_add_text(shim_tree
, tvb
, p
, 4, "Reserved2");
1549 case SHIM6_TYPE_PROBE
:
1550 dissect_shim6_ct(shim_tree
, hf_ipv6_shim6_ct
, tvb
, p
, "Receiver Context Tag");
1553 tmp
= tvb_get_guint8(tvb
, p
);
1554 probes_sent
= tmp
& SHIM6_BITMASK_PSENT
;
1555 probes_rcvd
= (tmp
& SHIM6_BITMASK_PRECVD
) >> 4;
1556 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_psent
, tvb
,
1557 p
, 1, ENC_BIG_ENDIAN
);
1558 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_precvd
, tvb
,
1559 p
, 1, ENC_BIG_ENDIAN
);
1562 sta
= val_to_str_const((tvb_get_guint8(tvb
, p
) & SHIM6_BITMASK_STA
) >> 6,
1563 shimreapstates
, "Unknown REAP State");
1564 proto_tree_add_uint_format_value(shim_tree
, hf_ipv6_shim6_reap
, tvb
,
1565 p
, 1, (tvb_get_guint8(tvb
, p
) & SHIM6_BITMASK_STA
) >> 6,
1568 proto_tree_add_text(shim_tree
, tvb
, p
, 3, "Reserved2");
1573 dissect_shim6_probes(shim_tree
, tvb
, p
, "Probes Sent",
1574 probes_sent
, FALSE
);
1575 p
+= 40 * probes_sent
;
1578 /* Probes Received */
1580 dissect_shim6_probes(shim_tree
, tvb
, p
, "Probes Received",
1582 p
+= 40 * probes_rcvd
;
1591 /* Dissect SHIM6 data: payload, common part, options */
1592 static const value_string shimctrlvals
[] = {
1593 { SHIM6_TYPE_I1
, "I1" },
1594 { SHIM6_TYPE_R1
, "R1" },
1595 { SHIM6_TYPE_I2
, "I2" },
1596 { SHIM6_TYPE_R2
, "R2" },
1597 { SHIM6_TYPE_R1BIS
, "R1bis" },
1598 { SHIM6_TYPE_I2BIS
, "I2bis" },
1599 { SHIM6_TYPE_UPD_REQ
, "Update Request" },
1600 { SHIM6_TYPE_UPD_ACK
, "Update Acknowledgment" },
1601 { SHIM6_TYPE_KEEPALIVE
, "Keepalive" },
1602 { SHIM6_TYPE_PROBE
, "Probe" },
1606 static void ipv6_shim6_checkum_additional_info(tvbuff_t
* tvb
, packet_info
* pinfo
,
1607 proto_item
* it_cksum
, int offset
, gboolean is_cksum_correct
)
1609 proto_tree
* checksum_tree
;
1612 checksum_tree
= proto_item_add_subtree(it_cksum
, ett_ipv6_shim6_cksum
);
1613 item
= proto_tree_add_boolean(checksum_tree
, hf_ipv6_shim6_checksum_good
, tvb
,
1614 offset
, 2, is_cksum_correct
);
1615 PROTO_ITEM_SET_GENERATED(item
);
1616 item
= proto_tree_add_boolean(checksum_tree
, hf_ipv6_shim6_checksum_bad
, tvb
,
1617 offset
, 2, !is_cksum_correct
);
1618 PROTO_ITEM_SET_GENERATED(item
);
1619 if (!is_cksum_correct
) {
1620 expert_add_info(pinfo
, item
, &ei_ipv6_shim6_checksum_bad
);
1621 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Shim6 CHECKSUM INCORRECT]");
1626 dissect_shim6(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
* pinfo
)
1628 struct ip6_shim shim
;
1631 proto_tree
*shim_tree
;
1635 tvb_memcpy(tvb
, (guint8
*)&shim
, offset
, sizeof(shim
));
1636 len
= (shim
.ip6s_len
+ 1) << 3;
1640 ti
= proto_tree_add_item(tree
, hf_ipv6_shim6
, tvb
, offset
, len
, ENC_NA
);
1641 shim_tree
= proto_item_add_subtree(ti
, ett_ipv6_shim6
);
1644 proto_tree_add_uint_format_value(shim_tree
, hf_ipv6_shim6_nxt
, tvb
,
1645 offset
+ (int)offsetof(struct ip6_shim
, ip6s_nxt
), 1, shim
.ip6s_nxt
,
1646 "%s (%u)", ipprotostr(shim
.ip6s_nxt
), shim
.ip6s_nxt
);
1648 /* Header Extension Length */
1649 proto_tree_add_uint_format_value(shim_tree
, hf_ipv6_shim6_len
, tvb
,
1650 offset
+ (int)offsetof(struct ip6_shim
, ip6s_len
), 1, shim
.ip6s_len
,
1651 "%u (%d bytes)", shim
.ip6s_len
, len
);
1654 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_p
, tvb
,
1655 offset
+ (int)offsetof(struct ip6_shim
, ip6s_p
), 1, ENC_BIG_ENDIAN
);
1657 /* skip the first 2 bytes (nxt hdr, hdr ext len, p+7bits) */
1660 if (shim
.ip6s_p
& SHIM6_BITMASK_P
)
1662 tmp
[0] = tvb_get_guint8(tvb
, p
++);
1663 tmp
[1] = tvb_get_guint8(tvb
, p
++);
1664 tmp
[2] = tvb_get_guint8(tvb
, p
++);
1665 tmp
[3] = tvb_get_guint8(tvb
, p
++);
1666 tmp
[4] = tvb_get_guint8(tvb
, p
++);
1668 /* Payload Extension Header */
1669 proto_tree_add_none_format(shim_tree
, hf_ipv6_shim6_ct
, tvb
,
1670 offset
+ (int)offsetof(struct ip6_shim
, ip6s_p
), 6,
1671 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
1672 shim
.ip6s_p
& SHIM6_BITMASK_CT
, tmp
[0], tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
1676 /* Control Message */
1681 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_type
, tvb
,
1682 offset
+ (int)offsetof(struct ip6_shim
, ip6s_p
), 1,
1686 /* Protocol bit (Must be zero for SHIM6) */
1687 proto_tree_add_item(shim_tree
, hf_ipv6_shim6_proto
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
1691 csum
= shim_checksum(tvb_get_ptr(tvb
, offset
, len
), len
);
1694 ti
= proto_tree_add_uint_format_value(shim_tree
, hf_ipv6_shim6_checksum
, tvb
, p
, 2,
1695 tvb_get_ntohs(tvb
, p
), "0x%04x [correct]", tvb_get_ntohs(tvb
, p
));
1696 ipv6_shim6_checkum_additional_info(tvb
, pinfo
, ti
, p
, TRUE
);
1698 ti
= proto_tree_add_uint_format_value(shim_tree
, hf_ipv6_shim6_checksum
, tvb
, p
, 2,
1699 tvb_get_ntohs(tvb
, p
), "0x%04x [incorrect: should be 0x%04x]",
1700 tvb_get_ntohs(tvb
, p
), in_cksum_shouldbe(tvb_get_ntohs(tvb
, p
), csum
));
1701 ipv6_shim6_checkum_additional_info(tvb
, pinfo
, ti
, p
, FALSE
);
1705 /* Type specific data */
1706 advance
= dissect_shimctrl(tvb
, p
, shim
.ip6s_p
& SHIM6_BITMASK_TYPE
, shim_tree
);
1710 while (p
< offset
+len
) {
1711 p
+= dissect_shimopts(tvb
, p
, shim_tree
, pinfo
);
1718 /* END SHIM6 PART */
1721 dissect_ipv6(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1723 proto_tree
*ipv6_tree
= NULL
;
1724 proto_item
*ipv6_item
= NULL
, *ti
;
1729 gboolean hopopts
, routing
, frag
, ah
, shim6
, dstopts
;
1733 fragment_head
*ipfd_head
;
1735 gboolean update_col_info
= TRUE
;
1736 gboolean save_fragmented
= FALSE
;
1737 const char *sep
= "IPv6 ";
1740 struct ip6_hdr ipv6
;
1742 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IPv6");
1743 col_clear(pinfo
->cinfo
, COL_INFO
);
1746 tvb_memcpy(tvb
, (guint8
*)&ipv6
, offset
, sizeof(ipv6
));
1748 /* Get extension header and payload length */
1749 plen
= g_ntohs(ipv6
.ip6_plen
);
1751 /* Adjust the length of this tvbuff to include only the IPv6 datagram. */
1752 set_actual_length(tvb
, plen
+ (guint
)sizeof (struct ip6_hdr
));
1754 TVB_SET_ADDRESS(&pinfo
->net_src
, AT_IPv6
, tvb
, offset
+ IP6H_SRC
, 16);
1755 TVB_SET_ADDRESS(&pinfo
->src
, AT_IPv6
, tvb
, offset
+ IP6H_SRC
, 16);
1756 TVB_SET_ADDRESS(&pinfo
->net_dst
, AT_IPv6
, tvb
, offset
+ IP6H_DST
, 16);
1757 TVB_SET_ADDRESS(&pinfo
->dst
, AT_IPv6
, tvb
, offset
+ IP6H_DST
, 16);
1762 proto_tree
*ipv6_tc_tree
;
1763 proto_item
*ipv6_tc
;
1766 ipv6_item
= proto_tree_add_item(tree
, proto_ipv6
, tvb
, offset
, -1, ENC_NA
);
1767 ipv6_tree
= proto_item_add_subtree(ipv6_item
, ett_ipv6
);
1769 /* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
1770 pi
= proto_tree_add_item(ipv6_tree
, hf_ipv6_version
, tvb
,
1771 offset
+ (int)offsetof(struct ip6_hdr
, ip6_vfc
), 1, ENC_BIG_ENDIAN
);
1772 pt
= proto_item_add_subtree(pi
,ett_ipv6_version
);
1773 pi
= proto_tree_add_item(pt
, hf_ip_version
, tvb
,
1774 offset
+ (int)offsetof(struct ip6_hdr
, ip6_vfc
), 1, ENC_BIG_ENDIAN
);
1775 PROTO_ITEM_SET_GENERATED(pi
);
1777 ipv6_tc
= proto_tree_add_item(ipv6_tree
, hf_ipv6_class
, tvb
,
1778 offset
+ (int)offsetof(struct ip6_hdr
, ip6_flow
), 4, ENC_BIG_ENDIAN
);
1780 ipv6_tc_tree
= proto_item_add_subtree(ipv6_tc
, ett_ipv6_traffic_class
);
1782 proto_tree_add_item(ipv6_tc_tree
, hf_ipv6_traffic_class_dscp
, tvb
,
1783 offset
+ (int)offsetof(struct ip6_hdr
, ip6_flow
), 4, ENC_BIG_ENDIAN
);
1784 proto_tree_add_item(ipv6_tc_tree
, hf_ipv6_traffic_class_ect
, tvb
,
1785 offset
+ (int)offsetof(struct ip6_hdr
, ip6_flow
), 4, ENC_BIG_ENDIAN
);
1787 proto_tree_add_item(ipv6_tc_tree
, hf_ipv6_traffic_class_ce
, tvb
,
1788 offset
+ (int)offsetof(struct ip6_hdr
, ip6_flow
), 4, ENC_BIG_ENDIAN
);
1790 proto_tree_add_item(ipv6_tree
, hf_ipv6_flow
, tvb
,
1791 offset
+ (int)offsetof(struct ip6_hdr
, ip6_flow
), 4, ENC_BIG_ENDIAN
);
1793 proto_tree_add_item(ipv6_tree
, hf_ipv6_plen
, tvb
,
1794 offset
+ (int)offsetof(struct ip6_hdr
, ip6_plen
), 2, ENC_BIG_ENDIAN
);
1796 proto_tree_add_uint_format_value(ipv6_tree
, hf_ipv6_nxt
, tvb
,
1797 offset
+ (int)offsetof(struct ip6_hdr
, ip6_nxt
), 1,
1800 ipprotostr(ipv6
.ip6_nxt
), ipv6
.ip6_nxt
);
1802 proto_tree_add_item(ipv6_tree
, hf_ipv6_hlim
, tvb
,
1803 offset
+ (int)offsetof(struct ip6_hdr
, ip6_hlim
), 1, ENC_BIG_ENDIAN
);
1804 /* Yes, there is not TTL in IPv6 Header... but it is the same of Hop Limit...*/
1805 pinfo
->ip_ttl
= tvb_get_guint8(tvb
, offset
+ (int)offsetof(struct ip6_hdr
, ip6_hlim
));
1807 /* Add the different items for the source address */
1808 proto_tree_add_item(ipv6_tree
, hf_ipv6_src
, tvb
,
1809 offset
+ (int)offsetof(struct ip6_hdr
, ip6_src
), 16, ENC_NA
);
1810 ti
= proto_tree_add_ipv6(ipv6_tree
, hf_ipv6_addr
, tvb
,
1811 offset
+ (int)offsetof(struct ip6_hdr
, ip6_src
),
1812 16, (guint8
*)&ipv6
.ip6_src
);
1813 PROTO_ITEM_SET_HIDDEN(ti
);
1814 name
= get_addr_name(&pinfo
->src
);
1815 if (ipv6_summary_in_tree
) {
1816 proto_item_append_text(ipv6_item
, ", Src: %s (%s)", name
, ip6_to_str(&ipv6
.ip6_src
));
1818 ti
= proto_tree_add_string(ipv6_tree
, hf_ipv6_src_host
, tvb
,
1819 offset
+ (int)offsetof(struct ip6_hdr
, ip6_src
),
1821 PROTO_ITEM_SET_GENERATED(ti
);
1822 PROTO_ITEM_SET_HIDDEN(ti
);
1823 ti
= proto_tree_add_string(ipv6_tree
, hf_ipv6_host
, tvb
,
1824 offset
+ (int)offsetof(struct ip6_hdr
, ip6_src
),
1826 PROTO_ITEM_SET_GENERATED(ti
);
1827 PROTO_ITEM_SET_HIDDEN(ti
);
1829 /* Extract embedded (IPv6 and MAC) address information */
1830 if (tvb_get_ntohs(tvb
, offset
+ IP6H_SRC
) == 0x2002) { /* RFC 3056 section 2 */
1831 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_src_6to4_gateway_ipv4
, tvb
,
1832 offset
+ IP6H_SRC
+ 2, 4, ENC_BIG_ENDIAN
);
1833 PROTO_ITEM_SET_GENERATED(ti
);
1834 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_src_6to4_sla_id
, tvb
,
1835 offset
+ IP6H_SRC
+ 6, 2, ENC_BIG_ENDIAN
);
1836 PROTO_ITEM_SET_GENERATED(ti
);
1837 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_6to4_gateway_ipv4
, tvb
,
1838 offset
+ IP6H_SRC
+ 2, 4, ENC_BIG_ENDIAN
);
1839 PROTO_ITEM_SET_GENERATED(ti
);
1840 PROTO_ITEM_SET_HIDDEN(ti
);
1841 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_6to4_sla_id
, tvb
,
1842 offset
+ IP6H_SRC
+ 6, 2, ENC_BIG_ENDIAN
);
1843 PROTO_ITEM_SET_GENERATED(ti
);
1844 PROTO_ITEM_SET_HIDDEN(ti
);
1845 } else if (tvb_get_ntohl(tvb
, offset
+ IP6H_SRC
) == 0x20010000) { /* RFC 4380 section 4 */
1846 guint16 mapped_port
= tvb_get_ntohs(tvb
, offset
+ IP6H_SRC
+ 10) ^ 0xffff;
1847 guint32 client_v4
= tvb_get_ipv4(tvb
, offset
+ IP6H_SRC
+ 12) ^ 0xffffffff;
1849 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_src_teredo_server_ipv4
, tvb
,
1850 offset
+ IP6H_SRC
+ 4, 4, ENC_BIG_ENDIAN
);
1851 PROTO_ITEM_SET_GENERATED(ti
);
1852 ti
= proto_tree_add_uint(ipv6_tree
, hf_ipv6_src_teredo_port
, tvb
,
1853 offset
+ IP6H_SRC
+ 10, 2, mapped_port
);
1854 PROTO_ITEM_SET_GENERATED(ti
);
1855 ti
= proto_tree_add_ipv4(ipv6_tree
, hf_ipv6_src_teredo_client_ipv4
, tvb
,
1856 offset
+ IP6H_SRC
+ 12, 4, client_v4
);
1857 PROTO_ITEM_SET_GENERATED(ti
);
1858 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_teredo_server_ipv4
, tvb
,
1859 offset
+ IP6H_SRC
+ 4, 4, ENC_BIG_ENDIAN
);
1860 PROTO_ITEM_SET_GENERATED(ti
);
1861 PROTO_ITEM_SET_HIDDEN(ti
);
1862 ti
= proto_tree_add_uint(ipv6_tree
, hf_ipv6_teredo_port
, tvb
,
1863 offset
+ IP6H_SRC
+ 10, 2, mapped_port
);
1864 PROTO_ITEM_SET_GENERATED(ti
);
1865 PROTO_ITEM_SET_HIDDEN(ti
);
1866 ti
= proto_tree_add_ipv4(ipv6_tree
, hf_ipv6_teredo_client_ipv4
, tvb
,
1867 offset
+ IP6H_SRC
+ 12, 4, client_v4
);
1868 PROTO_ITEM_SET_GENERATED(ti
);
1869 PROTO_ITEM_SET_HIDDEN(ti
);
1872 if (tvb_get_guint8(tvb
, offset
+ IP6H_SRC
+ 8) & 0x02 && tvb_get_ntohs(tvb
, offset
+ IP6H_SRC
+ 11) == 0xfffe) { /* RFC 4291 appendix A */
1873 mac_addr
= (guint8
*)wmem_alloc(wmem_packet_scope(), 6);
1874 tvb_memcpy(tvb
, mac_addr
, offset
+ IP6H_SRC
+ 8, 3);
1875 tvb_memcpy(tvb
, mac_addr
+3, offset
+ IP6H_SRC
+ 13, 3);
1876 mac_addr
[0] &= ~0x02;
1877 ti
= proto_tree_add_ether(ipv6_tree
, hf_ipv6_src_sa_mac
, tvb
,
1878 offset
+ IP6H_SRC
+ 8, 6, mac_addr
);
1879 PROTO_ITEM_SET_GENERATED(ti
);
1880 ti
= proto_tree_add_ether(ipv6_tree
, hf_ipv6_sa_mac
, tvb
,
1881 offset
+ IP6H_SRC
+ 8, 6, mac_addr
);
1882 PROTO_ITEM_SET_GENERATED(ti
);
1883 PROTO_ITEM_SET_HIDDEN(ti
);
1884 } else if ((tvb_get_ntohl(tvb
, offset
+ IP6H_SRC
+ 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1885 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_src_isatap_ipv4
, tvb
,
1886 offset
+ IP6H_SRC
+ 12, 4, ENC_BIG_ENDIAN
);
1887 PROTO_ITEM_SET_GENERATED(ti
);
1888 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_isatap_ipv4
, tvb
,
1889 offset
+ IP6H_SRC
+ 12, 4, ENC_BIG_ENDIAN
);
1890 PROTO_ITEM_SET_GENERATED(ti
);
1891 PROTO_ITEM_SET_HIDDEN(ti
);
1894 /* Add different items for the destination address */
1895 proto_tree_add_item(ipv6_tree
, hf_ipv6_dst
, tvb
,
1896 offset
+ (int)offsetof(struct ip6_hdr
, ip6_dst
), 16, ENC_NA
);
1897 ti
= proto_tree_add_ipv6(ipv6_tree
, hf_ipv6_addr
, tvb
,
1898 offset
+ (int)offsetof(struct ip6_hdr
, ip6_dst
),
1899 16, (guint8
*)&ipv6
.ip6_dst
);
1900 PROTO_ITEM_SET_HIDDEN(ti
);
1901 name
= get_addr_name(&pinfo
->dst
);
1902 if (ipv6_summary_in_tree
) {
1903 proto_item_append_text(ipv6_item
, ", Dst: %s (%s)", name
, ip6_to_str(&ipv6
.ip6_dst
));
1905 ti
= proto_tree_add_string(ipv6_tree
, hf_ipv6_dst_host
, tvb
,
1906 offset
+ (int)offsetof(struct ip6_hdr
, ip6_dst
),
1908 PROTO_ITEM_SET_GENERATED(ti
);
1909 PROTO_ITEM_SET_HIDDEN(ti
);
1910 ti
= proto_tree_add_string(ipv6_tree
, hf_ipv6_host
, tvb
,
1911 offset
+ (int)offsetof(struct ip6_hdr
, ip6_dst
),
1913 PROTO_ITEM_SET_GENERATED(ti
);
1914 PROTO_ITEM_SET_HIDDEN(ti
);
1916 /* Extract embedded (IPv6 and MAC) address information */
1917 if (tvb_get_ntohs(tvb
, offset
+ IP6H_DST
) == 0x2002) { /* RFC 3056 section 2 */
1918 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_dst_6to4_gateway_ipv4
, tvb
,
1919 offset
+ IP6H_DST
+ 2, 4, ENC_BIG_ENDIAN
);
1920 PROTO_ITEM_SET_GENERATED(ti
);
1921 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_dst_6to4_sla_id
, tvb
,
1922 offset
+ IP6H_DST
+ 6, 2, ENC_BIG_ENDIAN
);
1923 PROTO_ITEM_SET_GENERATED(ti
);
1924 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_6to4_gateway_ipv4
, tvb
,
1925 offset
+ IP6H_DST
+ 2, 4, ENC_BIG_ENDIAN
);
1926 PROTO_ITEM_SET_GENERATED(ti
);
1927 PROTO_ITEM_SET_HIDDEN(ti
);
1928 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_6to4_sla_id
, tvb
,
1929 offset
+ IP6H_DST
+ 6, 2, ENC_BIG_ENDIAN
);
1930 PROTO_ITEM_SET_GENERATED(ti
);
1931 PROTO_ITEM_SET_HIDDEN(ti
);
1932 } else if (tvb_get_ntohl(tvb
, offset
+ IP6H_DST
) == 0x20010000) { /* RFC 4380 section 4 */
1933 guint16 mapped_port
= tvb_get_ntohs(tvb
, offset
+ IP6H_DST
+ 10) ^ 0xffff;
1934 guint32 client_v4
= tvb_get_ipv4(tvb
, offset
+ IP6H_DST
+ 12) ^ 0xffffffff;
1936 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_dst_teredo_server_ipv4
, tvb
,
1937 offset
+ IP6H_DST
+ 4, 4, ENC_BIG_ENDIAN
);
1938 PROTO_ITEM_SET_GENERATED(ti
);
1939 ti
= proto_tree_add_uint(ipv6_tree
, hf_ipv6_dst_teredo_port
, tvb
,
1940 offset
+ IP6H_DST
+ 10, 2, mapped_port
);
1941 PROTO_ITEM_SET_GENERATED(ti
);
1942 ti
= proto_tree_add_ipv4(ipv6_tree
, hf_ipv6_dst_teredo_client_ipv4
, tvb
,
1943 offset
+ IP6H_DST
+ 12, 4, client_v4
);
1944 PROTO_ITEM_SET_GENERATED(ti
);
1945 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_teredo_server_ipv4
, tvb
,
1946 offset
+ IP6H_DST
+ 4, 4, ENC_BIG_ENDIAN
);
1947 PROTO_ITEM_SET_GENERATED(ti
);
1948 PROTO_ITEM_SET_HIDDEN(ti
);
1949 ti
= proto_tree_add_uint(ipv6_tree
, hf_ipv6_teredo_port
, tvb
,
1950 offset
+ IP6H_DST
+ 10, 2, mapped_port
);
1951 PROTO_ITEM_SET_GENERATED(ti
);
1952 PROTO_ITEM_SET_HIDDEN(ti
);
1953 ti
= proto_tree_add_ipv4(ipv6_tree
, hf_ipv6_teredo_client_ipv4
, tvb
,
1954 offset
+ IP6H_DST
+ 12, 4, client_v4
);
1955 PROTO_ITEM_SET_GENERATED(ti
);
1956 PROTO_ITEM_SET_HIDDEN(ti
);
1959 if (tvb_get_guint8(tvb
, offset
+ IP6H_DST
+ 8) & 0x02 && tvb_get_ntohs(tvb
, offset
+ IP6H_DST
+ 11) == 0xfffe) { /* RFC 4291 appendix A */
1960 mac_addr
= (guint8
*)wmem_alloc(wmem_packet_scope(), 6);
1961 tvb_memcpy(tvb
, mac_addr
, offset
+ IP6H_DST
+ 8, 3);
1962 tvb_memcpy(tvb
, mac_addr
+3, offset
+ IP6H_DST
+ 13, 3);
1963 mac_addr
[0] &= ~0x02;
1964 ti
= proto_tree_add_ether(ipv6_tree
, hf_ipv6_dst_sa_mac
, tvb
,
1965 offset
+ IP6H_DST
+ 8, 6, mac_addr
);
1966 PROTO_ITEM_SET_GENERATED(ti
);
1967 ti
= proto_tree_add_ether(ipv6_tree
, hf_ipv6_sa_mac
, tvb
,
1968 offset
+ IP6H_DST
+ 8, 6, mac_addr
);
1969 PROTO_ITEM_SET_GENERATED(ti
);
1970 PROTO_ITEM_SET_HIDDEN(ti
);
1971 } else if ((tvb_get_ntohl(tvb
, offset
+ IP6H_DST
+ 8) & 0xfcffffff) == 0x00005efe) { /* RFC 5214 section 6.1 */
1972 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_dst_isatap_ipv4
, tvb
,
1973 offset
+ IP6H_DST
+ 12, 4, ENC_BIG_ENDIAN
);
1974 PROTO_ITEM_SET_GENERATED(ti
);
1975 ti
= proto_tree_add_item(ipv6_tree
, hf_ipv6_isatap_ipv4
, tvb
,
1976 offset
+ IP6H_DST
+ 12, 4, ENC_BIG_ENDIAN
);
1977 PROTO_ITEM_SET_GENERATED(ti
);
1978 PROTO_ITEM_SET_HIDDEN(ti
);
1982 #ifdef HAVE_GEOIP_V6
1983 if (tree
&& ipv6_use_geoip
) {
1984 add_geoip_info(ipv6_tree
, tvb
, offset
, &ipv6
.ip6_src
, &ipv6
.ip6_dst
);
1988 /* start of the new header (could be a extension header) */
1989 nxt
= tvb_get_guint8(tvb
, offset
+ 6);
1990 offset
+= (int)sizeof(struct ip6_hdr
);
1994 /* start out assuming this isn't fragmented, and has none of the other
1995 non-final headers */
2005 case IP_PROTO_HOPOPTS
:
2007 advance
= dissect_hopopts(tvb
, offset
, ipv6_tree
, pinfo
);
2008 nxt
= tvb_get_guint8(tvb
, offset
);
2013 case IP_PROTO_ROUTING
:
2015 advance
= dissect_routing6(tvb
, offset
, ipv6_tree
, pinfo
);
2016 nxt
= tvb_get_guint8(tvb
, offset
);
2021 case IP_PROTO_FRAGMENT
:
2022 advance
= dissect_frag6(tvb
, offset
, pinfo
, ipv6_tree
,
2024 nxt
= tvb_get_guint8(tvb
, offset
);
2027 frag
= offlg
& (IP6F_OFF_MASK
| IP6F_MORE_FRAG
);
2028 save_fragmented
|= frag
;
2029 if (ipv6_reassemble
&& frag
&& tvb_bytes_exist(tvb
, offset
, plen
)) {
2030 ipfd_head
= fragment_add_check(&ipv6_reassembly_table
,
2031 tvb
, offset
, pinfo
, ident
, NULL
,
2032 offlg
& IP6F_OFF_MASK
,
2034 offlg
& IP6F_MORE_FRAG
);
2035 next_tvb
= process_reassembled_data(tvb
, offset
, pinfo
, "Reassembled IPv6",
2036 ipfd_head
, &ipv6_frag_items
, &update_col_info
, ipv6_tree
);
2037 if (next_tvb
) { /* Process post-fragment headers after reassembly... */
2044 if (!(offlg
& IP6F_OFF_MASK
)) /*...or in the first fragment */
2050 advance
= dissect_ah_header(tvb_new_subset_remaining(tvb
, offset
),
2051 pinfo
, ipv6_tree
, NULL
, NULL
);
2052 nxt
= tvb_get_guint8(tvb
, offset
);
2057 case IP_PROTO_SHIM6
:
2058 case IP_PROTO_SHIM6_OLD
:
2060 advance
= dissect_shim6(tvb
, offset
, ipv6_tree
, pinfo
);
2061 nxt
= tvb_get_guint8(tvb
, offset
);
2062 stype
= tvb_get_guint8(tvb
, offset
+2);
2067 case IP_PROTO_DSTOPTS
:
2069 advance
= dissect_dstopts(tvb
, offset
, ipv6_tree
, pinfo
);
2070 nxt
= tvb_get_guint8(tvb
, offset
);
2079 /* Since we did not recognize this IPv6 option, check
2080 * whether it is a known protocol. If not, then it
2081 * is an unknown IPv6 option
2083 if (!dissector_get_uint_handle(ip_dissector_table
, nxt
)) {
2084 advance
= dissect_unknown_option(tvb
, offset
, ipv6_tree
);
2085 nxt
= tvb_get_guint8(tvb
, offset
);
2092 proto_item_set_len (ipv6_item
, offset
);
2094 /* collect packet info */
2095 pinfo
->ipproto
= nxt
;
2096 tap_queue_packet(ipv6_tap
, pinfo
, &ipv6
);
2098 if (offlg
& IP6F_OFF_MASK
|| (ipv6_reassemble
&& offlg
& IP6F_MORE_FRAG
)) {
2099 /* Not the first fragment, or the first when we are reassembling and there are more. */
2100 /* Don't dissect it; just show this as a fragment. */
2101 /* COL_INFO was filled in by "dissect_frag6()" */
2102 call_dissector(data_handle
, tvb_new_subset_remaining(tvb
, offset
), pinfo
, tree
);
2105 /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
2107 /* Get a tvbuff for the payload. */
2108 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2111 * If this is the first fragment, but not the only fragment,
2112 * tell the next protocol that.
2114 if (offlg
& IP6F_MORE_FRAG
)
2115 pinfo
->fragmented
= TRUE
;
2117 pinfo
->fragmented
= FALSE
;
2121 /* do lookup with the subdissector table */
2122 if (!dissector_try_uint(ip_dissector_table
, nxt
, next_tvb
, pinfo
, tree
)) {
2123 /* Unknown protocol.
2124 Handle "no next header" specially. */
2125 if (nxt
== IP_PROTO_NONE
) {
2126 /* If we had an Authentication Header, the AH dissector already
2127 put something in the Info column; leave it there. */
2129 if (hopopts
|| routing
|| dstopts
|| shim6
) {
2131 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%shop-by-hop options",
2136 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%srouting", sep
);
2140 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%sdestination options",
2144 if (stype
& SHIM6_BITMASK_P
) {
2145 col_append_str(pinfo
->cinfo
, COL_INFO
, "Shim6 (Payload)");
2148 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Shim6 (%s)",
2149 val_to_str_const(stype
& SHIM6_BITMASK_TYPE
, shimctrlvals
, "Unknown"));
2153 col_set_str(pinfo
->cinfo
, COL_INFO
, "IPv6 no next header");
2156 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s (%u)", ipprotostr(nxt
), nxt
);
2158 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
2160 pinfo
->fragmented
= save_fragmented
;
2164 proto_register_ipv6(void)
2166 static hf_register_info hf
[] = {
2168 { "Version", "ipv6.version",
2169 FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}},
2171 { "This field makes the filter \"ip.version == 6\" possible", "ip.version",
2172 FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}},
2174 { "Traffic class", "ipv6.class",
2175 FT_UINT32
, BASE_HEX
, NULL
, 0x0FF00000, NULL
, HFILL
}},
2177 { "Flowlabel", "ipv6.flow",
2178 FT_UINT32
, BASE_HEX
, NULL
, 0x000FFFFF, NULL
, HFILL
}},
2180 { "Payload length", "ipv6.plen",
2181 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2183 { "Next header", "ipv6.nxt",
2184 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ipproto_val_ext
, 0x0, NULL
, HFILL
}},
2186 { "Hop limit", "ipv6.hlim",
2187 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2189 { "Source", "ipv6.src",
2190 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2191 "Source IPv6 Address", HFILL
}},
2192 { &hf_ipv6_src_host
,
2193 { "Source Host", "ipv6.src_host",
2194 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2195 "Source IPv6 Host", HFILL
}},
2196 { &hf_ipv6_src_sa_mac
,
2197 { "Source SA MAC", "ipv6.src_sa_mac",
2198 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
2199 "Source IPv6 Stateless Autoconfiguration MAC Address", HFILL
}},
2200 { &hf_ipv6_src_isatap_ipv4
,
2201 { "Source ISATAP IPv4", "ipv6.src_isatap_ipv4",
2202 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2203 "Source IPv6 ISATAP Encapsulated IPv4 Address", HFILL
}},
2204 { &hf_ipv6_src_6to4_gateway_ipv4
,
2205 { "Source 6to4 Gateway IPv4", "ipv6.src_6to4_gw_ipv4",
2206 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2207 "Source IPv6 6to4 Gateway IPv4 Address", HFILL
}},
2208 { &hf_ipv6_src_6to4_sla_id
,
2209 { "Source 6to4 SLA ID", "ipv6.src_6to4_sla_id",
2210 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2211 "Source IPv6 6to4 SLA ID", HFILL
}},
2212 { &hf_ipv6_src_teredo_server_ipv4
,
2213 { "Source Teredo Server IPv4", "ipv6.src_ts_ipv4",
2214 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2215 "Source IPv6 Teredo Server Encapsulated IPv4 Address", HFILL
}},
2216 { &hf_ipv6_src_teredo_port
,
2217 { "Source Teredo Port", "ipv6.src_tc_port",
2218 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2219 "Source IPv6 Teredo Client Mapped Port", HFILL
}},
2220 { &hf_ipv6_src_teredo_client_ipv4
,
2221 { "Source Teredo Client IPv4", "ipv6.src_tc_ipv4",
2222 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2223 "Source IPv6 Teredo Client Encapsulated IPv4 Address", HFILL
}},
2225 { "Destination", "ipv6.dst",
2226 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2227 "Destination IPv6 Address", HFILL
}},
2228 { &hf_ipv6_dst_host
,
2229 { "Destination Host", "ipv6.dst_host",
2230 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2231 "Destination IPv6 Host", HFILL
}},
2232 { &hf_ipv6_dst_sa_mac
,
2233 { "Destination SA MAC", "ipv6.dst_sa_mac",
2234 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
2235 "Destination IPv6 Stateless Autoconfiguration MAC Address", HFILL
}},
2236 { &hf_ipv6_dst_isatap_ipv4
,
2237 { "Destination ISATAP IPv4", "ipv6.dst_isatap_ipv4",
2238 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2239 "Destination IPv6 ISATAP Encapsulated IPv4 Address", HFILL
}},
2240 { &hf_ipv6_dst_6to4_gateway_ipv4
,
2241 { "Destination 6to4 Gateway IPv4", "ipv6.dst_6to4_gw_ipv4",
2242 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2243 "Destination IPv6 6to4 Gateway IPv4 Address", HFILL
}},
2244 { &hf_ipv6_dst_6to4_sla_id
,
2245 { "Destination 6to4 SLA ID", "ipv6.dst_6to4_sla_id",
2246 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2247 "Destination IPv6 6to4 SLA ID", HFILL
}},
2248 { &hf_ipv6_dst_teredo_server_ipv4
,
2249 { "Destination Teredo Server IPv4", "ipv6.dst_ts_ipv4",
2250 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2251 "Destination IPv6 Teredo Server Encapsulated IPv4 Address", HFILL
}},
2252 { &hf_ipv6_dst_teredo_port
,
2253 { "Destination Teredo Port", "ipv6.dst_tc_port",
2254 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2255 "Destination IPv6 Teredo Client Mapped Port", HFILL
}},
2256 { &hf_ipv6_dst_teredo_client_ipv4
,
2257 { "Destination Teredo Client IPv4", "ipv6.dst_tc_ipv4",
2258 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2259 "Destination IPv6 Teredo Client Encapsulated IPv4 Address", HFILL
}},
2261 { "Source or Destination Address", "ipv6.addr",
2262 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2265 { "Source or Destination Host", "ipv6.host",
2266 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2270 { "SA MAC", "ipv6.sa_mac",
2271 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
2272 "IPv6 Stateless Autoconfiguration MAC Address", HFILL
}},
2273 { &hf_ipv6_isatap_ipv4
,
2274 { "ISATAP IPv4", "ipv6.isatap_ipv4",
2275 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2276 "IPv6 ISATAP Encapsulated IPv4 Address", HFILL
}},
2277 { &hf_ipv6_6to4_gateway_ipv4
,
2278 { "6to4 Gateway IPv4", "ipv6.6to4_gw_ipv4",
2279 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2280 "IPv6 6to4 Gateway IPv4 Address", HFILL
}},
2281 { &hf_ipv6_6to4_sla_id
,
2282 { "6to4 SLA ID", "ipv6.6to4_sla_id",
2283 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2284 "IPv6 6to4 SLA ID", HFILL
}},
2285 { &hf_ipv6_teredo_server_ipv4
,
2286 { "Teredo Server IPv4", "ipv6.ts_ipv4",
2287 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2288 "IPv6 Teredo Server Encapsulated IPv4 Address", HFILL
}},
2289 { &hf_ipv6_teredo_port
,
2290 { "Teredo Port", "ipv6.tc_port",
2291 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2292 "IPv6 Teredo Client Mapped Port", HFILL
}},
2293 { &hf_ipv6_teredo_client_ipv4
,
2294 { "Teredo Client IPv4", "ipv6.tc_ipv4",
2295 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2296 "IPv6 Teredo Client Encapsulated IPv4 Address", HFILL
}},
2297 #ifdef HAVE_GEOIP_V6
2298 { &hf_geoip_country
,
2299 { "Source or Destination GeoIP Country", "ipv6.geoip.country",
2300 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2303 { "Source or Destination GeoIP City", "ipv6.geoip.city",
2304 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2307 { "Source or Destination GeoIP Organization", "ipv6.geoip.org",
2308 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2311 { "Source or Destination GeoIP ISP", "ipv6.geoip.isp",
2312 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2315 { "Source or Destination GeoIP AS Number", "ipv6.geoip.asnum",
2316 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2319 { "Source or Destination GeoIP Latitude", "ipv6.geoip.lat",
2320 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2323 { "Source or Destination GeoIP Longitude", "ipv6.geoip.lon",
2324 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2326 { &hf_geoip_src_country
,
2327 { "Source GeoIP Country", "ipv6.geoip.src_country",
2328 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2330 { &hf_geoip_src_city
,
2331 { "Source GeoIP City", "ipv6.geoip.src_city",
2332 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2334 { &hf_geoip_src_org
,
2335 { "Source GeoIP Organization", "ipv6.geoip.src_org",
2336 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2338 { &hf_geoip_src_isp
,
2339 { "Source GeoIP ISP", "ipv6.geoip.src_isp",
2340 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2342 { &hf_geoip_src_asnum
,
2343 { "Source GeoIP AS Number", "ipv6.geoip.src_asnum",
2344 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2346 { &hf_geoip_src_lat
,
2347 { "Source GeoIP Latitude", "ipv6.geoip.src_lat",
2348 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2350 { &hf_geoip_src_lon
,
2351 { "Source GeoIP Longitude", "ipv6.geoip.src_lon",
2352 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2354 { &hf_geoip_dst_country
,
2355 { "Destination GeoIP Country", "ipv6.geoip.dst_country",
2356 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2358 { &hf_geoip_dst_city
,
2359 { "Destination GeoIP City", "ipv6.geoip.dst_city",
2360 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2362 { &hf_geoip_dst_org
,
2363 { "Destination GeoIP Organization", "ipv6.geoip.dst_org",
2364 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2366 { &hf_geoip_dst_isp
,
2367 { "Destination GeoIP ISP", "ipv6.geoip.dst_isp",
2368 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2370 { &hf_geoip_dst_asnum
,
2371 { "Destination GeoIP AS Number", "ipv6.geoip.dst_asnum",
2372 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2374 { &hf_geoip_dst_lat
,
2375 { "Destination GeoIP Latitude", "ipv6.geoip.dst_lat",
2376 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2378 { &hf_geoip_dst_lon
,
2379 { "Destination GeoIP Longitude", "ipv6.geoip.dst_lon",
2380 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
2382 #endif /* HAVE_GEOIP_V6 */
2386 { "Destination Option", "ipv6.dst_opt",
2387 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2390 { "Hop-by-Hop Option", "ipv6.hop_opt",
2391 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2394 { "Unknown Extension Header", "ipv6.unknown_hdr",
2395 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2398 { "IPv6 Option", "ipv6.opt",
2399 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2401 { &hf_ipv6_opt_type
,
2402 { "Type", "ipv6.opt.type",
2403 FT_UINT8
, BASE_DEC
, VALS(ipv6_opt_vals
), 0x0,
2404 "Options type", HFILL
}},
2405 { &hf_ipv6_opt_length
,
2406 { "Length", "ipv6.opt.length",
2407 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2408 "Length in units of 8 octets", HFILL
}},
2409 { &hf_ipv6_opt_pad1
,
2410 { "Pad1", "ipv6.opt.pad1",
2411 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2412 "Pad1 Option", HFILL
}},
2413 { &hf_ipv6_opt_padn
,
2414 { "PadN", "ipv6.opt.padn",
2415 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2416 "PadN Option", HFILL
}},
2417 { &hf_ipv6_opt_rtalert
,
2418 { "Router Alert", "ipv6.opt.router_alert",
2419 FT_UINT16
, BASE_DEC
, VALS(rtalertvals
), 0x0,
2422 { "Tunnel Encapsulation Limit", "ipv6.opt.tel",
2423 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2424 "How many further levels of encapsulation are permitted", HFILL
}},
2425 { &hf_ipv6_opt_jumbo
,
2426 { "Jumbo", "ipv6.opt.jumbo",
2427 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2428 "Length of the IPv6 packet in octets", HFILL
}},
2429 { &hf_ipv6_opt_calipso_doi
,
2430 { "CALIPSO Domain of Interpretation","ipv6.opt.calipso.doi",
2431 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2433 { &hf_ipv6_opt_calipso_cmpt_length
,
2434 { "Compartment Length","ipv6.opt.calipso.cmpt.length",
2435 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2437 { &hf_ipv6_opt_calipso_sens_level
,
2438 { "Sensitivity Level","ipv6.opt.calipso.sens_level",
2439 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2441 { &hf_ipv6_opt_calipso_checksum
,
2442 { "Checksum","ipv6.opt.calipso.checksum",
2443 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2445 { &hf_ipv6_opt_calipso_cmpt_bitmap
,
2446 { "Compartment Bitmap","ipv6.opt.calipso.cmpt_bitmap",
2447 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2449 { &hf_ipv6_opt_qs_func
,
2450 { "Function", "ipv6.opt.qs_func",
2451 FT_UINT8
, BASE_DEC
, VALS(qs_func_vals
), QS_FUNC_MASK
,
2453 { &hf_ipv6_opt_qs_rate
,
2454 { "Rate", "ipv6.opt.qs_rate",
2455 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &qs_rate_vals_ext
, QS_RATE_MASK
,
2457 { &hf_ipv6_opt_qs_ttl
,
2458 { "QS TTL", "ipv6.opt.qs_ttl",
2459 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2461 { &hf_ipv6_opt_qs_ttl_diff
,
2462 { "TTL Diff", "ipv6.opt.qs_ttl_diff",
2463 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2465 { &hf_ipv6_opt_qs_unused
,
2466 { "Not Used", "ipv6.opt.qs_unused",
2467 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2469 { &hf_ipv6_opt_qs_nonce
,
2470 { "QS Nonce", "ipv6.opt.qs_nonce",
2471 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFFFC,
2473 { &hf_ipv6_opt_qs_reserved
,
2474 { "Reserved", "ipv6.opt.qs_reserved",
2475 FT_UINT32
, BASE_HEX
, NULL
, 0x0003,
2477 { &hf_ipv6_opt_rpl_flag
,
2478 { "Flag", "ipv6.opt.rpl.flag",
2479 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2481 { &hf_ipv6_opt_rpl_flag_o
,
2482 { "Down", "ipv6.opt.rpl.flag.o",
2483 FT_BOOLEAN
, 8, NULL
, 0x80,
2484 "The packet is expected to progress Up or Down", HFILL
}},
2485 { &hf_ipv6_opt_rpl_flag_r
,
2486 { "Rank Error", "ipv6.opt.rpl.flag.r",
2487 FT_BOOLEAN
, 8, NULL
, 0x40,
2488 "Indicating whether a rank error was detected", HFILL
}},
2489 { &hf_ipv6_opt_rpl_flag_f
,
2490 { "Forwarding Error", "ipv6.opt.rpl.flag.f",
2491 FT_BOOLEAN
, 8, NULL
, 0x20,
2492 "Indicating that this node can not forward the packet further towards the destination", HFILL
}},
2493 { &hf_ipv6_opt_rpl_flag_rsv
,
2494 { "Reserved", "ipv6.opt.rpl.flag.rsv",
2495 FT_UINT8
, BASE_HEX
, NULL
, 0x1F,
2496 "Reserved (Must Be Zero)", HFILL
}},
2497 { &hf_ipv6_opt_rpl_instance_id
,
2498 { "RPLInstanceID", "ipv6.opt.rpl.instance_id",
2499 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2500 "Indicating the DODAG instance along which the packet is sent", HFILL
}},
2501 { &hf_ipv6_opt_rpl_senderrank
,
2502 { "Sender Rank", "ipv6.opt.rpl.sender_rank",
2503 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2504 "Set to zero by the source and to DAGRank(rank) by a router that forwards inside the RPL network", HFILL
}},
2505 { &hf_ipv6_opt_experimental
,
2506 { "Experimental Option","ipv6.opt.experimental",
2507 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2509 { &hf_ipv6_opt_unknown
,
2510 { "Unknown Option Payload","ipv6.opt.unknown",
2511 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2513 { &hf_ipv6_routing_hdr_opt
,
2514 { "Routing Header, Type","ipv6.routing_hdr",
2515 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2516 "Routing Header Option", HFILL
}},
2517 { &hf_ipv6_routing_hdr_type
,
2518 { "Type", "ipv6.routing_hdr.type",
2519 FT_UINT8
, BASE_DEC
, VALS(routing_header_type
), 0x0,
2520 "Routing Header Type", HFILL
}},
2521 { &hf_ipv6_routing_hdr_left
,
2522 { "Segments Left", "ipv6.routing_hdr.left",
2523 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2524 "Routing Header Segments Left", HFILL
}},
2525 { &hf_ipv6_routing_hdr_addr
,
2526 { "Address", "ipv6.routing_hdr.addr",
2527 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2528 "Routing Header Address", HFILL
}},
2529 { &hf_ipv6_frag_nxt
,
2530 { "Next header", "ipv6.fragment.nxt",
2531 FT_UINT16
, BASE_DEC
| BASE_EXT_STRING
, &ipproto_val_ext
, 0x0,
2532 "Fragment next header", HFILL
}},
2533 { &hf_ipv6_frag_reserved
,
2534 { "Reserved octet", "ipv6.fragment.reserved_octet",
2535 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2536 "Should always be 0", HFILL
}},
2537 { &hf_ipv6_frag_offset
,
2538 { "Offset", "ipv6.fragment.offset",
2539 FT_UINT16
, BASE_DEC_HEX
, NULL
, IP6F_OFF_MASK
,
2540 "Fragment Offset", HFILL
}},
2541 { &hf_ipv6_frag_reserved_bits
,
2542 { "Reserved bits", "ipv6.fragment.reserved_bits",
2543 FT_UINT16
, BASE_DEC_HEX
, NULL
, IP6F_RESERVED_MASK
,
2545 { &hf_ipv6_frag_more
,
2546 { "More Fragment", "ipv6.fragment.more",
2547 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), IP6F_MORE_FRAG
,
2548 "More Fragments", HFILL
}},
2550 { "Identification", "ipv6.fragment.id",
2551 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2552 "Fragment Identification", HFILL
}},
2553 { &hf_ipv6_fragment_overlap
,
2554 { "Fragment overlap", "ipv6.fragment.overlap",
2555 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2556 "Fragment overlaps with other fragments", HFILL
}},
2558 { &hf_ipv6_fragment_overlap_conflict
,
2559 { "Conflicting data in fragment overlap", "ipv6.fragment.overlap.conflict",
2560 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2561 "Overlapping fragments contained conflicting data", HFILL
}},
2563 { &hf_ipv6_fragment_multiple_tails
,
2564 { "Multiple tail fragments found", "ipv6.fragment.multipletails",
2565 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2566 "Several tails were found when defragmenting the packet", HFILL
}},
2568 { &hf_ipv6_fragment_too_long_fragment
,
2569 { "Fragment too long", "ipv6.fragment.toolongfragment",
2570 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2571 "Fragment contained data past end of packet", HFILL
}},
2573 { &hf_ipv6_fragment_error
,
2574 { "Defragmentation error", "ipv6.fragment.error",
2575 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2576 "Defragmentation error due to illegal fragments", HFILL
}},
2578 { &hf_ipv6_fragment_count
,
2579 { "Fragment count", "ipv6.fragment.count",
2580 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2583 { &hf_ipv6_fragment
,
2584 { "IPv6 Fragment", "ipv6.fragment",
2585 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2588 { &hf_ipv6_fragments
,
2589 { "IPv6 Fragments", "ipv6.fragments",
2590 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2593 { &hf_ipv6_reassembled_in
,
2594 { "Reassembled IPv6 in frame", "ipv6.reassembled_in",
2595 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2596 "This IPv6 packet is reassembled in this frame", HFILL
}},
2598 { &hf_ipv6_reassembled_length
,
2599 { "Reassembled IPv6 length", "ipv6.reassembled.length",
2600 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2601 "The total length of the reassembled payload", HFILL
}},
2603 { &hf_ipv6_reassembled_data
,
2604 { "Reassembled IPv6 data", "ipv6.reassembled.data",
2605 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2606 "The reassembled payload", HFILL
}},
2607 /* RPL Routing Header */
2608 { &hf_ipv6_routing_hdr_rpl_cmprI
,
2609 { "Compressed Internal Octets (CmprI)", "ipv6.routing_hdr.rpl.cmprI",
2610 FT_UINT32
, BASE_DEC
, NULL
, IP6RRPL_BITMASK_CMPRI
,
2611 "Elided octets from all but last segment", HFILL
}},
2613 { &hf_ipv6_routing_hdr_rpl_cmprE
,
2614 { "Compressed Final Octets (CmprE)", "ipv6.routing_hdr.rpl.cmprE",
2615 FT_UINT32
, BASE_DEC
, NULL
, IP6RRPL_BITMASK_CMPRE
,
2616 "Elided octets from last segment address", HFILL
}},
2618 { &hf_ipv6_routing_hdr_rpl_pad
,
2619 { "Padding Bytes", "ipv6.routing_hdr.rpl.pad",
2620 FT_UINT32
, BASE_DEC
, NULL
, IP6RRPL_BITMASK_PAD
,
2623 { &hf_ipv6_routing_hdr_rpl_reserved
,
2624 { "Reserved", "ipv6.routing_hdr.rpl.reserved",
2625 FT_UINT32
, BASE_DEC
, NULL
, IP6RRPL_BITMASK_RESERVED
,
2626 "Must be Zero", HFILL
}},
2628 { &hf_ipv6_routing_hdr_rpl_segments
,
2629 { "Total Segments", "ipv6.routing_hdr.rpl.segments",
2630 FT_INT32
, BASE_DEC
, NULL
, 0,
2633 { &hf_ipv6_routing_hdr_rpl_addr
,
2634 { "Address", "ipv6.routing_hdr.rpl.address",
2635 FT_BYTES
, BASE_NONE
, NULL
, 0,
2638 { &hf_ipv6_routing_hdr_rpl_fulladdr
,
2639 { "Full Address", "ipv6.routing_hdr.rpl.full_address",
2640 FT_IPv6
, BASE_NONE
, NULL
, 0,
2641 "Uncompressed IPv6 Address", HFILL
}},
2644 { &hf_ipv6_mipv6_home_address
,
2645 { "Home Address", "ipv6.mipv6_home_address",
2646 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2651 { "SHIM6", "ipv6.shim6",
2652 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2655 { &hf_ipv6_shim6_nxt
,
2656 { "Next Header", "ipv6.shim6.nxt",
2657 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2660 { &hf_ipv6_shim6_len
,
2661 { "Header Ext Length", "ipv6.shim6.len",
2662 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2666 { "P Bit", "ipv6.shim6.p",
2667 FT_BOOLEAN
, 8, NULL
, SHIM6_BITMASK_P
,
2670 { &hf_ipv6_shim6_ct
,
2671 { "Context Tag", "ipv6.shim6.ct",
2672 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2675 { &hf_ipv6_shim6_type
,
2676 { "Message Type", "ipv6.shim6.type",
2678 VALS(shimctrlvals
), SHIM6_BITMASK_TYPE
,
2681 { &hf_ipv6_shim6_proto
,
2682 { "Protocol", "ipv6.shim6.proto",
2684 VALS(shim6_protocol
), SHIM6_BITMASK_PROTOCOL
,
2687 { &hf_ipv6_shim6_checksum
,
2688 { "Checksum", "ipv6.shim6.checksum",
2689 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2690 "Shim6 Checksum", HFILL
}},
2691 { &hf_ipv6_shim6_checksum_bad
,
2692 { "Bad Checksum", "ipv6.shim6.checksum_bad",
2693 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2694 "Shim6 Bad Checksum", HFILL
}},
2696 { &hf_ipv6_shim6_checksum_good
,
2697 { "Good Checksum", "ipv6.shim6.checksum_good",
2698 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2701 { &hf_ipv6_shim6_inonce
,
2702 { "Initiator Nonce", "ipv6.shim6.inonce",
2703 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
2706 { &hf_ipv6_shim6_rnonce
,
2707 { "Responder Nonce", "ipv6.shim6.rnonce",
2708 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
2711 { &hf_ipv6_shim6_precvd
,
2712 { "Probes Received", "ipv6.shim6.precvd",
2713 FT_UINT8
, BASE_DEC
, NULL
, SHIM6_BITMASK_PRECVD
,
2716 { &hf_ipv6_shim6_psent
,
2717 { "Probes Sent", "ipv6.shim6.psent",
2718 FT_UINT8
, BASE_DEC
, NULL
, SHIM6_BITMASK_PSENT
,
2721 { &hf_ipv6_shim6_psrc
,
2722 { "Source Address", "ipv6.shim6.psrc",
2723 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2724 "Shim6 Probe Source Address", HFILL
}},
2726 { &hf_ipv6_shim6_pdst
,
2727 { "Destination Address", "ipv6.shim6.pdst",
2728 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2729 "Shim6 Probe Destination Address", HFILL
}},
2731 { &hf_ipv6_shim6_pnonce
,
2732 { "Nonce", "ipv6.shim6.pnonce",
2733 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
2734 "Shim6 Probe Nonce", HFILL
}},
2736 { &hf_ipv6_shim6_pdata
,
2737 { "Data", "ipv6.shim6.pdata",
2738 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2739 "Shim6 Probe Data", HFILL
}},
2741 { &hf_ipv6_shim6_sulid
,
2742 { "Sender ULID", "ipv6.shim6.sulid",
2743 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2744 "Shim6 Sender ULID", HFILL
}},
2746 { &hf_ipv6_shim6_rulid
,
2747 { "Receiver ULID", "ipv6.shim6.rulid",
2748 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2749 "Shim6 Receiver ULID", HFILL
}},
2751 { &hf_ipv6_shim6_reap
,
2752 { "REAP State", "ipv6.shim6.reap",
2753 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2756 { &hf_ipv6_shim6_opt_type
,
2757 { "Option Type", "ipv6.shim6.opt.type",
2758 FT_UINT16
, BASE_DEC
,
2759 VALS(shimoptvals
), SHIM6_BITMASK_OPT_TYPE
,
2760 "Shim6 Option Type", HFILL
}},
2762 { &hf_ipv6_shim6_opt_critical
,
2763 { "Option Critical Bit", "ipv6.shim6.opt.critical",
2766 SHIM6_BITMASK_CRITICAL
,
2767 "TRUE : option is critical, FALSE: option is not critical",
2770 { &hf_ipv6_shim6_opt_len
,
2771 { "Content Length", "ipv6.shim6.opt.len",
2772 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2773 "Content Length Option", HFILL
}},
2775 { &hf_ipv6_shim6_opt_total_len
,
2776 { "Total Length", "ipv6.shim6.opt.total_len",
2777 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2778 "Total Option Length", HFILL
}},
2780 { &hf_ipv6_shim6_opt_loc_verif_methods
,
2781 { "Verification Method", "ipv6.shim6.opt.verif_method",
2783 VALS(shimverifmethods
), 0x0,
2784 "Locator Verification Method", HFILL
}},
2786 { &hf_ipv6_shim6_opt_loclist
,
2787 { "Locator List Generation", "ipv6.shim6.opt.loclist",
2788 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
2791 { &hf_ipv6_shim6_locator
,
2792 { "Locator", "ipv6.shim6.locator",
2793 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2794 "Shim6 Locator", HFILL
}},
2796 { &hf_ipv6_shim6_opt_locnum
,
2797 { "Num Locators", "ipv6.shim6.opt.locnum",
2798 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2799 "Number of Locators in Locator List", HFILL
}},
2801 { &hf_ipv6_shim6_opt_elemlen
,
2802 { "Element Length", "ipv6.shim6.opt.elemlen",
2803 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2804 "Length of Elements in Locator Preferences Option", HFILL
}},
2805 { &hf_ipv6_shim6_loc_flag
,
2806 { "Flags", "ipv6.shim6.loc.flags",
2807 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2808 "Locator Preferences Flags", HFILL
}},
2810 { &hf_ipv6_shim6_loc_prio
,
2811 { "Priority", "ipv6.shim6.loc.prio",
2812 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2813 "Locator Preferences Priority", HFILL
}},
2815 { &hf_ipv6_shim6_loc_weight
,
2816 { "Weight", "ipv6.shim6.loc.weight",
2817 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2818 "Locator Preferences Weight", HFILL
}},
2820 { &hf_ipv6_shim6_opt_fii
,
2821 { "Forked Instance Identifier", "ipv6.shim6.opt.fii",
2822 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
2825 { &hf_ipv6_traffic_class_dscp
,
2826 { "Differentiated Services Field", "ipv6.traffic_class.dscp",
2827 FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &dscp_vals_ext
, 0x0FC00000, NULL
, HFILL
}},
2829 { &hf_ipv6_traffic_class_ect
,
2830 { "ECN-Capable Transport (ECT)", "ipv6.traffic_class.ect",
2831 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), 0x0200000, NULL
, HFILL
}},
2833 { &hf_ipv6_traffic_class_ce
,
2834 { "ECN-CE", "ipv6.traffic_class.ce",
2835 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), 0x0100000, NULL
, HFILL
}},
2837 static gint
*ett
[] = {
2843 &ett_ipv6_shim6_option
,
2844 &ett_ipv6_shim6_locators
,
2845 &ett_ipv6_shim6_verif_methods
,
2846 &ett_ipv6_shim6_loc_pref
,
2847 &ett_ipv6_shim6_probes_sent
,
2848 &ett_ipv6_shim6_probes_rcvd
,
2849 &ett_ipv6_shim6_probe_sent
,
2850 &ett_ipv6_shim6_probe_rcvd
,
2851 &ett_ipv6_shim6_cksum
,
2852 &ett_ipv6_fragments
,
2854 &ett_ipv6_traffic_class
,
2855 #ifdef HAVE_GEOIP_V6
2857 #endif /* HAVE_GEOIP_V6 */
2859 static ei_register_info ei
[] = {
2860 { &ei_ipv6_dst_addr_not_multicast
, { "ipv6.dst_addr.not_multicast", PI_PROTOCOL
, PI_WARN
, "Destination address must not be a multicast address", EXPFILL
}},
2861 { &ei_ipv6_src_route_list_mult_inst_same_addr
, { "ipv6.src_route_list.mult_inst_same_addr", PI_PROTOCOL
, PI_ERROR
, "Multiple instances of the same address must not appear in the source route list", EXPFILL
}},
2862 { &ei_ipv6_src_route_list_src_addr
, { "ipv6.src_route_list.src_addr", PI_PROTOCOL
, PI_ERROR
, "Source address must not appear in the source route list", EXPFILL
}},
2863 { &ei_ipv6_src_route_list_dst_addr
, { "ipv6.src_route_list.dst_addr", PI_PROTOCOL
, PI_ERROR
, "Destination address must not appear in the source route list", EXPFILL
}},
2864 { &ei_ipv6_src_route_list_multicast_addr
, { "ipv6.src_route_list.multicast_addr", PI_PROTOCOL
, PI_ERROR
, "Multicast addresses must not appear in the source route list", EXPFILL
}},
2865 { &ei_ipv6_cmpri_cmpre_pad
, { "ipv6.routing_hdr.rpl.cmprI.cmprE.pad", PI_PROTOCOL
, PI_WARN
, "When cmprI equals 0 and cmprE equals 0, pad MUST equal 0 but instead was X", EXPFILL
}},
2866 { &ei_ipv6_routing_hdr_rpl_reserved
, { "ipv6.routing_hdr.rpl.reserved.not0", PI_PROTOCOL
, PI_WARN
, "Reserved field must equal 0 but instead was X", EXPFILL
}},
2867 { &ei_ipv6_opt_tel_invalid_len
, { "ipv6.opt.tel.invalid_len", PI_MALFORMED
, PI_ERROR
, "Tunnel Encapsulation Limit: Invalid length", EXPFILL
}},
2868 { &ei_ipv6_opt_jumbo_invalid_len
, { "ipv6.opt.jumbo.invalid_len", PI_MALFORMED
, PI_ERROR
, "Jumbo payload: Invalid length", EXPFILL
}},
2869 { &ei_ipv6_opt_rtalert_invalid_len
, { "ipv6.opt.router_alert.invalid_len", PI_MALFORMED
, PI_ERROR
, "Router alert: Invalid Length", EXPFILL
}},
2870 { &ei_ipv6_mipv6_home_address_invalid_len
, { "ipv6.mipv6_home_address.invalid_len", PI_MALFORMED
, PI_ERROR
, "Home Address: Invalid length", EXPFILL
}},
2871 { &ei_ipv6_shim6_opt_elemlen_invalid
, { "ipv6.shim6.opt.elemlen.invalid", PI_MALFORMED
, PI_ERROR
, "Invalid element length", EXPFILL
}},
2872 { &ei_ipv6_shim6_checksum_bad
, { "ipv6.shim6.checksum_bad.expert", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
2873 { &ei_ipv6_routing_hdr_rpl_segments_ge0
, { "ipv6.routing_hdr.rpl.segments.ge0", PI_MALFORMED
, PI_ERROR
, "Calculated total segments must be greater than or equal to 0, instead was X", EXPFILL
}},
2876 module_t
*ipv6_module
;
2877 expert_module_t
* expert_ipv6
;
2879 proto_ipv6
= proto_register_protocol("Internet Protocol Version 6", "IPv6", "ipv6");
2880 proto_register_field_array(proto_ipv6
, hf
, array_length(hf
));
2881 proto_register_subtree_array(ett
, array_length(ett
));
2882 expert_ipv6
= expert_register_protocol(proto_ipv6
);
2883 expert_register_field_array(expert_ipv6
, ei
, array_length(ei
));
2885 /* Register configuration options */
2886 ipv6_module
= prefs_register_protocol(proto_ipv6
, NULL
);
2887 prefs_register_bool_preference(ipv6_module
, "defragment",
2888 "Reassemble fragmented IPv6 datagrams",
2889 "Whether fragmented IPv6 datagrams should be reassembled",
2891 prefs_register_bool_preference(ipv6_module
, "summary_in_tree",
2892 "Show IPv6 summary in protocol tree",
2893 "Whether the IPv6 summary line should be shown in the protocol tree",
2894 &ipv6_summary_in_tree
);
2895 #ifdef HAVE_GEOIP_V6
2896 prefs_register_bool_preference(ipv6_module
, "use_geoip" ,
2897 "Enable GeoIP lookups",
2898 "Whether to look up IPv6 addresses in each GeoIP database we have loaded",
2900 #endif /* HAVE_GEOIP_V6 */
2902 /* RPL Strict Header Checking */
2903 prefs_register_bool_preference(ipv6_module
, "perform_strict_rpl_srh_rfc_checking",
2904 "Perform strict checking for adherence to the RFC for RPL Source Routing Headers (RFC 6554)",
2905 "Whether to check that all RPL Source Routing Headers adhere to RFC 6554",
2906 &g_ipv6_rpl_srh_strict_rfc_checking
);
2908 register_dissector("ipv6", dissect_ipv6
, proto_ipv6
);
2909 register_init_routine(ipv6_reassemble_init
);
2910 ipv6_tap
= register_tap("ipv6");
2914 proto_reg_handoff_ipv6(void)
2916 dissector_handle_t ipv6_handle
;
2918 data_handle
= find_dissector("data");
2919 ipv6_handle
= find_dissector("ipv6");
2920 dissector_add_uint("ethertype", ETHERTYPE_IPv6
, ipv6_handle
);
2921 dissector_add_uint("ppp.protocol", PPP_IPV6
, ipv6_handle
);
2922 dissector_add_uint("ppp.protocol", ETHERTYPE_IPv6
, ipv6_handle
);
2923 dissector_add_uint("gre.proto", ETHERTYPE_IPv6
, ipv6_handle
);
2924 dissector_add_uint("ip.proto", IP_PROTO_IPV6
, ipv6_handle
);
2925 dissector_add_uint("null.type", BSD_AF_INET6_BSD
, ipv6_handle
);
2926 dissector_add_uint("null.type", BSD_AF_INET6_FREEBSD
, ipv6_handle
);
2927 dissector_add_uint("null.type", BSD_AF_INET6_DARWIN
, ipv6_handle
);
2928 dissector_add_uint("chdlc.protocol", ETHERTYPE_IPv6
, ipv6_handle
);
2929 dissector_add_uint("fr.nlpid", NLPID_IP6
, ipv6_handle
);
2930 dissector_add_uint("osinl.excl", NLPID_IP6
, ipv6_handle
);
2931 dissector_add_uint("x.25.spi", NLPID_IP6
, ipv6_handle
);
2932 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IPv6
, ipv6_handle
);
2934 ip_dissector_table
= find_dissector_table("ip.proto");
2943 * indent-tabs-mode: nil
2946 * ex: set shiftwidth=2 tabstop=8 expandtab:
2947 * :indentSize=2:tabSize=8:noTabs=true: