HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-ip.c
blobabe4156611a19e4a0ce67e133b7035d6e814b255
1 /* packet-ip.c
2 * Routines for IP and miscellaneous IP protocol packet disassembly
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Wednesday, January 17, 2006
11 * Support for the CIPSO IPv4 option
12 * (http://sourceforge.net/docman/display_doc.php?docid=34650&group_id=174379)
13 * by Paul Moore <paul.moore@hp.com>
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "config.h"
32 #include <string.h>
33 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/addr_resolv.h>
37 #include <epan/ipproto.h>
38 #include <epan/expert.h>
39 #include <epan/ip_opts.h>
40 #include <epan/prefs.h>
41 #include <epan/reassemble.h>
42 #include <epan/etypes.h>
43 #include <epan/greproto.h>
44 #include <epan/ppptypes.h>
45 #include <epan/llcsaps.h>
46 #include <epan/aftypes.h>
47 #include <epan/arcnet_pids.h>
48 #include <epan/in_cksum.h>
49 #include <epan/nlpid.h>
50 #include <epan/ax25_pids.h>
51 #include <epan/tap.h>
52 #include <epan/wmem/wmem.h>
54 #include "packet-ip.h"
55 #include "packet-ipsec.h"
57 #ifdef HAVE_GEOIP
58 #include <GeoIP.h>
59 #include <epan/geoip_db.h>
60 #endif /* HAVE_GEOIP */
63 static int ip_tap = -1;
65 /* Decode the old IPv4 TOS field as the DiffServ DS Field (RFC2474/2475) */
66 static gboolean g_ip_dscp_actif = TRUE;
68 /* Defragment fragmented IP datagrams */
69 static gboolean ip_defragment = TRUE;
71 /* Place IP summary in proto tree */
72 static gboolean ip_summary_in_tree = TRUE;
74 /* Perform IP checksum */
75 static gboolean ip_check_checksum = TRUE;
77 /* Assume TSO and correct zero-length IP packets */
78 static gboolean ip_tso_supported = TRUE;
80 /* Use heuristics to determine subdissector */
81 static gboolean try_heuristic_first = FALSE;
83 #ifdef HAVE_GEOIP
84 /* Look up addresses in GeoIP */
85 static gboolean ip_use_geoip = TRUE;
86 #endif /* HAVE_GEOIP */
88 /* Interpret the reserved flag as security flag (RFC 3514) */
89 static gboolean ip_security_flag = FALSE;
91 int proto_ip = -1;
92 static int hf_ip_version = -1;
93 static int hf_ip_hdr_len = -1;
94 static int hf_ip_dsfield = -1;
95 static int hf_ip_dsfield_dscp = -1;
96 static int hf_ip_dsfield_ecn = -1;
97 static int hf_ip_tos = -1;
98 static int hf_ip_tos_precedence = -1;
99 static int hf_ip_tos_delay = -1;
100 static int hf_ip_tos_throughput = -1;
101 static int hf_ip_tos_reliability = -1;
102 static int hf_ip_tos_cost = -1;
103 static int hf_ip_len = -1;
104 static int hf_ip_id = -1;
105 static int hf_ip_dst = -1;
106 static int hf_ip_dst_host = -1;
107 static int hf_ip_src = -1;
108 static int hf_ip_src_host = -1;
109 static int hf_ip_addr = -1;
110 static int hf_ip_host = -1;
111 static int hf_ip_flags = -1;
112 static int hf_ip_flags_sf = -1;
113 static int hf_ip_flags_rf = -1;
114 static int hf_ip_flags_df = -1;
115 static int hf_ip_flags_mf = -1;
116 static int hf_ip_frag_offset = -1;
117 static int hf_ip_ttl = -1;
118 static int hf_ip_proto = -1;
119 static int hf_ip_checksum = -1;
120 static int hf_ip_checksum_good = -1;
121 static int hf_ip_checksum_bad = -1;
123 /* IP option fields */
124 static int hf_ip_opt_type = -1;
125 static int hf_ip_opt_type_copy = -1;
126 static int hf_ip_opt_type_class = -1;
127 static int hf_ip_opt_type_number = -1;
128 static int hf_ip_opt_len = -1;
129 static int hf_ip_opt_ptr = -1;
130 static int hf_ip_opt_sid = -1;
131 static int hf_ip_opt_mtu = -1;
132 static int hf_ip_opt_id_number = -1;
133 static int hf_ip_opt_ohc = -1;
134 static int hf_ip_opt_rhc = -1;
135 static int hf_ip_opt_originator = -1;
136 static int hf_ip_opt_ra = -1;
137 static int hf_ip_opt_addr = -1;
138 static int hf_ip_opt_padding = -1;
139 static int hf_ip_opt_qs_func = -1;
140 static int hf_ip_opt_qs_rate = -1;
141 static int hf_ip_opt_qs_ttl = -1;
142 static int hf_ip_opt_qs_ttl_diff = -1;
143 static int hf_ip_opt_qs_unused = -1;
144 static int hf_ip_opt_qs_nonce = -1;
145 static int hf_ip_opt_qs_reserved = -1;
146 static int hf_ip_opt_sec_rfc791_sec = -1;
147 static int hf_ip_opt_sec_rfc791_comp = -1;
148 static int hf_ip_opt_sec_rfc791_hr = -1;
149 static int hf_ip_opt_sec_rfc791_tcc = -1;
150 static int hf_ip_opt_sec_cl = -1;
151 static int hf_ip_opt_sec_prot_auth_flags = -1;
152 static int hf_ip_opt_sec_prot_auth_genser = -1;
153 static int hf_ip_opt_sec_prot_auth_siop_esi = -1;
154 static int hf_ip_opt_sec_prot_auth_sci = -1;
155 static int hf_ip_opt_sec_prot_auth_nsa = -1;
156 static int hf_ip_opt_sec_prot_auth_doe = -1;
157 static int hf_ip_opt_sec_prot_auth_unassigned = -1;
158 static int hf_ip_opt_sec_prot_auth_unassigned2 = -1;
159 static int hf_ip_opt_sec_prot_auth_fti = -1;
160 static int hf_ip_opt_ext_sec_add_sec_info_format_code = -1;
161 static int hf_ip_opt_ext_sec_add_sec_info = -1;
162 static int hf_ip_rec_rt = -1;
163 static int hf_ip_rec_rt_host = -1;
164 static int hf_ip_cur_rt = -1;
165 static int hf_ip_cur_rt_host = -1;
166 static int hf_ip_src_rt = -1;
167 static int hf_ip_src_rt_host = -1;
168 static int hf_ip_empty_rt = -1;
169 static int hf_ip_empty_rt_host = -1;
171 static int hf_ip_fragments = -1;
172 static int hf_ip_fragment = -1;
173 static int hf_ip_fragment_overlap = -1;
174 static int hf_ip_fragment_overlap_conflict = -1;
175 static int hf_ip_fragment_multiple_tails = -1;
176 static int hf_ip_fragment_too_long_fragment = -1;
177 static int hf_ip_fragment_error = -1;
178 static int hf_ip_fragment_count = -1;
179 static int hf_ip_reassembled_in = -1;
180 static int hf_ip_reassembled_length = -1;
181 static int hf_ip_reassembled_data = -1;
183 #ifdef HAVE_GEOIP
184 static int hf_geoip_country = -1;
185 static int hf_geoip_city = -1;
186 static int hf_geoip_org = -1;
187 static int hf_geoip_isp = -1;
188 static int hf_geoip_asnum = -1;
189 static int hf_geoip_lat = -1;
190 static int hf_geoip_lon = -1;
191 static int hf_geoip_src_country = -1;
192 static int hf_geoip_src_city = -1;
193 static int hf_geoip_src_org = -1;
194 static int hf_geoip_src_isp = -1;
195 static int hf_geoip_src_asnum = -1;
196 static int hf_geoip_src_lat = -1;
197 static int hf_geoip_src_lon = -1;
198 static int hf_geoip_dst_country = -1;
199 static int hf_geoip_dst_city = -1;
200 static int hf_geoip_dst_org = -1;
201 static int hf_geoip_dst_isp = -1;
202 static int hf_geoip_dst_asnum = -1;
203 static int hf_geoip_dst_lat = -1;
204 static int hf_geoip_dst_lon = -1;
205 #endif /* HAVE_GEOIP */
207 static gint ett_ip = -1;
208 static gint ett_ip_dsfield = -1;
209 static gint ett_ip_tos = -1;
210 static gint ett_ip_off = -1;
211 static gint ett_ip_options = -1;
212 static gint ett_ip_option_eool = -1;
213 static gint ett_ip_option_nop = -1;
214 static gint ett_ip_option_sec = -1;
215 static gint ett_ip_option_route = -1;
216 static gint ett_ip_option_timestamp = -1;
217 static gint ett_ip_option_ext_security = -1;
218 static gint ett_ip_option_cipso = -1;
219 static gint ett_ip_option_sid = -1;
220 static gint ett_ip_option_mtu = -1;
221 static gint ett_ip_option_tr = -1;
222 static gint ett_ip_option_ra = -1;
223 static gint ett_ip_option_sdb = -1;
224 static gint ett_ip_option_qs = -1;
225 static gint ett_ip_option_other = -1;
226 static gint ett_ip_fragments = -1;
227 static gint ett_ip_fragment = -1;
228 static gint ett_ip_checksum = -1;
229 static gint ett_ip_opt_type = -1;
230 static gint ett_ip_opt_sec_prot_auth_flags = -1;
232 static expert_field ei_ip_opt_len_invalid = EI_INIT;
233 static expert_field ei_ip_opt_sec_prot_auth_fti = EI_INIT;
234 static expert_field ei_ip_extraneous_data = EI_INIT;
235 static expert_field ei_ip_opt_ptr_before_address = EI_INIT;
236 static expert_field ei_ip_opt_ptr_middle_address = EI_INIT;
237 static expert_field ei_ip_subopt_too_long = EI_INIT;
238 static expert_field ei_ip_nop = EI_INIT;
239 static expert_field ei_ip_bogus_ip_length = EI_INIT;
240 static expert_field ei_ip_evil_packet = EI_INIT;
241 static expert_field ei_ip_checksum_bad = EI_INIT;
242 static expert_field ei_ip_ttl_lncb = EI_INIT;
243 static expert_field ei_ip_ttl_too_small = EI_INIT;
246 #ifdef HAVE_GEOIP
247 static gint ett_geoip_info = -1;
248 #endif /* HAVE_GEOIP */
250 static const fragment_items ip_frag_items = {
251 &ett_ip_fragment,
252 &ett_ip_fragments,
253 &hf_ip_fragments,
254 &hf_ip_fragment,
255 &hf_ip_fragment_overlap,
256 &hf_ip_fragment_overlap_conflict,
257 &hf_ip_fragment_multiple_tails,
258 &hf_ip_fragment_too_long_fragment,
259 &hf_ip_fragment_error,
260 &hf_ip_fragment_count,
261 &hf_ip_reassembled_in,
262 &hf_ip_reassembled_length,
263 &hf_ip_reassembled_data,
264 "IPv4 fragments"
267 static heur_dissector_list_t heur_subdissector_list;
269 static dissector_table_t ip_dissector_table;
271 static dissector_handle_t ipv6_handle;
272 static dissector_handle_t data_handle;
275 /* IP structs and definitions */
277 /* Offsets of fields within an IP header. */
278 #define IPH_V_HL 0
279 #define IPH_TOS 1
280 #define IPH_LEN 2
281 #define IPH_ID 4
282 #define IPH_TTL 6
283 #define IPH_OFF 8
284 #define IPH_P 9
285 #define IPH_SUM 10
286 #define IPH_SRC 12
287 #define IPH_DST 16
289 /* Minimum IP header length. */
290 #define IPH_MIN_LEN 20
292 /* Width (in bits) of the fragment offset IP header field */
293 #define IP_OFFSET_WIDTH 13
295 /* Width (in bits) of the flags IP header field */
296 #define IP_FLAGS_WIDTH 3
298 /* IP flags. */
299 #define IP_RF 0x8000 /* Flag: "Reserved bit" */
300 #define IP_DF 0x4000 /* Flag: "Don't Fragment" */
301 #define IP_MF 0x2000 /* Flag: "More Fragments" */
302 #define IP_OFFSET 0x1FFF /* "Fragment Offset" part */
304 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
305 #define IPDSFIELD_DSCP_MASK 0xFC
306 #define IPDSFIELD_ECN_MASK 0x03
307 #define IPDSFIELD_DSCP_SHIFT 2
309 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
310 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
312 #define IPDSFIELD_DSCP_DEFAULT 0x00
313 #define IPDSFIELD_DSCP_CS1 0x08
314 #define IPDSFIELD_DSCP_AF11 0x0A
315 #define IPDSFIELD_DSCP_AF12 0x0C
316 #define IPDSFIELD_DSCP_AF13 0x0E
317 #define IPDSFIELD_DSCP_CS2 0x10
318 #define IPDSFIELD_DSCP_AF21 0x12
319 #define IPDSFIELD_DSCP_AF22 0x14
320 #define IPDSFIELD_DSCP_AF23 0x16
321 #define IPDSFIELD_DSCP_CS3 0x18
322 #define IPDSFIELD_DSCP_AF31 0x1A
323 #define IPDSFIELD_DSCP_AF32 0x1C
324 #define IPDSFIELD_DSCP_AF33 0x1E
325 #define IPDSFIELD_DSCP_CS4 0x20
326 #define IPDSFIELD_DSCP_AF41 0x22
327 #define IPDSFIELD_DSCP_AF42 0x24
328 #define IPDSFIELD_DSCP_AF43 0x26
329 #define IPDSFIELD_DSCP_CS5 0x28
330 #define IPDSFIELD_DSCP_EF 0x2E
331 #define IPDSFIELD_DSCP_CS6 0x30
332 #define IPDSFIELD_DSCP_CS7 0x38
334 #define IPDSFIELD_ECT_NOT 0x00
335 #define IPDSFIELD_ECT_1 0x01
336 #define IPDSFIELD_ECT_0 0x02
337 #define IPDSFIELD_CE 0x03
339 /* IP TOS, superseded by the DS Field, RFC 2474. */
340 #define IPTOS_TOS_MASK 0x1E
341 #define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
342 #define IPTOS_NONE 0x00
343 #define IPTOS_LOWCOST 0x02
344 #define IPTOS_RELIABILITY 0x04
345 #define IPTOS_THROUGHPUT 0x08
346 #define IPTOS_LOWDELAY 0x10
347 #define IPTOS_SECURITY 0x1E
349 #define IPTOS_PREC_MASK 0xE0
350 #define IPTOS_PREC_SHIFT 5
351 #define IPTOS_PREC(tos) (((tos)&IPTOS_PREC_MASK)>>IPTOS_PREC_SHIFT)
352 #define IPTOS_PREC_NETCONTROL 7
353 #define IPTOS_PREC_INTERNETCONTROL 6
354 #define IPTOS_PREC_CRITIC_ECP 5
355 #define IPTOS_PREC_FLASHOVERRIDE 4
356 #define IPTOS_PREC_FLASH 3
357 #define IPTOS_PREC_IMMEDIATE 2
358 #define IPTOS_PREC_PRIORITY 1
359 #define IPTOS_PREC_ROUTINE 0
361 /* IP options */
362 #define IPOPT_COPY 0x80
364 #define IPOPT_CONTROL 0x00
365 #define IPOPT_RESERVED1 0x20
366 #define IPOPT_MEASUREMENT 0x40
367 #define IPOPT_RESERVED2 0x60
369 /* REF: http://www.iana.org/assignments/ip-parameters */
370 /* TODO: Not all of these are implemented. */
371 #define IPOPT_EOOL (0 |IPOPT_CONTROL)
372 #define IPOPT_NOP (1 |IPOPT_CONTROL)
373 #define IPOPT_SEC (2 |IPOPT_COPY|IPOPT_CONTROL) /* RFC 791/1108 */
374 #define IPOPT_LSR (3 |IPOPT_COPY|IPOPT_CONTROL)
375 #define IPOPT_TS (4 |IPOPT_MEASUREMENT)
376 #define IPOPT_ESEC (5 |IPOPT_COPY|IPOPT_CONTROL) /* RFC 1108 */
377 #define IPOPT_CIPSO (6 |IPOPT_COPY|IPOPT_CONTROL) /* draft-ietf-cipso-ipsecurity-01 */
378 #define IPOPT_RR (7 |IPOPT_CONTROL)
379 #define IPOPT_SID (8 |IPOPT_COPY|IPOPT_CONTROL)
380 #define IPOPT_SSR (9 |IPOPT_COPY|IPOPT_CONTROL)
381 #define IPOPT_ZSU (10|IPOPT_CONTROL) /* Zsu */
382 #define IPOPT_MTUP (11|IPOPT_CONTROL) /* RFC 1063 */
383 #define IPOPT_MTUR (12|IPOPT_CONTROL) /* RFC 1063 */
384 #define IPOPT_FINN (13|IPOPT_COPY|IPOPT_MEASUREMENT) /* Finn */
385 #define IPOPT_VISA (14|IPOPT_COPY|IPOPT_CONTROL) /* Estrin */
386 #define IPOPT_ENCODE (15|IPOPT_CONTROL) /* VerSteeg */
387 #define IPOPT_IMITD (16|IPOPT_COPY|IPOPT_CONTROL) /* Lee */
388 #define IPOPT_EIP (17|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1385 */
389 #define IPOPT_TR (18|IPOPT_MEASUREMENT) /* RFC 1393 */
390 #define IPOPT_ADDEXT (19|IPOPT_COPY|IPOPT_CONTROL) /* Ullmann IPv7 */
391 #define IPOPT_RTRALT (20|IPOPT_COPY|IPOPT_CONTROL) /* RFC 2113 */
392 #define IPOPT_SDB (21|IPOPT_COPY|IPOPT_CONTROL) /* RFC 1770 Graff */
393 #define IPOPT_UN (22|IPOPT_COPY|IPOPT_CONTROL) /* Released 18-Oct-2005 */
394 #define IPOPT_DPS (23|IPOPT_COPY|IPOPT_CONTROL) /* Malis */
395 #define IPOPT_UMP (24|IPOPT_COPY|IPOPT_CONTROL) /* Farinacci */
396 #define IPOPT_QS (25|IPOPT_CONTROL) /* RFC 4782 */
397 #define IPOPT_EXP (30|IPOPT_CONTROL) /* RFC 4727 */
400 /* IP option lengths */
401 #define IPOLEN_SEC_MIN 3
402 #define IPOLEN_LSR_MIN 3
403 #define IPOLEN_TS_MIN 4
404 #define IPOLEN_ESEC_MIN 3
405 #define IPOLEN_CIPSO_MIN 10
406 #define IPOLEN_RR_MIN 3
407 #define IPOLEN_SID 4
408 #define IPOLEN_SSR_MIN 3
409 #define IPOLEN_MTU 4
410 #define IPOLEN_TR 12
411 #define IPOLEN_RA 4
412 #define IPOLEN_SDB_MIN 6
413 #define IPOLEN_QS 8
414 #define IPOLEN_MAX 40
416 #define IPSEC_RFC791_UNCLASSIFIED 0x0000
417 #define IPSEC_RFC791_CONFIDENTIAL 0xF135
418 #define IPSEC_RFC791_EFTO 0x789A
419 #define IPSEC_RFC791_MMMM 0xBC4D
420 #define IPSEC_RFC791_PROG 0x5E26
421 #define IPSEC_RFC791_RESTRICTED 0xAF13
422 #define IPSEC_RFC791_SECRET 0xD788
423 #define IPSEC_RFC791_TOPSECRET 0x6BC5
424 #define IPSEC_RFC791_RESERVED1 0x35E2
425 #define IPSEC_RFC791_RESERVED2 0x9AF1
426 #define IPSEC_RFC791_RESERVED3 0x4D78
427 #define IPSEC_RFC791_RESERVED4 0x24BD
428 #define IPSEC_RFC791_RESERVED5 0x135E
429 #define IPSEC_RFC791_RESERVED6 0x89AF
430 #define IPSEC_RFC791_RESERVED7 0xC4D6
431 #define IPSEC_RFC791_RESERVED8 0xE26B
433 #define IPSEC_RESERVED4 0x01
434 #define IPSEC_TOPSECRET 0x3D
435 #define IPSEC_SECRET 0x5A
436 #define IPSEC_CONFIDENTIAL 0x96
437 #define IPSEC_RESERVED3 0x66
438 #define IPSEC_RESERVED2 0xCC
439 #define IPSEC_UNCLASSIFIED 0xAB
440 #define IPSEC_RESERVED1 0xF1
442 #define IPOPT_TS_TSONLY 0 /* timestamps only */
443 #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
444 #define IPOPT_TS_PRESPEC 3 /* specified modules only */
446 #define IPLOCAL_NETWRK_CTRL_BLK_VRRP_ADDR 0xE0000012
447 #define IPLOCAL_NETWRK_CTRL_BLK_VRRP_TTL 0xFF
448 #define IPLOCAL_NETWRK_CTRL_BLK_GLPB_ADDR 0xE0000066
449 #define IPLOCAL_NETWRK_CTRL_BLK_GLPB_TTL 0XFF
450 #define IPLOCAL_NETWRK_CTRL_BLK_MDNS_ADDR 0xE00000FB
451 #define IPLOCAL_NETWRK_CTRL_BLK_MDNS_TTL 0XFF
452 #define IPLOCAL_NETWRK_CTRL_BLK_LLMNR_ADDR 0xE00000FC
454 #define IPLOCAL_NETWRK_CTRL_BLK_ANY_TTL 0x1000 /* larger than max ttl */
455 #define IPLOCAL_NETWRK_CTRL_BLK_DEFAULT_TTL 0X01
457 /* Return true if the address is in the 224.0.0.0/24 network block */
458 #define is_a_local_network_control_block_addr(addr) \
459 ((addr & 0xffffff00) == 0xe0000000)
461 /* Return true if the address is in the 224.0.0.0/4 network block */
462 #define is_a_multicast_addr(addr) \
463 ((addr & 0xf0000000) == 0xe0000000)
466 * defragmentation of IPv4
468 static reassembly_table ip_reassembly_table;
470 static void
471 ip_defragment_init(void)
473 reassembly_table_init(&ip_reassembly_table,
474 &addresses_reassembly_table_functions);
477 void
478 capture_ip(const guchar *pd, int offset, int len, packet_counts *ld) {
479 if (!BYTES_ARE_IN_FRAME(offset, len, IPH_MIN_LEN)) {
480 ld->other++;
481 return;
483 switch (pd[offset + 9]) {
484 case IP_PROTO_TCP:
485 ld->tcp++;
486 break;
487 case IP_PROTO_UDP:
488 case IP_PROTO_UDPLITE:
489 ld->udp++;
490 break;
491 case IP_PROTO_ICMP:
492 case IP_PROTO_ICMPV6: /* XXX - separate counters? */
493 ld->icmp++;
494 break;
495 case IP_PROTO_SCTP:
496 ld->sctp++;
497 break;
498 case IP_PROTO_OSPF:
499 ld->ospf++;
500 break;
501 case IP_PROTO_GRE:
502 ld->gre++;
503 break;
504 case IP_PROTO_VINES:
505 ld->vines++;
506 break;
507 default:
508 ld->other++;
512 #ifdef HAVE_GEOIP
513 static void
514 add_geoip_info_entry(proto_item *geoip_info_item, tvbuff_t *tvb, gint offset, guint32 ip, int isdst)
516 proto_tree *geoip_info_tree;
518 guint num_dbs = geoip_db_num_dbs();
519 guint item_cnt = 0;
520 guint dbnum;
522 geoip_info_tree = proto_item_add_subtree(geoip_info_item, ett_geoip_info);
524 for (dbnum = 0; dbnum < num_dbs; dbnum++) {
525 const char *geoip_str = geoip_db_lookup_ipv4(dbnum, ip, NULL);
526 int db_type = geoip_db_type(dbnum);
528 int geoip_hf, geoip_local_hf;
530 switch (db_type) {
531 case GEOIP_COUNTRY_EDITION:
532 geoip_hf = hf_geoip_country;
533 geoip_local_hf = (isdst) ? hf_geoip_dst_country : hf_geoip_src_country;
534 break;
535 case GEOIP_CITY_EDITION_REV0:
536 geoip_hf = hf_geoip_city;
537 geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
538 break;
539 case GEOIP_CITY_EDITION_REV1:
540 geoip_hf = hf_geoip_city;
541 geoip_local_hf = (isdst) ? hf_geoip_dst_city : hf_geoip_src_city;
542 break;
543 case GEOIP_ORG_EDITION:
544 geoip_hf = hf_geoip_org;
545 geoip_local_hf = (isdst) ? hf_geoip_dst_org : hf_geoip_src_org;
546 break;
547 case GEOIP_ISP_EDITION:
548 geoip_hf = hf_geoip_isp;
549 geoip_local_hf = (isdst) ? hf_geoip_dst_isp : hf_geoip_src_isp;
550 break;
551 case GEOIP_ASNUM_EDITION:
552 geoip_hf = hf_geoip_asnum;
553 geoip_local_hf = (isdst) ? hf_geoip_dst_asnum : hf_geoip_src_asnum;
554 break;
555 case WS_LAT_FAKE_EDITION:
556 geoip_hf = hf_geoip_lat;
557 geoip_local_hf = (isdst) ? hf_geoip_dst_lat : hf_geoip_src_lat;
558 break;
559 case WS_LON_FAKE_EDITION:
560 geoip_hf = hf_geoip_lon;
561 geoip_local_hf = (isdst) ? hf_geoip_dst_lon : hf_geoip_src_lon;
562 break;
563 default:
564 continue;
565 break;
568 if (geoip_str) {
569 proto_item *item;
570 if (db_type == WS_LAT_FAKE_EDITION || db_type == WS_LON_FAKE_EDITION) {
571 /* Convert latitude, longitude to double. Fix bug #5077 */
572 item = proto_tree_add_double_format_value(geoip_info_tree, geoip_local_hf,
573 tvb, offset, 4, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
574 PROTO_ITEM_SET_GENERATED(item);
575 item = proto_tree_add_double_format_value(geoip_info_tree, geoip_hf,
576 tvb, offset, 4, g_ascii_strtod(geoip_str, NULL), "%s", geoip_str);
577 PROTO_ITEM_SET_GENERATED(item);
578 PROTO_ITEM_SET_HIDDEN(item);
579 } else {
580 item = proto_tree_add_unicode_string(geoip_info_tree, geoip_local_hf,
581 tvb, offset, 4, geoip_str);
582 PROTO_ITEM_SET_GENERATED(item);
583 item = proto_tree_add_unicode_string(geoip_info_tree, geoip_hf,
584 tvb, offset, 4, geoip_str);
585 PROTO_ITEM_SET_GENERATED(item);
586 PROTO_ITEM_SET_HIDDEN(item);
589 item_cnt++;
590 proto_item_append_text(geoip_info_item, "%s%s",
591 plurality(item_cnt, "", ", "), geoip_str);
595 if (item_cnt == 0)
596 proto_item_append_text(geoip_info_item, "Unknown");
599 static void
600 add_geoip_info(proto_tree *tree, tvbuff_t *tvb, gint offset, guint32 src32,
601 guint32 dst32)
603 guint num_dbs;
604 proto_item *geoip_info_item;
606 num_dbs = geoip_db_num_dbs();
607 if (num_dbs < 1)
608 return;
610 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IPH_SRC, 4, "Source GeoIP: ");
611 PROTO_ITEM_SET_GENERATED(geoip_info_item);
612 add_geoip_info_entry(geoip_info_item, tvb, offset + IPH_SRC, src32, 0);
614 geoip_info_item = proto_tree_add_text(tree, tvb, offset + IPH_DST, 4,
615 "Destination GeoIP: ");
616 PROTO_ITEM_SET_GENERATED(geoip_info_item);
617 add_geoip_info_entry(geoip_info_item, tvb, offset + IPH_DST, dst32, 1);
619 #endif /* HAVE_GEOIP */
621 const value_string ipopt_type_class_vals[] = {
622 {(IPOPT_CONTROL & IPOPT_CLASS_MASK) >> 5, "Control"},
623 {(IPOPT_RESERVED1 & IPOPT_CLASS_MASK) >> 5, "Reserved for future use"},
624 {(IPOPT_MEASUREMENT & IPOPT_CLASS_MASK) >> 5, "Debugging and measurement"},
625 {(IPOPT_RESERVED2 & IPOPT_CLASS_MASK) >> 5, "Reserved for future use"},
626 {0, NULL}
629 const value_string ipopt_type_number_vals[] = {
630 {IPOPT_EOOL & IPOPT_NUMBER_MASK, "End of Option List (EOL)"},
631 {IPOPT_NOP & IPOPT_NUMBER_MASK, "No-Operation (NOP)"},
632 {IPOPT_SEC & IPOPT_NUMBER_MASK, "Security"},
633 {IPOPT_LSR & IPOPT_NUMBER_MASK, "Loose source route"},
634 {IPOPT_TS & IPOPT_NUMBER_MASK, "Time stamp"},
635 {IPOPT_ESEC & IPOPT_NUMBER_MASK, "Extended security"},
636 {IPOPT_CIPSO & IPOPT_NUMBER_MASK, "Commercial IP security option"},
637 {IPOPT_RR & IPOPT_NUMBER_MASK, "Record route"},
638 {IPOPT_SID & IPOPT_NUMBER_MASK, "Stream identifier"},
639 {IPOPT_SSR & IPOPT_NUMBER_MASK, "Strict source route"},
640 {IPOPT_ZSU & IPOPT_NUMBER_MASK, "Experimental Measurement"},
641 {IPOPT_MTUP & IPOPT_NUMBER_MASK, "MTU probe"},
642 {IPOPT_MTUR & IPOPT_NUMBER_MASK, "MTU Reply"},
643 {IPOPT_FINN & IPOPT_NUMBER_MASK, "Experimental Flow Control"},
644 {IPOPT_VISA & IPOPT_NUMBER_MASK, "Experimental Access Control"},
645 {IPOPT_ENCODE & IPOPT_NUMBER_MASK, "Ask Estrin"},
646 {IPOPT_IMITD & IPOPT_NUMBER_MASK, "IMI Traffic Descriptor"},
647 {IPOPT_EIP & IPOPT_NUMBER_MASK, "Extended Internet Protocol"},
648 {IPOPT_TR & IPOPT_NUMBER_MASK, "Traceroute"},
649 {IPOPT_ADDEXT & IPOPT_NUMBER_MASK, "Address Extension"},
650 {IPOPT_RTRALT & IPOPT_NUMBER_MASK, "Router Alert"},
651 {IPOPT_SDB & IPOPT_NUMBER_MASK, "Selective Directed Broadcast"},
652 {IPOPT_UN & IPOPT_NUMBER_MASK, "Unassigned"},
653 {IPOPT_DPS & IPOPT_NUMBER_MASK, "Dynamic Packet State"},
654 {IPOPT_UMP & IPOPT_NUMBER_MASK, "Upstream Multicast Packet"},
655 {IPOPT_QS & IPOPT_NUMBER_MASK, "Quick-Start"},
656 {IPOPT_EXP & IPOPT_NUMBER_MASK, "RFC 3692-style experiment"},
657 {0, NULL}
660 static ip_tcp_opt_type IP_OPT_TYPES = {&hf_ip_opt_type, &ett_ip_opt_type,
661 &hf_ip_opt_type_copy, &hf_ip_opt_type_class, &hf_ip_opt_type_number};
663 static void
664 dissect_ipopt_type(tvbuff_t *tvb, int offset, proto_tree *tree, ip_tcp_opt_type* opttypes)
666 proto_tree *type_tree;
667 proto_item *ti;
669 ti = proto_tree_add_item(tree, *opttypes->phf_opt_type, tvb, offset, 1, ENC_NA);
670 type_tree = proto_item_add_subtree(ti, *opttypes->pett_opt_type);
671 proto_tree_add_item(type_tree, *opttypes->phf_opt_type_copy, tvb, offset, 1, ENC_NA);
672 proto_tree_add_item(type_tree, *opttypes->phf_opt_type_class, tvb, offset, 1, ENC_NA);
673 proto_tree_add_item(type_tree, *opttypes->phf_opt_type_number, tvb, offset, 1, ENC_NA);
676 static void
677 dissect_ipopt_eool(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
678 guint optlen _U_, packet_info *pinfo _U_,
679 proto_tree *opt_tree, void * data _U_)
681 proto_tree *field_tree;
682 proto_item *tf;
684 tf = proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", optp->name);
685 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
686 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
689 #define dissect_ipopt_nop dissect_ipopt_eool
691 static const value_string secl_rfc791_vals[] = {
692 {IPSEC_RFC791_UNCLASSIFIED, "Unclassified"},
693 {IPSEC_RFC791_CONFIDENTIAL, "Confidential"},
694 {IPSEC_RFC791_EFTO, "EFTO" },
695 {IPSEC_RFC791_MMMM, "MMMM" },
696 {IPSEC_RFC791_PROG, "PROG" },
697 {IPSEC_RFC791_RESTRICTED, "Restricted" },
698 {IPSEC_RFC791_SECRET, "Secret" },
699 {IPSEC_RFC791_TOPSECRET, "Top secret" },
700 {IPSEC_RFC791_RESERVED1, "Reserved" },
701 {IPSEC_RFC791_RESERVED2, "Reserved" },
702 {IPSEC_RFC791_RESERVED3, "Reserved" },
703 {IPSEC_RFC791_RESERVED4, "Reserved" },
704 {IPSEC_RFC791_RESERVED5, "Reserved" },
705 {IPSEC_RFC791_RESERVED6, "Reserved" },
706 {IPSEC_RFC791_RESERVED7, "Reserved" },
707 {IPSEC_RFC791_RESERVED8, "Reserved" },
708 {0, NULL }
711 static const value_string sec_cl_vals[] = {
712 {IPSEC_RESERVED4, "Reserved 4" },
713 {IPSEC_TOPSECRET, "Top secret" },
714 {IPSEC_SECRET, "Secret" },
715 {IPSEC_CONFIDENTIAL, "Confidential"},
716 {IPSEC_RESERVED3, "Reserved 3" },
717 {IPSEC_RESERVED2, "Reserved 2" },
718 {IPSEC_UNCLASSIFIED, "Unclassified"},
719 {IPSEC_RESERVED1, "Reserved 1" },
720 {0, NULL }
723 static const true_false_string ip_opt_sec_prot_auth_flag_tfs = {
724 "Datagram protected in accordance with its rules",
725 "Datagram not protected in accordance with its rules"
728 static const true_false_string ip_opt_sec_prot_auth_fti_tfs = {
729 "Additional octet present",
730 "Final octet"
733 static const int *ip_opt_sec_prot_auth_fields_byte_1[] = {
734 &hf_ip_opt_sec_prot_auth_genser,
735 &hf_ip_opt_sec_prot_auth_siop_esi,
736 &hf_ip_opt_sec_prot_auth_sci,
737 &hf_ip_opt_sec_prot_auth_nsa,
738 &hf_ip_opt_sec_prot_auth_doe,
739 &hf_ip_opt_sec_prot_auth_unassigned,
740 &hf_ip_opt_sec_prot_auth_fti,
741 NULL
744 static const int *ip_opt_sec_prot_auth_fields_byte_n[] = {
745 &hf_ip_opt_sec_prot_auth_unassigned2,
746 &hf_ip_opt_sec_prot_auth_fti,
747 NULL
749 static void
750 dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
751 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
752 void * data _U_)
754 proto_tree *field_tree;
755 proto_item *tf;
756 proto_item *tf_sub;
757 guint val;
758 guint curr_offset = offset;
760 tf = proto_tree_add_text(opt_tree, tvb, curr_offset, optlen, "%s (%u bytes)",
761 optp->name, optlen);
762 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
763 dissect_ipopt_type(tvb, curr_offset, field_tree, &IP_OPT_TYPES);
764 curr_offset++;
765 tf_sub = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, curr_offset, 1, ENC_NA);
766 if (optlen > IPOLEN_MAX)
767 expert_add_info(pinfo, tf_sub, &ei_ip_opt_len_invalid);
768 curr_offset++;
770 if (optlen == 11) {
771 /* Analyze payload start to decide whether it should be dissected
772 according to RFC 791 or RFC 1108 */
773 val = tvb_get_ntohs(tvb, curr_offset);
774 if (try_val_to_str(val, secl_rfc791_vals)) {
775 /* Dissect as RFC 791 */
776 proto_tree_add_item(field_tree, hf_ip_opt_sec_rfc791_sec,
777 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
778 curr_offset += 2;
779 proto_tree_add_item(field_tree, hf_ip_opt_sec_rfc791_comp,
780 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
781 curr_offset += 2;
782 proto_tree_add_item(field_tree, hf_ip_opt_sec_rfc791_hr,
783 tvb, curr_offset, 2, ENC_ASCII|ENC_NA);
784 curr_offset += 2;
785 proto_tree_add_item(field_tree, hf_ip_opt_sec_rfc791_tcc,
786 tvb, curr_offset, 3, ENC_ASCII|ENC_NA);
787 return;
791 /* Dissect as RFC 108 */
792 proto_tree_add_item(field_tree, hf_ip_opt_sec_cl, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
793 curr_offset++;
794 if ((curr_offset - offset) >= optlen) {
795 return;
797 val = tvb_get_guint8(tvb, curr_offset);
798 proto_tree_add_bitmask(field_tree, tvb, curr_offset, hf_ip_opt_sec_prot_auth_flags,
799 ett_ip_opt_sec_prot_auth_flags, ip_opt_sec_prot_auth_fields_byte_1,
800 ENC_BIG_ENDIAN);
801 curr_offset++;
802 while (val & 0x01) {
803 if ((val & 0x01) && ((curr_offset - offset) == optlen)) {
804 expert_add_info(pinfo, tf_sub, &ei_ip_opt_sec_prot_auth_fti);
805 break;
807 val = tvb_get_guint8(tvb, curr_offset);
808 proto_tree_add_bitmask(field_tree, tvb, curr_offset, hf_ip_opt_sec_prot_auth_flags,
809 ett_ip_opt_sec_prot_auth_flags, ip_opt_sec_prot_auth_fields_byte_n,
810 ENC_BIG_ENDIAN);
811 curr_offset++;
813 if ((curr_offset - offset) < optlen) {
814 expert_add_info(pinfo, tf, &ei_ip_extraneous_data);
818 static void
819 dissect_ipopt_ext_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
820 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
821 void * data _U_)
823 proto_tree *field_tree;
824 proto_item *tf;
825 proto_item *tf_sub;
826 guint curr_offset = offset;
827 gint remaining;
829 tf = proto_tree_add_text(opt_tree, tvb, curr_offset, optlen, "%s (%u bytes)",
830 optp->name, optlen);
831 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
832 dissect_ipopt_type(tvb, curr_offset, field_tree, &IP_OPT_TYPES);
833 curr_offset++;
834 tf_sub = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, curr_offset, 1, ENC_NA);
835 if (optlen > IPOLEN_MAX)
836 expert_add_info(pinfo, tf_sub, &ei_ip_opt_len_invalid);
837 curr_offset++;
838 proto_tree_add_item(field_tree, hf_ip_opt_ext_sec_add_sec_info_format_code, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
839 curr_offset++;
840 remaining = optlen - (curr_offset - offset);
841 if (remaining > 0) {
842 proto_tree_add_item(field_tree, hf_ip_opt_ext_sec_add_sec_info, tvb, curr_offset, remaining, ENC_NA);
846 /* USHRT_MAX can hold at most 5 (base 10) digits (6 for the NULL byte) */
847 #define USHRT_MAX_STRLEN 6
849 /* Maximum CIPSO tag length:
850 * (IP hdr max)60 - (IPv4 hdr std)20 - (CIPSO base)6 = 34 */
851 #define CIPSO_TAG_LEN_MAX 34
853 /* The Commercial IP Security Option (CIPSO) is defined in IETF draft
854 * draft-ietf-cipso-ipsecurity-01.txt and FIPS 188, a copy of both documents
855 * can be found at the NetLabel project page, http://netlabel.sf.net or at
856 * http://tools.ietf.org/html/draft-ietf-cipso-ipsecurity-01 */
857 static void
858 dissect_ipopt_cipso(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
859 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
860 void * data _U_)
862 proto_tree *field_tree;
863 proto_item *tf;
864 guint tagtype, taglen;
865 int offset_max = offset + optlen;
867 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
868 optp->name, optlen);
869 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
870 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
871 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
872 if (optlen > IPOLEN_MAX)
873 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
875 offset += 2;
877 proto_tree_add_text(field_tree, tvb, offset, 4, "DOI: %u",
878 tvb_get_ntohl(tvb, offset));
879 offset += 4;
881 /* loop through all of the tags in the CIPSO option */
882 while (offset < offset_max) {
883 tagtype = tvb_get_guint8(tvb, offset);
885 if ((offset + 1) < offset_max)
886 taglen = tvb_get_guint8(tvb, offset + 1);
887 else
888 taglen = 1;
890 switch (tagtype) {
891 case 0:
892 /* padding - skip this tag */
893 offset += 1;
894 continue;
895 case 1:
896 /* restrictive bitmap, see CIPSO draft section 3.4.2 for tag format */
897 if ((taglen < 4) || (taglen > CIPSO_TAG_LEN_MAX) ||
898 ((offset + (int)taglen - 1) > offset_max)) {
899 proto_tree_add_text(field_tree, tvb, offset, offset_max - offset,
900 "Malformed CIPSO tag");
901 return;
904 proto_tree_add_text(field_tree, tvb, offset, 1,
905 "Tag Type: Restrictive Category Bitmap (%u)",
906 tagtype);
908 /* skip past alignment octet */
909 offset += 3;
911 proto_tree_add_text(field_tree, tvb, offset, 1, "Sensitivity Level: %u",
912 tvb_get_guint8(tvb, offset));
913 offset += 1;
915 if (taglen > 4) {
916 guint bit_spot = 0;
917 guint byte_spot = 0;
918 unsigned char bitmask;
919 char *cat_str;
920 char *cat_str_tmp = (char *)wmem_alloc(wmem_packet_scope(), USHRT_MAX_STRLEN);
921 size_t cat_str_len;
922 const guint8 *val_ptr = tvb_get_ptr(tvb, offset, taglen - 4);
924 /* this is just a guess regarding string size, but we grow it below
925 * if needed */
926 cat_str_len = 256;
927 cat_str = (char *)wmem_alloc0(wmem_packet_scope(), cat_str_len);
929 /* we checked the length above so the highest category value
930 * possible here is 240 */
931 while (byte_spot < (taglen - 4)) {
932 bitmask = 0x80;
933 bit_spot = 0;
934 while (bit_spot < 8) {
935 if (val_ptr[byte_spot] & bitmask) {
936 g_snprintf(cat_str_tmp, USHRT_MAX_STRLEN, "%u",
937 byte_spot * 8 + bit_spot);
938 if (cat_str_len < (strlen(cat_str) + 2 + USHRT_MAX_STRLEN)) {
939 char *cat_str_new;
941 while (cat_str_len < (strlen(cat_str) + 2 + USHRT_MAX_STRLEN))
942 cat_str_len += cat_str_len;
943 cat_str_new = (char *)wmem_alloc(wmem_packet_scope(), cat_str_len);
944 g_strlcpy(cat_str_new, cat_str, cat_str_len);
945 cat_str_new[cat_str_len - 1] = '\0';
946 cat_str = cat_str_new;
948 if (cat_str[0] != '\0')
949 g_strlcat(cat_str, ",", cat_str_len);
950 g_strlcat(cat_str, cat_str_tmp, cat_str_len);
952 bit_spot++;
953 bitmask >>= 1;
955 byte_spot++;
958 if (cat_str)
959 proto_tree_add_text(field_tree, tvb, offset, taglen - 4,
960 "Categories: %s", cat_str);
961 else
962 proto_tree_add_text(field_tree, tvb, offset, taglen - 4,
963 "Categories: ERROR PARSING CATEGORIES");
964 offset += taglen - 4;
966 break;
967 case 2:
968 /* enumerated categories, see CIPSO draft section 3.4.3 for tag format */
969 if ((taglen < 4) || (taglen > CIPSO_TAG_LEN_MAX) ||
970 ((offset + (int)taglen - 1) > offset_max)) {
971 proto_tree_add_text(field_tree, tvb, offset, offset_max - offset,
972 "Malformed CIPSO tag");
973 return;
976 proto_tree_add_text(field_tree, tvb, offset, 1,
977 "Tag Type: Enumerated Categories (%u)", tagtype);
979 /* skip past alignment octet */
980 offset += 3;
982 /* sensitivity level */
983 proto_tree_add_text(field_tree, tvb, offset, 1, "Sensitivity Level: %u",
984 tvb_get_guint8(tvb, offset));
985 offset += 1;
987 if (taglen > 4) {
988 int offset_max_cat = offset + taglen - 4;
989 char *cat_str = (char *)wmem_alloc0(wmem_packet_scope(), USHRT_MAX_STRLEN * 15);
990 char *cat_str_tmp = (char *)wmem_alloc(wmem_packet_scope(), USHRT_MAX_STRLEN);
992 while ((offset + 2) <= offset_max_cat) {
993 g_snprintf(cat_str_tmp, USHRT_MAX_STRLEN, "%u",
994 tvb_get_ntohs(tvb, offset));
995 offset += 2;
996 if (cat_str[0] != '\0')
997 g_strlcat(cat_str, ",", USHRT_MAX_STRLEN * 15);
998 g_strlcat(cat_str, cat_str_tmp, USHRT_MAX_STRLEN * 15);
1001 proto_tree_add_text(field_tree, tvb, offset - taglen + 4, taglen - 4,
1002 "Categories: %s", cat_str);
1004 break;
1005 case 5:
1006 /* ranged categories, see CIPSO draft section 3.4.4 for tag format */
1007 if ((taglen < 4) || (taglen > CIPSO_TAG_LEN_MAX) ||
1008 ((offset + (int)taglen - 1) > offset_max)) {
1009 proto_tree_add_text(field_tree, tvb, offset, offset_max - offset,
1010 "Malformed CIPSO tag");
1011 return;
1014 proto_tree_add_text(field_tree, tvb, offset, 1,
1015 "Tag Type: Ranged Categories (%u)", tagtype);
1017 /* skip past alignment octet */
1018 offset += 3;
1020 /* sensitivity level */
1021 proto_tree_add_text(field_tree, tvb, offset, 1, "Sensitivity Level: %u",
1022 tvb_get_guint8(tvb, offset));
1023 offset += 1;
1025 if (taglen > 4) {
1026 guint16 cat_low, cat_high;
1027 int offset_max_cat = offset + taglen - 4;
1028 char *cat_str = (char *)wmem_alloc0(wmem_packet_scope(), USHRT_MAX_STRLEN * 16);
1029 char *cat_str_tmp = (char *)wmem_alloc(wmem_packet_scope(), USHRT_MAX_STRLEN * 2);
1031 while ((offset + 2) <= offset_max_cat) {
1032 cat_high = tvb_get_ntohs(tvb, offset);
1033 if ((offset + 4) <= offset_max_cat) {
1034 cat_low = tvb_get_ntohs(tvb, offset + 2);
1035 offset += 4;
1036 } else {
1037 cat_low = 0;
1038 offset += 2;
1040 if (cat_low != cat_high)
1041 g_snprintf(cat_str_tmp, USHRT_MAX_STRLEN * 2, "%u-%u",
1042 cat_high, cat_low);
1043 else
1044 g_snprintf(cat_str_tmp, USHRT_MAX_STRLEN * 2, "%u", cat_high);
1046 if (cat_str[0] != '\0')
1047 g_strlcat(cat_str, ",", USHRT_MAX_STRLEN * 16);
1048 g_strlcat(cat_str, cat_str_tmp, USHRT_MAX_STRLEN * 16);
1051 proto_tree_add_text(field_tree, tvb, offset - taglen + 4, taglen - 4,
1052 "Categories: %s", cat_str);
1054 break;
1055 case 6:
1056 /* permissive categories, see FIPS 188 section 6.9 for tag format */
1057 if ((taglen < 4) || (taglen > CIPSO_TAG_LEN_MAX) ||
1058 ((offset + (int)taglen - 1) > offset_max)) {
1059 proto_tree_add_text(field_tree, tvb, offset, offset_max - offset,
1060 "Malformed CIPSO tag");
1061 return;
1064 proto_tree_add_text(field_tree, tvb, offset, 1,
1065 "Tag Type: Permissive Categories (%u)", tagtype);
1066 proto_tree_add_text(field_tree, tvb, offset + 2, taglen - 2, "Tag data");
1067 offset += taglen;
1068 break;
1069 case 7:
1070 /* free form, see FIPS 188 section 6.10 for tag format */
1071 if ((taglen < 2) || (taglen > CIPSO_TAG_LEN_MAX) ||
1072 ((offset + (int)taglen - 1) > offset_max)) {
1073 proto_tree_add_text(field_tree, tvb, offset, offset_max - offset,
1074 "Malformed CIPSO tag");
1075 return;
1078 proto_tree_add_text(field_tree, tvb, offset, 1,
1079 "Tag Type: Free Form (%u)", tagtype);
1080 proto_tree_add_text(field_tree, tvb, offset + 2, taglen - 2, "Tag data");
1081 offset += taglen;
1082 break;
1083 default:
1084 /* unknown tag - stop parsing this IPv4 option */
1085 if ((offset + 1) <= offset_max) {
1086 taglen = tvb_get_guint8(tvb, offset + 1);
1087 proto_tree_add_text(field_tree, tvb, offset, 1,
1088 "Tag Type: Unknown (%u) (%u bytes)",
1089 tagtype, taglen);
1090 return;
1092 proto_tree_add_text(field_tree, tvb, offset, 1,
1093 "Tag Type: Unknown (%u) (invalid format)", tagtype);
1094 return;
1099 static void
1100 dissect_option_route(proto_tree *tree, tvbuff_t *tvb, int offset, int hf,
1101 int hf_host, gboolean next)
1103 proto_item *ti;
1104 guint32 route;
1106 route = tvb_get_ipv4(tvb, offset);
1107 if (next)
1108 proto_tree_add_ipv4_format_value(tree, hf, tvb, offset, 4, route,
1109 "%s <- (next)",
1110 ip_to_str((gchar *)&route));
1111 else
1112 proto_tree_add_ipv4(tree, hf, tvb, offset, 4, route);
1113 ti = proto_tree_add_string(tree, hf_host, tvb, offset, 4, get_hostname(route));
1114 PROTO_ITEM_SET_GENERATED(ti);
1115 PROTO_ITEM_SET_HIDDEN(ti);
1118 static void
1119 dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1120 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1121 void * data _U_)
1123 proto_tree *field_tree;
1124 proto_item *tf;
1125 guint8 len, ptr;
1126 int optoffset = 0;
1128 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
1129 optp->name, optlen);
1130 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1131 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1132 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1133 if (optlen > IPOLEN_MAX)
1134 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1135 ptr = tvb_get_guint8(tvb, offset + 2);
1136 tf = proto_tree_add_item(field_tree, hf_ip_opt_ptr, tvb, offset + 2, 1, ENC_NA);
1137 if ((ptr < (optp->optlen + 1)) || (ptr & 3)) {
1138 if (ptr < (optp->optlen + 1)) {
1139 expert_add_info(pinfo, tf, &ei_ip_opt_ptr_before_address);
1141 else {
1142 expert_add_info(pinfo, tf, &ei_ip_opt_ptr_middle_address);
1144 return;
1147 len = optlen;
1148 optoffset = 3; /* skip past type, length and pointer */
1149 for (optlen -= 3; optlen > 0; optlen -= 4, optoffset += 4) {
1150 if (optlen < 4) {
1151 expert_add_info(pinfo, tf, &ei_ip_subopt_too_long);
1152 break;
1155 if (ptr > len) {
1156 /* This is a recorded route */
1157 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
1158 hf_ip_rec_rt_host, FALSE);
1159 } else if (optoffset == (len - 4)) {
1160 /* This is the the destination */
1161 proto_item *item;
1162 guint32 addr;
1163 const char *dst_host;
1165 addr = tvb_get_ipv4(tvb, offset + optoffset);
1166 dst_host = get_hostname(addr);
1167 proto_tree_add_ipv4(field_tree, hf_ip_dst, tvb,
1168 offset + optoffset, 4, addr);
1169 item = proto_tree_add_ipv4(field_tree, hf_ip_addr, tvb,
1170 offset + optoffset, 4, addr);
1171 PROTO_ITEM_SET_HIDDEN(item);
1172 item = proto_tree_add_string(field_tree, hf_ip_dst_host, tvb,
1173 offset + optoffset, 4, dst_host);
1174 PROTO_ITEM_SET_GENERATED(item);
1175 PROTO_ITEM_SET_HIDDEN(item);
1176 item = proto_tree_add_string(field_tree, hf_ip_host, tvb,
1177 offset + optoffset, 4, dst_host);
1178 PROTO_ITEM_SET_GENERATED(item);
1179 PROTO_ITEM_SET_HIDDEN(item);
1180 } else if ((optoffset + 1) < ptr) {
1181 /* This is also a recorded route */
1182 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
1183 hf_ip_rec_rt_host, FALSE);
1184 } else if ((optoffset + 1) == ptr) {
1185 /* This is the next source route. TODO: Should we use separate hf's
1186 * for this, such as hf_ip_next_rt and hf_ip_next_rt_host and avoid
1187 * having to pass TRUE/FALSE to dissect_option_route()? */
1188 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_src_rt,
1189 hf_ip_src_rt_host, TRUE);
1190 } else {
1191 /* This must be a source route */
1192 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_src_rt,
1193 hf_ip_src_rt_host, FALSE);
1198 static void
1199 dissect_ipopt_record_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1200 guint optlen, packet_info *pinfo,
1201 proto_tree *opt_tree, void * data _U_)
1203 proto_tree *field_tree;
1204 proto_item *tf;
1205 guint8 len, ptr;
1206 int optoffset = 0;
1208 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
1209 optp->name, optlen);
1210 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1211 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1212 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1213 if (optlen > IPOLEN_MAX)
1214 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1215 ptr = tvb_get_guint8(tvb, offset + 2);
1216 tf = proto_tree_add_item(field_tree, hf_ip_opt_ptr, tvb, offset + 2, 1, ENC_NA);
1218 if ((ptr < (optp->optlen + 1)) || (ptr & 3)) {
1219 if (ptr < (optp->optlen + 1)) {
1220 expert_add_info(pinfo, tf, &ei_ip_opt_ptr_before_address);
1222 else {
1223 expert_add_info(pinfo, tf, &ei_ip_opt_ptr_middle_address);
1225 return;
1228 len = optlen;
1229 optoffset = 3; /* skip past type, length and pointer */
1230 for (optlen -= 3; optlen > 0; optlen -= 4, optoffset += 4) {
1231 if (optlen < 4) {
1232 expert_add_info(pinfo, tf, &ei_ip_subopt_too_long);
1233 break;
1236 if (ptr > len) {
1237 /* The recorded route data area is full. */
1238 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
1239 hf_ip_rec_rt_host, FALSE);
1240 } else if ((optoffset + 1) < ptr) {
1241 /* This is a recorded route */
1242 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_rec_rt,
1243 hf_ip_rec_rt_host, FALSE);
1244 } else if ((optoffset + 1) == ptr) {
1245 /* This is the next available slot. TODO: Should we use separate hf's
1246 * for this, such as hf_ip_next_rt and hf_ip_next_rt_host and avoid
1247 * having to pass TRUE/FALSE to dissect_option_route()? */
1248 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_empty_rt,
1249 hf_ip_empty_rt_host, TRUE);
1250 } else {
1251 /* This must be an available slot too. */
1252 dissect_option_route(field_tree, tvb, offset + optoffset, hf_ip_empty_rt,
1253 hf_ip_empty_rt_host, FALSE);
1258 /* Stream Identifier */
1259 static void
1260 dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1261 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1262 void * data _U_)
1264 proto_tree *field_tree;
1265 proto_item *tf;
1267 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes): %u",
1268 optp->name, optlen, tvb_get_ntohs(tvb, offset + 2));
1269 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1270 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1271 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1272 if (optlen != (guint)optp->optlen)
1273 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1274 proto_tree_add_item(field_tree, hf_ip_opt_sid, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1277 /* RFC 1063: MTU Probe and MTU Reply */
1278 static void
1279 dissect_ipopt_mtu(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1280 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1281 void * data _U_)
1283 proto_tree *field_tree;
1284 proto_item *tf;
1286 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes): %u",
1287 optp->name, optlen, tvb_get_ntohs(tvb, offset + 2));
1288 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1289 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1290 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1291 if (optlen != (guint)optp->optlen)
1292 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1293 proto_tree_add_item(field_tree, hf_ip_opt_mtu, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1296 /* RFC 1393: Traceroute */
1297 static void
1298 dissect_ipopt_tr(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1299 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1300 void * data _U_)
1302 proto_tree *field_tree;
1303 proto_item *tf;
1305 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
1306 optp->name, optlen);
1307 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1308 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1309 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1310 if (optlen != (guint)optp->optlen)
1311 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1313 proto_tree_add_item(field_tree, hf_ip_opt_id_number, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1314 proto_tree_add_item(field_tree, hf_ip_opt_ohc, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
1315 proto_tree_add_item(field_tree, hf_ip_opt_rhc, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
1316 proto_tree_add_item(field_tree, hf_ip_opt_originator, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
1319 static void
1320 dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
1321 int offset, guint optlen, packet_info *pinfo,
1322 proto_tree *opt_tree, void * data _U_)
1324 proto_tree *field_tree;
1325 proto_item *tf;
1326 int ptr;
1327 int optoffset = 0;
1328 int flg;
1329 static const value_string flag_vals[] = {
1330 {IPOPT_TS_TSONLY, "Time stamps only" },
1331 {IPOPT_TS_TSANDADDR, "Time stamp and address" },
1332 {IPOPT_TS_PRESPEC, "Time stamps for prespecified addresses"},
1333 {0, NULL }};
1334 guint32 addr;
1335 guint ts;
1337 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
1338 optp->name, optlen);
1339 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1340 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1341 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1342 if (optlen > IPOLEN_MAX)
1343 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1344 optoffset += 2; /* skip past type and length */
1345 optlen -= 2; /* subtract size of type and length */
1347 ptr = tvb_get_guint8(tvb, offset + optoffset);
1348 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Pointer: %d%s",
1349 ptr, ((ptr == 1) ? " (header is full)" :
1350 (ptr < 5) ? " (points before first address)" :
1351 (((ptr - 1) & 3) ? " (points to middle of field)" : "")));
1352 optoffset++;
1353 optlen--;
1354 ptr--; /* ptr is 1-origin */
1356 flg = tvb_get_guint8(tvb, offset + optoffset);
1357 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Overflow: %u",
1358 flg >> 4);
1359 flg &= 0xF;
1360 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Flag: %s",
1361 val_to_str(flg, flag_vals, "Unknown (0x%x)"));
1362 optoffset++;
1363 optlen--;
1365 while (optlen > 0) {
1366 if (flg == IPOPT_TS_TSANDADDR || flg == IPOPT_TS_PRESPEC) {
1367 if (optlen < 8) {
1368 proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
1369 "(suboption would go past end of option)");
1370 break;
1372 addr = tvb_get_ipv4(tvb, offset + optoffset);
1373 ts = tvb_get_ntohl(tvb, offset + optoffset + 4);
1374 optlen -= 8;
1375 proto_tree_add_text(field_tree, tvb, offset + optoffset, 8,
1376 "Address = %s, time stamp = %u",
1377 ((addr == 0) ? "-" :
1378 get_hostname(addr)), ts);
1379 optoffset += 8;
1380 } else {
1381 if (optlen < 4) {
1382 proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
1383 "(suboption would go past end of option)");
1384 break;
1386 ts = tvb_get_ntohl(tvb, offset + optoffset);
1387 optlen -= 4;
1388 proto_tree_add_text(field_tree, tvb, offset + optoffset, 4,
1389 "Time stamp = %u", ts);
1390 optoffset += 4;
1395 /* Router Alert */
1396 static const range_string ra_rvals[] = {
1397 {0, 0, "Router shall examine packet"},
1398 {1, 65535, "Reserved"},
1399 {0, 0, NULL}
1402 static void
1403 dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1404 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1405 void * data _U_)
1407 /* Router-Alert, as defined by RFC2113 */
1408 proto_tree *field_tree;
1409 proto_item *tf;
1410 guint16 value = tvb_get_ntohs(tvb, offset + 2);
1412 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen,
1413 "%s (%u bytes): %s (%u)", optp->name, optlen,
1414 rval_to_str(value, ra_rvals, "Unknown (%u)"),
1415 value);
1416 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1417 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1418 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1419 if (optlen != (guint)optp->optlen)
1420 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1421 proto_tree_add_item(field_tree, hf_ip_opt_ra, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1424 /* RFC 1770: Selective Directed Broadcast */
1425 static void
1426 dissect_ipopt_sdb(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1427 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1428 void * data _U_)
1430 proto_tree *field_tree;
1431 proto_item *tf;
1433 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
1434 optp->name, optlen);
1435 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1436 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1437 tf = proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1438 if (optlen > IPOLEN_MAX)
1439 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1440 for (offset += 2, optlen -= 2; optlen >= 4; offset += 4, optlen -= 4)
1441 proto_tree_add_item(field_tree, hf_ip_opt_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
1443 if (optlen > 0)
1444 proto_tree_add_item(field_tree, hf_ip_opt_padding, tvb, offset, optlen, ENC_NA);
1447 const value_string qs_func_vals[] = {
1448 {QS_RATE_REQUEST, "Rate request"},
1449 {QS_RATE_REPORT, "Rate report"},
1450 {0, NULL}
1453 static const value_string qs_rate_vals[] = {
1454 { 0, "0 bit/s"},
1455 { 1, "80 Kbit/s"},
1456 { 2, "160 Kbit/s"},
1457 { 3, "320 Kbit/s"},
1458 { 4, "640 Kbit/s"},
1459 { 5, "1.28 Mbit/s"},
1460 { 6, "2.56 Mbit/s"},
1461 { 7, "5.12 Mbit/s"},
1462 { 8, "10.24 Mbit/s"},
1463 { 9, "20.48 Mbit/s"},
1464 {10, "40.96 Mbit/s"},
1465 {11, "81.92 Mbit/s"},
1466 {12, "163.84 Mbit/s"},
1467 {13, "327.68 Mbit/s"},
1468 {14, "655.36 Mbit/s"},
1469 {15, "1.31072 Gbit/s"},
1470 {0, NULL}
1472 value_string_ext qs_rate_vals_ext = VALUE_STRING_EXT_INIT(qs_rate_vals);
1474 static void
1475 dissect_ipopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1476 guint optlen, packet_info *pinfo, proto_tree *opt_tree,
1477 void * data _U_)
1479 proto_tree *field_tree;
1480 proto_item *tf;
1481 proto_item *ti;
1483 guint8 command = tvb_get_guint8(tvb, offset + 2);
1484 guint8 function = command >> 4;
1485 guint8 rate = command & QS_RATE_MASK;
1486 guint8 ttl_diff;
1488 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen,
1489 "%s (%u bytes): %s (%u)", optp->name, optlen,
1490 val_to_str(function, qs_func_vals, "Unknown (%u)"),
1491 function);
1492 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1494 dissect_ipopt_type(tvb, offset, field_tree, &IP_OPT_TYPES);
1495 proto_tree_add_item(field_tree, hf_ip_opt_len, tvb, offset + 1, 1, ENC_NA);
1496 if (optlen != (guint)optp->optlen)
1497 expert_add_info(pinfo, tf, &ei_ip_opt_len_invalid);
1498 proto_tree_add_item(field_tree, hf_ip_opt_qs_func, tvb, offset + 2, 1, ENC_NA);
1500 if (function == QS_RATE_REQUEST) {
1501 proto_tree_add_item(field_tree, hf_ip_opt_qs_rate, tvb, offset + 2, 1, ENC_NA);
1502 proto_tree_add_item(field_tree, hf_ip_opt_qs_ttl, tvb, offset + 3, 1, ENC_NA);
1503 ttl_diff = (pinfo->ip_ttl - tvb_get_guint8(tvb, offset + 3) % 256);
1504 ti = proto_tree_add_uint_format_value(field_tree, hf_ip_opt_qs_ttl_diff,
1505 tvb, offset + 3, 1, ttl_diff,
1506 "%u", ttl_diff);
1507 PROTO_ITEM_SET_GENERATED(ti);
1508 proto_item_append_text(tf, ", %s, QS TTL %u, QS TTL diff %u",
1509 val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"),
1510 tvb_get_guint8(tvb, offset + 3), ttl_diff);
1511 proto_tree_add_item(field_tree, hf_ip_opt_qs_nonce, tvb, offset + 4, 4, ENC_NA);
1512 proto_tree_add_item(field_tree, hf_ip_opt_qs_reserved, tvb, offset + 4, 4, ENC_NA);
1513 } else if (function == QS_RATE_REPORT) {
1514 proto_tree_add_item(field_tree, hf_ip_opt_qs_rate, tvb, offset + 2, 1, ENC_NA);
1515 proto_item_append_text(tf, ", %s",
1516 val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown (%u)"));
1517 proto_tree_add_item(field_tree, hf_ip_opt_qs_unused, tvb, offset + 3, 1, ENC_NA);
1518 proto_tree_add_item(field_tree, hf_ip_opt_qs_nonce, tvb, offset + 4, 4, ENC_NA);
1519 proto_tree_add_item(field_tree, hf_ip_opt_qs_reserved, tvb, offset + 4, 4, ENC_NA);
1523 static const ip_tcp_opt ipopts[] = {
1524 {IPOPT_EOOL, "End of Options List (EOL)", &ett_ip_option_eool,
1525 OPT_LEN_NO_LENGTH, 0, dissect_ipopt_eool},
1526 {IPOPT_NOP, "No Operation (NOP)", &ett_ip_option_nop,
1527 OPT_LEN_NO_LENGTH, 0, dissect_ipopt_nop},
1528 {IPOPT_SEC, "Security", &ett_ip_option_sec,
1529 OPT_LEN_VARIABLE_LENGTH, IPOLEN_SEC_MIN, dissect_ipopt_security},
1530 {IPOPT_LSR, "Loose Source Route", &ett_ip_option_route,
1531 OPT_LEN_VARIABLE_LENGTH, IPOLEN_LSR_MIN, dissect_ipopt_route},
1532 {IPOPT_TS, "Time Stamp", &ett_ip_option_timestamp,
1533 OPT_LEN_VARIABLE_LENGTH, IPOLEN_TS_MIN, dissect_ipopt_timestamp},
1534 {IPOPT_ESEC, "Extended Security", &ett_ip_option_ext_security,
1535 OPT_LEN_VARIABLE_LENGTH, IPOLEN_ESEC_MIN, dissect_ipopt_ext_security},
1536 {IPOPT_CIPSO, "Commercial Security", &ett_ip_option_cipso,
1537 OPT_LEN_VARIABLE_LENGTH, IPOLEN_CIPSO_MIN, dissect_ipopt_cipso},
1538 {IPOPT_RR, "Record Route", &ett_ip_option_route,
1539 OPT_LEN_VARIABLE_LENGTH, IPOLEN_RR_MIN, dissect_ipopt_record_route},
1540 {IPOPT_SID, "Stream ID", &ett_ip_option_sid,
1541 OPT_LEN_FIXED_LENGTH, IPOLEN_SID, dissect_ipopt_sid},
1542 {IPOPT_SSR, "Strict Source Route", &ett_ip_option_route,
1543 OPT_LEN_VARIABLE_LENGTH, IPOLEN_SSR_MIN, dissect_ipopt_route},
1544 #if 0 /* TODO */
1545 {IPOPT_ZSU, "Experimental Measurement", &ett_ip_option_zsu,
1546 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_ZSU_MIN, dissect_ipopt_zsu},
1547 #endif
1548 {IPOPT_MTUP, "MTU Probe", &ett_ip_option_mtu,
1549 OPT_LEN_FIXED_LENGTH, IPOLEN_MTU, dissect_ipopt_mtu},
1550 {IPOPT_MTUR, "MTU Reply", &ett_ip_option_mtu,
1551 OPT_LEN_FIXED_LENGTH, IPOLEN_MTU, dissect_ipopt_mtu},
1552 #if 0 /* TODO */
1553 {IPOPT_FINN, "Experimental Flow Control", &ett_ip_option_finn,
1554 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_FINN_MIN, dissect_ipopt_finn},
1555 {IPOPT_VISA, "Experimental Access Control", &ett_ip_option_visa,
1556 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_VISA_MIN, dissect_ipopt_visa},
1557 {IPOPT_ENCODE, "???", &ett_ip_option_encode,
1558 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_ENCODE_MIN, dissect_ipopt_encode},
1559 {IPOPT_IMITD, "IMI Traffic Descriptor", &ett_ip_option_imitd,
1560 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_IMITD_MIN, dissect_ipopt_imitd},
1561 {IPOPT_EIP, "Extended Internet Protocol", &ett_ip_option_eip,
1562 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_EIP_MIN, dissect_ipopt_eip},
1563 #endif
1564 {IPOPT_TR, "Traceroute", &ett_ip_option_tr,
1565 OPT_LEN_FIXED_LENGTH, IPOLEN_TR, dissect_ipopt_tr},
1566 #if 0 /* TODO */
1567 {IPOPT_ADDEXT, "Address Extension", &ett_ip_option_addext,
1568 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_ADDEXT_MIN, dissect_ipopt_addext},
1569 #endif
1570 {IPOPT_RTRALT, "Router Alert", &ett_ip_option_ra,
1571 OPT_LEN_FIXED_LENGTH, IPOLEN_RA, dissect_ipopt_ra},
1572 {IPOPT_SDB, "Selective Directed Broadcast", &ett_ip_option_sdb,
1573 OPT_LEN_VARIABLE_LENGTH, IPOLEN_SDB_MIN, dissect_ipopt_sdb},
1574 #if 0 /* TODO */
1575 {IPOPT_UN, "Unassigned", &ett_ip_option_un,
1576 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_UN_MIN, dissect_ipopt_un},
1577 {IPOPT_DPS, "Dynamic Packet State", &ett_ip_option_dps,
1578 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_DPS_MIN, dissect_ipopt_dps},
1579 {IPOPT_UMP, "Upstream Multicast Pkt.", &ett_ip_option_ump,
1580 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_UMP_MIN, dissect_ipopt_ump},
1581 #endif
1582 {IPOPT_QS, "Quick-Start", &ett_ip_option_qs,
1583 OPT_LEN_FIXED_LENGTH, IPOLEN_QS, dissect_ipopt_qs}
1584 #if 0 /* TODO */
1585 {IPOPT_EXP, "RFC3692-style Experiment", &ett_ip_option_exp,
1586 OPT_LEN_VARIABLE_LENGTH /* ? */, IPOLEN_EXP_MIN, dissect_ipopt_exp}
1587 #endif
1590 #define N_IP_OPTS array_length(ipopts)
1592 /* Dissect the IP, TCP or various PPP protocols (IPCP, CP, LCP, VSNCP, BAP)
1593 * options in a packet. */
1594 void
1595 dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
1596 const ip_tcp_opt *opttab, int nopts, int eol,
1597 ip_tcp_opt_type* opttypes, expert_field* ei_bad,
1598 packet_info *pinfo, proto_tree *opt_tree,
1599 proto_item *opt_item, void * data)
1601 guchar opt;
1602 const ip_tcp_opt *optp;
1603 opt_len_type len_type;
1604 unsigned int optlen;
1605 const char *name;
1606 void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
1607 int, guint, packet_info *, proto_tree *,
1608 void *);
1609 guint len, nop_count = 0;
1611 while (length > 0) {
1612 opt = tvb_get_guint8(tvb, offset);
1613 for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
1614 if (optp->optcode == opt)
1615 break;
1617 if (optp == &opttab[nopts]) {
1618 /* We assume that the only OPT_LEN_NO_LENGTH options are EOL and NOP options,
1619 so that we can treat unknown options as OPT_LEN_VARIABLE_LENGTH with a
1620 minimum of 2, and at least be able to move on to the next option
1621 by using the length in the option. */
1622 optp = NULL; /* indicate that we don't know this option */
1623 len_type = OPT_LEN_VARIABLE_LENGTH;
1624 optlen = 2;
1625 name = wmem_strdup_printf(wmem_packet_scope(), "Unknown (0x%02x)", opt);
1626 dissect = NULL;
1627 nop_count = 0;
1628 } else {
1629 len_type = optp->len_type;
1630 optlen = optp->optlen;
1631 name = optp->name;
1632 dissect = optp->dissect;
1633 if (opt_item && len_type == OPT_LEN_NO_LENGTH && optlen == 0 && opt == 1 &&
1634 (nop_count == 0 || offset % 4)) { /* opt 1 = NOP in both IP and TCP */
1635 /* Count number of NOP in a row within a uint32 */
1636 nop_count++;
1637 } else {
1638 nop_count = 0;
1641 --length; /* account for type byte */
1642 if (len_type != OPT_LEN_NO_LENGTH) {
1643 /* Option has a length. Is it in the packet? */
1644 if (length == 0) {
1645 /* Bogus - packet must at least include option code byte and
1646 length byte! */
1647 proto_tree_add_expert_format(opt_tree, pinfo, ei_bad, tvb, offset, 1,
1648 "%s (length byte past end of options)", name);
1649 return;
1651 len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
1652 --length; /* account for length byte */
1653 if (len < 2) {
1654 /* Bogus - option length is too short to include option code and
1655 option length. */
1656 proto_tree_add_expert_format(opt_tree, pinfo, ei_bad, tvb, offset, 2,
1657 "%s (with too-short option length = %u byte%s)",
1658 name, len, plurality(len, "", "s"));
1659 return;
1660 } else if (len - 2 > length) {
1661 /* Bogus - option goes past the end of the header. */
1662 proto_tree_add_expert_format(opt_tree, pinfo, ei_bad, tvb, offset, length,
1663 "%s (option length = %u byte%s says option goes past end of options)",
1664 name, len, plurality(len, "", "s"));
1665 return;
1666 } else if (len_type == OPT_LEN_FIXED_LENGTH && len != optlen) {
1667 /* Bogus - option length isn't what it's supposed to be for this
1668 option. */
1669 proto_tree_add_expert_format(opt_tree, pinfo, ei_bad, tvb, offset, len,
1670 "%s (with option length = %u byte%s; should be %u)",
1671 name, len, plurality(len, "", "s"), optlen);
1672 return;
1673 } else if (len_type == OPT_LEN_VARIABLE_LENGTH && len < optlen) {
1674 /* Bogus - option length is less than what it's supposed to be for
1675 this option. */
1676 proto_tree_add_expert_format(opt_tree, pinfo, ei_bad, tvb, offset, len,
1677 "%s (with option length = %u byte%s; should be >= %u)",
1678 name, len, plurality(len, "", "s"), optlen);
1679 return;
1680 } else {
1681 if (optp == NULL) {
1682 proto_tree_add_text(opt_tree, tvb, offset, len, "%s (%u byte%s)",
1683 name, len, plurality(len, "", "s"));
1684 } else {
1685 if (dissect != NULL) {
1686 /* Option has a dissector. */
1687 proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s",
1688 optp->name);
1689 (*dissect)(optp, tvb, offset, len, pinfo, opt_tree, data);
1690 } else {
1691 proto_tree *field_tree;
1692 proto_item *tf;
1694 /* Option has no data, hence no dissector. */
1695 proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s",
1696 name);
1697 tf = proto_tree_add_text(opt_tree, tvb, offset, len, "%s", name);
1698 field_tree = proto_item_add_subtree(tf, ett_ip_option_other);
1699 dissect_ipopt_type(tvb, offset, field_tree, opttypes);
1702 len -= 2; /* subtract size of type and length */
1703 offset += 2 + len;
1705 length -= len;
1706 } else {
1707 if (dissect != NULL) {
1708 proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s",
1709 optp->name);
1710 (*dissect)(optp, tvb, offset, 1, pinfo, opt_tree, data);
1711 } else {
1712 proto_tree *field_tree;
1713 proto_item *tf;
1715 /* Option has no data, hence no dissector. */
1716 proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s", name);
1717 tf = proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
1718 field_tree = proto_item_add_subtree(tf, ett_ip_option_other);
1719 dissect_ipopt_type(tvb, offset, field_tree, opttypes);
1721 offset += 1;
1723 if (nop_count == 4 && strcmp (name, "No-Operation (NOP)") == 0) {
1724 expert_add_info(pinfo, opt_item, &ei_ip_nop);
1727 if (opt == eol)
1728 break;
1732 /* This function searches the IP options for either a loose or strict source
1733 * route option, then returns the offset to the destination address if the
1734 * pointer is still valid or zero if the pointer is greater than the length.
1736 * The guts of this function was taken from dissect_ip_tcp_options().
1738 static int
1739 get_dst_offset(tvbuff_t *tvb, int offset, guint length,
1740 const ip_tcp_opt *opttab, int nopts, int eol)
1742 guchar opt;
1743 const ip_tcp_opt *optp;
1744 opt_len_type len_type;
1745 unsigned int optlen;
1746 guint len;
1747 int orig_offset = offset;
1749 while (length > 0) {
1750 opt = tvb_get_guint8(tvb, offset);
1751 for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
1752 if (optp->optcode == opt)
1753 break;
1755 if (optp == &opttab[nopts]) {
1756 /* We assume that the only NO_LENGTH options are EOL and NOP options,
1757 so that we can treat unknown options as VARIABLE_LENGTH with a
1758 minimum of 2, and at least be able to move on to the next option
1759 by using the length in the option. */
1760 optp = NULL; /* indicate that we don't know this option */
1761 len_type = OPT_LEN_VARIABLE_LENGTH;
1762 optlen = 2;
1763 } else {
1764 len_type = optp->len_type;
1765 optlen = optp->optlen;
1767 --length; /* account for type byte */
1768 if (len_type != OPT_LEN_NO_LENGTH) {
1769 /* Option has a length. Is it in the packet? */
1770 if (length == 0) {
1771 /* Bogus - packet must at least include option code byte and
1772 length byte! */
1773 return 0;
1775 len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
1776 --length; /* account for length byte */
1777 if (len < 2) {
1778 /* Bogus - option length is too short to include option code and
1779 option length. */
1780 return 0;
1781 } else if (len - 2 > length) {
1782 /* Bogus - option goes past the end of the header. */
1783 return 0;
1784 } else if (len_type == OPT_LEN_FIXED_LENGTH && len != optlen) {
1785 /* Bogus - option length isn't what it's supposed to be for this
1786 option. */
1787 return 0;
1788 } else if (len_type == OPT_LEN_VARIABLE_LENGTH && len < optlen) {
1789 /* Bogus - option length is less than what it's supposed to be for
1790 this option. */
1791 return 0;
1792 } else {
1793 if (optp != NULL) {
1794 if (opt == IPOPT_SSR || opt == IPOPT_LSR) {
1795 /* Hmm, what if you have both options? */
1796 guint8 ptr;
1798 ptr = tvb_get_guint8(tvb, offset + 2);
1799 if (ptr < 4 || (ptr & 3) || (ptr > len)) {
1800 return 0;
1802 return (offset - orig_offset) + 4 + (len - 4);
1805 len -= 2; /* subtract size of type and length */
1806 offset += 2 + len;
1808 length -= len;
1809 } else {
1810 offset += 1;
1812 if (opt == eol)
1813 return 0;
1815 return 0;
1818 /* Returns the valid ttl for the group address */
1819 static guint16
1820 local_network_control_block_addr_valid_ttl(guint32 addr)
1822 /* An exception list, as some protocols seem to insist on
1823 * doing differently:
1826 /* IETF's VRRP (rfc3768) */
1827 if (IPLOCAL_NETWRK_CTRL_BLK_VRRP_ADDR == addr)
1828 return IPLOCAL_NETWRK_CTRL_BLK_VRRP_TTL;
1829 /* Cisco's GLPB */
1830 if (IPLOCAL_NETWRK_CTRL_BLK_GLPB_ADDR == addr)
1831 return IPLOCAL_NETWRK_CTRL_BLK_GLPB_TTL;
1832 /* mDNS (draft-cheshire-dnsext-multicastdns-07) */
1833 if (IPLOCAL_NETWRK_CTRL_BLK_MDNS_ADDR == addr)
1834 return IPLOCAL_NETWRK_CTRL_BLK_MDNS_TTL;
1835 /* LLMNR (rfc4795) */
1836 if (IPLOCAL_NETWRK_CTRL_BLK_LLMNR_ADDR == addr)
1837 return IPLOCAL_NETWRK_CTRL_BLK_ANY_TTL;
1838 return IPLOCAL_NETWRK_CTRL_BLK_DEFAULT_TTL;
1841 static const value_string dscp_vals[] = {
1842 { IPDSFIELD_DSCP_DEFAULT, "Default" },
1843 { IPDSFIELD_DSCP_CS1, "Class Selector 1" },
1844 { IPDSFIELD_DSCP_AF11, "Assured Forwarding 11" },
1845 { IPDSFIELD_DSCP_AF12, "Assured Forwarding 12" },
1846 { IPDSFIELD_DSCP_AF13, "Assured Forwarding 13" },
1847 { IPDSFIELD_DSCP_CS2, "Class Selector 2" },
1848 { IPDSFIELD_DSCP_AF21, "Assured Forwarding 21" },
1849 { IPDSFIELD_DSCP_AF22, "Assured Forwarding 22" },
1850 { IPDSFIELD_DSCP_AF23, "Assured Forwarding 23" },
1851 { IPDSFIELD_DSCP_CS3, "Class Selector 3" },
1852 { IPDSFIELD_DSCP_AF31, "Assured Forwarding 31" },
1853 { IPDSFIELD_DSCP_AF32, "Assured Forwarding 32" },
1854 { IPDSFIELD_DSCP_AF33, "Assured Forwarding 33" },
1855 { IPDSFIELD_DSCP_CS4, "Class Selector 4" },
1856 { IPDSFIELD_DSCP_AF41, "Assured Forwarding 41" },
1857 { IPDSFIELD_DSCP_AF42, "Assured Forwarding 42" },
1858 { IPDSFIELD_DSCP_AF43, "Assured Forwarding 43" },
1859 { IPDSFIELD_DSCP_CS5, "Class Selector 5" },
1860 { IPDSFIELD_DSCP_EF, "Expedited Forwarding" },
1861 { IPDSFIELD_DSCP_CS6, "Class Selector 6" },
1862 { IPDSFIELD_DSCP_CS7, "Class Selector 7" },
1863 { 0, NULL }};
1864 value_string_ext dscp_vals_ext = VALUE_STRING_EXT_INIT(dscp_vals);
1866 const value_string ecn_vals[] = {
1867 { IPDSFIELD_ECT_NOT, "Not-ECT (Not ECN-Capable Transport)" },
1868 { IPDSFIELD_ECT_1, "ECT(1) (ECN-Capable Transport)" },
1869 { IPDSFIELD_ECT_0, "ECT(0) (ECN-Capable Transport)" },
1870 { IPDSFIELD_CE, "CE (Congestion Experienced)" },
1871 { 0, NULL }};
1873 static const value_string precedence_vals[] = {
1874 { IPTOS_PREC_ROUTINE, "routine" },
1875 { IPTOS_PREC_PRIORITY, "priority" },
1876 { IPTOS_PREC_IMMEDIATE, "immediate" },
1877 { IPTOS_PREC_FLASH, "flash" },
1878 { IPTOS_PREC_FLASHOVERRIDE, "flash override" },
1879 { IPTOS_PREC_CRITIC_ECP, "CRITIC/ECP" },
1880 { IPTOS_PREC_INTERNETCONTROL, "internetwork control" },
1881 { IPTOS_PREC_NETCONTROL, "network control" },
1882 { 0, NULL }};
1884 static const value_string iptos_vals[] = {
1885 { IPTOS_NONE, "None" },
1886 { IPTOS_LOWCOST, "Minimize cost" },
1887 { IPTOS_RELIABILITY, "Maximize reliability" },
1888 { IPTOS_THROUGHPUT, "Maximize throughput" },
1889 { IPTOS_LOWDELAY, "Minimize delay" },
1890 { IPTOS_SECURITY, "Maximize security" },
1891 { 0, NULL }
1894 static const true_false_string tos_set_low = {
1895 "Low",
1896 "Normal"
1899 static const true_false_string tos_set_high = {
1900 "High",
1901 "Normal"
1904 static const true_false_string flags_sf_set_evil = {
1905 "Evil",
1906 "Not evil"
1909 guint16
1910 ip_checksum(const guint8 *ptr, int len)
1912 vec_t cksum_vec[1];
1914 cksum_vec[0].ptr = ptr;
1915 cksum_vec[0].len = len;
1916 return in_cksum(&cksum_vec[0], 1);
1919 static void
1920 dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1922 proto_tree *ip_tree = NULL, *field_tree = NULL;
1923 proto_item *ti = NULL, *tf;
1924 guint32 addr;
1925 int offset = 0, dst_off;
1926 guint hlen, optlen;
1927 guint16 flags;
1928 guint8 nxt;
1929 guint16 ipsum;
1930 fragment_head *ipfd_head = NULL;
1931 tvbuff_t *next_tvb;
1932 gboolean update_col_info = TRUE;
1933 gboolean save_fragmented;
1934 ws_ip *iph;
1935 const guchar *src_addr, *dst_addr;
1936 guint32 src32, dst32;
1937 proto_tree *tree;
1938 proto_item *item = NULL, *ttl_item;
1939 proto_tree *checksum_tree;
1940 guint16 ttl;
1942 tree = parent_tree;
1943 iph = (ws_ip *)wmem_alloc(wmem_packet_scope(), sizeof(ws_ip));
1945 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPv4");
1946 col_clear(pinfo->cinfo, COL_INFO);
1948 iph->ip_v_hl = tvb_get_guint8(tvb, offset);
1949 if ( hi_nibble(iph->ip_v_hl) == 6) {
1950 call_dissector(ipv6_handle, tvb, pinfo, parent_tree);
1951 return;
1954 hlen = lo_nibble(iph->ip_v_hl) * 4; /* IP header length, in bytes */
1956 if (tree) {
1957 ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, ENC_NA);
1958 ip_tree = proto_item_add_subtree(ti, ett_ip);
1960 proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1,
1961 hi_nibble(iph->ip_v_hl));
1964 /* if IP is not referenced from any filters we don't need to worry about
1965 generating any tree items. We must do this after we created the actual
1966 protocol above so that proto hier stat still works though.
1967 XXX: Note that because of the following optimization expert items must
1968 not be generated inside of an 'if (tree) ...'
1969 so that Analyze ! Expert ... will work.
1971 if (!proto_field_is_referenced(parent_tree, proto_ip)) {
1972 tree = NULL;
1975 if (hlen < IPH_MIN_LEN) {
1976 col_add_fstr(pinfo->cinfo, COL_INFO,
1977 "Bogus IP header length (%u, must be at least %u)",
1978 hlen, IPH_MIN_LEN);
1979 if (tree) {
1980 proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
1981 "%u bytes (bogus, must be at least %u)", hlen, IPH_MIN_LEN);
1983 return;
1986 if (tree) {
1987 proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
1988 "%u bytes", hlen);
1991 iph->ip_tos = tvb_get_guint8(tvb, offset + 1);
1992 if (g_ip_dscp_actif) {
1993 col_add_fstr(pinfo->cinfo, COL_DSCP_VALUE, "%u",
1994 IPDSFIELD_DSCP(iph->ip_tos));
1997 if (tree) {
1998 if (g_ip_dscp_actif) {
1999 tf = proto_tree_add_uint_format_value(ip_tree, hf_ip_dsfield, tvb, offset + 1,
2000 1, iph->ip_tos, "0x%02x (DSCP 0x%02x: %s; ECN: 0x%02x: %s)", iph->ip_tos,
2001 IPDSFIELD_DSCP(iph->ip_tos), val_to_str_ext_const(IPDSFIELD_DSCP(iph->ip_tos),
2002 &dscp_vals_ext, "Unknown DSCP"),
2003 IPDSFIELD_ECN(iph->ip_tos), val_to_str_const(IPDSFIELD_ECN(iph->ip_tos),
2004 ecn_vals, "Unknown ECN"));
2006 field_tree = proto_item_add_subtree(tf, ett_ip_dsfield);
2007 proto_tree_add_item(field_tree, hf_ip_dsfield_dscp, tvb, offset + 1, 1, ENC_NA);
2008 proto_tree_add_item(field_tree, hf_ip_dsfield_ecn, tvb, offset + 1, 1, ENC_NA);
2009 } else {
2010 tf = proto_tree_add_uint_format_value(ip_tree, hf_ip_tos, tvb, offset + 1, 1,
2011 iph->ip_tos,
2012 "0x%02x (%s)",
2013 iph->ip_tos,
2014 val_to_str_const(IPTOS_TOS(iph->ip_tos),
2015 iptos_vals, "Unknown"));
2017 field_tree = proto_item_add_subtree(tf, ett_ip_tos);
2018 proto_tree_add_item(field_tree, hf_ip_tos_precedence, tvb, offset + 1, 1, ENC_NA);
2019 proto_tree_add_item(field_tree, hf_ip_tos_delay, tvb, offset + 1, 1, ENC_NA);
2020 proto_tree_add_item(field_tree, hf_ip_tos_throughput, tvb, offset + 1, 1, ENC_NA);
2021 proto_tree_add_item(field_tree, hf_ip_tos_reliability, tvb, offset + 1, 1, ENC_NA);
2022 proto_tree_add_item(field_tree, hf_ip_tos_cost, tvb, offset + 1, 1, ENC_NA);
2026 /* Length of IP datagram.
2027 XXX - what if this is greater than the reported length of the
2028 tvbuff? This could happen, for example, in an IP datagram
2029 inside an ICMP datagram; we need to somehow let the
2030 dissector we call know that, as it might want to avoid
2031 doing its checksumming. */
2032 iph->ip_len = tvb_get_ntohs(tvb, offset + 2);
2034 if (iph->ip_len < hlen) {
2035 if (ip_tso_supported && !iph->ip_len) {
2036 /* TSO support enabled, and zero length. Assume the zero length is
2037 * the result of TSO, and use the reported length instead. Note that
2038 * we need to use the frame/reported length instead of the actually-
2039 * available length, just in case a snaplen was used on capture. */
2040 iph->ip_len = tvb_reported_length(tvb);
2041 if (tree) {
2042 tf = proto_tree_add_uint_format_value(ip_tree, hf_ip_len, tvb, offset + 2, 2,
2043 iph->ip_len,
2044 "%u bytes (reported as 0, presumed to be because of \"TCP segmentation offload\" (TSO))",
2045 iph->ip_len);
2046 PROTO_ITEM_SET_GENERATED(tf);
2048 } else {
2049 /* TSO support not enabled, or non-zero length, so treat it as an error. */
2050 col_add_fstr(pinfo->cinfo, COL_INFO,
2051 "Bogus IP length (%u, less than header length %u)",
2052 iph->ip_len, hlen);
2053 tf = proto_tree_add_uint_format_value(ip_tree, hf_ip_len, tvb, offset + 2, 2,
2054 iph->ip_len,
2055 "%u bytes (bogus, less than header length %u)",
2056 iph->ip_len, hlen);
2057 expert_add_info(pinfo, tf, &ei_ip_bogus_ip_length);
2058 /* Can't dissect any further */
2059 return;
2061 } else {
2063 * Now that we know that the total length of this IP datagram isn't
2064 * obviously bogus, adjust the length of this tvbuff to include only
2065 * the IP datagram.
2067 set_actual_length(tvb, iph->ip_len);
2069 if (tree)
2070 proto_tree_add_uint(ip_tree, hf_ip_len, tvb, offset + 2, 2, iph->ip_len);
2073 iph->ip_id = tvb_get_ntohs(tvb, offset + 4);
2074 if (tree)
2075 proto_tree_add_uint(ip_tree, hf_ip_id, tvb, offset + 4, 2, iph->ip_id);
2077 iph->ip_off = tvb_get_ntohs(tvb, offset + 6);
2078 if (tree) {
2079 int bit_offset = (offset + 6) * 8;
2081 flags = (iph->ip_off & (IP_RF | IP_DF | IP_MF)) >> IP_OFFSET_WIDTH;
2082 tf = proto_tree_add_uint(ip_tree, hf_ip_flags, tvb, offset + 6, 1, flags);
2083 field_tree = proto_item_add_subtree(tf, ett_ip_off);
2084 if (ip_security_flag) {
2085 proto_item *sf;
2087 sf = proto_tree_add_bits_item(field_tree, hf_ip_flags_sf, tvb,
2088 bit_offset + 0, 1, ENC_BIG_ENDIAN);
2089 if (iph->ip_off & IP_RF) {
2090 proto_item_append_text(tf, " (Evil packet!)");
2091 expert_add_info(pinfo, sf, &ei_ip_evil_packet);
2093 } else {
2094 proto_tree_add_bits_item(field_tree, hf_ip_flags_rf, tvb, bit_offset + 0,
2095 1, ENC_LITTLE_ENDIAN);
2097 if (iph->ip_off & IP_DF)
2098 proto_item_append_text(tf, " (Don't Fragment)");
2099 proto_tree_add_bits_item(field_tree, hf_ip_flags_df, tvb, bit_offset + 1,
2100 1, ENC_BIG_ENDIAN);
2101 if (iph->ip_off & IP_MF)
2102 proto_item_append_text(tf, " (More Fragments)");
2103 proto_tree_add_bits_item(field_tree, hf_ip_flags_mf, tvb, bit_offset + 2,
2104 1, ENC_BIG_ENDIAN);
2105 proto_tree_add_uint(ip_tree, hf_ip_frag_offset, tvb, offset + 6, 2,
2106 (iph->ip_off & IP_OFFSET)*8);
2109 iph->ip_ttl = tvb_get_guint8(tvb, offset + 8);
2110 pinfo->ip_ttl = iph->ip_ttl;
2111 if (tree) {
2112 ttl_item = proto_tree_add_item(ip_tree, hf_ip_ttl, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
2113 } else {
2114 ttl_item = NULL;
2117 iph->ip_p = tvb_get_guint8(tvb, offset + 9);
2118 if (tree) {
2119 proto_tree_add_item(ip_tree, hf_ip_proto, tvb, offset + 9, 1, ENC_BIG_ENDIAN);
2122 iph->ip_sum = tvb_get_ntohs(tvb, offset + 10);
2125 * If checksum checking is enabled, and we have the entire IP header
2126 * available, and this isn't inside an ICMP error packet, check the
2127 * checksum.
2129 if (ip_check_checksum && tvb_bytes_exist(tvb, offset, hlen)&&(!pinfo->flags.in_error_pkt)) {
2130 ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen);
2131 if (tree) {
2132 if (ipsum == 0) {
2133 item = proto_tree_add_uint_format_value(ip_tree, hf_ip_checksum, tvb,
2134 offset + 10, 2, iph->ip_sum,
2135 "0x%04x [correct]",
2136 iph->ip_sum);
2137 checksum_tree = proto_item_add_subtree(item, ett_ip_checksum);
2138 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_good, tvb,
2139 offset + 10, 2, TRUE);
2140 PROTO_ITEM_SET_GENERATED(item);
2141 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_bad, tvb,
2142 offset + 10, 2, FALSE);
2143 PROTO_ITEM_SET_GENERATED(item);
2144 } else {
2145 item = proto_tree_add_uint_format_value(ip_tree, hf_ip_checksum, tvb,
2146 offset + 10, 2, iph->ip_sum,
2147 "0x%04x"
2148 "[incorrect, should be 0x%04x "
2149 "(may be caused by \"IP checksum "
2150 "offload\"?)]", iph->ip_sum,
2151 in_cksum_shouldbe(iph->ip_sum,
2152 ipsum));
2153 checksum_tree = proto_item_add_subtree(item, ett_ip_checksum);
2154 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_good, tvb,
2155 offset + 10, 2, FALSE);
2156 PROTO_ITEM_SET_GENERATED(item);
2157 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_bad, tvb,
2158 offset + 10, 2, TRUE);
2159 PROTO_ITEM_SET_GENERATED(item);
2162 if (ipsum != 0) {
2163 /* Add expert item always (so tap gets called if present);
2164 if (tree == NULL) then item will be NULL
2165 else item should be from the
2166 add_boolean(..., hf_ip_checksum_bad, ...) above */
2167 expert_add_info(pinfo, item, &ei_ip_checksum_bad);
2169 } else {
2170 ipsum = 0;
2171 if (tree) {
2172 item = proto_tree_add_uint_format_value(ip_tree, hf_ip_checksum, tvb,
2173 offset + 10, 2, iph->ip_sum,
2174 "0x%04x [%s]",
2175 iph->ip_sum,
2176 ip_check_checksum ?
2177 (pinfo->flags.in_error_pkt ?
2178 "in ICMP error packet" :
2179 "not all data available") :
2180 "validation disabled");
2181 checksum_tree = proto_item_add_subtree(item, ett_ip_checksum);
2182 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_good, tvb,
2183 offset + 10, 2, FALSE);
2184 PROTO_ITEM_SET_GENERATED(item);
2185 item = proto_tree_add_boolean(checksum_tree, hf_ip_checksum_bad, tvb,
2186 offset + 10, 2, FALSE);
2187 PROTO_ITEM_SET_GENERATED(item);
2190 src_addr = tvb_get_ptr(tvb, offset + IPH_SRC, 4);
2191 src32 = tvb_get_ntohl(tvb, offset + IPH_SRC);
2192 SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, src_addr);
2193 SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src_addr);
2194 SET_ADDRESS(&iph->ip_src, AT_IPv4, 4, src_addr);
2195 if (tree) {
2196 const char *src_host;
2198 memcpy(&addr, iph->ip_src.data, 4);
2199 src_host = get_hostname(addr);
2200 if (ip_summary_in_tree) {
2201 proto_item_append_text(ti, ", Src: %s (%s)", src_host,
2202 ip_to_str((guint8 *)iph->ip_src.data));
2204 proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, addr);
2205 item = proto_tree_add_ipv4(ip_tree, hf_ip_addr, tvb, offset + 12, 4, addr);
2206 PROTO_ITEM_SET_HIDDEN(item);
2207 item = proto_tree_add_string(ip_tree, hf_ip_src_host, tvb, offset + 12, 4,
2208 src_host);
2209 PROTO_ITEM_SET_GENERATED(item);
2210 PROTO_ITEM_SET_HIDDEN(item);
2211 item = proto_tree_add_string(ip_tree, hf_ip_host, tvb, offset + 12, 4,
2212 src_host);
2213 PROTO_ITEM_SET_GENERATED(item);
2214 PROTO_ITEM_SET_HIDDEN(item);
2217 /* If there's an IP strict or loose source routing option, then the final
2218 * L3 IP destination address will be the last entry in the routing header
2219 * EXCEPT when the table is exhausted (pointer is greater than the length).
2220 * In this case, the final L3 IP destination address is the one in the L3
2221 * header. (REF: http://tools.ietf.org/html/rfc791#section-3.1)
2223 if (hlen > IPH_MIN_LEN) {
2224 /* There's more than just the fixed-length header. See if we've got
2225 * either a strict or loose source route option and if so, return the
2226 * offset into the tvb to where the real destination IP address is located.
2228 dst_off = get_dst_offset(tvb, offset + 20, hlen - IPH_MIN_LEN, ipopts,
2229 N_IP_OPTS, IPOPT_EOOL);
2231 else
2232 dst_off = 0;
2234 dst_addr = tvb_get_ptr(tvb, offset + IPH_DST + dst_off, 4);
2235 dst32 = tvb_get_ntohl(tvb, offset + IPH_DST + dst_off);
2236 SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr);
2237 SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr);
2238 SET_ADDRESS(&iph->ip_dst, AT_IPv4, 4, dst_addr);
2240 /* If an IP is destined for an IP address in the Local Network Control Block
2241 * (e.g. 224.0.0.0/24), the packet should never be routed and the TTL would
2242 * be expected to be 1. (see RFC 3171) Flag a TTL greater than 1.
2244 * Flag a low TTL if the packet is not destined for a multicast address
2245 * (e.g. 224.0.0.0/4) ... and the payload isn't protocol 103 (PIM).
2246 * (see http://tools.ietf.org/html/rfc3973#section-4.7).
2248 if (is_a_local_network_control_block_addr(dst32)) {
2249 ttl = local_network_control_block_addr_valid_ttl(dst32);
2250 if (ttl != iph->ip_ttl && ttl != IPLOCAL_NETWRK_CTRL_BLK_ANY_TTL) {
2251 expert_add_info_format(pinfo, ttl_item, &ei_ip_ttl_lncb, "\"Time To Live\" != %d for a packet sent to the "
2252 "Local Network Control Block (see RFC 3171)",
2253 ttl);
2255 } else if (!is_a_multicast_addr(dst32) && iph->ip_ttl < 5 &&
2256 (iph->ip_p != IP_PROTO_PIM)) {
2257 expert_add_info_format(pinfo, ttl_item, &ei_ip_ttl_too_small, "\"Time To Live\" only %u", iph->ip_ttl);
2260 if (tree) {
2261 const char *dst_host;
2262 guint32 cur_rt;
2264 memcpy(&addr, iph->ip_dst.data, 4);
2265 dst_host = get_hostname(addr);
2266 if (dst_off)
2267 cur_rt = tvb_get_ipv4(tvb, offset + 16);
2268 if (ip_summary_in_tree) {
2269 proto_item_append_text(ti, ", Dst: %s (%s)", dst_host,
2270 ip_to_str((guint8 *)iph->ip_dst.data));
2271 if (dst_off)
2272 proto_item_append_text(ti, ", Via: %s (%s)", get_hostname(cur_rt),
2273 ip_to_str((gchar *)&cur_rt));
2276 if (dst_off) {
2277 proto_tree_add_ipv4(ip_tree, hf_ip_cur_rt, tvb, offset + 16, 4, cur_rt);
2278 item = proto_tree_add_string(ip_tree, hf_ip_cur_rt_host, tvb,
2279 offset + 16, 4, get_hostname(cur_rt));
2280 PROTO_ITEM_SET_GENERATED(item);
2281 PROTO_ITEM_SET_HIDDEN(item);
2283 else {
2284 proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, addr);
2285 item = proto_tree_add_ipv4(ip_tree, hf_ip_addr, tvb, offset + 16, 4,
2286 addr);
2287 PROTO_ITEM_SET_HIDDEN(item);
2288 item = proto_tree_add_string(ip_tree, hf_ip_dst_host, tvb, offset + 16,
2289 4, dst_host);
2290 PROTO_ITEM_SET_GENERATED(item);
2291 PROTO_ITEM_SET_HIDDEN(item);
2292 item = proto_tree_add_string(ip_tree, hf_ip_host, tvb,
2293 offset + 16 + dst_off, 4, dst_host);
2294 PROTO_ITEM_SET_GENERATED(item);
2295 PROTO_ITEM_SET_HIDDEN(item);
2299 #ifdef HAVE_GEOIP
2300 if (tree && ip_use_geoip) {
2301 add_geoip_info(ip_tree, tvb, offset, src32, dst32);
2303 #endif
2305 /* Decode IP options, if any. */
2306 if (hlen > IPH_MIN_LEN) {
2307 /* There's more than just the fixed-length header. Decode the options. */
2308 optlen = hlen - IPH_MIN_LEN; /* length of options, in bytes */
2309 tf = proto_tree_add_text(ip_tree, tvb, offset + 20, optlen,
2310 "Options: (%u bytes)", optlen);
2311 field_tree = proto_item_add_subtree(tf, ett_ip_options);
2312 dissect_ip_tcp_options(tvb, offset + 20, optlen, ipopts, N_IP_OPTS,
2313 IPOPT_EOOL, &IP_OPT_TYPES, &ei_ip_opt_len_invalid, pinfo, field_tree, tf, NULL);
2316 pinfo->ipproto = iph->ip_p;
2317 tap_queue_packet(ip_tap, pinfo, iph);
2319 /* Skip over header + options */
2320 offset += hlen;
2321 nxt = iph->ip_p; /* XXX - what if this isn't the same for all fragments? */
2323 /* If ip_defragment is on, this is a fragment, we have all the data
2324 * in the fragment, and the header checksum is valid, then just add
2325 * the fragment to the hashtable.
2327 save_fragmented = pinfo->fragmented;
2328 if (ip_defragment && (iph->ip_off & (IP_MF|IP_OFFSET)) &&
2329 tvb_bytes_exist(tvb, offset, iph->ip_len - hlen) &&
2330 ipsum == 0) {
2331 ipfd_head = fragment_add_check(&ip_reassembly_table, tvb, offset,
2332 pinfo,
2333 iph->ip_p ^ iph->ip_id ^ src32 ^ dst32,
2334 NULL,
2335 (iph->ip_off & IP_OFFSET) * 8,
2336 iph->ip_len - hlen,
2337 iph->ip_off & IP_MF);
2339 next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv4",
2340 ipfd_head, &ip_frag_items,
2341 &update_col_info, ip_tree);
2342 } else {
2343 /* If this is the first fragment, dissect its contents, otherwise
2344 just show it as a fragment.
2346 XXX - if we eventually don't save the reassembled contents of all
2347 fragmented datagrams, we may want to always reassemble. */
2348 if (iph->ip_off & IP_OFFSET) {
2349 /* Not the first fragment - don't dissect it. */
2350 next_tvb = NULL;
2351 } else {
2352 /* First fragment, or not fragmented. Dissect what we have here. */
2354 /* Get a tvbuff for the payload. */
2355 next_tvb = tvb_new_subset_remaining(tvb, offset);
2358 * If this is the first fragment, but not the only fragment,
2359 * tell the next protocol that.
2361 if (iph->ip_off & IP_MF)
2362 pinfo->fragmented = TRUE;
2363 else
2364 pinfo->fragmented = FALSE;
2368 if (next_tvb == NULL) {
2369 /* Just show this as a fragment. */
2370 col_add_fstr(pinfo->cinfo, COL_INFO,
2371 "Fragmented IP protocol (proto=%s %u, off=%u, ID=%04x)",
2372 ipprotostr(iph->ip_p), iph->ip_p,
2373 (iph->ip_off & IP_OFFSET) * 8, iph->ip_id);
2374 if ( ipfd_head && ipfd_head->reassembled_in != pinfo->fd->num ) {
2375 col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled in #%u]",
2376 ipfd_head->reassembled_in);
2379 call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo,
2380 parent_tree);
2381 pinfo->fragmented = save_fragmented;
2382 return;
2385 /* Hand off to the next protocol.
2387 XXX - setting the columns only after trying various dissectors means
2388 that if one of those dissectors throws an exception, the frame won't
2389 even be labeled as an IP frame; ideally, if a frame being dissected
2390 throws an exception, it'll be labeled as a mangled frame of the
2391 type in question. */
2392 if ((try_heuristic_first) && (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, iph))) {
2393 /* We're good */
2394 } else if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo,
2395 parent_tree)) {
2396 if ((!try_heuristic_first) && (!dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, iph))) {
2397 /* Unknown protocol */
2398 if (update_col_info) {
2399 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%u)",
2400 ipprotostr(iph->ip_p), iph->ip_p);
2402 call_dissector(data_handle,next_tvb, pinfo, parent_tree);
2405 pinfo->fragmented = save_fragmented;
2408 static gboolean
2409 dissect_ip_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2411 int length, tot_length;
2412 guint8 oct, version, ihl;
2415 0 1 2 3
2416 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2417 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2418 |Version| IHL |Type of Service| Total Length |
2419 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2422 length = tvb_length(tvb);
2423 if(length<4){
2424 /* Need at least 4 bytes to make some sort of decision */
2425 return FALSE;
2427 oct = tvb_get_guint8(tvb,0);
2428 ihl = oct & 0x0f;
2429 version = oct >> 4;
2430 if(version == 6){
2431 /* TODO: Add IPv6 checks here */
2433 3. IPv6 Header Format
2435 0 1 2 3
2436 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2437 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2438 |Version| Traffic Class | Flow Label |
2439 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2440 | Payload Length | Next Header | Hop Limit |
2441 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2445 + Source Address +
2449 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2453 + Destination Address +
2457 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2459 Version 4-bit Internet Protocol version number = 6.
2461 Traffic Class 8-bit traffic class field. See section 7.
2463 Flow Label 20-bit flow label. See section 6.
2465 Payload Length 16-bit unsigned integer. Length of the IPv6
2466 payload, i.e., the rest of the packet following
2467 this IPv6 header, in octets. (Note that any
2468 extension headers [section 4] present are
2469 considered part of the payload, i.e., included
2470 in the length count.)
2474 if(length<8){
2475 /* Need at least 8 bytes to make a decision */
2476 return FALSE;
2478 tot_length = tvb_get_ntohs(tvb,4);
2479 if((tot_length + 40) != (int)tvb_reported_length(tvb)){
2480 return FALSE;
2482 call_dissector(ipv6_handle, tvb, pinfo, tree);
2483 return TRUE;
2485 /* version == IPv4 , the minimum value for a correct header is 5 */
2486 if((version != 4)|| (ihl < 5)){
2487 return FALSE;
2489 /* Total Length is the length of the datagram, measured in octets,
2490 * including internet header and data.
2492 tot_length = tvb_get_ntohs(tvb,2);
2494 if(tot_length != (int)tvb_reported_length(tvb)){
2495 return FALSE;
2498 dissect_ip(tvb, pinfo, tree);
2499 return TRUE;
2502 void
2503 proto_register_ip(void)
2505 #define ARG_TO_STR(ARG) #ARG
2506 #define FLAGS_OFFSET_WIDTH_MSG(WIDTH) \
2507 "Flags (" ARG_TO_STR(WIDTH) " bits)"
2508 #define FRAG_OFFSET_WIDTH_MSG(WIDTH) \
2509 "Fragment offset (" ARG_TO_STR(WIDTH) " bits)"
2511 static hf_register_info hf[] = {
2512 { &hf_ip_version,
2513 { "Version", "ip.version", FT_UINT8, BASE_DEC,
2514 NULL, 0x0, NULL, HFILL }},
2516 { &hf_ip_hdr_len,
2517 { "Header Length", "ip.hdr_len", FT_UINT8, BASE_DEC,
2518 NULL, 0x0, NULL, HFILL }},
2520 { &hf_ip_dsfield,
2521 { "Differentiated Services Field", "ip.dsfield", FT_UINT8, BASE_DEC,
2522 NULL, 0x0, NULL, HFILL }},
2524 { &hf_ip_dsfield_dscp,
2525 { "Differentiated Services Codepoint", "ip.dsfield.dscp", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
2526 &dscp_vals_ext, IPDSFIELD_DSCP_MASK, NULL, HFILL }},
2528 { &hf_ip_dsfield_ecn,
2529 { "Explicit Congestion Notification", "ip.dsfield.ecn", FT_UINT8, BASE_HEX,
2530 VALS(ecn_vals), IPDSFIELD_ECN_MASK, NULL, HFILL }},
2532 { &hf_ip_tos,
2533 { "Type of Service", "ip.tos", FT_UINT8, BASE_DEC,
2534 NULL, 0x0, NULL, HFILL }},
2536 { &hf_ip_tos_precedence,
2537 { "Precedence", "ip.tos.precedence", FT_UINT8, BASE_DEC,
2538 VALS(precedence_vals), IPTOS_PREC_MASK, NULL, HFILL }},
2540 { &hf_ip_tos_delay,
2541 { "Delay", "ip.tos.delay", FT_BOOLEAN, 8,
2542 TFS(&tos_set_low), IPTOS_LOWDELAY, NULL, HFILL }},
2544 { &hf_ip_tos_throughput,
2545 { "Throughput", "ip.tos.throughput", FT_BOOLEAN, 8,
2546 TFS(&tos_set_high), IPTOS_THROUGHPUT, NULL, HFILL }},
2548 { &hf_ip_tos_reliability,
2549 { "Reliability", "ip.tos.reliability", FT_BOOLEAN, 8,
2550 TFS(&tos_set_high), IPTOS_RELIABILITY, NULL, HFILL }},
2552 { &hf_ip_tos_cost,
2553 { "Cost", "ip.tos.cost", FT_BOOLEAN, 8,
2554 TFS(&tos_set_low), IPTOS_LOWCOST, NULL, HFILL }},
2556 { &hf_ip_len,
2557 { "Total Length", "ip.len", FT_UINT16, BASE_DEC,
2558 NULL, 0x0, NULL, HFILL }},
2560 { &hf_ip_id,
2561 { "Identification", "ip.id", FT_UINT16, BASE_HEX_DEC,
2562 NULL, 0x0, NULL, HFILL }},
2564 { &hf_ip_dst,
2565 { "Destination", "ip.dst", FT_IPv4, BASE_NONE,
2566 NULL, 0x0, NULL, HFILL }},
2568 { &hf_ip_dst_host,
2569 { "Destination Host", "ip.dst_host", FT_STRING, BASE_NONE,
2570 NULL, 0x0, NULL, HFILL }},
2572 { &hf_ip_src,
2573 { "Source", "ip.src", FT_IPv4, BASE_NONE,
2574 NULL, 0x0, NULL, HFILL }},
2576 { &hf_ip_src_host,
2577 { "Source Host", "ip.src_host", FT_STRING, BASE_NONE,
2578 NULL, 0x0, NULL, HFILL }},
2580 { &hf_ip_addr,
2581 { "Source or Destination Address", "ip.addr", FT_IPv4, BASE_NONE,
2582 NULL, 0x0, NULL, HFILL }},
2584 { &hf_ip_host,
2585 { "Source or Destination Host", "ip.host", FT_STRING, BASE_NONE,
2586 NULL, 0x0, NULL, HFILL }},
2588 #ifdef HAVE_GEOIP
2589 { &hf_geoip_country,
2590 { "Source or Destination GeoIP Country", "ip.geoip.country",
2591 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2592 { &hf_geoip_city,
2593 { "Source or Destination GeoIP City", "ip.geoip.city",
2594 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2595 { &hf_geoip_org,
2596 { "Source or Destination GeoIP Organization", "ip.geoip.org",
2597 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2598 { &hf_geoip_isp,
2599 { "Source or Destination GeoIP ISP", "ip.geoip.isp",
2600 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2601 { &hf_geoip_asnum,
2602 { "Source or Destination GeoIP AS Number", "ip.geoip.asnum",
2603 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2604 { &hf_geoip_lat,
2605 { "Source or Destination GeoIP Latitude", "ip.geoip.lat",
2606 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2607 { &hf_geoip_lon,
2608 { "Source or Destination GeoIP Longitude", "ip.geoip.lon",
2609 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2610 { &hf_geoip_src_country,
2611 { "Source GeoIP Country", "ip.geoip.src_country",
2612 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2613 { &hf_geoip_src_city,
2614 { "Source GeoIP City", "ip.geoip.src_city",
2615 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2616 { &hf_geoip_src_org,
2617 { "Source GeoIP Organization", "ip.geoip.src_org",
2618 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2619 { &hf_geoip_src_isp,
2620 { "Source GeoIP ISP", "ip.geoip.src_isp",
2621 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2622 { &hf_geoip_src_asnum,
2623 { "Source GeoIP AS Number", "ip.geoip.src_asnum",
2624 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2625 { &hf_geoip_src_lat,
2626 { "Source GeoIP Latitude", "ip.geoip.src_lat",
2627 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2628 { &hf_geoip_src_lon,
2629 { "Source GeoIP Longitude", "ip.geoip.src_lon",
2630 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2631 { &hf_geoip_dst_country,
2632 { "Destination GeoIP Country", "ip.geoip.dst_country",
2633 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2634 { &hf_geoip_dst_city,
2635 { "Destination GeoIP City", "ip.geoip.dst_city",
2636 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2637 { &hf_geoip_dst_org,
2638 { "Destination GeoIP Organization", "ip.geoip.dst_org",
2639 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2640 { &hf_geoip_dst_isp,
2641 { "Destination GeoIP ISP", "ip.geoip.dst_isp",
2642 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2643 { &hf_geoip_dst_asnum,
2644 { "Destination GeoIP AS Number", "ip.geoip.dst_asnum",
2645 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2646 { &hf_geoip_dst_lat,
2647 { "Destination GeoIP Latitude", "ip.geoip.dst_lat",
2648 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2649 { &hf_geoip_dst_lon,
2650 { "Destination GeoIP Longitude", "ip.geoip.dst_lon",
2651 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2652 #endif /* HAVE_GEOIP */
2654 { &hf_ip_flags,
2655 { "Flags", "ip.flags", FT_UINT8, BASE_HEX,
2656 NULL, 0x0, FLAGS_OFFSET_WIDTH_MSG(IP_FLAGS_WIDTH), HFILL }},
2658 { &hf_ip_flags_sf,
2659 { "Security flag", "ip.flags.sf", FT_BOOLEAN, BASE_NONE,
2660 TFS(&flags_sf_set_evil), 0x0, "Security flag (RFC 3514)", HFILL }},
2662 { &hf_ip_flags_rf,
2663 { "Reserved bit", "ip.flags.rb", FT_BOOLEAN, BASE_NONE,
2664 TFS(&tfs_set_notset), 0x0, NULL, HFILL }},
2666 { &hf_ip_flags_df,
2667 { "Don't fragment", "ip.flags.df", FT_BOOLEAN, BASE_NONE,
2668 TFS(&tfs_set_notset), 0x0, NULL, HFILL }},
2670 { &hf_ip_flags_mf,
2671 { "More fragments", "ip.flags.mf", FT_BOOLEAN, BASE_NONE,
2672 TFS(&tfs_set_notset), 0x0, NULL, HFILL }},
2674 { &hf_ip_frag_offset,
2675 { "Fragment offset", "ip.frag_offset", FT_UINT16, BASE_DEC,
2676 NULL, 0x0, FRAG_OFFSET_WIDTH_MSG(IP_OFFSET_WIDTH), HFILL }},
2678 { &hf_ip_ttl,
2679 { "Time to live", "ip.ttl", FT_UINT8, BASE_DEC,
2680 NULL, 0x0, NULL, HFILL }},
2682 { &hf_ip_proto,
2683 { "Protocol", "ip.proto", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2684 &ipproto_val_ext, 0x0, NULL, HFILL }},
2686 { &hf_ip_checksum,
2687 { "Header checksum", "ip.checksum", FT_UINT16, BASE_HEX,
2688 NULL, 0x0, NULL, HFILL }},
2690 { &hf_ip_checksum_good,
2691 { "Good", "ip.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2692 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
2694 { &hf_ip_checksum_bad,
2695 { "Bad", "ip.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2696 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
2698 /* IP options related fields */
2699 { &hf_ip_opt_type,
2700 { "Type", "ip.opt.type", FT_UINT8, BASE_DEC,
2701 NULL, 0x0, NULL, HFILL }},
2703 { &hf_ip_opt_type_copy,
2704 { "Copy on fragmentation", "ip.opt.type.copy", FT_BOOLEAN, 8,
2705 TFS(&tfs_yes_no), IPOPT_COPY_MASK, NULL, HFILL }},
2707 { &hf_ip_opt_type_class,
2708 { "Class", "ip.opt.type.class", FT_UINT8, BASE_DEC,
2709 VALS(ipopt_type_class_vals), IPOPT_CLASS_MASK, NULL, HFILL }},
2711 { &hf_ip_opt_type_number,
2712 { "Number", "ip.opt.type.number", FT_UINT8, BASE_DEC,
2713 VALS(ipopt_type_number_vals), IPOPT_NUMBER_MASK, NULL, HFILL }},
2715 { &hf_ip_opt_len,
2716 { "Length", "ip.opt.len", FT_UINT8, BASE_DEC,
2717 NULL, 0x0, NULL, HFILL }},
2719 { &hf_ip_opt_ptr,
2720 { "Pointer", "ip.opt.ptr", FT_UINT8, BASE_DEC,
2721 NULL, 0x0, NULL, HFILL }},
2723 { &hf_ip_opt_sid,
2724 { "Stream Identifier", "ip.opt.sid", FT_UINT16, BASE_DEC,
2725 NULL, 0x0, "SATNET stream identifier", HFILL }},
2727 { &hf_ip_opt_mtu,
2728 { "MTU", "ip.opt.mtu", FT_UINT16, BASE_DEC,
2729 NULL, 0x0, NULL, HFILL }},
2731 { &hf_ip_opt_id_number,
2732 { "ID Number", "ip.opt.id_number", FT_UINT16, BASE_DEC,
2733 NULL, 0x0, NULL, HFILL }},
2735 { &hf_ip_opt_ohc,
2736 { "Outbound Hop Count", "ip.opt.ohc", FT_UINT16, BASE_DEC,
2737 NULL, 0x0, NULL, HFILL }},
2739 { &hf_ip_opt_rhc,
2740 { "Return Hop Count", "ip.opt.rhc", FT_UINT16, BASE_DEC,
2741 NULL, 0x0, NULL, HFILL }},
2743 { &hf_ip_opt_originator,
2744 { "Originator IP Address", "ip.opt.originator", FT_IPv4, BASE_NONE,
2745 NULL, 0x0, NULL, HFILL }},
2747 { &hf_ip_opt_ra,
2748 { "Router Alert", "ip.opt.ra", FT_UINT16, BASE_DEC | BASE_RANGE_STRING,
2749 RVALS(ra_rvals), 0x0, NULL, HFILL }},
2751 { &hf_ip_opt_addr,
2752 { "IP Address", "ip.opt.addr", FT_IPv4, BASE_NONE,
2753 NULL, 0x0, NULL, HFILL }},
2755 { &hf_ip_opt_padding,
2756 { "Padding", "ip.opt.padding", FT_BYTES, BASE_NONE,
2757 NULL, 0x0, NULL, HFILL }},
2759 { &hf_ip_opt_qs_func,
2760 { "Function", "ip.opt.qs_func", FT_UINT8, BASE_DEC,
2761 VALS(qs_func_vals), QS_FUNC_MASK, NULL, HFILL }},
2763 { &hf_ip_opt_qs_rate,
2764 { "Rate", "ip.opt.qs_rate", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2765 &qs_rate_vals_ext, QS_RATE_MASK, NULL, HFILL }},
2767 { &hf_ip_opt_qs_ttl,
2768 { "QS TTL", "ip.opt.qs_ttl", FT_UINT8, BASE_DEC,
2769 NULL, 0x0, NULL, HFILL }},
2771 { &hf_ip_opt_qs_ttl_diff,
2772 { "TTL Diff", "ip.opt.qs_ttl_diff", FT_UINT8, BASE_DEC,
2773 NULL, 0x0, NULL, HFILL }},
2775 { &hf_ip_opt_qs_unused,
2776 { "Not Used", "ip.opt.qs_unused", FT_UINT8, BASE_DEC,
2777 NULL, 0x0, NULL, HFILL }},
2779 { &hf_ip_opt_qs_nonce,
2780 { "QS Nonce", "ip.opt.qs_nonce", FT_UINT32, BASE_HEX,
2781 NULL, 0xFFFFFFFC, NULL, HFILL }},
2783 { &hf_ip_opt_qs_reserved,
2784 { "Reserved", "ip.opt.qs_reserved", FT_UINT32, BASE_HEX,
2785 NULL, 0x00000003, NULL, HFILL }},
2787 { &hf_ip_opt_sec_rfc791_sec,
2788 { "Security", "ip.opt.sec_rfc791_sec", FT_UINT8, BASE_HEX,
2789 VALS(secl_rfc791_vals), 0x0, NULL, HFILL }},
2791 { &hf_ip_opt_sec_rfc791_comp,
2792 { "Compartments", "ip.opt.sec_rfc791_comp", FT_UINT16, BASE_DEC,
2793 NULL, 0x0, NULL, HFILL }},
2795 { &hf_ip_opt_sec_rfc791_hr,
2796 { "Handling Restrictions", "ip.opt.sec_rfc791_hr", FT_STRING, BASE_NONE,
2797 NULL, 0x0, NULL, HFILL }},
2799 { &hf_ip_opt_sec_rfc791_tcc,
2800 { "Transmission Control Code", "ip.opt.sec_rfc791_tcc", FT_STRING, BASE_NONE,
2801 NULL, 0x0, NULL, HFILL }},
2803 { &hf_ip_opt_sec_cl,
2804 { "Classification Level", "ip.opt.sec_cl", FT_UINT8, BASE_HEX,
2805 VALS(sec_cl_vals), 0x0, NULL, HFILL }},
2807 { &hf_ip_opt_sec_prot_auth_flags,
2808 { "Protection Authority Flags", "ip.opt.sec_prot_auth_flags", FT_UINT8, BASE_HEX,
2809 NULL, 0x0, NULL, HFILL }},
2811 { &hf_ip_opt_sec_prot_auth_genser,
2812 { "GENSER", "ip.opt.sec_prot_auth_genser", FT_BOOLEAN, 8,
2813 TFS(&ip_opt_sec_prot_auth_flag_tfs), 0x80, NULL, HFILL }},
2815 { &hf_ip_opt_sec_prot_auth_siop_esi,
2816 { "SIOP-ESI", "ip.opt.sec_prot_auth_siop_esi", FT_BOOLEAN, 8,
2817 TFS(&ip_opt_sec_prot_auth_flag_tfs), 0x40, NULL, HFILL }},
2819 { &hf_ip_opt_sec_prot_auth_sci,
2820 { "SCI", "ip.opt.sec_prot_auth_sci", FT_BOOLEAN, 8,
2821 TFS(&ip_opt_sec_prot_auth_flag_tfs), 0x20, NULL, HFILL }},
2823 { &hf_ip_opt_sec_prot_auth_nsa,
2824 { "NSA", "ip.opt.sec_prot_auth_nsa", FT_BOOLEAN, 8,
2825 TFS(&ip_opt_sec_prot_auth_flag_tfs), 0x10, NULL, HFILL }},
2827 { &hf_ip_opt_sec_prot_auth_doe,
2828 { "DOE", "ip.opt.sec_prot_auth_doe", FT_BOOLEAN, 8,
2829 TFS(&ip_opt_sec_prot_auth_flag_tfs), 0x08, NULL, HFILL }},
2831 { &hf_ip_opt_sec_prot_auth_unassigned,
2832 { "Unassigned", "ip.opt.sec_prot_auth_unassigned", FT_UINT8, BASE_HEX,
2833 NULL, 0x06, NULL, HFILL }},
2835 { &hf_ip_opt_sec_prot_auth_unassigned2,
2836 { "Unassigned", "ip.opt.sec_prot_auth_unassigned", FT_UINT8, BASE_HEX,
2837 NULL, 0xFE, NULL, HFILL }},
2839 { &hf_ip_opt_sec_prot_auth_fti,
2840 { "Field Termination Indicator", "ip.opt.sec_prot_auth_fti", FT_BOOLEAN, 8,
2841 TFS(&ip_opt_sec_prot_auth_fti_tfs), 0x01, NULL, HFILL }},
2843 { &hf_ip_opt_ext_sec_add_sec_info_format_code,
2844 { "Additional Security Info Format Code", "ip.opt.ext_sec_add_sec_info_format_code", FT_UINT8, BASE_HEX,
2845 NULL, 0x0, NULL, HFILL }},
2847 { &hf_ip_opt_ext_sec_add_sec_info,
2848 { "Additional Security Info", "ip.opt.ext_sec_add_sec_info", FT_BYTES, BASE_NONE,
2849 NULL, 0x0, NULL, HFILL }},
2851 { &hf_ip_rec_rt,
2852 { "Recorded Route", "ip.rec_rt", FT_IPv4, BASE_NONE, NULL, 0x0,
2853 NULL, HFILL }},
2855 { &hf_ip_rec_rt_host,
2856 { "Recorded Route Host", "ip.rec_rt_host", FT_STRING, BASE_NONE,
2857 NULL, 0x0, NULL, HFILL }},
2859 { &hf_ip_cur_rt,
2860 { "Current Route", "ip.cur_rt", FT_IPv4, BASE_NONE, NULL, 0x0,
2861 NULL, HFILL }},
2863 { &hf_ip_cur_rt_host,
2864 { "Current Route Host", "ip.cur_rt_host", FT_STRING, BASE_NONE,
2865 NULL, 0x0, NULL, HFILL }},
2867 { &hf_ip_src_rt,
2868 { "Source Route", "ip.src_rt", FT_IPv4, BASE_NONE, NULL, 0x0,
2869 NULL, HFILL }},
2871 { &hf_ip_src_rt_host,
2872 { "Source Route Host", "ip.src_rt_host", FT_STRING, BASE_NONE,
2873 NULL, 0x0, NULL, HFILL }},
2875 { &hf_ip_empty_rt,
2876 { "Empty Route", "ip.empty_rt", FT_IPv4, BASE_NONE, NULL, 0x0,
2877 NULL, HFILL }},
2879 { &hf_ip_empty_rt_host,
2880 { "Empty Route Host", "ip.empty_rt_host", FT_STRING, BASE_NONE,
2881 NULL, 0x0, NULL, HFILL }},
2883 { &hf_ip_fragment_overlap,
2884 { "Fragment overlap", "ip.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2885 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2887 { &hf_ip_fragment_overlap_conflict,
2888 { "Conflicting data in fragment overlap", "ip.fragment.overlap.conflict",
2889 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2890 "Overlapping fragments contained conflicting data", HFILL }},
2892 { &hf_ip_fragment_multiple_tails,
2893 { "Multiple tail fragments found", "ip.fragment.multipletails",
2894 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2895 "Several tails were found when defragmenting the packet", HFILL }},
2897 { &hf_ip_fragment_too_long_fragment,
2898 { "Fragment too long", "ip.fragment.toolongfragment",
2899 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2900 "Fragment contained data past end of packet", HFILL }},
2902 { &hf_ip_fragment_error,
2903 { "Defragmentation error", "ip.fragment.error", FT_FRAMENUM, BASE_NONE,
2904 NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
2906 { &hf_ip_fragment_count,
2907 { "Fragment count", "ip.fragment.count", FT_UINT32, BASE_DEC,
2908 NULL, 0x0, NULL, HFILL }},
2910 { &hf_ip_fragment,
2911 { "IPv4 Fragment", "ip.fragment", FT_FRAMENUM, BASE_NONE,
2912 NULL, 0x0, NULL, HFILL }},
2914 { &hf_ip_fragments,
2915 { "IPv4 Fragments", "ip.fragments", FT_BYTES, BASE_NONE,
2916 NULL, 0x0, NULL, HFILL }},
2918 { &hf_ip_reassembled_in,
2919 { "Reassembled IPv4 in frame", "ip.reassembled_in", FT_FRAMENUM, BASE_NONE,
2920 NULL, 0x0, "This IPv4 packet is reassembled in this frame", HFILL }},
2922 { &hf_ip_reassembled_length,
2923 { "Reassembled IPv4 length", "ip.reassembled.length", FT_UINT32, BASE_DEC,
2924 NULL, 0x0, "The total length of the reassembled payload", HFILL }},
2926 { &hf_ip_reassembled_data,
2927 { "Reassembled IPv4 data", "ip.reassembled.data", FT_BYTES, BASE_NONE,
2928 NULL, 0x0, "The reassembled payload", HFILL }}
2931 static gint *ett[] = {
2932 &ett_ip,
2933 &ett_ip_dsfield,
2934 &ett_ip_tos,
2935 &ett_ip_off,
2936 &ett_ip_options,
2937 &ett_ip_option_eool,
2938 &ett_ip_option_nop,
2939 &ett_ip_option_sec,
2940 &ett_ip_option_route,
2941 &ett_ip_option_timestamp,
2942 &ett_ip_option_ext_security,
2943 &ett_ip_option_cipso,
2944 &ett_ip_option_sid,
2945 &ett_ip_option_mtu,
2946 &ett_ip_option_tr,
2947 &ett_ip_option_ra,
2948 &ett_ip_option_sdb,
2949 &ett_ip_option_qs,
2950 &ett_ip_option_other,
2951 &ett_ip_fragments,
2952 &ett_ip_fragment,
2953 &ett_ip_checksum,
2954 &ett_ip_opt_type,
2955 &ett_ip_opt_sec_prot_auth_flags,
2956 #ifdef HAVE_GEOIP
2957 &ett_geoip_info
2958 #endif
2960 static ei_register_info ei[] = {
2961 { &ei_ip_opt_len_invalid, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
2962 { &ei_ip_opt_sec_prot_auth_fti, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Field Termination Indicator set to 1 for last byte of option", EXPFILL }},
2963 { &ei_ip_extraneous_data, { "ip.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Extraneous data in option", EXPFILL }},
2964 { &ei_ip_opt_ptr_before_address, { "ip.opt.ptr.before_address", PI_PROTOCOL, PI_WARN, "Pointer points before first address", EXPFILL }},
2965 { &ei_ip_opt_ptr_middle_address, { "ip.opt.ptr.middle_address", PI_PROTOCOL, PI_WARN, "Pointer points to middle of address", EXPFILL }},
2966 { &ei_ip_subopt_too_long, { "ip.subopt_too_long", PI_PROTOCOL, PI_WARN, "Suboption would go past end of option", EXPFILL }},
2967 { &ei_ip_nop, { "ip.nop", PI_PROTOCOL, PI_WARN, "4 NOP in a row - a router may have removed some options", EXPFILL }},
2968 { &ei_ip_bogus_ip_length, { "ip.bogus_ip_length", PI_PROTOCOL, PI_ERROR, "Bogus IP length", EXPFILL }},
2969 { &ei_ip_evil_packet, { "ip.evil_packet", PI_PROTOCOL, PI_WARN, "Suboption would go past end of option", EXPFILL }},
2970 { &ei_ip_checksum_bad, { "ip.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
2971 { &ei_ip_ttl_lncb, { "ip.ttl.lncb", PI_SEQUENCE, PI_NOTE, "Time To Live", EXPFILL }},
2972 { &ei_ip_ttl_too_small, { "ip.ttl.too_small", PI_SEQUENCE, PI_NOTE, "Time To Live", EXPFILL }},
2975 module_t *ip_module;
2976 expert_module_t* expert_ip;
2978 proto_ip = proto_register_protocol("Internet Protocol Version 4", "IPv4", "ip");
2979 proto_register_field_array(proto_ip, hf, array_length(hf));
2980 proto_register_subtree_array(ett, array_length(ett));
2981 expert_ip = expert_register_protocol(proto_ip);
2982 expert_register_field_array(expert_ip, ei, array_length(ei));
2984 /* subdissector code */
2985 ip_dissector_table = register_dissector_table("ip.proto", "IPv4 protocol",
2986 FT_UINT8, BASE_DEC);
2987 register_heur_dissector_list("ip", &heur_subdissector_list);
2989 /* Register configuration options */
2990 ip_module = prefs_register_protocol(proto_ip, NULL);
2991 prefs_register_bool_preference(ip_module, "decode_tos_as_diffserv",
2992 "Decode IPv4 TOS field as DiffServ field",
2993 "Whether the IPv4 type-of-service field should be decoded as a "
2994 "Differentiated Services field (see RFC2474/RFC2475)", &g_ip_dscp_actif);
2995 prefs_register_bool_preference(ip_module, "defragment",
2996 "Reassemble fragmented IPv4 datagrams",
2997 "Whether fragmented IPv4 datagrams should be reassembled", &ip_defragment);
2998 prefs_register_bool_preference(ip_module, "summary_in_tree",
2999 "Show IPv4 summary in protocol tree",
3000 "Whether the IPv4 summary line should be shown in the protocol tree",
3001 &ip_summary_in_tree);
3002 prefs_register_bool_preference(ip_module, "check_checksum",
3003 "Validate the IPv4 checksum if possible",
3004 "Whether to validate the IPv4 checksum", &ip_check_checksum);
3005 prefs_register_bool_preference(ip_module, "tso_support",
3006 "Support packet-capture from IP TSO-enabled hardware",
3007 "Whether to correct for TSO-enabled (TCP segmentation offload) hardware "
3008 "captures, such as spoofing the IP packet length", &ip_tso_supported);
3009 #ifdef HAVE_GEOIP
3010 prefs_register_bool_preference(ip_module, "use_geoip",
3011 "Enable GeoIP lookups",
3012 "Whether to look up IP addresses in each GeoIP database we have loaded",
3013 &ip_use_geoip);
3014 #endif /* HAVE_GEOIP */
3015 prefs_register_bool_preference(ip_module, "security_flag" ,
3016 "Interpret Reserved flag as Security flag (RFC 3514)",
3017 "Whether to interpret the originally reserved flag as security flag",
3018 &ip_security_flag);
3019 prefs_register_bool_preference(ip_module, "try_heuristic_first",
3020 "Try heuristic sub-dissectors first",
3021 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
3022 &try_heuristic_first);
3024 register_dissector("ip", dissect_ip, proto_ip);
3025 register_init_routine(ip_defragment_init);
3026 ip_tap = register_tap("ip");
3029 void
3030 proto_reg_handoff_ip(void)
3032 dissector_handle_t ip_handle;
3034 ip_handle = find_dissector("ip");
3035 ipv6_handle = find_dissector("ipv6");
3036 data_handle = find_dissector("data");
3038 dissector_add_uint("ethertype", ETHERTYPE_IP, ip_handle);
3039 dissector_add_uint("ppp.protocol", PPP_IP, ip_handle);
3040 dissector_add_uint("ppp.protocol", ETHERTYPE_IP, ip_handle);
3041 dissector_add_uint("gre.proto", ETHERTYPE_IP, ip_handle);
3042 dissector_add_uint("gre.proto", GRE_WCCP, ip_handle);
3043 dissector_add_uint("llc.dsap", SAP_IP, ip_handle);
3044 dissector_add_uint("ip.proto", IP_PROTO_IPIP, ip_handle);
3045 dissector_add_uint("null.type", BSD_AF_INET, ip_handle);
3046 dissector_add_uint("chdlc.protocol", ETHERTYPE_IP, ip_handle);
3047 dissector_add_uint("osinl.excl", NLPID_IP, ip_handle);
3048 dissector_add_uint("fr.nlpid", NLPID_IP, ip_handle);
3049 dissector_add_uint("x.25.spi", NLPID_IP, ip_handle);
3050 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IP_1051, ip_handle);
3051 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_IP_1201, ip_handle);
3052 dissector_add_uint("ax25.pid", AX25_P_IP, ip_handle);
3053 dissector_add_handle("udp.port", ip_handle);
3055 heur_dissector_add("tipc", dissect_ip_heur, proto_ip);
3059 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3061 * Local variables:
3062 * c-basic-offset: 2
3063 * tab-width: 8
3064 * indent-tabs-mode: nil
3065 * End:
3067 * vi: set shiftwidth=2 tabstop=8 expandtab:
3068 * :indentSize=2:tabSize=8:noTabs=true: