2 * Routines for IP and miscellaneous IP protocol packet disassembly
4 * $Id: packet-ip.c,v 1.134 2001/06/05 05:54:14 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h>
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
55 #include "packet-ip.h"
56 #include "packet-ipsec.h"
60 static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *);
62 /* Decode the old IPv4 TOS field as the DiffServ DS Field */
63 static gboolean g_ip_dscp_actif = TRUE;
65 /* Defragment fragmented IP datagrams */
66 static gboolean ip_defragment = FALSE;
68 /* Place IP summary in proto tree */
69 static gboolean ip_summary_in_tree = TRUE;
71 static int proto_ip = -1;
72 static int hf_ip_version = -1;
73 static int hf_ip_hdr_len = -1;
74 static int hf_ip_dsfield = -1;
75 static int hf_ip_dsfield_dscp = -1;
76 static int hf_ip_dsfield_ect = -1;
77 static int hf_ip_dsfield_ce = -1;
78 static int hf_ip_tos = -1;
79 static int hf_ip_tos_precedence = -1;
80 static int hf_ip_tos_delay = -1;
81 static int hf_ip_tos_throughput = -1;
82 static int hf_ip_tos_reliability = -1;
83 static int hf_ip_tos_cost = -1;
84 static int hf_ip_len = -1;
85 static int hf_ip_id = -1;
86 static int hf_ip_dst = -1;
87 static int hf_ip_src = -1;
88 static int hf_ip_addr = -1;
89 static int hf_ip_flags = -1;
90 static int hf_ip_flags_df = -1;
91 static int hf_ip_flags_mf = -1;
92 static int hf_ip_frag_offset = -1;
93 static int hf_ip_ttl = -1;
94 static int hf_ip_proto = -1;
95 static int hf_ip_checksum = -1;
96 static int hf_ip_checksum_bad = -1;
97 static int hf_ip_fragments = -1;
98 static int hf_ip_fragment = -1;
99 static int hf_ip_fragment_overlap = -1;
100 static int hf_ip_fragment_overlap_conflict = -1;
101 static int hf_ip_fragment_multiple_tails = -1;
102 static int hf_ip_fragment_too_long_fragment = -1;
103 static int hf_ip_fragment_error = -1;
105 static gint ett_ip = -1;
106 static gint ett_ip_dsfield = -1;
107 static gint ett_ip_tos = -1;
108 static gint ett_ip_off = -1;
109 static gint ett_ip_options = -1;
110 static gint ett_ip_option_sec = -1;
111 static gint ett_ip_option_route = -1;
112 static gint ett_ip_option_timestamp = -1;
113 static gint ett_ip_fragments = -1;
114 static gint ett_ip_fragment = -1;
116 /* Used by IPv6 as well, so not static */
117 dissector_table_t ip_dissector_table;
119 static int proto_icmp = -1;
120 static int hf_icmp_type = -1;
121 static int hf_icmp_code = -1;
122 static int hf_icmp_checksum = -1;
123 static int hf_icmp_checksum_bad = -1;
125 static gint ett_icmp = -1;
127 /* ICMP definitions */
129 #define ICMP_ECHOREPLY 0
130 #define ICMP_UNREACH 3
131 #define ICMP_SOURCEQUENCH 4
132 #define ICMP_REDIRECT 5
134 #define ICMP_RTRADVERT 9
135 #define ICMP_RTRSOLICIT 10
136 #define ICMP_TIMXCEED 11
137 #define ICMP_PARAMPROB 12
138 #define ICMP_TSTAMP 13
139 #define ICMP_TSTAMPREPLY 14
141 #define ICMP_IREQREPLY 16
142 #define ICMP_MASKREQ 17
143 #define ICMP_MASKREPLY 18
145 /* ICMP UNREACHABLE */
147 #define ICMP_NET_UNREACH 0 /* Network Unreachable */
148 #define ICMP_HOST_UNREACH 1 /* Host Unreachable */
149 #define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */
150 #define ICMP_PORT_UNREACH 3 /* Port Unreachable */
151 #define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */
152 #define ICMP_SR_FAILED 5 /* Source Route failed */
153 #define ICMP_NET_UNKNOWN 6
154 #define ICMP_HOST_UNKNOWN 7
155 #define ICMP_HOST_ISOLATED 8
156 #define ICMP_NET_ANO 9
157 #define ICMP_HOST_ANO 10
158 #define ICMP_NET_UNR_TOS 11
159 #define ICMP_HOST_UNR_TOS 12
160 #define ICMP_PKT_FILTERED 13 /* Packet filtered */
161 #define ICMP_PREC_VIOLATION 14 /* Precedence violation */
162 #define ICMP_PREC_CUTOFF 15 /* Precedence cut off */
165 /* IP structs and definitions */
169 guint8 ip_v_hl; /* combines ip_v and ip_hl */
181 /* Offsets of fields within an IP header. */
193 /* Minimum IP header length. */
194 #define IPH_MIN_LEN 20
197 #define IP_CE 0x8000 /* Flag: "Congestion" */
198 #define IP_DF 0x4000 /* Flag: "Don't Fragment" */
199 #define IP_MF 0x2000 /* Flag: "More Fragments" */
200 #define IP_OFFSET 0x1FFF /* "Fragment Offset" part */
202 /* Differentiated Services Field. See RFCs 2474, 2597 and 2598. */
203 #define IPDSFIELD_DSCP_MASK 0xFC
204 #define IPDSFIELD_ECN_MASK 0x03
205 #define IPDSFIELD_DSCP_SHIFT 2
206 #define IPDSFIELD_DSCP(dsfield) (((dsfield)&IPDSFIELD_DSCP_MASK)>>IPDSFIELD_DSCP_SHIFT)
207 #define IPDSFIELD_ECN(dsfield) ((dsfield)&IPDSFIELD_ECN_MASK)
208 #define IPDSFIELD_DSCP_DEFAULT 0x00
209 #define IPDSFIELD_DSCP_CS1 0x08
210 #define IPDSFIELD_DSCP_CS2 0x10
211 #define IPDSFIELD_DSCP_CS3 0x18
212 #define IPDSFIELD_DSCP_CS4 0x20
213 #define IPDSFIELD_DSCP_CS5 0x28
214 #define IPDSFIELD_DSCP_CS6 0x30
215 #define IPDSFIELD_DSCP_CS7 0x38
216 #define IPDSFIELD_DSCP_AF11 0x0A
217 #define IPDSFIELD_DSCP_AF12 0x0C
218 #define IPDSFIELD_DSCP_AF13 0x0E
219 #define IPDSFIELD_DSCP_AF21 0x12
220 #define IPDSFIELD_DSCP_AF22 0x14
221 #define IPDSFIELD_DSCP_AF23 0x16
222 #define IPDSFIELD_DSCP_AF31 0x1A
223 #define IPDSFIELD_DSCP_AF32 0x1C
224 #define IPDSFIELD_DSCP_AF33 0x1E
225 #define IPDSFIELD_DSCP_AF41 0x22
226 #define IPDSFIELD_DSCP_AF42 0x24
227 #define IPDSFIELD_DSCP_AF43 0x26
228 #define IPDSFIELD_DSCP_EF 0x2E
229 #define IPDSFIELD_ECT_MASK 0x02
230 #define IPDSFIELD_CE_MASK 0x01
232 /* IP TOS, superseded by the DS Field, RFC 2474. */
233 #define IPTOS_TOS_MASK 0x1E
234 #define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
235 #define IPTOS_NONE 0x00
236 #define IPTOS_LOWCOST 0x02
237 #define IPTOS_RELIABILITY 0x04
238 #define IPTOS_THROUGHPUT 0x08
239 #define IPTOS_LOWDELAY 0x10
240 #define IPTOS_SECURITY 0x1E
242 #define IPTOS_PREC_MASK 0xE0
243 #define IPTOS_PREC_SHIFT 5
244 #define IPTOS_PREC(tos) (((tos)&IPTOS_PREC_MASK)>>IPTOS_PREC_SHIFT)
245 #define IPTOS_PREC_NETCONTROL 7
246 #define IPTOS_PREC_INTERNETCONTROL 6
247 #define IPTOS_PREC_CRITIC_ECP 5
248 #define IPTOS_PREC_FLASHOVERRIDE 4
249 #define IPTOS_PREC_FLASH 3
250 #define IPTOS_PREC_IMMEDIATE 2
251 #define IPTOS_PREC_PRIORITY 1
252 #define IPTOS_PREC_ROUTINE 0
255 #define IPOPT_COPY 0x80
257 #define IPOPT_CONTROL 0x00
258 #define IPOPT_RESERVED1 0x20
259 #define IPOPT_MEASUREMENT 0x40
260 #define IPOPT_RESERVED2 0x60
262 #define IPOPT_END (0 |IPOPT_CONTROL)
263 #define IPOPT_NOOP (1 |IPOPT_CONTROL)
264 #define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
265 #define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
266 #define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
267 #define IPOPT_RR (7 |IPOPT_CONTROL)
268 #define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
269 #define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
270 #define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY)
272 /* IP option lengths */
273 #define IPOLEN_SEC 11
274 #define IPOLEN_LSRR_MIN 3
275 #define IPOLEN_TIMESTAMP_MIN 5
276 #define IPOLEN_RR_MIN 3
278 #define IPOLEN_SSRR_MIN 3
281 #define IPSEC_UNCLASSIFIED 0x0000
282 #define IPSEC_CONFIDENTIAL 0xF135
283 #define IPSEC_EFTO 0x789A
284 #define IPSEC_MMMM 0xBC4D
285 #define IPSEC_RESTRICTED 0xAF13
286 #define IPSEC_SECRET 0xD788
287 #define IPSEC_TOPSECRET 0x6BC5
288 #define IPSEC_RESERVED1 0x35E2
289 #define IPSEC_RESERVED2 0x9AF1
290 #define IPSEC_RESERVED3 0x4D78
291 #define IPSEC_RESERVED4 0x24BD
292 #define IPSEC_RESERVED5 0x135E
293 #define IPSEC_RESERVED6 0x89AF
294 #define IPSEC_RESERVED7 0xC4D6
295 #define IPSEC_RESERVED8 0xE26B
297 #define IPOPT_TS_TSONLY 0 /* timestamps only */
298 #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
299 #define IPOPT_TS_PRESPEC 3 /* specified modules only */
302 * defragmentation of IPv4
304 static GHashTable *ip_fragment_table=NULL;
306 typedef struct _ip_fragment_key {
312 /* make sure that all flags that are set in a fragment entry is also set for
313 * the flags field of ipfd_head !!!
315 /* only in ipfd_head: packet is defragmented */
316 #define IPD_DEFRAGMENTED 0x0001
317 /* there are overlapping fragments */
318 #define IPD_OVERLAP 0x0002
319 /* overlapping fragments contain different data */
320 #define IPD_OVERLAPCONFLICT 0x0004
321 /* more than one fragment which indicates end-of data */
322 #define IPD_MULTIPLETAILS 0x0008
323 /* fragment contains data past the end of the datagram */
324 #define IPD_TOOLONGFRAGMENT 0x0010
325 typedef struct _ip_fragment_data {
326 struct _ip_fragment_data *next;
330 guint32 datalen; /*Only valid in first item of list */
335 #define LINK_FRAG(ipfd_head,ipfd) \
336 { ip_fragment_data *ipfd_i; \
337 /* add fragment to list, keep list sorted */ \
338 for(ipfd_i=ipfd_head;ipfd_i->next;ipfd_i=ipfd_i->next){ \
339 if( (ipfd->offset) < (ipfd_i->next->offset) ) \
342 ipfd->next=ipfd_i->next; \
348 ip_fragment_equal(gconstpointer k1, gconstpointer k2)
350 ip_fragment_key* key1 = (ip_fragment_key*) k1;
351 ip_fragment_key* key2 = (ip_fragment_key*) k2;
353 return ( ( (key1->srcip == key2->srcip) &&
354 (key1->dstip == key2->dstip) &&
355 (key1->id == key2->id)
361 ip_fragment_hash(gconstpointer k)
363 ip_fragment_key* key = (ip_fragment_key*) k;
365 return (key->srcip ^ key->dstip ^ key->id);
369 free_all_fragments(gpointer key, gpointer value, gpointer user_data)
371 ip_fragment_data *ipfd_head;
372 ip_fragment_data *ipfd_i;
376 ipfd_i=ipfd_head->next;
378 g_free(ipfd_head->data);
389 ip_defragment_init(void)
391 if( ip_fragment_table != NULL ){
392 /* The fragment hash table exists.
394 * Remove all entries and free all memory.
396 g_hash_table_foreach_remove(ip_fragment_table,free_all_fragments,NULL);
398 /* The fragment table does not exist. Create it */
399 ip_fragment_table = g_hash_table_new(ip_fragment_hash,
404 /* This function adds a new fragment to the fragment hash table
405 * If this is the first fragment seen in for this ip packet,
406 * a new entry is created in the hash table, otherwise
407 * This fragment is just added to the linked list of
408 * fragments for this packet.
409 * The list of fragments for a specific ip-packet is kept sorted for
411 * tvb had better contain an IPv4 packet, or BAD things will probably happen.
413 * Returns a pointer to the head of the fragment data list if we have all the
414 * fragments, NULL otherwise.
416 static ip_fragment_data *
417 ip_fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
420 ip_fragment_key *ipfk;
421 ip_fragment_data *ipfd_head;
422 ip_fragment_data *ipfd;
423 ip_fragment_data *ipfd_i;
428 /* create key to search hash with */
429 ipfk=g_malloc(sizeof(ip_fragment_key));
430 memcpy(&ipfk->srcip, pinfo->src.data, sizeof(ipfk->srcip));
431 memcpy(&ipfk->dstip, pinfo->dst.data, sizeof(ipfk->dstip));
434 ipfd_head=g_hash_table_lookup(ip_fragment_table, ipfk);
437 /* have we already seen this frame ?*/
438 if( pinfo->fd->flags.visited ){
440 if (ipfd_head != NULL && ipfd_head->flags & IPD_DEFRAGMENTED) {
449 frag_offset = (floff & IP_OFFSET)*8;
451 if (ipfd_head==NULL){
452 /* not found, this must be the first snooped fragment for this
453 * ip packet. Create list-head.
455 ipfd_head=g_malloc(sizeof(ip_fragment_data));
456 /* head/first structure in list only holds no other data than
457 * 'datalen' then we dont have to change the head of the list
458 * even if we want to keep it sorted
460 ipfd_head->next=NULL;
461 ipfd_head->datalen=0;
465 ipfd_head->data=NULL;
466 g_hash_table_insert(ip_fragment_table, ipfk, ipfd_head);
468 /* this was not the first fragment, so we can throw ipfk
469 * away, only used for the first fragment, 3 lines up
475 /* create new ipfd describing this fragment */
476 ipfd = g_malloc(sizeof(ip_fragment_data));
479 ipfd->frame = pinfo->fd->num;
480 ipfd->offset = frag_offset;
481 ipfd->len = pinfo->iplen;
482 ipfd->len -= (pinfo->iphdrlen*4);
487 if( !(floff&IP_MF) ){
488 /* this is a tail fragment */
489 if (ipfd_head->datalen) {
490 /* ok we have already seen other tails for this packet
491 * it might be a duplicate.
493 if (ipfd_head->datalen != (ipfd->offset + ipfd->len) ){
494 /* Oops, this tail indicates a different packet
495 * len than the previous ones. Somethings wrong
497 ipfd->flags |= IPD_MULTIPLETAILS;
498 ipfd_head->flags |= IPD_MULTIPLETAILS;
501 /* this was the first tail fragment, now we know the
502 * length of the packet
504 ipfd_head->datalen = ipfd->offset + ipfd->len;
511 /* If the packet is already defragmented, this MUST be an overlap.
512 * The entire defragmented packet is in ipfd_head->data
513 * Even if we have previously defragmented this packet, we still check
514 * check it. Someone might play overlap and TTL games.
516 if (ipfd_head->flags & IPD_DEFRAGMENTED) {
517 ipfd->flags |= IPD_OVERLAP;
518 ipfd_head->flags |= IPD_OVERLAP;
519 /* make sure its not too long */
520 if (ipfd->offset + ipfd->len > ipfd_head->datalen) {
521 ipfd->flags |= IPD_TOOLONGFRAGMENT;
522 ipfd_head->flags |= IPD_TOOLONGFRAGMENT;
523 LINK_FRAG(ipfd_head,ipfd);
526 /* make sure it doesnt conflict with previous data */
527 if ( memcmp(ipfd_head->data+ipfd->offset,
528 tvb_get_ptr(tvb,offset,ipfd->len),ipfd->len) ){
529 ipfd->flags |= IPD_OVERLAPCONFLICT;
530 ipfd_head->flags |= IPD_OVERLAPCONFLICT;
531 LINK_FRAG(ipfd_head,ipfd);
534 /* it was just an overlap, link it and return */
535 LINK_FRAG(ipfd_head,ipfd);
541 /* If we have reached this point, the packet is not defragmented yet.
542 * Save all payload in a buffer until we can defragment.
544 ipfd->data = g_malloc(ipfd->len);
545 tvb_memcpy(tvb, ipfd->data, offset, ipfd->len);
546 LINK_FRAG(ipfd_head,ipfd);
549 if( !(ipfd_head->datalen) ){
550 /* if we dont know the datalen, there are still missing
551 * packets. Cheaper than the check below.
557 /* check if we have received the entire fragment
558 * this is easy since the list is sorted and the head is faked.
561 for (ipfd_i=ipfd_head->next;ipfd_i;ipfd_i=ipfd_i->next) {
562 if ( ((ipfd_i->offset)<=max) &&
563 ((ipfd_i->offset+ipfd_i->len)>max) ){
564 max = ipfd_i->offset+ipfd_i->len;
568 if (max < (ipfd_head->datalen)) {
569 /* we have not received all packets yet */
574 if (max > (ipfd_head->datalen)) {
575 /* oops, too long fragment detected */
576 ipfd->flags |= IPD_TOOLONGFRAGMENT;
577 ipfd_head->flags |= IPD_TOOLONGFRAGMENT;
581 /* we have received an entire packet, defragment it and
584 ipfd_head->data = g_malloc(max);
586 /* add all data fragments */
587 for (dfpos=0,ipfd_i=ipfd_head;ipfd_i;ipfd_i=ipfd_i->next) {
589 if (ipfd_i->offset < dfpos) {
590 ipfd_i->flags |= IPD_OVERLAP;
591 ipfd_head->flags |= IPD_OVERLAP;
592 if ( memcmp(ipfd_head->data+ipfd_i->offset,
594 MIN(ipfd_i->len,(dfpos-ipfd_i->offset))
596 ipfd_i->flags |= IPD_OVERLAPCONFLICT;
597 ipfd_head->flags |= IPD_OVERLAPCONFLICT;
600 memcpy(ipfd_head->data+ipfd_i->offset,ipfd_i->data,ipfd_i->len);
601 g_free(ipfd_i->data);
604 dfpos=MAX(dfpos,(ipfd_i->offset+ipfd_i->len));
608 /* mark this packet as defragmented.
609 allows us to skip any trailing fragments */
610 ipfd_head->flags |= IPD_DEFRAGMENTED;
618 capture_ip(const u_char *pd, int offset, packet_counts *ld) {
619 if (!BYTES_ARE_IN_FRAME(offset, IPH_MIN_LEN)) {
623 switch (pd[offset + 9]) {
651 dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
652 guint optlen, frame_data *fd, proto_tree *opt_tree)
654 proto_tree *field_tree = NULL;
657 static const value_string secl_vals[] = {
658 {IPSEC_UNCLASSIFIED, "Unclassified"},
659 {IPSEC_CONFIDENTIAL, "Confidential"},
660 {IPSEC_EFTO, "EFTO" },
661 {IPSEC_MMMM, "MMMM" },
662 {IPSEC_RESTRICTED, "Restricted" },
663 {IPSEC_SECRET, "Secret" },
664 {IPSEC_TOPSECRET, "Top secret" },
665 {IPSEC_RESERVED1, "Reserved" },
666 {IPSEC_RESERVED2, "Reserved" },
667 {IPSEC_RESERVED3, "Reserved" },
668 {IPSEC_RESERVED4, "Reserved" },
669 {IPSEC_RESERVED5, "Reserved" },
670 {IPSEC_RESERVED6, "Reserved" },
671 {IPSEC_RESERVED7, "Reserved" },
672 {IPSEC_RESERVED8, "Reserved" },
675 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
676 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
679 val = tvb_get_ntohs(tvb, offset);
680 proto_tree_add_text(field_tree, tvb, offset, 2,
681 "Security: %s", val_to_str(val, secl_vals, "Unknown (0x%x)"));
684 val = tvb_get_ntohs(tvb, offset);
685 proto_tree_add_text(field_tree, tvb, offset, 2,
686 "Compartments: %u", val);
689 proto_tree_add_text(field_tree, tvb, offset, 2,
690 "Handling restrictions: %c%c",
691 tvb_get_guint8(tvb, offset),
692 tvb_get_guint8(tvb, offset + 1));
695 proto_tree_add_text(field_tree, tvb, offset, 3,
696 "Transmission control code: %c%c%c",
697 tvb_get_guint8(tvb, offset),
698 tvb_get_guint8(tvb, offset + 1),
699 tvb_get_guint8(tvb, offset + 2));
703 dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
704 guint optlen, frame_data *fd, proto_tree *opt_tree)
706 proto_tree *field_tree = NULL;
712 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)",
714 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
716 optoffset += 2; /* skip past type and length */
717 optlen -= 2; /* subtract size of type and length */
719 ptr = tvb_get_guint8(tvb, offset + optoffset);
720 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
721 "Pointer: %d%s", ptr,
722 ((ptr < 4) ? " (points before first address)" :
723 ((ptr & 3) ? " (points to middle of address)" : "")));
726 ptr--; /* ptr is 1-origin */
730 proto_tree_add_text(field_tree, tvb, offset, optlen,
731 "(suboption would go past end of option)");
735 /* Avoids alignment problems on many architectures. */
736 tvb_memcpy(tvb, (guint8 *)&addr, offset + optoffset, sizeof(addr));
738 proto_tree_add_text(field_tree, tvb, offset + optoffset, 4,
740 ((addr.s_addr == 0) ? "-" : (char *)get_hostname(addr.s_addr)),
741 ((optoffset == ptr) ? " <- (current)" : ""));
748 dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
749 guint optlen, frame_data *fd, proto_tree *opt_tree)
751 proto_tree_add_text(opt_tree, tvb, offset, optlen,
752 "%s: %u", optp->name, tvb_get_ntohs(tvb, offset + 2));
757 dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
758 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
760 proto_tree *field_tree = NULL;
765 static const value_string flag_vals[] = {
766 {IPOPT_TS_TSONLY, "Time stamps only" },
767 {IPOPT_TS_TSANDADDR, "Time stamp and address" },
768 {IPOPT_TS_PRESPEC, "Time stamps for prespecified addresses"},
773 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
774 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
776 optoffset += 2; /* skip past type and length */
777 optlen -= 2; /* subtract size of type and length */
779 ptr = tvb_get_guint8(tvb, offset + optoffset);
780 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
781 "Pointer: %d%s", ptr,
782 ((ptr < 5) ? " (points before first address)" :
783 (((ptr - 1) & 3) ? " (points to middle of address)" : "")));
786 ptr--; /* ptr is 1-origin */
788 flg = tvb_get_guint8(tvb, offset + optoffset);
789 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
790 "Overflow: %u", flg >> 4);
792 proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
793 "Flag: %s", val_to_str(flg, flag_vals, "Unknown (0x%x)"));
798 if (flg == IPOPT_TS_TSANDADDR) {
800 proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
801 "(suboption would go past end of option)");
804 tvb_memcpy(tvb, (char *)&addr, offset + optoffset, sizeof(addr));
805 ts = tvb_get_ntohl(tvb, offset + optoffset + 4);
807 proto_tree_add_text(field_tree, tvb, offset + optoffset, 8,
808 "Address = %s, time stamp = %u",
809 ((addr.s_addr == 0) ? "-" : (char *)get_hostname(addr.s_addr)),
814 proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
815 "(suboption would go past end of option)");
818 ts = tvb_get_ntohl(tvb, offset + optoffset);
820 proto_tree_add_text(field_tree, tvb, offset + optoffset, 4,
821 "Time stamp = %u", ts);
828 dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
829 guint optlen, frame_data *fd, proto_tree *opt_tree)
831 /* Router-Alert, as defined by RFC2113 */
832 int opt = tvb_get_ntohs(tvb, offset + 2);
833 static const value_string ra_opts[] = {
834 {0, "Every router examines packet"},
838 proto_tree_add_text(opt_tree, tvb, offset, optlen,
839 "%s: %s", optp->name, val_to_str(opt, ra_opts, "Unknown (%d)"));
843 static const ip_tcp_opt ipopts[] = {
866 dissect_ipopt_security
870 "Strict source route",
871 &ett_ip_option_route,
878 "Loose source route",
879 &ett_ip_option_route,
887 &ett_ip_option_route,
903 &ett_ip_option_timestamp,
905 IPOLEN_TIMESTAMP_MIN,
906 dissect_ipopt_timestamp
918 #define N_IP_OPTS (sizeof ipopts / sizeof ipopts[0])
920 /* Dissect the IP or TCP options in a packet. */
922 dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
923 const ip_tcp_opt *opttab, int nopts, int eol,
924 frame_data *fd, proto_tree *opt_tree)
927 const ip_tcp_opt *optp;
928 opt_len_type len_type;
931 char name_str[7+1+1+2+2+1+1]; /* "Unknown (0x%02x)" */
932 void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
933 int, guint, frame_data *, proto_tree *);
937 opt = tvb_get_guint8(tvb, offset);
938 for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
939 if (optp->optcode == opt)
942 if (optp == &opttab[nopts]) {
943 /* We assume that the only NO_LENGTH options are EOL and NOP options,
944 so that we can treat unknown options as VARIABLE_LENGTH with a
945 minimum of 2, and at least be able to move on to the next option
946 by using the length in the option. */
947 optp = NULL; /* indicate that we don't know this option */
948 len_type = VARIABLE_LENGTH;
950 snprintf(name_str, sizeof name_str, "Unknown (0x%02x)", opt);
954 len_type = optp->len_type;
955 optlen = optp->optlen;
957 dissect = optp->dissect;
959 --length; /* account for type byte */
960 if (len_type != NO_LENGTH) {
961 /* Option has a length. Is it in the packet? */
963 /* Bogus - packet must at least include option code byte and
965 proto_tree_add_text(opt_tree, tvb, offset, 1,
966 "%s (length byte past end of options)", name);
969 len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
970 --length; /* account for length byte */
972 /* Bogus - option length is too short to include option code and
974 proto_tree_add_text(opt_tree, tvb, offset, 2,
975 "%s (with too-short option length = %u byte%s)", name,
976 len, plurality(len, "", "s"));
978 } else if (len - 2 > length) {
979 /* Bogus - option goes past the end of the header. */
980 proto_tree_add_text(opt_tree, tvb, offset, length,
981 "%s (option length = %u byte%s says option goes past end of options)",
982 name, len, plurality(len, "", "s"));
984 } else if (len_type == FIXED_LENGTH && len != optlen) {
985 /* Bogus - option length isn't what it's supposed to be for this
987 proto_tree_add_text(opt_tree, tvb, offset, len,
988 "%s (with option length = %u byte%s; should be %u)", name,
989 len, plurality(len, "", "s"), optlen);
991 } else if (len_type == VARIABLE_LENGTH && len < optlen) {
992 /* Bogus - option length is less than what it's supposed to be for
994 proto_tree_add_text(opt_tree, tvb, offset, len,
995 "%s (with option length = %u byte%s; should be >= %u)", name,
996 len, plurality(len, "", "s"), optlen);
1000 proto_tree_add_text(opt_tree, tvb, offset, len, "%s (%u byte%s)",
1001 name, len, plurality(len, "", "s"));
1003 if (dissect != NULL) {
1004 /* Option has a dissector. */
1005 (*dissect)(optp, tvb, offset, len, fd, opt_tree);
1007 /* Option has no data, hence no dissector. */
1008 proto_tree_add_text(opt_tree, tvb, offset, len, "%s", name);
1011 len -= 2; /* subtract size of type and length */
1016 proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name);
1024 static const value_string dscp_vals[] = {
1025 { IPDSFIELD_DSCP_DEFAULT, "Default" },
1026 { IPDSFIELD_DSCP_CS1, "Class Selector 1" },
1027 { IPDSFIELD_DSCP_CS2, "Class Selector 2" },
1028 { IPDSFIELD_DSCP_CS3, "Class Selector 3" },
1029 { IPDSFIELD_DSCP_CS4, "Class Selector 4" },
1030 { IPDSFIELD_DSCP_CS5, "Class Selector 5" },
1031 { IPDSFIELD_DSCP_CS6, "Class Selector 6" },
1032 { IPDSFIELD_DSCP_CS7, "Class Selector 7" },
1033 { IPDSFIELD_DSCP_AF11, "Assured Forwarding 11" },
1034 { IPDSFIELD_DSCP_AF12, "Assured Forwarding 12" },
1035 { IPDSFIELD_DSCP_AF13, "Assured Forwarding 13" },
1036 { IPDSFIELD_DSCP_AF21, "Assured Forwarding 21" },
1037 { IPDSFIELD_DSCP_AF22, "Assured Forwarding 22" },
1038 { IPDSFIELD_DSCP_AF23, "Assured Forwarding 23" },
1039 { IPDSFIELD_DSCP_AF31, "Assured Forwarding 31" },
1040 { IPDSFIELD_DSCP_AF32, "Assured Forwarding 32" },
1041 { IPDSFIELD_DSCP_AF33, "Assured Forwarding 33" },
1042 { IPDSFIELD_DSCP_AF41, "Assured Forwarding 41" },
1043 { IPDSFIELD_DSCP_AF42, "Assured Forwarding 42" },
1044 { IPDSFIELD_DSCP_AF43, "Assured Forwarding 43" },
1045 { IPDSFIELD_DSCP_EF, "Expedited Forwarding" },
1048 static const value_string precedence_vals[] = {
1049 { IPTOS_PREC_ROUTINE, "routine" },
1050 { IPTOS_PREC_PRIORITY, "priority" },
1051 { IPTOS_PREC_IMMEDIATE, "immediate" },
1052 { IPTOS_PREC_FLASH, "flash" },
1053 { IPTOS_PREC_FLASHOVERRIDE, "flash override" },
1054 { IPTOS_PREC_CRITIC_ECP, "CRITIC/ECP" },
1055 { IPTOS_PREC_INTERNETCONTROL, "internetwork control" },
1056 { IPTOS_PREC_NETCONTROL, "network control" },
1059 static const value_string iptos_vals[] = {
1060 { IPTOS_NONE, "None" },
1061 { IPTOS_LOWCOST, "Minimize cost" },
1062 { IPTOS_RELIABILITY, "Maximize reliability" },
1063 { IPTOS_THROUGHPUT, "Maximize throughput" },
1064 { IPTOS_LOWDELAY, "Minimize delay" },
1065 { IPTOS_SECURITY, "Maximize security" },
1069 static const true_false_string tos_set_low = {
1074 static const true_false_string tos_set_high = {
1079 static const true_false_string flags_set_truth = {
1084 static guint16 ip_checksum(const guint8 *ptr, int len)
1088 cksum_vec[0].ptr = ptr;
1089 cksum_vec[0].len = len;
1090 return in_cksum(&cksum_vec[0], 1);
1094 dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1097 proto_tree *ip_tree = NULL, *field_tree;
1098 proto_item *ti, *tf;
1100 guint hlen, optlen, len, payload_len, reported_payload_len, padding;
1104 ip_fragment_data *ipfd_head;
1106 packet_info save_pi;
1107 gboolean must_restore_pi = FALSE;
1108 gboolean update_col_info = TRUE;
1110 if (check_col(pinfo->fd, COL_PROTOCOL))
1111 col_set_str(pinfo->fd, COL_PROTOCOL, "IP");
1112 if (check_col(pinfo->fd, COL_INFO))
1113 col_clear(pinfo->fd, COL_INFO);
1115 /* Avoids alignment problems on many architectures. */
1116 tvb_memcpy(tvb, (guint8 *)&iph, offset, sizeof(e_ip));
1117 iph.ip_len = ntohs(iph.ip_len);
1118 iph.ip_id = ntohs(iph.ip_id);
1119 iph.ip_off = ntohs(iph.ip_off);
1120 iph.ip_sum = ntohs(iph.ip_sum);
1122 /* Length of payload handed to us. */
1123 reported_payload_len = tvb_reported_length(tvb);
1124 payload_len = tvb_length(tvb);
1126 /* Length of IP datagram. */
1129 if (len < reported_payload_len) {
1130 /* Adjust the length of this tvbuff to include only the IP datagram.
1131 Our caller may use that to determine how much of its packet
1133 tvb_set_reported_length(tvb, len);
1135 /* Shrink the total payload by the amount of padding. */
1136 padding = reported_payload_len - len;
1137 if (pinfo->len >= padding)
1138 pinfo->len -= padding;
1140 /* Shrink the captured payload by the amount of padding in the
1141 captured payload (which may be less than the amount of padding,
1142 as the padding may not have been captured). */
1143 if (len < payload_len) {
1144 padding = payload_len - len;
1145 if (pinfo->captured_len >= padding)
1146 pinfo->captured_len -= padding;
1150 hlen = lo_nibble(iph.ip_v_hl) * 4; /* IP header length, in bytes */
1153 if (ip_summary_in_tree && hlen >= IPH_MIN_LEN) {
1154 ti = proto_tree_add_protocol_format(tree, proto_ip, tvb, offset, hlen,
1155 "Internet Protocol, Src Addr: %s (%s), Dst Addr: %s (%s)",
1156 get_hostname(iph.ip_src), ip_to_str((guint8 *) &iph.ip_src),
1157 get_hostname(iph.ip_dst), ip_to_str((guint8 *) &iph.ip_dst));
1159 ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, FALSE);
1161 ip_tree = proto_item_add_subtree(ti, ett_ip);
1164 if (hlen < IPH_MIN_LEN) {
1165 if (check_col(pinfo->fd, COL_INFO))
1166 col_add_fstr(pinfo->fd, COL_INFO, "Bogus IP header length (%u, must be at least %u)",
1169 proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
1170 "Header length: %u bytes (bogus, must be at least %u)", hlen,
1177 * Compute the checksum of the IP header.
1179 ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen);
1182 proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1, hi_nibble(iph.ip_v_hl));
1183 proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
1184 "Header length: %u bytes", hlen);
1186 if (g_ip_dscp_actif) {
1187 tf = proto_tree_add_uint_format(ip_tree, hf_ip_dsfield, tvb, offset + 1, 1, iph.ip_tos,
1188 "Differentiated Services Field: 0x%02x (DSCP 0x%02x: %s; ECN: 0x%02x)", iph.ip_tos,
1189 IPDSFIELD_DSCP(iph.ip_tos), val_to_str(IPDSFIELD_DSCP(iph.ip_tos), dscp_vals,
1190 "Unknown DSCP"),IPDSFIELD_ECN(iph.ip_tos));
1192 field_tree = proto_item_add_subtree(tf, ett_ip_dsfield);
1193 proto_tree_add_uint(field_tree, hf_ip_dsfield_dscp, tvb, offset + 1, 1, iph.ip_tos);
1194 proto_tree_add_uint(field_tree, hf_ip_dsfield_ect, tvb, offset + 1, 1, iph.ip_tos);
1195 proto_tree_add_uint(field_tree, hf_ip_dsfield_ce, tvb, offset + 1, 1, iph.ip_tos);
1197 tf = proto_tree_add_uint_format(ip_tree, hf_ip_tos, tvb, offset + 1, 1, iph.ip_tos,
1198 "Type of service: 0x%02x (%s)", iph.ip_tos,
1199 val_to_str( IPTOS_TOS(iph.ip_tos), iptos_vals, "Unknown") );
1201 field_tree = proto_item_add_subtree(tf, ett_ip_tos);
1202 proto_tree_add_uint(field_tree, hf_ip_tos_precedence, tvb, offset + 1, 1, iph.ip_tos);
1203 proto_tree_add_boolean(field_tree, hf_ip_tos_delay, tvb, offset + 1, 1, iph.ip_tos);
1204 proto_tree_add_boolean(field_tree, hf_ip_tos_throughput, tvb, offset + 1, 1, iph.ip_tos);
1205 proto_tree_add_boolean(field_tree, hf_ip_tos_reliability, tvb, offset + 1, 1, iph.ip_tos);
1206 proto_tree_add_boolean(field_tree, hf_ip_tos_cost, tvb, offset + 1, 1, iph.ip_tos);
1208 proto_tree_add_uint(ip_tree, hf_ip_len, tvb, offset + 2, 2, iph.ip_len);
1209 proto_tree_add_uint(ip_tree, hf_ip_id, tvb, offset + 4, 2, iph.ip_id);
1211 flags = (iph.ip_off & (IP_DF|IP_MF)) >> 12;
1212 tf = proto_tree_add_uint(ip_tree, hf_ip_flags, tvb, offset + 6, 1, flags);
1213 field_tree = proto_item_add_subtree(tf, ett_ip_off);
1214 proto_tree_add_boolean(field_tree, hf_ip_flags_df, tvb, offset + 6, 1, flags),
1215 proto_tree_add_boolean(field_tree, hf_ip_flags_mf, tvb, offset + 6, 1, flags),
1217 proto_tree_add_uint(ip_tree, hf_ip_frag_offset, tvb, offset + 6, 2,
1218 (iph.ip_off & IP_OFFSET)*8);
1220 proto_tree_add_uint(ip_tree, hf_ip_ttl, tvb, offset + 8, 1, iph.ip_ttl);
1221 proto_tree_add_uint_format(ip_tree, hf_ip_proto, tvb, offset + 9, 1, iph.ip_p,
1222 "Protocol: %s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p);
1225 proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum,
1226 "Header checksum: 0x%04x (correct)", iph.ip_sum);
1229 proto_tree_add_item_hidden(ip_tree, hf_ip_checksum_bad, tvb, offset + 10, 2, TRUE);
1230 proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum,
1231 "Header checksum: 0x%04x (incorrect, should be 0x%04x)", iph.ip_sum,
1232 in_cksum_shouldbe(iph.ip_sum, ipsum));
1235 proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, iph.ip_src);
1236 proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, iph.ip_dst);
1237 proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 12, 4, iph.ip_src);
1238 proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 16, 4, iph.ip_dst);
1240 /* Decode IP options, if any. */
1241 if (hlen > sizeof (e_ip)) {
1242 /* There's more than just the fixed-length header. Decode the
1244 optlen = hlen - sizeof (e_ip); /* length of options, in bytes */
1245 tf = proto_tree_add_text(ip_tree, tvb, offset + 20, optlen,
1246 "Options: (%u bytes)", optlen);
1247 field_tree = proto_item_add_subtree(tf, ett_ip_options);
1248 dissect_ip_tcp_options(tvb, offset + 20, optlen,
1249 ipopts, N_IP_OPTS, IPOPT_END, pinfo->fd, field_tree);
1253 pinfo->ipproto = iph.ip_p;
1255 pinfo->iplen = iph.ip_len;
1257 pinfo->iphdrlen = lo_nibble(iph.ip_v_hl);
1259 SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
1260 SET_ADDRESS(&pinfo->src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
1261 SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
1262 SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
1264 /* Skip over header + options */
1266 nxt = iph.ip_p; /* XXX - what if this isn't the same for all fragments? */
1268 /* If ip_defragment is on and this is a fragment, then just add the fragment
1271 if (ip_defragment && (iph.ip_off & (IP_MF|IP_OFFSET))) {
1272 /* We're reassembling, and this is part of a fragmented datagram.
1273 Add the fragment to the hash table if the checksum is ok
1274 and the frame isn't truncated. */
1275 if ((ipsum==0) && (tvb_reported_length(tvb) <= tvb_length(tvb))) {
1276 ipfd_head = ip_fragment_add(tvb, offset, pinfo, iph.ip_id, iph.ip_off);
1281 if (ipfd_head != NULL) {
1282 ip_fragment_data *ipfd;
1283 proto_tree *ft=NULL;
1284 proto_item *fi=NULL;
1286 /* OK, we have the complete reassembled payload. */
1287 /* show all fragments */
1288 fi = proto_tree_add_item(ip_tree, hf_ip_fragments,
1290 ft = proto_item_add_subtree(fi, ett_ip_fragments);
1291 for (ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
1292 if (ipfd->flags & (IPD_OVERLAP|IPD_OVERLAPCONFLICT
1293 |IPD_MULTIPLETAILS|IPD_TOOLONGFRAGMENT) ) {
1294 /* this fragment has some flags set, create a subtree
1295 * for it and display the flags.
1297 proto_tree *fet=NULL;
1298 proto_item *fei=NULL;
1301 if (ipfd->flags & (IPD_OVERLAPCONFLICT
1302 |IPD_MULTIPLETAILS|IPD_TOOLONGFRAGMENT) ) {
1303 hf = hf_ip_fragment_error;
1305 hf = hf_ip_fragment;
1307 fei = proto_tree_add_none_format(ft, hf,
1309 "Frame:%d payload:%d-%d",
1312 ipfd->offset+ipfd->len-1
1314 fet = proto_item_add_subtree(fei, ett_ip_fragment);
1315 if (ipfd->flags&IPD_OVERLAP) {
1316 proto_tree_add_boolean(fet,
1317 hf_ip_fragment_overlap, tvb, 0, 0,
1320 if (ipfd->flags&IPD_OVERLAPCONFLICT) {
1321 proto_tree_add_boolean(fet,
1322 hf_ip_fragment_overlap_conflict, tvb, 0, 0,
1325 if (ipfd->flags&IPD_MULTIPLETAILS) {
1326 proto_tree_add_boolean(fet,
1327 hf_ip_fragment_multiple_tails, tvb, 0, 0,
1330 if (ipfd->flags&IPD_TOOLONGFRAGMENT) {
1331 proto_tree_add_boolean(fet,
1332 hf_ip_fragment_too_long_fragment, tvb, 0, 0,
1336 /* nothing of interest for this fragment */
1337 proto_tree_add_none_format(ft, hf_ip_fragment,
1339 "Frame:%d payload:%d-%d",
1342 ipfd->offset+ipfd->len-1
1346 if (ipfd_head->flags & (IPD_OVERLAPCONFLICT
1347 |IPD_MULTIPLETAILS|IPD_TOOLONGFRAGMENT) ) {
1348 if (check_col(pinfo->fd, COL_INFO)) {
1349 col_set_str(pinfo->fd, COL_INFO, "[Illegal fragments]");
1350 update_col_info = FALSE;
1354 /* Allocate a new tvbuff, referring to the reassembled payload. */
1355 next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen,
1356 ipfd_head->datalen, "Reassembled");
1358 /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
1359 were handed refers, so it'll get cleaned up when that tvbuff
1361 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1363 /* Add the defragmented data to the data source list. */
1364 pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
1366 /* It's not fragmented. */
1367 pinfo->fragmented = FALSE;
1369 /* Save the current value of "pi", and adjust certain fields to
1370 reflect the new tvbuff. */
1372 pi.compat_top_tvb = next_tvb;
1373 pi.len = tvb_reported_length(next_tvb);
1374 pi.captured_len = tvb_length(next_tvb);
1375 must_restore_pi = TRUE;
1377 /* We don't have the complete reassembled payload. */
1381 /* If this is the first fragment, dissect its contents, otherwise
1382 just show it as a fragment.
1384 XXX - if we eventually don't save the reassembled contents of all
1385 fragmented datagrams, we may want to always reassemble. */
1386 if (iph.ip_off & IP_OFFSET) {
1387 /* Not the first fragment - don't dissect it. */
1390 /* First fragment, or not fragmented. Dissect what we have here. */
1392 /* Get a tvbuff for the payload. */
1393 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1396 * If this is the first fragment, but not the only fragment,
1397 * tell the next protocol that.
1399 if (iph.ip_off & IP_MF)
1400 pinfo->fragmented = TRUE;
1402 pinfo->fragmented = FALSE;
1406 if (next_tvb == NULL) {
1407 /* Just show this as a fragment. */
1408 if (check_col(pinfo->fd, COL_INFO))
1409 col_add_fstr(pinfo->fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)",
1410 ipprotostr(iph.ip_p), iph.ip_p, (iph.ip_off & IP_OFFSET) * 8);
1411 dissect_data(tvb, offset, pinfo, tree);
1413 /* As we haven't reassembled anything, we haven't changed "pi", so
1414 we don't have to restore it. */
1418 /* Hand off to the next protocol.
1420 XXX - setting the columns only after trying various dissectors means
1421 that if one of those dissectors throws an exception, the frame won't
1422 even be labelled as an IP frame; ideally, if a frame being dissected
1423 throws an exception, it'll be labelled as a mangled frame of the
1424 type in question. */
1425 if (!dissector_try_port(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
1426 /* Unknown protocol */
1427 if (update_col_info) {
1428 if (check_col(pinfo->fd, COL_INFO))
1429 col_add_fstr(pinfo->fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p);
1431 dissect_data(next_tvb, 0, pinfo, tree);
1434 if (must_restore_pi)
1439 static const gchar *unreach_str[] = {"Network unreachable",
1441 "Protocol unreachable",
1443 "Fragmentation needed",
1444 "Source route failed",
1445 "Destination network unknown",
1446 "Destination host unknown",
1447 "Source host isolated",
1448 "Network administratively prohibited",
1449 "Host administratively prohibited",
1450 "Network unreachable for TOS",
1451 "Host unreachable for TOS",
1452 "Communication administratively filtered",
1453 "Host precedence violation",
1454 "Precedence cutoff in effect"};
1456 #define N_UNREACH (sizeof unreach_str / sizeof unreach_str[0])
1458 static const gchar *redir_str[] = {"Redirect for network",
1459 "Redirect for host",
1460 "Redirect for TOS and network",
1461 "Redirect for TOS and host"};
1463 #define N_REDIRECT (sizeof redir_str / sizeof redir_str[0])
1465 static const gchar *ttl_str[] = {"TTL equals 0 during transit",
1466 "TTL equals 0 during reassembly"};
1468 #define N_TIMXCEED (sizeof ttl_str / sizeof ttl_str[0])
1470 static const gchar *par_str[] = {"IP header bad", "Required option missing"};
1472 #define N_PARAMPROB (sizeof par_str / sizeof par_str[0])
1475 dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1477 proto_tree *icmp_tree;
1481 guint length, reported_length;
1482 guint16 cksum, computed_cksum;
1483 gchar type_str[64], code_str[64] = "";
1484 guint8 num_addrs = 0;
1485 guint8 addr_entry_size = 0;
1488 if (check_col(pinfo->fd, COL_PROTOCOL))
1489 col_set_str(pinfo->fd, COL_PROTOCOL, "ICMP");
1490 if (check_col(pinfo->fd, COL_INFO))
1491 col_clear(pinfo->fd, COL_INFO);
1493 /* To do: check for runts, errs, etc. */
1494 icmp_type = tvb_get_guint8(tvb, 0);
1495 icmp_code = tvb_get_guint8(tvb, 1);
1496 cksum = tvb_get_ntohs(tvb, 2);
1498 switch (icmp_type) {
1499 case ICMP_ECHOREPLY:
1500 strcpy(type_str, "Echo (ping) reply");
1503 strcpy(type_str, "Destination unreachable");
1504 if (icmp_code < N_UNREACH) {
1505 sprintf(code_str, "(%s)", unreach_str[icmp_code]);
1507 strcpy(code_str, "(Unknown - error?)");
1510 case ICMP_SOURCEQUENCH:
1511 strcpy(type_str, "Source quench (flow control)");
1514 strcpy(type_str, "Redirect");
1515 if (icmp_code < N_REDIRECT) {
1516 sprintf(code_str, "(%s)", redir_str[icmp_code]);
1518 strcpy(code_str, "(Unknown - error?)");
1522 strcpy(type_str, "Echo (ping) request");
1524 case ICMP_RTRADVERT:
1525 strcpy(type_str, "Router advertisement");
1527 case ICMP_RTRSOLICIT:
1528 strcpy(type_str, "Router solicitation");
1531 strcpy(type_str, "Time-to-live exceeded");
1532 if (icmp_code < N_TIMXCEED) {
1533 sprintf(code_str, "(%s)", ttl_str[icmp_code]);
1535 strcpy(code_str, "(Unknown - error?)");
1538 case ICMP_PARAMPROB:
1539 strcpy(type_str, "Parameter problem");
1540 if (icmp_code < N_PARAMPROB) {
1541 sprintf(code_str, "(%s)", par_str[icmp_code]);
1543 strcpy(code_str, "(Unknown - error?)");
1547 strcpy(type_str, "Timestamp request");
1549 case ICMP_TSTAMPREPLY:
1550 strcpy(type_str, "Timestamp reply");
1553 strcpy(type_str, "Information request");
1555 case ICMP_IREQREPLY:
1556 strcpy(type_str, "Information reply");
1559 strcpy(type_str, "Address mask request");
1561 case ICMP_MASKREPLY:
1562 strcpy(type_str, "Address mask reply");
1565 strcpy(type_str, "Unknown ICMP (obsolete or malformed?)");
1568 if (check_col(pinfo->fd, COL_INFO))
1569 col_add_str(pinfo->fd, COL_INFO, type_str);
1572 length = tvb_length(tvb);
1573 reported_length = tvb_reported_length(tvb);
1574 ti = proto_tree_add_item(tree, proto_icmp, tvb, 0, length, FALSE);
1575 icmp_tree = proto_item_add_subtree(ti, ett_icmp);
1576 proto_tree_add_uint_format(icmp_tree, hf_icmp_type, tvb, 0, 1,
1579 icmp_type, type_str);
1580 proto_tree_add_uint_format(icmp_tree, hf_icmp_code, tvb, 1, 1,
1583 icmp_code, code_str);
1585 if (!pinfo->fragmented && length >= reported_length) {
1586 /* The packet isn't part of a fragmented datagram and isn't
1587 truncated, so we can checksum it. */
1589 computed_cksum = ip_checksum(tvb_get_ptr(tvb, 0, reported_length),
1591 if (computed_cksum == 0) {
1592 proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2,
1594 "Checksum: 0x%04x (correct)", cksum);
1596 proto_tree_add_item_hidden(icmp_tree, hf_icmp_checksum_bad,
1598 proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2,
1600 "Checksum: 0x%04x (incorrect, should be 0x%04x)",
1601 cksum, in_cksum_shouldbe(cksum, computed_cksum));
1604 proto_tree_add_uint(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum);
1607 /* Decode the second 4 bytes of the packet. */
1608 switch (icmp_type) {
1609 case ICMP_ECHOREPLY:
1612 case ICMP_TSTAMPREPLY:
1614 case ICMP_IREQREPLY:
1616 case ICMP_MASKREPLY:
1617 proto_tree_add_text(icmp_tree, tvb, 4, 2, "Identifier: 0x%04x",
1618 tvb_get_ntohs(tvb, 4));
1619 proto_tree_add_text(icmp_tree, tvb, 6, 2, "Sequence number: %02x:%02x",
1620 tvb_get_guint8(tvb, 6), tvb_get_guint8(tvb, 7));
1624 switch (icmp_code) {
1625 case ICMP_FRAG_NEEDED:
1626 proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u",
1627 tvb_get_ntohs(tvb, 6));
1632 case ICMP_RTRADVERT:
1633 num_addrs = tvb_get_guint8(tvb, 4);
1634 proto_tree_add_text(icmp_tree, tvb, 4, 1, "Number of addresses: %u",
1636 addr_entry_size = tvb_get_guint8(tvb, 5);
1637 proto_tree_add_text(icmp_tree, tvb, 5, 1, "Address entry size: %u",
1639 proto_tree_add_text(icmp_tree, tvb, 6, 2, "Lifetime: %s",
1640 time_secs_to_str(tvb_get_ntohs(tvb, 6)));
1643 case ICMP_PARAMPROB:
1644 proto_tree_add_text(icmp_tree, tvb, 4, 1, "Pointer: %u",
1645 tvb_get_guint8(tvb, 4));
1649 proto_tree_add_text(icmp_tree, tvb, 4, 4, "Gateway address: %s",
1650 ip_to_str(tvb_get_ptr(tvb, 4, 4)));
1654 /* Decode the additional information in the packet. */
1655 switch (icmp_type) {
1658 case ICMP_PARAMPROB:
1659 case ICMP_SOURCEQUENCH:
1661 /* Decode the IP header and first 64 bits of data from the
1664 XXX - for now, just display it as data; not all dissection
1665 routines can handle a short packet without exploding. */
1666 dissect_data(tvb, 8, pinfo, icmp_tree);
1669 case ICMP_ECHOREPLY:
1671 dissect_data(tvb, 8, pinfo, icmp_tree);
1674 case ICMP_RTRADVERT:
1675 if (addr_entry_size == 2) {
1676 for (i = 0; i < num_addrs; i++) {
1677 proto_tree_add_text(icmp_tree, tvb, 8 + (i*8), 4,
1678 "Router address: %s",
1679 ip_to_str(tvb_get_ptr(tvb, 8 + (i*8), 4)));
1680 proto_tree_add_text(icmp_tree, tvb, 12 + (i*8), 4,
1681 "Preference level: %u", tvb_get_ntohl(tvb, 12 + (i*8)));
1684 dissect_data(tvb, 8, pinfo, icmp_tree);
1688 case ICMP_TSTAMPREPLY:
1689 proto_tree_add_text(icmp_tree, tvb, 8, 4, "Originate timestamp: %u",
1690 tvb_get_ntohl(tvb, 8));
1691 proto_tree_add_text(icmp_tree, tvb, 12, 4, "Receive timestamp: %u",
1692 tvb_get_ntohl(tvb, 12));
1693 proto_tree_add_text(icmp_tree, tvb, 16, 4, "Transmit timestamp: %u",
1694 tvb_get_ntohl(tvb, 16));
1698 case ICMP_MASKREPLY:
1699 proto_tree_add_text(icmp_tree, tvb, 8, 4, "Address mask: %s (0x%08x)",
1700 ip_to_str(tvb_get_ptr(tvb, 8, 4)), tvb_get_ntohl(tvb, 8));
1707 proto_register_ip(void)
1709 static hf_register_info hf[] = {
1712 { "Version", "ip.version", FT_UINT8, BASE_DEC, NULL, 0x0,
1716 { "Header Length", "ip.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1720 { "Differentiated Services field", "ip.dsfield", FT_UINT8, BASE_DEC, NULL, 0x0,
1723 { &hf_ip_dsfield_dscp,
1724 { "Differentiated Services Codepoint", "ip.dsfield.dscp", FT_UINT8, BASE_HEX,
1725 VALS(dscp_vals), IPDSFIELD_DSCP_MASK,
1728 { &hf_ip_dsfield_ect,
1729 { "ECN-Capable Transport (ECT)", "ip.dsfield.ect", FT_UINT8, BASE_DEC, NULL,
1733 { &hf_ip_dsfield_ce,
1734 { "ECN-CE", "ip.dsfield.ce", FT_UINT8, BASE_DEC, NULL,
1739 { "Type of Service", "ip.tos", FT_UINT8, BASE_DEC, NULL, 0x0,
1742 { &hf_ip_tos_precedence,
1743 { "Precedence", "ip.tos.precedence", FT_UINT8, BASE_DEC, VALS(precedence_vals),
1748 { "Delay", "ip.tos.delay", FT_BOOLEAN, 8, TFS(&tos_set_low),
1752 { &hf_ip_tos_throughput,
1753 { "Throughput", "ip.tos.throughput", FT_BOOLEAN, 8, TFS(&tos_set_high),
1757 { &hf_ip_tos_reliability,
1758 { "Reliability", "ip.tos.reliability", FT_BOOLEAN, 8, TFS(&tos_set_high),
1763 { "Cost", "ip.tos.cost", FT_BOOLEAN, 8, TFS(&tos_set_low),
1768 { "Total Length", "ip.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1772 { "Identification", "ip.id", FT_UINT16, BASE_HEX, NULL, 0x0,
1776 { "Destination", "ip.dst", FT_IPv4, BASE_NONE, NULL, 0x0,
1780 { "Source", "ip.src", FT_IPv4, BASE_NONE, NULL, 0x0,
1784 { "Source or Destination Address", "ip.addr", FT_IPv4, BASE_NONE, NULL, 0x0,
1788 { "Flags", "ip.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1792 { "Don't fragment", "ip.flags.df", FT_BOOLEAN, 4, TFS(&flags_set_truth), IP_DF>>12,
1796 { "More fragments", "ip.flags.mf", FT_BOOLEAN, 4, TFS(&flags_set_truth), IP_MF>>12,
1799 { &hf_ip_frag_offset,
1800 { "Fragment offset", "ip.frag_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
1804 { "Time to live", "ip.ttl", FT_UINT8, BASE_DEC, NULL, 0x0,
1808 { "Protocol", "ip.proto", FT_UINT8, BASE_HEX, NULL, 0x0,
1812 { "Header checksum", "ip.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1815 { &hf_ip_checksum_bad,
1816 { "Bad Header checksum", "ip.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1819 { &hf_ip_fragment_overlap,
1820 { "Fragment overlap", "ip.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1821 "Fragment overlaps with other fragments" }},
1823 { &hf_ip_fragment_overlap_conflict,
1824 { "Conflicting data in fragment overlap", "ip.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1825 "Overlapping fragments contained conflicting data" }},
1827 { &hf_ip_fragment_multiple_tails,
1828 { "Multiple tail fragments found", "ip.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1829 "Several tails were found when defragmenting the packet" }},
1831 { &hf_ip_fragment_too_long_fragment,
1832 { "Fragment too long", "ip.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1833 "Fragment contained data past end of packet" }},
1835 { &hf_ip_fragment_error,
1836 { "Defragmentation error", "ip.fragment.error", FT_NONE, BASE_NONE, NULL, 0x0,
1837 "Defragmentation error due to illegal fragments" }},
1840 { "IP Fragment", "ip.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
1844 { "IP Fragments", "ip.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
1847 static gint *ett[] = {
1854 &ett_ip_option_route,
1855 &ett_ip_option_timestamp,
1859 module_t *ip_module;
1861 proto_ip = proto_register_protocol("Internet Protocol", "IP", "ip");
1862 proto_register_field_array(proto_ip, hf, array_length(hf));
1863 proto_register_subtree_array(ett, array_length(ett));
1865 /* subdissector code */
1866 ip_dissector_table = register_dissector_table("ip.proto");
1868 /* Register a configuration option for decoding TOS as DSCP */
1869 ip_module = prefs_register_protocol(proto_ip, NULL);
1870 prefs_register_bool_preference(ip_module, "decode_tos_as_diffserv",
1871 "Decode IPv4 TOS field as DiffServ field",
1872 "Whether the IPv4 type-of-service field should be decoded as a Differentiated Services field",
1874 prefs_register_bool_preference(ip_module, "defragment",
1875 "Reassemble fragmented IP datagrams",
1876 "Whether fragmented IP datagrams should be reassembled",
1878 prefs_register_bool_preference(ip_module, "ip_summary_in_tree",
1879 "Show IP summary in protocol tree",
1880 "Whether the IP summary line should be shown in the protocol tree",
1881 &ip_summary_in_tree);
1883 register_dissector("ip", dissect_ip, proto_ip);
1884 register_init_routine(ip_defragment_init);
1888 proto_reg_handoff_ip(void)
1890 dissector_add("ethertype", ETHERTYPE_IP, dissect_ip, proto_ip);
1891 dissector_add("ppp.protocol", PPP_IP, dissect_ip, proto_ip);
1892 dissector_add("ppp.protocol", ETHERTYPE_IP, dissect_ip, proto_ip);
1893 dissector_add("gre.proto", ETHERTYPE_IP, dissect_ip, proto_ip);
1894 dissector_add("gre.proto", GRE_WCCP, dissect_ip, proto_ip);
1895 dissector_add("llc.dsap", SAP_IP, dissect_ip, proto_ip);
1896 dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip, proto_ip);
1897 dissector_add("null.type", BSD_AF_INET, dissect_ip, proto_ip);
1898 dissector_add("chdlctype", ETHERTYPE_IP, dissect_ip, proto_ip);
1899 dissector_add("fr.ietf", NLPID_IP, dissect_ip, proto_ip);
1903 proto_register_icmp(void)
1905 static hf_register_info hf[] = {
1908 { "Type", "icmp.type", FT_UINT8, BASE_DEC, NULL, 0x0,
1912 { "Code", "icmp.code", FT_UINT8, BASE_HEX, NULL, 0x0,
1915 { &hf_icmp_checksum,
1916 { "Checksum", "icmp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1919 { &hf_icmp_checksum_bad,
1920 { "Bad Checksum", "icmp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1923 static gint *ett[] = {
1927 proto_icmp = proto_register_protocol("Internet Control Message Protocol",
1929 proto_register_field_array(proto_icmp, hf, array_length(hf));
1930 proto_register_subtree_array(ett, array_length(ett));
1934 proto_reg_handoff_icmp(void)
1936 dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp, proto_icmp);