FIXUP: WIP: verification_trailer
[wireshark-wip.git] / epan / dissectors / packet-lisp.c
blob9f17831f13b936fd7044dd22c286fd794f12dc03
1 /* packet-lisp.c
2 * Routines for Locator/ID Separation Protocol (LISP) Control Message dissection
3 * Copyright 2011, Lorand Jakab <lj@lispmon.net>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24 * USA.
27 #include "config.h"
29 #include <epan/packet.h>
30 #include <epan/to_str.h>
31 #include <epan/afn.h>
32 #include <epan/ipv6-utils.h>
33 #include <epan/expert.h>
34 #include <epan/wmem/wmem.h>
36 #define INET_ADDRLEN 4
37 #define INET6_ADDRLEN 16
40 * See RFC 6830 "Locator/ID Separation Protocol (LISP)",
41 * draft-ietf-lisp-lcaf-02 "LISP Canonical Address Format (LCAF)",
42 * draft-ietf-lisp-sec-04 "LISP-Security (LISP-SEC)", and
43 * draft-ermagan-lisp-nat-traversal-03 "NAT traversal for LISP" for packet
44 * format and protocol information.
47 #define LCAF_DRAFT_VERSION 10
48 #define LISP_CONTROL_PORT 4342
50 /* LISP Control Message types */
51 #define LISP_MAP_REQUEST 1
52 #define LISP_MAP_REPLY 2
53 #define LISP_MAP_REGISTER 3
54 #define LISP_MAP_NOTIFY 4
55 #define LISP_MAP_REFERRAL 6
56 #define LISP_INFO 7
57 #define LISP_ECM 8
59 #define LISP_ACT_NONE 0
60 #define LISP_ACT_FWD_NATIVE 1
61 #define LISP_ACT_MREQ 2
62 #define LISP_ACT_DROP 3
64 #define DDT_NODE_REF 0
65 #define DDT_MS_REF 1
66 #define DDT_MS_ACK 2
67 #define DDT_MS_NREG 3
68 #define DDT_DLGT_HOLE 4
69 #define DDT_NAUTH 5
71 #define LCAF_NULL 0
72 #define LCAF_AFI_LIST 1
73 #define LCAF_IID 2
74 #define LCAF_ASN 3
75 #define LCAF_APP_DATA 4
76 #define LCAF_GEO 5
77 #define LCAF_OKEY 6
78 #define LCAF_NATT 7
79 #define LCAF_NONCE_LOC 8
80 #define LCAF_MCAST_INFO 9
81 #define LCAF_ELP 10
82 #define LCAF_SEC_KEY 11
83 #define LCAF_SRC_DST_KEY 12
85 #define LCAF_HEADER_LEN 6
86 #define LISP_ECM_HEADER_LEN 4
87 #define LISP_XTRID_LEN 16
88 #define LISP_SITEID_LEN 8
90 #define LISP_MAP_ACT 0xE000
91 #define LISP_MAP_AUTH 0x1000
92 #define REFERRAL_INCOMPLETE 0x0800
93 #define LOCAL_BIT_MASK 0x0004
94 #define PROBE_BIT_MASK 0x0002
95 #define REACH_BIT_MASK 0x0001
97 #define MAP_REQ_FLAG_A 0x080000
98 #define MAP_REQ_FLAG_M 0x040000
99 #define MAP_REQ_FLAG_P 0x020000
100 #define MAP_REQ_FLAG_S 0x010000
101 #define MAP_REQ_FLAG_p 0x008000
102 #define MAP_REQ_FLAG_s 0x004000
103 #define MAP_REQ_RESERVED 0x003FE0
105 #define MAP_REP_FLAG_P 0x080000
106 #define MAP_REP_FLAG_E 0x040000
107 #define MAP_REP_FLAG_S 0x020000
108 #define MAP_REP_RESERVED 0x01FFFF
110 #define MAP_REG_FLAG_P 0x080000
111 #define MAP_REG_FLAG_S 0x040000
112 #define MAP_REG_FLAG_I 0x020000
113 #define MAP_REG_FLAG_R 0x010000
114 #define MAP_REG_RESERVED 0x00FFFE
115 #define MAP_REG_FLAG_M 0x000001
117 #define MAP_NOT_FLAG_I 0x080000
118 #define MAP_NOT_FLAG_R 0x040000
119 #define MAP_NOT_RESERVED 0x03FFFF
121 #define MAP_REF_RESERVED 0x0FFFFF
123 #define INFO_FLAG_R 0x080000
124 #define INFO_RESERVED 0x07FFFFFF
126 #define ECM_FLAG_S 0x08000000
127 #define ECM_FLAG_D 0x04000000
129 /* Initialize the protocol and registered fields */
130 static int proto_lisp = -1;
131 static int hf_lisp_type = -1;
132 static int hf_lisp_irc = -1;
133 static int hf_lisp_records = -1;
134 static int hf_lisp_nonce = -1;
135 static int hf_lisp_keyid = -1;
136 static int hf_lisp_authlen = -1;
137 static int hf_lisp_auth = -1;
138 static int hf_lisp_msrtr_keyid = -1;
139 static int hf_lisp_msrtr_authlen = -1;
140 static int hf_lisp_msrtr_auth = -1;
141 static int hf_lisp_xtrid = -1;
142 static int hf_lisp_siteid = -1;
144 /* Map-Request fields */
145 static int hf_lisp_mreq_flags = -1;
146 static int hf_lisp_mreq_flags_auth = -1;
147 static int hf_lisp_mreq_flags_mrp = -1;
148 static int hf_lisp_mreq_flags_probe = -1;
149 static int hf_lisp_mreq_flags_smr = -1;
150 static int hf_lisp_mreq_flags_pitr = -1;
151 static int hf_lisp_mreq_flags_smri = -1;
152 static int hf_lisp_mreq_res = -1;
153 static int hf_lisp_mreq_srceid_afi = -1;
154 static int hf_lisp_mreq_srceid_string = -1;
155 static int hf_lisp_mreq_srceid_ipv4 = -1;
156 static int hf_lisp_mreq_srceid_ipv6 = -1;
157 static int hf_lisp_mreq_srceid_lacf = -1;
158 static int hf_lisp_mreq_itr_rloc = -1;
159 static int hf_lisp_mreq_itr_rloc_afi = -1;
160 static int hf_lisp_mreq_srcitr = -1;
161 static int hf_lisp_mreq_srcitrv6 = -1;
162 static int hf_lisp_mreq_record = -1;
163 static int hf_lisp_mreq_record_reserved = -1;
164 static int hf_lisp_mreq_record_prefix_length = -1;
165 static int hf_lisp_mreq_record_prefix_afi = -1;
166 static int hf_lisp_mreq_record_prefix_ipv4 = -1;
167 static int hf_lisp_mreq_record_prefix_ipv6 = -1;
168 static int hf_lisp_mreq_record_prefix_lcaf = -1;
170 /* Map-Reply fields */
171 static int hf_lisp_mrep_flags_probe = -1;
172 static int hf_lisp_mrep_flags_enlr = -1;
173 static int hf_lisp_mrep_flags_sec = -1;
174 static int hf_lisp_mrep_res = -1;
176 /* Map-Register fields */
177 static int hf_lisp_mreg_flags_pmr = -1;
178 static int hf_lisp_mreg_flags_sec = -1;
179 static int hf_lisp_mreg_flags_xtrid = -1;
180 static int hf_lisp_mreg_flags_rtr = -1;
181 static int hf_lisp_mreg_flags_wmn = -1;
182 static int hf_lisp_mreg_res = -1;
184 /* Map-Notify fields */
185 static int hf_lisp_mnot_flags_xtrid = -1;
186 static int hf_lisp_mnot_flags_rtr = -1;
187 static int hf_lisp_mnot_res = -1;
189 /* Map-Referral fields */
190 static int hf_lisp_mref_res = -1;
191 static int hf_lisp_referral_sigcnt = -1;
192 static int hf_lisp_referral_incomplete = -1;
194 /* Info fields */
195 static int hf_lisp_info_r = -1;
196 static int hf_lisp_info_res1 = -1;
197 static int hf_lisp_info_ttl = -1;
198 static int hf_lisp_info_res2 = -1;
199 static int hf_lisp_info_afi = -1;
201 /* Mapping record fields */
202 static int hf_lisp_mapping = -1;
203 static int hf_lisp_mapping_ttl = -1;
204 static int hf_lisp_mapping_loccnt = -1;
205 static int hf_lisp_mapping_eid_masklen = -1;
206 static int hf_lisp_mapping_act = -1;
207 static int hf_lisp_mapping_auth = -1;
208 static int hf_lisp_mapping_res1 = -1;
209 static int hf_lisp_mapping_res2 = -1;
210 static int hf_lisp_mapping_ver = -1;
211 static int hf_lisp_mapping_eid_afi = -1;
212 static int hf_lisp_mapping_eid = -1;
214 /* Locator fields */
215 static int hf_lisp_loc = -1;
216 static int hf_lisp_loc_priority = -1;
217 static int hf_lisp_loc_weight = -1;
218 static int hf_lisp_loc_mpriority = -1;
219 static int hf_lisp_loc_mweight = -1;
220 static int hf_lisp_loc_flags = -1;
221 static int hf_lisp_loc_flags_local = -1;
222 static int hf_lisp_loc_flags_probe = -1;
223 static int hf_lisp_loc_flags_reach = -1;
224 static int hf_lisp_loc_flags_rsv = -1;
225 static int hf_lisp_loc_afi = -1;
226 static int hf_lisp_loc_locator = -1;
228 /* LCAF fields */
229 static int hf_lisp_lcaf_res1 = -1;
230 static int hf_lisp_lcaf_flags = -1;
231 static int hf_lisp_lcaf_type = -1;
232 static int hf_lisp_lcaf_res2 = -1;
233 static int hf_lisp_lcaf_length = -1;
235 /* LCAF IID fields */
236 static int hf_lisp_lcaf_iid = -1;
238 /* LCAF NATT fields */
239 static int hf_lisp_lcaf_natt_msport = -1;
240 static int hf_lisp_lcaf_natt_etrport = -1;
242 /* Encapsulated Control Message fields */
243 static int hf_lisp_ecm_flags_sec = -1;
244 static int hf_lisp_ecm_flags_ddt = -1;
245 static int hf_lisp_ecm_res = -1;
247 /* Initialize the subtree pointers */
248 static gint ett_lisp = -1;
249 static gint ett_lisp_mr = -1;
250 static gint ett_lisp_mreq_flags = -1;
251 static gint ett_lisp_mapping = -1;
252 static gint ett_lisp_itr = -1;
253 static gint ett_lisp_record = -1;
254 static gint ett_lisp_lcaf = -1;
255 static gint ett_lisp_loc = -1;
256 static gint ett_lisp_loc_flags = -1;
257 static gint ett_lisp_elp = -1;
259 static expert_field ei_lisp_undecoded = EI_INIT;
260 static expert_field ei_lisp_lcaf_type = EI_INIT;
261 static expert_field ei_lisp_expected_field = EI_INIT;
262 static expert_field ei_lisp_unexpected_field = EI_INIT;
264 static dissector_handle_t lisp_handle;
266 static dissector_handle_t ipv4_handle;
267 static dissector_handle_t ipv6_handle;
268 static dissector_handle_t data_handle;
270 static gboolean encapsulated = FALSE;
271 static gboolean ddt_originated = FALSE;
273 const value_string lisp_typevals[] = {
274 { LISP_MAP_REQUEST, "Map-Request" },
275 { LISP_MAP_REPLY, "Map-Reply" },
276 { LISP_MAP_REGISTER, "Map-Register" },
277 { LISP_MAP_NOTIFY, "Map-Notify" },
278 { LISP_MAP_REFERRAL, "Map-Referral" },
279 { LISP_INFO, "Info" },
280 { LISP_ECM, "Encapsulated Control Message" },
281 { 0, NULL}
284 const value_string mapping_actions[] = {
285 { LISP_ACT_NONE, "No-Action" },
286 { LISP_ACT_FWD_NATIVE, "Natively-Forward" },
287 { LISP_ACT_MREQ, "Send-Map-Request" },
288 { LISP_ACT_DROP, "Drop" },
289 { 0, NULL}
292 const value_string referral_actions[] = {
293 { DDT_NODE_REF, "Node Referral" },
294 { DDT_MS_REF, "Map-Server Referral" },
295 { DDT_MS_ACK, "Map-Server ACK" },
296 { DDT_MS_NREG, "Map-Server Not Registered" },
297 { DDT_DLGT_HOLE, "Delegation Hole" },
298 { DDT_NAUTH, "Not Authoritative" },
299 { 0, NULL}
302 const value_string lcaf_typevals[] = {
303 { LCAF_NULL, "Null Body" },
304 { LCAF_AFI_LIST, "AFI List" },
305 { LCAF_IID, "Instance ID" },
306 { LCAF_ASN, "AS Number" },
307 { LCAF_APP_DATA, "Application Data" },
308 { LCAF_GEO, "Geo Coordinates" },
309 { LCAF_OKEY, "Opaque Key" },
310 { LCAF_NATT, "NAT Traversal" },
311 { LCAF_NONCE_LOC, "Nonce Locator" },
312 { LCAF_MCAST_INFO, "Multicast Info" },
313 { LCAF_ELP, "Explicit Locator Path" },
314 { LCAF_SEC_KEY, "Security Key" },
315 { LCAF_SRC_DST_KEY, "Source/Dest Key" },
316 { 0, NULL}
320 static int
321 dissect_lcaf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset);
323 static int
324 get_lcaf_data(tvbuff_t *tvb, gint offset, guint8 *lcaf_type, guint16 *len)
326 /* Jump over Rsvd1 and Flags (16 bits) */
327 offset += 2;
329 /* Type (8 bits) */
330 if (lcaf_type)
331 *lcaf_type = tvb_get_guint8(tvb, offset);
332 offset += 1;
334 /* Jump over Rsvd2 bits (8 bits) */
335 offset += 1;
337 /* Length (16 bits) */
338 if (len)
339 /* Adding the size of the LCAF header as well */
340 *len = tvb_get_ntohs(tvb, offset) + LCAF_HEADER_LEN;
341 offset += 2;
343 return offset;
346 static const gchar *
347 get_addr_str(tvbuff_t *tvb, gint offset, guint16 afi, guint16 *addr_len)
349 const gchar *notset_str = "not set";
350 const gchar *addr_str;
351 guint32 locator_v4;
352 struct e_in6_addr locator_v6;
353 guint8 lcaf_type;
354 guint32 iid;
355 guint16 cur_len;
357 switch (afi) {
358 case AFNUM_RESERVED:
359 *addr_len = 0;
360 return notset_str;
361 case AFNUM_INET:
362 locator_v4 = tvb_get_ipv4(tvb, offset);
363 *addr_len = INET_ADDRLEN;
364 addr_str = ip_to_str((guint8 *)&locator_v4);
365 return addr_str;
366 case AFNUM_INET6:
367 tvb_get_ipv6(tvb, offset, &locator_v6);
368 *addr_len = INET6_ADDRLEN;
369 addr_str = ip6_to_str(&locator_v6);
370 return addr_str;
371 case AFNUM_LCAF:
372 get_lcaf_data(tvb, offset, &lcaf_type, addr_len);
373 addr_str = val_to_str(lcaf_type, lcaf_typevals, "Unknown LCAF Type (%d)");
374 if (lcaf_type == LCAF_IID) {
375 iid = tvb_get_ntohl(tvb, offset + LCAF_HEADER_LEN);
376 afi = tvb_get_ntohs(tvb, offset + LCAF_HEADER_LEN + 4);
377 addr_str = get_addr_str(tvb, offset + LCAF_HEADER_LEN + 6, afi, &cur_len);
378 return wmem_strdup_printf(wmem_packet_scope(), "[%d] %s", iid, addr_str);
380 return addr_str;
381 default:
382 return NULL;
386 static int
387 dissect_lcaf_natt_rloc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
388 gint offset, const gchar *str, int idx)
390 guint16 addr_len = 0;
391 guint16 rloc_afi;
392 const gchar *rloc_str;
394 rloc_afi = tvb_get_ntohs(tvb, offset); offset += 2;
395 rloc_str = get_addr_str(tvb, offset, rloc_afi, &addr_len);
397 if (rloc_str == NULL) {
398 expert_add_info_format(pinfo, tree, &ei_lisp_unexpected_field,
399 "Unexpected RLOC AFI (%d), cannot decode", rloc_afi);
400 return offset;
403 if (idx) {
404 proto_tree_add_text(tree, tvb, offset - 2, 2 + addr_len, str, idx, rloc_str);
405 } else {
406 proto_tree_add_text(tree, tvb, offset - 2, 2 + addr_len, str, rloc_str);
409 return addr_len + 2;
412 static int
413 dissect_lcaf_elp_hop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
414 gint offset, int idx)
416 guint16 addr_len = 0;
417 guint16 hop_afi;
418 guint16 hop_flags;
419 const gchar *hop_str;
420 proto_item *ti;
422 hop_afi = tvb_get_ntohs(tvb, offset); offset += 2;
423 hop_flags = tvb_get_ntohs(tvb, offset); offset += 2;
424 hop_str = get_addr_str(tvb, offset, hop_afi, &addr_len);
426 if (hop_str == NULL) {
427 expert_add_info_format(pinfo, tree, &ei_lisp_unexpected_field,
428 "Unexpected reencap hop AFI (%d), cannot decode", hop_afi);
429 return offset;
432 if (idx) {
433 ti = proto_tree_add_text(tree, tvb, offset - 4, addr_len + 4, "Reencap hop %d: %s", idx, hop_str);
434 } else {
435 ti = proto_tree_add_text(tree, tvb, offset - 4, addr_len + 4, "Reencap hop: %s", hop_str);
437 if (hop_flags & 0x04)
438 proto_item_append_text(ti, ", Lookup");
439 if (hop_flags & 0x02)
440 proto_item_append_text(ti, ", RLOC-Probe");
441 if (hop_flags & 0x01)
442 proto_item_append_text(ti, ", Strict");
444 return addr_len + 4;
449 * Dissector code for AFI List
453 static int
454 dissect_lcaf_afi_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
455 gint offset, guint16 length)
457 gint old_offset;
458 gint remaining = length;
459 gint i = 1;
461 guint16 addr_len = 0;
462 guint16 afi;
463 guint32 ipv4;
464 struct e_in6_addr ipv6;
465 const gchar *lcaf_str;
466 proto_item *tir;
467 proto_tree *lisp_elp_tree;
469 while (remaining > 0) {
470 afi = tvb_get_ntohs(tvb, offset); offset += 2; remaining -= 2;
472 switch (afi) {
473 case AFNUM_INET:
474 ipv4 = tvb_get_ipv4(tvb, offset);
475 proto_tree_add_text(tree, tvb, offset - 2, 2 + INET_ADDRLEN,
476 "%d. IPv4 Addess: %s", i, ip_to_str((guint8 *)&ipv4));
477 offset += INET_ADDRLEN;
478 remaining -= INET_ADDRLEN;
479 break;
480 case AFNUM_INET6:
481 tvb_get_ipv6(tvb, offset, &ipv6);
482 proto_tree_add_text(tree, tvb, offset - 2, 2 + INET6_ADDRLEN,
483 "%d. IPv6 Addess: %s", i, ip6_to_str(&ipv6));
484 offset += INET6_ADDRLEN;
485 remaining -= INET6_ADDRLEN;
486 break;
487 case AFNUM_LCAF:
488 old_offset = offset;
489 lcaf_str = get_addr_str(tvb, offset, afi, &addr_len);
490 tir = proto_tree_add_text(tree, tvb, offset - 2, 2 + addr_len,
491 "%d. %s", i, lcaf_str);
492 /* XXX need to check LCAF type */
493 lisp_elp_tree = proto_item_add_subtree(tir, ett_lisp_elp);
494 offset = dissect_lcaf(tvb, pinfo, lisp_elp_tree, offset);
495 remaining -= (offset - old_offset);
496 break;
497 default:
498 expert_add_info_format(pinfo, tree, &ei_lisp_unexpected_field,
499 "Unexpected AFI (%d), cannot decode", afi);
500 return -1;
502 i++;
505 return offset;
510 * Dissector code for Instance ID
512 * 0 1 2 3
513 * 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
514 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
515 * | AFI = 16387 | Rsvd1 | Flags |
516 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
517 * | Type = 2 | Rsvd2 | 4 + n |
518 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
519 * | Instance ID |
520 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
521 * | AFI = x | Address ... |
522 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
526 static int
527 dissect_lcaf_iid(tvbuff_t *tvb, proto_tree *tree, gint offset)
529 /* For now, we don't print reserved and length fields */
530 offset += 3;
532 proto_tree_add_item(tree, hf_lisp_lcaf_iid, tvb, offset, 4, ENC_BIG_ENDIAN);
533 offset += 4;
534 return offset;
539 * Dissector code for NAT-Traversal
541 * 0 1 2 3
542 * 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
543 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
544 * | AFI = 16387 | Rsvd1 | Flags |
545 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
546 * | Type = 7 | Rsvd2 | 4 + n |
547 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
548 * | MS UDP Port Number | ETR UDP Port Number |
549 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
550 * | AFI = x | Global ETR RLOC Address ... |
551 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
552 * | AFI = x | MS RLOC Address ... |
553 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
554 * | AFI = x | Private ETR RLOC Address ... |
555 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
556 * | AFI = x | RTR RLOC Address 1 ... |
557 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
558 * | AFI = x | RTR RLOC Address n ... |
559 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
563 static int
564 dissect_lcaf_natt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
565 gint offset, guint16 length)
567 gint i;
568 gint len;
569 gint remaining = length;
570 const gchar *global_etr = "Global ETR RLOC: %s";
571 const gchar *ms = "MS RLOC: %s";
572 const gchar *private_etr = "Private ETR RLOC: %s";
573 const gchar *rtr = "RTR RLOC %d: %s";
575 remaining -= 4;
577 proto_tree_add_item(tree, hf_lisp_lcaf_natt_msport, tvb, offset, 2, ENC_BIG_ENDIAN);
578 offset += 2;
579 remaining -= 2;
580 proto_tree_add_item(tree, hf_lisp_lcaf_natt_etrport, tvb, offset, 2, ENC_BIG_ENDIAN);
581 offset += 2;
582 remaining -= 2;
584 len = dissect_lcaf_natt_rloc(tvb, pinfo, tree, offset, global_etr, 0);
585 offset += len;
586 remaining -= len;
588 len = dissect_lcaf_natt_rloc(tvb, pinfo, tree, offset, ms, 0);
589 offset += len;
590 remaining -= len;
592 len = dissect_lcaf_natt_rloc(tvb, pinfo, tree, offset, private_etr, 0);
593 offset += len;
594 remaining -= len;
596 i = 1;
597 while (remaining > 0) {
598 len = dissect_lcaf_natt_rloc(tvb, pinfo, tree, offset, rtr, i);
599 offset += len;
600 remaining -= len;
601 i++;
604 return offset;
609 * Dissector code for Explicit Locator Path
611 * 0 1 2 3
612 * 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
613 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
614 * | AFI = 16387 | Rsvd1 | Flags |
615 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
616 * | Type = 10 | Rsvd2 | n |
617 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
618 * | AFI = x | Rsvd3 |L|P|S|
619 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
620 * | Reencap Hop 1 ... |
621 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
622 * | AFI = x | Rsvd3 |L|P|S|
623 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
624 * | Reencap Hop k ... |
625 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
629 static int
630 dissect_lcaf_elp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
631 gint offset, guint16 length)
633 gint len;
634 gint remaining = length;
635 gint i = 1;
637 while (remaining > 0) {
638 len = dissect_lcaf_elp_hop(tvb, pinfo, tree, offset, i);
639 offset += len;
640 remaining -= len;
641 i++;
644 return offset;
649 * Dissector code for LISP Canonical Address Format (LCAF)
651 * 0 1 2 3
652 * 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
653 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
654 * | AFI = 16387 | Rsvd1 | Flags |
655 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
656 * | Type | Rsvd2 | Length |
657 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
659 * Type 0: Null Body Type
660 * Type 1: AFI List Type
661 * Type 2: Instance ID Type
662 * Type 3: AS Number Type
663 * Type 4: Application Data Type
664 * Type 5: Geo Coordinates Type
665 * Type 6: Opaque Key Type
666 * Type 7: NAT-Traversal Type
667 * Type 8: Nonce Locator Type
668 * Type 9: Multicast Info Type
669 * Type 10: Explicit Locator Path Type
670 * Type 11: Security Key Type
671 * Type 12: Source/Dest Key Type
675 static int
676 dissect_lcaf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
678 guint8 lcaf_type;
679 guint16 len;
680 proto_item *tir;
681 proto_tree *lcaf_tree;
683 lcaf_type = tvb_get_guint8(tvb, offset + 2);
684 len = tvb_get_ntohs(tvb, offset + 4);
686 tir = proto_tree_add_text(tree, tvb, offset, 6,
687 "LCAF Header (Type: %s, Length: %d bytes)",
688 val_to_str(lcaf_type, lcaf_typevals, "Unknown (%d)"),
689 len);
690 lcaf_tree = proto_item_add_subtree(tir, ett_lisp_lcaf);
692 /* Reserved bits (8 bits) */
693 proto_tree_add_item(lcaf_tree, hf_lisp_lcaf_res1, tvb, offset, 1, ENC_BIG_ENDIAN);
694 offset += 1;
696 /* Flags (8 bits) */
697 proto_tree_add_item(lcaf_tree, hf_lisp_lcaf_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
698 offset += 1;
700 /* Type (8 bits) */
701 proto_tree_add_item(lcaf_tree, hf_lisp_lcaf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
702 offset += 1;
704 /* Reserved bits (8 bits) */
705 proto_tree_add_item(lcaf_tree, hf_lisp_lcaf_res2, tvb, offset, 1, ENC_BIG_ENDIAN);
706 offset += 1;
708 /* Length (16 bits) */
709 proto_tree_add_item(lcaf_tree, hf_lisp_lcaf_length, tvb, offset, 2, ENC_BIG_ENDIAN);
710 offset += 2;
712 switch (lcaf_type) {
713 case LCAF_NULL:
714 break;
715 case LCAF_AFI_LIST:
716 offset = dissect_lcaf_afi_list(tvb, pinfo, tree, offset, len);
717 break;
718 case LCAF_IID:
719 offset = dissect_lcaf_iid(tvb, tree, offset);
720 break;
721 case LCAF_NATT:
722 offset = dissect_lcaf_natt(tvb, pinfo, tree, offset, len);
723 break;
724 case LCAF_ELP:
725 offset = dissect_lcaf_elp(tvb, pinfo, tree, offset, len);
726 break;
727 default:
728 if (lcaf_type < 13)
729 proto_tree_add_expert(tree, pinfo, &ei_lisp_undecoded, tvb, offset, len);
730 else
731 expert_add_info_format(pinfo, tree, &ei_lisp_lcaf_type,
732 "LCAF type %d is not defined in draft-farinacci-lisp-lcaf-%d",
733 lcaf_type, LCAF_DRAFT_VERSION);
734 return offset + len;
736 return offset;
741 * Dissector code for locator records within control packets
743 * 0 1 2 3
744 * 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
745 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
746 * | Priority | Weight | M Priority | M Weight |
747 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
748 * | Unused Flags |L|p|R| Loc-AFI |
749 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
750 * | Locator |
751 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
755 static int
756 dissect_lisp_locator(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_mapping_tree)
758 gint offset = 0;
759 guint16 addr_len = 0;
760 guint8 prio;
761 guint8 weight;
762 guint8 m_prio;
763 guint8 m_weight;
764 guint16 flags;
765 guint16 loc_afi;
766 const gchar *locator;
767 proto_item *tir, *ti_flags;
768 proto_tree *lisp_elp_tree, *lisp_loc_tree, *lisp_flags_tree;
770 tir = proto_tree_add_item(lisp_mapping_tree, hf_lisp_loc, tvb, offset, 8, ENC_NA);
772 lisp_loc_tree = proto_item_add_subtree(tir, ett_lisp_loc);
774 proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
775 prio = tvb_get_guint8(tvb, offset);
776 offset += 1;
778 proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_weight, tvb, offset, 1, ENC_BIG_ENDIAN);
779 weight = tvb_get_guint8(tvb, offset);
780 offset += 1;
782 proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_mpriority, tvb, offset, 1, ENC_BIG_ENDIAN);
783 m_prio = tvb_get_guint8(tvb, offset);
784 offset += 1;
786 proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_mweight, tvb, offset, 1, ENC_BIG_ENDIAN);
787 m_weight = tvb_get_guint8(tvb, offset);
788 offset += 1;
790 ti_flags = proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
791 lisp_flags_tree = proto_item_add_subtree(ti_flags, ett_lisp_loc_flags);
792 proto_tree_add_item(lisp_flags_tree, hf_lisp_loc_flags_reach, tvb, offset, 2, ENC_BIG_ENDIAN);
793 proto_tree_add_item(lisp_flags_tree, hf_lisp_loc_flags_probe, tvb, offset, 2, ENC_BIG_ENDIAN);
794 proto_tree_add_item(lisp_flags_tree, hf_lisp_loc_flags_local, tvb, offset, 2, ENC_BIG_ENDIAN);
795 proto_tree_add_item(lisp_flags_tree, hf_lisp_loc_flags_rsv, tvb, offset, 2, ENC_BIG_ENDIAN);
796 flags = tvb_get_ntohs(tvb, offset);
797 offset += 2;
799 proto_tree_add_item(lisp_loc_tree, hf_lisp_loc_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
800 loc_afi = tvb_get_ntohs(tvb, offset);
801 offset += 2;
803 locator = get_addr_str(tvb, offset, loc_afi, &addr_len);
805 if (locator == NULL) {
806 expert_add_info_format(pinfo, lisp_mapping_tree, &ei_lisp_unexpected_field,
807 "Unexpected locator AFI (%d), cannot decode", loc_afi);
808 return offset;
811 proto_tree_add_string(lisp_loc_tree, hf_lisp_loc_locator, tvb, offset, addr_len, locator);
813 if (loc_afi == AFNUM_LCAF) {
814 /* Create a sub-tree for the mapping */
815 lisp_elp_tree = proto_item_add_subtree(tir, ett_lisp_elp);
816 offset = dissect_lcaf(tvb, pinfo, lisp_elp_tree, offset);
817 } else {
818 offset += addr_len;
821 proto_item_append_text(tir, " %s%s, %s, Priority/Weight: %d/%d, Multicast Priority/Weight: %d/%d",
822 locator,
823 (flags&PROBE_BIT_MASK) ? " (probed)" : "",
824 (flags&REACH_BIT_MASK) ? "Reachable" : "Unreachable",
825 prio, weight, m_prio, m_weight);
826 proto_item_set_len(tir, 8 + addr_len);
828 return offset;
833 * Dissector code for mapping records within control packets
835 * 0 1 2 3
836 * 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
837 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
838 * | Record TTL |
839 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
840 * | Locator Count | EID mask-len | ACT |A| Reserved |
841 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
842 * | Rsvd | Map-Version Number | EID-AFI |
843 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
844 * | EID-prefix |
845 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
849 static int
850 dissect_lisp_mapping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
851 guint8 rec_cnt, gboolean referral)
853 int i;
854 gint offset = 0;
855 guint16 addr_len = 0;
856 guint8 prefix_mask, loc_cnt;
857 guint16 flags;
858 guint16 act;
859 guint16 prefix_afi;
860 const gchar *prefix;
861 proto_item *tir;
862 proto_tree *lisp_mapping_tree;
864 prefix_mask = tvb_get_guint8(tvb, 5);
865 flags = tvb_get_ntohs(tvb, 6);
866 prefix_afi = tvb_get_ntohs(tvb, 10);
868 act = flags & LISP_MAP_ACT;
869 act >>= 13;
871 prefix = get_addr_str(tvb, 12, prefix_afi, &addr_len);
873 if (prefix == NULL) {
874 expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
875 "Unexpected EID prefix AFI (%d), cannot decode", prefix_afi);
876 return offset;
878 tir = proto_tree_add_item(lisp_tree, hf_lisp_mapping, tvb, 0, 12 + addr_len, ENC_NA);
880 /* Update the INFO column if there is only one record */
881 if (rec_cnt == 1)
882 col_append_fstr(pinfo->cinfo, COL_INFO, " for %s/%d",
883 prefix, prefix_mask);
885 /* Create a sub-tree for the mapping */
886 lisp_mapping_tree = proto_item_add_subtree(tir, ett_lisp_mapping);
888 /* TTL (32 bits) */
889 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_ttl, tvb, offset, 4, ENC_BIG_ENDIAN);
890 if(tvb_get_ntohl(tvb, offset) == 0xFFFFFFFF){
891 proto_item_append_text(tir, " TTL: Unlimited");
892 }else{
893 proto_item_append_text(tir, " TTL: %d", tvb_get_ntohl(tvb, offset));
895 offset += 4;
897 /* Locator count (8 bits) */
898 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_loccnt, tvb, offset, 1, ENC_BIG_ENDIAN);
899 loc_cnt = tvb_get_guint8(tvb, offset);
900 offset += 1;
902 /* EID mask length (8 bits) */
903 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_eid_masklen, tvb, offset, 1, ENC_BIG_ENDIAN);
904 offset += 1;
906 /* Action (3 bits) */
907 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_act, tvb, offset, 2, ENC_BIG_ENDIAN);
908 proto_item_append_text(tir, " %s%s", val_to_str(act, (referral) ? referral_actions : mapping_actions, "Invalid action code (%d)"), (referral&&(flags&REFERRAL_INCOMPLETE)) ? " (Incomplete)" : "");
910 /* Authoritative bit */
911 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_auth, tvb, offset, 2, ENC_BIG_ENDIAN);
912 if(flags&LISP_MAP_AUTH){
913 proto_item_append_text(tir, ", Authoritative");
914 }else{
915 proto_item_append_text(tir, ", Not Authoritative");
917 /* Incomplete bit in Map-Referrals */
918 if (referral)
919 proto_tree_add_item(lisp_mapping_tree, hf_lisp_referral_incomplete, tvb, offset, 2, ENC_BIG_ENDIAN);
921 /* Reserved (11 bits) */
922 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_res1, tvb, offset, 2, ENC_BIG_ENDIAN);
923 offset += 2;
925 if (referral) {
926 /* SigCnt (4 bits) */
927 proto_tree_add_item(lisp_mapping_tree, hf_lisp_referral_sigcnt, tvb, offset, 2, ENC_BIG_ENDIAN);
928 } else {
929 /* Reserved (4 bits) */
930 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_res2, tvb, offset, 2, ENC_BIG_ENDIAN);
933 /* Map-Version Number (12 bits) */
934 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_ver, tvb, offset, 2, ENC_BIG_ENDIAN);
935 offset += 2;
937 /* EID prefix AFI (16 bits) */
938 proto_tree_add_item(lisp_mapping_tree, hf_lisp_mapping_eid_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
939 offset += 2;
941 /* EID */
942 proto_tree_add_string(lisp_mapping_tree, hf_lisp_mapping_eid, tvb, offset, addr_len, prefix);
943 proto_item_append_text(tir, ", EID Prefix: %s/%d", prefix, prefix_mask);
944 offset += addr_len;
946 /* Locators */
947 for(i=0; i < loc_cnt; i++) {
948 tvbuff_t *loc_tvb;
949 int len = 0;
951 loc_tvb = tvb_new_subset_remaining(tvb, offset);
952 len = dissect_lisp_locator(loc_tvb, pinfo, lisp_mapping_tree);
953 offset += len;
956 return offset;
961 * Dissector code for Map-Request type control packets
963 * 0 1 2 3
964 * 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
965 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
966 * |Type=1 |A|M|P|S|p|s| Reserved | IRC | Record Count |
967 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
968 * | Nonce . . . |
969 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
970 * | . . . Nonce |
971 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
972 * | Source-EID-AFI | Source EID Address ... |
973 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
974 * | ITR-RLOC-AFI 1 | ITR-RLOC Address 1 ... |
975 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
976 * | ... |
977 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
978 * | ITR-RLOC-AFI n | ITR-RLOC Address n ... |
979 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
980 * / | Reserved | EID mask-len | EID-prefix-AFI |
981 * Rec +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
982 * \ | EID-prefix ... |
983 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
984 * | Map-Reply Record ... |
985 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
989 static void
990 dissect_lisp_map_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
992 int i;
993 guint16 addr_len = 0;
994 gint offset = 0;
995 guint16 flags;
996 gboolean mrep = FALSE;
997 gboolean smr = FALSE;
998 gboolean probe = FALSE;
999 gboolean pitr = FALSE;
1000 gboolean smr_invoked = FALSE;
1001 guint8 itr_rec_cnt = 0;
1002 guint8 rec_cnt = 0;
1003 guint16 src_eid_afi;
1004 const gchar *src_eid;
1005 proto_item *ti_flags;
1006 proto_tree *flags_tree;
1007 tvbuff_t *next_tvb;
1009 /* Flags (6 bits)*/
1010 flags = tvb_get_ntohs(tvb, offset);
1011 mrep = flags & (MAP_REQ_FLAG_M >> 8);
1012 smr = flags & (MAP_REQ_FLAG_S >> 8);
1013 probe = flags & (MAP_REQ_FLAG_P >> 8);
1014 pitr = flags & (MAP_REQ_FLAG_p >> 8);
1015 smr_invoked = flags & (MAP_REQ_FLAG_s >> 8);
1017 ti_flags = proto_tree_add_item(lisp_tree, hf_lisp_mreq_flags, tvb, offset, 3, ENC_BIG_ENDIAN);
1018 flags_tree = proto_item_add_subtree(ti_flags, ett_lisp_mreq_flags);
1019 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_auth, tvb, offset, 3, ENC_BIG_ENDIAN);
1020 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_mrp, tvb, offset, 3, ENC_BIG_ENDIAN);
1021 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_probe, tvb, offset, 3, ENC_BIG_ENDIAN);
1022 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_smr, tvb, offset, 3, ENC_BIG_ENDIAN);
1023 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_pitr, tvb, offset, 3, ENC_BIG_ENDIAN);
1024 proto_tree_add_item(flags_tree, hf_lisp_mreq_flags_smri, tvb, offset, 3, ENC_BIG_ENDIAN);
1026 if (pitr)
1027 col_append_str(pinfo->cinfo, COL_INFO, " by P-ITR");
1029 if (smr)
1030 col_append_str(pinfo->cinfo, COL_INFO, " (SMR)");
1032 if (probe)
1033 col_append_str(pinfo->cinfo, COL_INFO, " (RLOC-probe)");
1035 if (smr_invoked)
1036 col_append_str(pinfo->cinfo, COL_INFO, " (SMR-invoked)");
1038 /* Reserved bits (9 bits) */
1039 proto_tree_add_item(flags_tree, hf_lisp_mreq_res, tvb, offset, 3, ENC_BIG_ENDIAN);
1041 /* ITR record count (5 bits) */
1042 itr_rec_cnt = tvb_get_guint8(tvb, offset + 2) & 0x1F;
1043 proto_tree_add_item(lisp_tree, hf_lisp_irc, tvb, offset, 3, ENC_BIG_ENDIAN);
1044 offset += 3;
1046 /* Record count (8 bits) */
1047 rec_cnt = tvb_get_guint8(tvb, offset);
1048 proto_tree_add_item(lisp_tree, hf_lisp_records, tvb, offset, 1, ENC_BIG_ENDIAN);
1049 offset += 1;
1051 /* Nonce (64 bits) */
1052 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1053 offset += 8;
1055 /* Source EID AFI (16 bits) */
1056 src_eid_afi = tvb_get_ntohs(tvb, offset);
1057 proto_tree_add_item(lisp_tree, hf_lisp_mreq_srceid_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
1058 offset += 2;
1060 /* Source EID */
1061 switch (src_eid_afi) {
1062 case AFNUM_RESERVED:
1063 proto_tree_add_string(lisp_tree, hf_lisp_mreq_srceid_string, tvb, offset, 0, "not set");
1064 break;
1065 case AFNUM_INET:
1066 proto_tree_add_item(lisp_tree,
1067 hf_lisp_mreq_srceid_ipv4, tvb, offset, INET_ADDRLEN, ENC_BIG_ENDIAN);
1068 offset += INET_ADDRLEN;
1069 break;
1070 case AFNUM_INET6:
1071 proto_tree_add_item(lisp_tree,
1072 hf_lisp_mreq_srceid_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
1073 offset += INET6_ADDRLEN;
1074 break;
1075 case AFNUM_LCAF:
1076 src_eid = get_addr_str(tvb, offset, src_eid_afi, &addr_len);
1077 proto_tree_add_string(lisp_tree, hf_lisp_mreq_srceid_lacf, tvb, offset, addr_len, src_eid);
1078 offset += addr_len;
1079 break;
1080 default:
1081 expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
1082 "Unexpected Source EID AFI (%d), cannot decode", src_eid_afi);
1083 next_tvb = tvb_new_subset_remaining(tvb, offset);
1084 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1085 return;
1088 /* ITR records */
1089 for(i=0; i < itr_rec_cnt+1; i++) {
1090 guint16 itr_afi;
1091 proto_item *tir;
1092 proto_tree *lisp_itr_tree;
1094 itr_afi = tvb_get_ntohs(tvb, offset);
1095 tir = proto_tree_add_item(lisp_tree, hf_lisp_mreq_itr_rloc, tvb, offset, 2, ENC_NA);
1096 lisp_itr_tree = proto_item_add_subtree(tir, ett_lisp_itr);
1097 proto_tree_add_item(lisp_itr_tree, hf_lisp_mreq_itr_rloc_afi, tvb, offset, 2, ENC_NA);
1098 offset += 2;
1100 switch (itr_afi) {
1101 case AFNUM_INET:
1102 proto_tree_add_item(lisp_itr_tree, hf_lisp_mreq_srcitr, tvb, offset, 4, ENC_BIG_ENDIAN);
1103 proto_item_append_text(tir, " %d: %s", i + 1, tvb_ip_to_str(tvb, offset));
1104 proto_item_set_len(tir, 2 + 4);
1105 offset += 4;
1106 break;
1107 case AFNUM_INET6:
1108 proto_tree_add_item(lisp_itr_tree, hf_lisp_mreq_srcitrv6, tvb, offset, 16, ENC_NA);
1109 proto_item_append_text(tir, " %d: %s", i + 1, tvb_ip6_to_str(tvb, offset));
1110 proto_item_set_len(tir, 2 + 16);
1111 offset += 16;
1112 break;
1113 default:
1114 expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
1115 "Unexpected ITR-RLOC-AFI (%d), cannot decode", itr_afi);
1116 next_tvb = tvb_new_subset_remaining(tvb, offset);
1117 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1118 return;
1122 /* Query records */
1123 for(i=0; i < rec_cnt; i++) {
1124 guint16 prefix_mask;
1125 guint16 prefix_afi;
1126 const gchar *prefix;
1127 proto_item *tir;
1128 proto_tree *lisp_record_tree;
1130 addr_len = 0;
1131 prefix_mask = tvb_get_guint8(tvb, offset + 1);
1132 prefix_afi = tvb_get_ntohs(tvb, offset + 2);
1133 prefix = get_addr_str(tvb, offset + 4, prefix_afi, &addr_len);
1135 if (prefix == NULL) {
1136 expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
1137 "Unexpected EID prefix AFI (%d), cannot decode", prefix_afi);
1138 next_tvb = tvb_new_subset_remaining(tvb, offset);
1139 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1140 return;
1143 tir = proto_tree_add_item(lisp_tree, hf_lisp_mreq_record, tvb, offset, 4+addr_len, ENC_NA);
1145 /* Update the INFO column if there is only one record */
1146 if (rec_cnt == 1)
1147 col_append_fstr(pinfo->cinfo, COL_INFO, " for %s/%d", prefix, prefix_mask);
1149 lisp_record_tree = proto_item_add_subtree(tir, ett_lisp_record);
1150 proto_tree_add_item(lisp_record_tree, hf_lisp_mreq_record_reserved, tvb, offset, 1, ENC_NA);
1151 offset += 1;
1153 proto_tree_add_item(lisp_record_tree, hf_lisp_mreq_record_prefix_length, tvb, offset, 1, ENC_NA);
1154 offset += 1;
1156 proto_tree_add_item(lisp_record_tree, hf_lisp_mreq_record_prefix_afi, tvb, offset, 2, ENC_NA);
1157 offset += 2;
1159 switch(prefix_afi){
1160 case AFNUM_INET:
1161 proto_tree_add_item(lisp_record_tree, hf_lisp_mreq_record_prefix_ipv4, tvb, offset, 4, ENC_NA);
1162 offset += 4;
1163 break;
1164 case AFNUM_INET6:
1165 proto_tree_add_item(lisp_record_tree, hf_lisp_mreq_record_prefix_ipv6, tvb, offset, 16, ENC_NA);
1166 offset += 16;
1167 break;
1168 case AFNUM_LCAF:
1169 proto_tree_add_string(lisp_record_tree, hf_lisp_mreq_record_prefix_lcaf, tvb, offset, addr_len, prefix);
1170 offset += addr_len;
1172 proto_item_append_text(tir, " %d: %s/%d", i+1, prefix, prefix_mask);
1175 /* If M bit is set, we also have a Map-Reply */
1176 if (mrep) {
1177 int len = 0;
1178 tvbuff_t *rep_tvb;
1179 proto_item *tim;
1180 proto_tree *lisp_mr_tree;
1182 tim = proto_tree_add_item(lisp_tree, hf_lisp_mreq_record, tvb, offset, -1, ENC_NA);
1183 lisp_mr_tree = proto_item_add_subtree(tim, ett_lisp_mr);
1185 rep_tvb = tvb_new_subset_remaining(tvb, offset);
1186 len = dissect_lisp_mapping(rep_tvb, pinfo, lisp_mr_tree, 0, FALSE);
1187 offset += len;
1190 next_tvb = tvb_new_subset_remaining(tvb, offset);
1191 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1196 * Dissector code for Map-Reply type control packets
1198 * 0 1 2 3
1199 * 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
1200 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1201 * |Type=2 |P|E|S| Reserved | Record Count |
1202 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1203 * | Nonce . . . |
1204 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1205 * | . . . Nonce |
1206 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1207 * | | Record TTL |
1208 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1209 * R | Locator Count | EID mask-len | ACT |A| Reserved |
1210 * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1211 * c | Rsvd | Map-Version Number | EID-AFI |
1212 * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1213 * r | EID-prefix |
1214 * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1215 * | /| Priority | Weight | M Priority | M Weight |
1216 * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1217 * | o | Unused Flags |L|p|R| Loc-AFI |
1218 * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1219 * | \| Locator |
1220 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1224 static void
1225 dissect_lisp_map_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
1227 int i;
1228 gint offset = 0;
1229 gboolean probe = FALSE;
1230 guint8 flags;
1231 guint8 rec_cnt = 0;
1232 tvbuff_t *next_tvb;
1234 /* Flags (2 bits) */
1235 flags = tvb_get_guint8(tvb, offset);
1236 probe = flags & (MAP_REP_FLAG_P >> 16);
1237 proto_tree_add_item(lisp_tree, hf_lisp_mrep_flags_probe, tvb, offset, 3, ENC_BIG_ENDIAN);
1238 proto_tree_add_item(lisp_tree, hf_lisp_mrep_flags_enlr, tvb, offset, 3, ENC_BIG_ENDIAN);
1240 /* Flags defined in LISP-SEC draft (1 bit) */
1241 proto_tree_add_item(lisp_tree, hf_lisp_mrep_flags_sec, tvb, offset, 3, ENC_BIG_ENDIAN);
1243 if (probe)
1244 col_append_str(pinfo->cinfo, COL_INFO, " (RLOC-probe reply)");
1246 /* Reserved bits (18 bits) */
1247 proto_tree_add_item(lisp_tree, hf_lisp_mrep_res, tvb, offset, 3, ENC_BIG_ENDIAN);
1248 offset += 3;
1250 /* Record count (8 bits) */
1251 rec_cnt = tvb_get_guint8(tvb, offset);
1252 proto_tree_add_item(lisp_tree, hf_lisp_records, tvb, offset, 1, ENC_BIG_ENDIAN);
1253 offset += 1;
1255 /* Nonce (64 bits) */
1256 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1257 offset += 8;
1259 /* Reply records */
1260 for(i=0; i < rec_cnt; i++) {
1261 tvbuff_t *rec_tvb;
1262 int len = 0;
1264 rec_tvb = tvb_new_subset_remaining(tvb, offset);
1265 len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, FALSE);
1266 offset += len;
1269 next_tvb = tvb_new_subset_remaining(tvb, offset);
1270 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1275 * Dissector code for Map-Register type control packets
1277 * 0 1 2 3
1278 * 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
1279 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1280 * |Type=3 |P|S|I|R| Reserved |M| Record Count |
1281 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1282 * | Nonce . . . |
1283 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1284 * | . . . Nonce |
1285 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1286 * | Key ID | Authentication Data Length |
1287 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1288 * ~ Authentication Data ~
1289 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1290 * | | Record TTL |
1291 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1292 * R | Locator Count | EID mask-len | ACT |A| Reserved |
1293 * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1294 * c | Rsvd | Map-Version Number | EID-AFI |
1295 * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1296 * r | EID-prefix |
1297 * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1298 * | /| Priority | Weight | M Priority | M Weight |
1299 * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1300 * | o | Unused Flags |L|p|R| Loc-AFI |
1301 * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1302 * | \| Locator |
1303 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1307 static void
1308 dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
1310 int i;
1311 gint offset = 0;
1312 guint8 rec_cnt = 0;
1313 tvbuff_t *next_tvb;
1314 guint16 authlen = 0;
1315 guint16 flags;
1316 gboolean xtrid = FALSE;
1317 gboolean rtr = FALSE;
1319 /* Flags (1 bit) */
1320 proto_tree_add_item(lisp_tree, hf_lisp_mreg_flags_pmr, tvb, offset, 3, ENC_BIG_ENDIAN);
1322 /* Flags defined in LISP-SEC draft (1 bit) */
1323 proto_tree_add_item(lisp_tree, hf_lisp_mreg_flags_sec, tvb, offset, 3, ENC_BIG_ENDIAN);
1325 /* Flags defined in NAT Traversal draft (2 bits) */
1326 flags = tvb_get_ntohs(tvb, offset);
1327 xtrid = flags & (MAP_REG_FLAG_I >> 8);
1328 rtr = flags & (MAP_REG_FLAG_R >> 8);
1330 proto_tree_add_item(lisp_tree, hf_lisp_mreg_flags_xtrid, tvb, offset, 3, ENC_BIG_ENDIAN);
1331 proto_tree_add_item(lisp_tree, hf_lisp_mreg_flags_rtr, tvb, offset, 3, ENC_BIG_ENDIAN);
1333 if (rtr)
1334 col_append_str(pinfo->cinfo, COL_INFO, " (RTR)");
1336 /* Reserved bits (15 bits) */
1337 proto_tree_add_item(lisp_tree, hf_lisp_mreg_res, tvb, offset, 3, ENC_BIG_ENDIAN);
1339 /* Flags (1 bit) */
1340 proto_tree_add_item(lisp_tree, hf_lisp_mreg_flags_wmn, tvb, offset, 3, ENC_BIG_ENDIAN);
1341 offset += 3;
1343 /* Record count (8 bits) */
1344 rec_cnt = tvb_get_guint8(tvb, offset);
1345 proto_tree_add_item(lisp_tree, hf_lisp_records, tvb, offset, 1, ENC_BIG_ENDIAN);
1346 offset += 1;
1348 /* Nonce (64 bits) */
1349 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1350 offset += 8;
1352 /* Key ID (16 bits) */
1353 proto_tree_add_item(lisp_tree, hf_lisp_keyid, tvb, offset, 2, ENC_BIG_ENDIAN);
1354 offset += 2;
1356 /* Authentication Data Length (16 bits) */
1357 authlen = tvb_get_ntohs(tvb, offset);
1358 proto_tree_add_item(lisp_tree, hf_lisp_authlen, tvb, offset, 2, ENC_BIG_ENDIAN);
1359 offset += 2;
1361 /* Authentication Data */
1362 /* XXX: need to check is there is still enough data in buffer */
1363 proto_tree_add_item(lisp_tree, hf_lisp_auth, tvb, offset, authlen, ENC_NA);
1364 offset += authlen;
1366 for(i=0; i < rec_cnt; i++) {
1367 tvbuff_t *rec_tvb;
1368 int len = 0;
1370 rec_tvb = tvb_new_subset_remaining(tvb, offset);
1371 len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, FALSE);
1372 offset += len;
1375 /* If I bit is set, we have an xTR-ID and a site-ID field */
1376 if (xtrid) {
1377 proto_tree_add_item(lisp_tree, hf_lisp_xtrid, tvb, offset, LISP_XTRID_LEN, ENC_NA);
1378 proto_tree_add_item(lisp_tree, hf_lisp_siteid, tvb, offset + LISP_XTRID_LEN, LISP_SITEID_LEN, ENC_NA);
1379 offset += LISP_XTRID_LEN + LISP_SITEID_LEN;
1382 next_tvb = tvb_new_subset_remaining(tvb, offset);
1383 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1388 * Dissector code for Map-Notify type control packets
1390 * 0 1 2 3
1391 * 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
1392 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1393 * |Type=4 |I|R| Reserved | Record Count |
1394 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1395 * | Nonce . . . |
1396 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1397 * | . . . Nonce |
1398 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1399 * | Key ID | Authentication Data Length |
1400 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1401 * ~ Authentication Data ~
1402 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1403 * | | Record TTL |
1404 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1405 * R | Locator Count | EID mask-len | ACT |A| Reserved |
1406 * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1407 * c | Rsvd | Map-Version Number | EID-AFI |
1408 * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1409 * r | EID-prefix |
1410 * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1411 * | /| Priority | Weight | M Priority | M Weight |
1412 * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1413 * | o | Unused Flags |L|p|R| Loc-AFI |
1414 * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1415 * | \| Locator |
1416 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1420 static void
1421 dissect_lisp_map_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
1423 int i;
1424 gint offset = 0;
1425 guint8 rec_cnt = 0;
1426 tvbuff_t *next_tvb;
1427 guint16 authlen = 0;
1428 guint16 flags;
1429 gboolean xtrid = FALSE;
1430 gboolean rtr = FALSE;
1432 /* Flags defined in NAT Traversal draft (2 bits) */
1433 flags = tvb_get_ntohs(tvb, offset);
1434 xtrid = flags & (MAP_NOT_FLAG_I >> 8);
1435 rtr = flags & (MAP_NOT_FLAG_R >> 8);
1437 proto_tree_add_item(lisp_tree, hf_lisp_mnot_flags_xtrid, tvb, offset, 3, ENC_BIG_ENDIAN);
1438 proto_tree_add_item(lisp_tree, hf_lisp_mnot_flags_rtr, tvb, offset, 3, ENC_BIG_ENDIAN);
1440 if (rtr)
1441 col_append_str(pinfo->cinfo, COL_INFO, " (RTR)");
1443 /* Reserved bits (18 bits) */
1444 proto_tree_add_item(lisp_tree, hf_lisp_mnot_res, tvb, offset, 3, ENC_BIG_ENDIAN);
1445 offset += 3;
1447 /* Record count (8 bits) */
1448 rec_cnt = tvb_get_guint8(tvb, offset);
1449 proto_tree_add_item(lisp_tree, hf_lisp_records, tvb, offset, 1, ENC_BIG_ENDIAN);
1450 offset += 1;
1452 /* Nonce (64 bits) */
1453 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1454 offset += 8;
1456 /* Key ID (16 bits) */
1457 proto_tree_add_item(lisp_tree, hf_lisp_keyid, tvb, offset, 2, ENC_BIG_ENDIAN);
1458 offset += 2;
1460 /* Authentication Data Length (16 bits) */
1461 authlen = tvb_get_ntohs(tvb, offset);
1462 proto_tree_add_item(lisp_tree, hf_lisp_authlen, tvb, offset, 2, ENC_BIG_ENDIAN);
1463 offset += 2;
1465 /* Authentication Data */
1466 /* XXX: need to check is there is still enough data in buffer */
1467 proto_tree_add_item(lisp_tree, hf_lisp_auth, tvb, offset, authlen, ENC_NA);
1468 offset += authlen;
1470 for(i=0; i < rec_cnt; i++) {
1471 tvbuff_t *rec_tvb;
1472 int len = 0;
1474 rec_tvb = tvb_new_subset_remaining(tvb, offset);
1475 len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, FALSE);
1476 offset += len;
1479 /* If I bit is set, we have an xTR-ID and a site-ID field */
1480 if (xtrid) {
1481 proto_tree_add_item(lisp_tree, hf_lisp_xtrid, tvb, offset, LISP_XTRID_LEN, ENC_NA);
1482 proto_tree_add_item(lisp_tree, hf_lisp_siteid, tvb, offset + LISP_XTRID_LEN, LISP_SITEID_LEN, ENC_NA);
1483 offset += LISP_XTRID_LEN + LISP_SITEID_LEN;
1486 /* If R bit is set, we have MS-RTR authentication data */
1487 if (rtr) {
1488 /* MS-RTR Key ID (16 bits) */
1489 proto_tree_add_item(lisp_tree, hf_lisp_msrtr_keyid, tvb, offset, 2, ENC_BIG_ENDIAN);
1490 offset += 2;
1492 /* MS-RTR Authentication Data Length (16 bits) */
1493 authlen = tvb_get_ntohs(tvb, offset);
1494 proto_tree_add_item(lisp_tree, hf_lisp_msrtr_authlen, tvb, offset, 2, ENC_BIG_ENDIAN);
1495 offset += 2;
1497 /* MS-RTR Authentication Data */
1498 /* XXX: need to check is there is still enough data in buffer */
1499 proto_tree_add_item(lisp_tree, hf_lisp_msrtr_auth, tvb, offset, authlen, ENC_NA);
1500 offset += authlen;
1503 next_tvb = tvb_new_subset_remaining(tvb, offset);
1504 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1508 * Dissector code for Map-Referral type control packets
1510 * 0 1 2 3
1511 * 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
1512 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1513 * |Type=6 | Reserved | Record Count |
1514 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1515 * | Nonce . . . |
1516 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1517 * | . . . Nonce |
1518 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1519 * | | Record TTL |
1520 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1521 * R | Referral Count| EID mask-len | ACT |A|I| Reserved |
1522 * e +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1523 * c |SigCnt | Map Version Number | EID-AFI |
1524 * o +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1525 * r | EID-prefix ... |
1526 * d +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1527 * | /| Priority | Weight | M Priority | M Weight |
1528 * | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1529 * | o | Unused Flags |R| Loc/LCAF-AFI |
1530 * | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1531 * | \| Locator ... |
1532 * +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1536 static void
1537 dissect_lisp_map_referral(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
1539 int i;
1540 gint offset = 0;
1541 guint8 rec_cnt = 0;
1542 tvbuff_t *next_tvb;
1544 /* Reserved bits (20 bits) */
1545 proto_tree_add_item(lisp_tree, hf_lisp_mref_res, tvb, offset, 3, ENC_BIG_ENDIAN);
1546 offset += 3;
1548 /* Record count (8 bits) */
1549 rec_cnt = tvb_get_guint8(tvb, offset);
1550 proto_tree_add_item(lisp_tree, hf_lisp_records, tvb, offset, 1, ENC_BIG_ENDIAN);
1551 offset += 1;
1553 /* Nonce (64 bits) */
1554 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1555 offset += 8;
1557 /* Referral records */
1558 for(i=0; i < rec_cnt; i++) {
1559 tvbuff_t *rec_tvb;
1560 int len = 0;
1562 rec_tvb = tvb_new_subset_remaining(tvb, offset);
1563 len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, TRUE);
1564 offset += len;
1567 next_tvb = tvb_new_subset_remaining(tvb, offset);
1568 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1573 * Dissector code for Info type control packets
1575 * 0 1 2 3
1576 * 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
1577 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1578 * |Type=7 |R| Reserved |
1579 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1580 * | Nonce . . . |
1581 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1582 * | . . . Nonce |
1583 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1584 * | Key ID | Authentication Data Length |
1585 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1586 * ~ Authentication Data ~
1587 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1588 * | TTL |
1589 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1590 * | Reserved | EID mask-len | EID-prefix-AFI |
1591 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1592 * | EID-prefix |
1593 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1594 * | AFI | ...
1595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1599 static void
1600 dissect_lisp_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
1602 gint offset = 0;
1603 tvbuff_t *next_tvb;
1604 guint8 flags;
1605 gboolean reply;
1606 guint16 authlen = 0;
1607 guint8 prefix_mask;
1608 guint16 prefix_afi, afi;
1609 const gchar *prefix;
1610 guint16 addr_len = 0;
1611 proto_item *tir;
1612 proto_tree *lisp_lcaf_tree;
1614 /* Flags (1 bit) */
1615 flags = tvb_get_guint8(tvb, offset);
1616 reply = flags & (INFO_FLAG_R >> 16);
1618 if (reply)
1619 col_append_str(pinfo->cinfo, COL_INFO, "-Reply");
1620 else
1621 col_append_str(pinfo->cinfo, COL_INFO, "-Request");
1623 proto_tree_add_item(lisp_tree, hf_lisp_info_r, tvb, offset, 3, ENC_BIG_ENDIAN);
1625 /* Reserved bits (27 bits) */
1626 proto_tree_add_item(lisp_tree, hf_lisp_info_res1, tvb, offset, 4, ENC_BIG_ENDIAN);
1627 offset += 4;
1629 /* Nonce (64 bits) */
1630 proto_tree_add_item(lisp_tree, hf_lisp_nonce, tvb, offset, 8, ENC_BIG_ENDIAN);
1631 offset += 8;
1633 /* Key ID (16 bits) */
1634 proto_tree_add_item(lisp_tree, hf_lisp_keyid, tvb, offset, 2, ENC_BIG_ENDIAN);
1635 offset += 2;
1637 /* Authentication Data Length (16 bits) */
1638 authlen = tvb_get_ntohs(tvb, offset);
1639 proto_tree_add_item(lisp_tree, hf_lisp_authlen, tvb, offset, 2, ENC_BIG_ENDIAN);
1640 offset += 2;
1642 /* Authentication Data */
1643 /* XXX: need to check is there is still enough data in buffer */
1644 proto_tree_add_item(lisp_tree, hf_lisp_auth, tvb, offset, authlen, ENC_NA);
1645 offset += authlen;
1647 /* TTL */
1648 proto_tree_add_item(lisp_tree, hf_lisp_info_ttl, tvb, offset, 4, ENC_BIG_ENDIAN);
1649 offset += 4;
1651 /* Reserved bits (8 bits) */
1652 proto_tree_add_item(lisp_tree, hf_lisp_info_res2, tvb, offset, 1, ENC_BIG_ENDIAN);
1653 offset += 1;
1655 prefix_mask = tvb_get_guint8(tvb, offset); offset += 1;
1656 prefix_afi = tvb_get_ntohs(tvb, offset); offset += 2;
1657 prefix = get_addr_str(tvb, offset, prefix_afi, &addr_len);
1659 if (prefix == NULL) {
1660 expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
1661 "Unexpected EID prefix AFI (%d), cannot decode", prefix_afi);
1662 next_tvb = tvb_new_subset_remaining(tvb, offset);
1663 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1664 return;
1667 proto_tree_add_text(lisp_tree, tvb, offset - 3, 3 + addr_len,
1668 "EID prefix: %s/%d", prefix, prefix_mask);
1669 offset += addr_len;
1671 /* Update the INFO column */
1672 col_append_fstr(pinfo->cinfo, COL_INFO, " for %s/%d", prefix, prefix_mask);
1674 tir = proto_tree_add_item(lisp_tree, hf_lisp_info_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
1675 afi = tvb_get_ntohs(tvb, offset); offset += 2;
1677 if (!reply) {
1678 if (afi != 0) {
1679 expert_add_info_format(pinfo, tir, &ei_lisp_expected_field,
1680 "Expecting NULL AFI (0), found %d, incorrect packet!", afi);
1682 } else {
1683 if (afi != AFNUM_LCAF) {
1684 expert_add_info_format(pinfo, tir, &ei_lisp_expected_field,
1685 "Expecting LCAF AFI (%d), found %d, incorrect packet!",
1686 AFNUM_LCAF, afi);
1687 } else {
1688 lisp_lcaf_tree = proto_item_add_subtree(tir, ett_lisp_lcaf);
1689 offset = dissect_lcaf(tvb, pinfo, lisp_lcaf_tree, offset);
1693 next_tvb = tvb_new_subset_remaining(tvb, offset);
1694 call_dissector(data_handle, next_tvb, pinfo, lisp_tree);
1699 * Dissector code for Encapsulated Control Message type packets
1701 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1702 * |Type=8 |S|D| Reserved |
1703 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1704 * | IPv4 or IPv6 Header |
1705 * | (uses RLOC or EID addresses) |
1706 * ~ ~
1710 static void
1711 dissect_lisp_ecm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *lisp_tree)
1713 tvbuff_t *next_tvb;
1714 guint8 flags;
1715 guint8 ip_ver;
1717 /* Flags (2 bits) */
1718 flags = tvb_get_guint8(tvb, 0);
1719 ddt_originated = flags & (ECM_FLAG_D >> 24);
1721 proto_tree_add_item(lisp_tree, hf_lisp_ecm_flags_sec, tvb, 0, 4, ENC_BIG_ENDIAN);
1722 proto_tree_add_item(lisp_tree, hf_lisp_ecm_flags_ddt, tvb, 0, 4, ENC_BIG_ENDIAN);
1723 proto_tree_add_item(lisp_tree, hf_lisp_ecm_res, tvb, 0, 4, ENC_BIG_ENDIAN);
1725 /* Determine if encapsulated packet is IPv4 or IPv6, and call dissector */
1726 next_tvb = tvb_new_subset_remaining(tvb, LISP_ECM_HEADER_LEN);
1727 ip_ver = tvb_get_bits8(next_tvb, 0, 4);
1729 switch (ip_ver) {
1730 case 4:
1731 call_dissector(ipv4_handle, next_tvb, pinfo, tree);
1732 break;
1733 case 6:
1734 call_dissector(ipv6_handle, next_tvb, pinfo, tree);
1735 break;
1736 default:
1737 call_dissector(data_handle, next_tvb, pinfo, tree);
1738 break;
1740 encapsulated = FALSE;
1745 * Main dissector code
1748 static int
1749 dissect_lisp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1751 guint8 type;
1753 proto_tree *lisp_tree = NULL;
1755 /* Clear Info column before fetching data in case an exception is thrown */
1756 col_clear(pinfo->cinfo, COL_INFO);
1758 type = tvb_get_bits8(tvb, 0, 4);
1760 /* Make entries in Protocol column and Info column on summary display */
1761 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LISP");
1763 if (encapsulated) {
1764 col_add_fstr(pinfo->cinfo, COL_INFO, "Encapsulated %s", val_to_str(type, lisp_typevals,
1765 "Unknown LISP Control Packet (%d)"));
1766 } else {
1767 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(type, lisp_typevals,
1768 "Unknown LISP Control Packet (%d)"));
1771 if (ddt_originated) {
1772 col_append_str(pinfo->cinfo, COL_INFO, " (DDT-originated)");
1773 ddt_originated = FALSE;
1776 if (tree) {
1777 proto_item *ti;
1779 /* create display subtree for the protocol */
1780 ti = proto_tree_add_item(tree, proto_lisp, tvb, 0,
1781 (type == LISP_ECM) ? LISP_ECM_HEADER_LEN : -1, ENC_NA);
1783 lisp_tree = proto_item_add_subtree(ti, ett_lisp);
1785 proto_tree_add_item(lisp_tree,
1786 hf_lisp_type, tvb, 0, 3, ENC_BIG_ENDIAN);
1789 /* Sub-dissectors are indirectly called by the following and thus
1790 this code should be executed whether or not tree==NULL.
1792 switch (type) {
1793 case LISP_MAP_REQUEST:
1794 dissect_lisp_map_request(tvb, pinfo, lisp_tree);
1795 break;
1796 case LISP_MAP_REPLY:
1797 dissect_lisp_map_reply(tvb, pinfo, lisp_tree);
1798 break;
1799 case LISP_MAP_REGISTER:
1800 dissect_lisp_map_register(tvb, pinfo, lisp_tree);
1801 break;
1802 case LISP_MAP_NOTIFY:
1803 dissect_lisp_map_notify(tvb, pinfo, lisp_tree);
1804 break;
1805 case LISP_MAP_REFERRAL:
1806 dissect_lisp_map_referral(tvb, pinfo, lisp_tree);
1807 break;
1808 case LISP_INFO:
1809 dissect_lisp_info(tvb, pinfo, lisp_tree);
1810 break;
1811 case LISP_ECM:
1812 encapsulated = TRUE;
1813 dissect_lisp_ecm(tvb, pinfo, tree, lisp_tree);
1814 break;
1815 default:
1816 call_dissector(data_handle, tvb, pinfo, tree);
1817 break;
1820 /* Return the amount of data this dissector was able to dissect */
1821 return tvb_length(tvb);
1826 * Register the LISP protocol with Wireshark
1829 void
1830 proto_register_lisp(void)
1832 /* Setup list of header fields */
1833 static hf_register_info hf[] = {
1834 { &hf_lisp_type,
1835 { "Type", "lisp.type",
1836 FT_UINT24, BASE_DEC, VALS(lisp_typevals), 0xF00000, "LISP Control Message Type", HFILL }},
1837 { &hf_lisp_irc,
1838 { "ITR-RLOC Count", "lisp.irc",
1839 FT_UINT24, BASE_DEC, NULL, 0x00001F, NULL, HFILL }},
1840 { &hf_lisp_records,
1841 { "Record Count", "lisp.records",
1842 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1843 { &hf_lisp_nonce,
1844 { "Nonce", "lisp.nonce",
1845 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1846 { &hf_lisp_mreq_flags,
1847 { "Flags", "lisp.mreq.flags",
1848 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1849 { &hf_lisp_mreq_flags_auth,
1850 { "A bit (Authoritative)", "lisp.mreq.flags.auth",
1851 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_A, NULL, HFILL }},
1852 { &hf_lisp_mreq_flags_mrp,
1853 { "M bit (Map-Reply present)", "lisp.mreq.flags.mrp",
1854 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_M, NULL, HFILL }},
1855 { &hf_lisp_mreq_flags_probe,
1856 { "P bit (Probe)", "lisp.mreq.flags.probe",
1857 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_P, NULL, HFILL }},
1858 { &hf_lisp_mreq_flags_smr,
1859 { "S bit (Solicit-Map-Request)", "lisp.mreq.flags.smr",
1860 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_S, NULL, HFILL }},
1861 { &hf_lisp_mreq_flags_pitr,
1862 { "p bit (Proxy ITR)", "lisp.mreq.flags.pitr",
1863 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_p, NULL, HFILL }},
1864 { &hf_lisp_mreq_flags_smri,
1865 { "s bit (SMR-invoked)", "lisp.mreq.flags.smri",
1866 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REQ_FLAG_s, NULL, HFILL }},
1867 { &hf_lisp_mreq_res,
1868 { "Reserved bits", "lisp.mreq.res",
1869 FT_UINT24, BASE_HEX, NULL, MAP_REQ_RESERVED, "Must be zero", HFILL }},
1870 { &hf_lisp_mreq_srceid_afi,
1871 { "Source EID AFI", "lisp.mreq.srceid_afi",
1872 FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Source EID Address Family Indicator", HFILL }},
1873 { &hf_lisp_mreq_srceid_string,
1874 { "Source EID", "lisp.mreq.srceid_string",
1875 FT_STRING, BASE_NONE, NULL, 0x0, "Source EID Address", HFILL }},
1876 { &hf_lisp_mreq_srceid_ipv4,
1877 { "Source EID", "lisp.mreq.srceid_ipv4",
1878 FT_IPv4, BASE_NONE, NULL, 0x0, "Source EID Address", HFILL }},
1879 { &hf_lisp_mreq_srceid_ipv6,
1880 { "Source EID", "lisp.mreq.srceid_ipv6",
1881 FT_IPv6, BASE_NONE, NULL, 0x0, "Source EID Address", HFILL }},
1882 { &hf_lisp_mreq_srceid_lacf,
1883 { "Source EID", "lisp.mreq.srceid_lacf",
1884 FT_STRING, BASE_NONE, NULL, 0x0, "Source EID Address", HFILL }},
1885 { &hf_lisp_mreq_itr_rloc,
1886 { "ITR-RLOC", "lisp.mreq.itr_rloc",
1887 FT_NONE, BASE_NONE, NULL, 0x0, "Originating ITR RLOC Address", HFILL }},
1888 { &hf_lisp_mreq_itr_rloc_afi,
1889 { "ITR-RLOC AFI", "lisp.mreq.itr_rloc.afi",
1890 FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Originating ITR RLOC Address Family Indicator", HFILL }},
1891 { &hf_lisp_mreq_srcitr,
1892 { "ITR-RLOC Address", "lisp.mreq.srcitr",
1893 FT_IPv4, BASE_NONE, NULL, 0x0, "Originating ITR RLOC Address", HFILL }},
1894 { &hf_lisp_mreq_srcitrv6,
1895 { "ITR-RLOC Address", "lisp.mreq.srcitrv6",
1896 FT_IPv6, BASE_NONE, NULL, 0x0, "Originating ITR RLOC Address", HFILL }},
1897 { &hf_lisp_mreq_record_reserved,
1898 { "Reserved", "lisp.mreq.record.reserved",
1899 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1900 { &hf_lisp_mreq_record_prefix_length,
1901 { "Prefix Length", "lisp.mreq.record.prefix.length",
1902 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1903 { &hf_lisp_mreq_record_prefix_afi,
1904 { "Prefix AFI", "lisp.mreq.record.prefix.afi",
1905 FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, NULL, HFILL }},
1906 { &hf_lisp_mreq_record_prefix_ipv4,
1907 { "Prefix (IPv4)", "lisp.mreq.record.prefix.ipv4",
1908 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1909 { &hf_lisp_mreq_record_prefix_ipv6,
1910 { "Prefix (IPv6)", "lisp.mreq.record.prefix.ipv6",
1911 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1912 { &hf_lisp_mreq_record_prefix_lcaf,
1913 { "Prefix (LCAF)", "lisp.mreq.record.prefix.lcaf",
1914 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1915 { &hf_lisp_mreq_record,
1916 { "Map-Reply record", "lisp.mreq.record",
1917 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1918 { &hf_lisp_mrep_flags_probe,
1919 { "P bit (Probe)", "lisp.mrep.flags.probe",
1920 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REP_FLAG_P, NULL, HFILL }},
1921 { &hf_lisp_mrep_flags_enlr,
1922 { "E bit (Echo-Nonce locator reachability algorithm enabled)", "lisp.mrep.flags.enlr",
1923 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REP_FLAG_E, NULL, HFILL }},
1924 { &hf_lisp_mrep_flags_sec,
1925 { "S bit (LISP-SEC capable)", "lisp.mrep.flags.sec",
1926 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REP_FLAG_S, NULL, HFILL }},
1927 { &hf_lisp_mrep_res,
1928 { "Reserved bits", "lisp.mrep.res",
1929 FT_UINT24, BASE_HEX, NULL, MAP_REP_RESERVED, "Must be zero", HFILL }},
1930 { &hf_lisp_mreg_flags_pmr,
1931 { "P bit (Proxy-Map-Reply)", "lisp.mreg.flags.pmr",
1932 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REG_FLAG_P, NULL, HFILL }},
1933 { &hf_lisp_mreg_flags_sec,
1934 { "S bit (LISP-SEC capable)", "lisp.mreg.flags.sec",
1935 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REG_FLAG_S, NULL, HFILL }},
1936 { &hf_lisp_mreg_flags_xtrid,
1937 { "I bit (xTR-ID present)", "lisp.mreg.flags.xtrid",
1938 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REG_FLAG_I, NULL, HFILL }},
1939 { &hf_lisp_mreg_flags_rtr,
1940 { "R bit (Built for an RTR)", "lisp.mreg.flags.rtr",
1941 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REG_FLAG_R, NULL, HFILL }},
1942 { &hf_lisp_mreg_flags_wmn,
1943 { "M bit (Want-Map-Notify)", "lisp.mreg.flags.wmn",
1944 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_REG_FLAG_M, NULL, HFILL }},
1945 { &hf_lisp_mreg_res,
1946 { "Reserved bits", "lisp.mreg.res",
1947 FT_UINT24, BASE_HEX, NULL, MAP_REG_RESERVED, "Must be zero", HFILL }},
1948 { &hf_lisp_mref_res,
1949 { "Reserved bits", "lisp.mref.res",
1950 FT_UINT24, BASE_HEX, NULL, MAP_REF_RESERVED, "Must be zero", HFILL }},
1951 { &hf_lisp_keyid,
1952 { "Key ID", "lisp.keyid",
1953 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1954 { &hf_lisp_authlen,
1955 { "Authentication Data Length", "lisp.authlen",
1956 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1957 { &hf_lisp_auth,
1958 { "Authentication Data", "lisp.auth",
1959 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1960 { &hf_lisp_msrtr_keyid,
1961 { "MS-RTR Key ID", "lisp.msrtr.keyid",
1962 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1963 { &hf_lisp_msrtr_authlen,
1964 { "MS-RTR Authentication Data Length", "lisp.msrtr.authlen",
1965 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1966 { &hf_lisp_msrtr_auth,
1967 { "MS-RTR Authentication Data", "lisp.msrtr.auth",
1968 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1969 { &hf_lisp_xtrid,
1970 { "xTR-ID", "lisp.xtrid",
1971 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1972 { &hf_lisp_siteid,
1973 { "Site-ID", "lisp.siteid",
1974 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1975 { &hf_lisp_mnot_flags_xtrid,
1976 { "I bit (xTR-ID present)", "lisp.mnot.flags.xtrid",
1977 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_NOT_FLAG_I, NULL, HFILL }},
1978 { &hf_lisp_mnot_flags_rtr,
1979 { "R bit (Built for an RTR)", "lisp.mnot.flags.rtr",
1980 FT_BOOLEAN, 24, TFS(&tfs_set_notset), MAP_NOT_FLAG_R, NULL, HFILL }},
1981 { &hf_lisp_mnot_res,
1982 { "Reserved bits", "lisp.mnot.res",
1983 FT_UINT24, BASE_HEX, NULL, MAP_NOT_RESERVED, "Must be zero", HFILL }},
1984 { &hf_lisp_info_r,
1985 { "R bit (Info-Reply)", "lisp.info.r",
1986 FT_BOOLEAN, 24, TFS(&tfs_set_notset), INFO_FLAG_R, NULL, HFILL }},
1987 { &hf_lisp_info_res1,
1988 { "Reserved bits", "lisp.info.res1",
1989 FT_UINT32, BASE_HEX, NULL, INFO_RESERVED, "Must be zero", HFILL }},
1990 { &hf_lisp_info_ttl,
1991 { "TTL", "lisp.info.ttl",
1992 FT_UINT32, BASE_DEC, NULL, 0x0, "RTR information time-to-live", HFILL }},
1993 { &hf_lisp_info_res2,
1994 { "Reserved bits", "lisp.info.res2",
1995 FT_UINT8, BASE_HEX, NULL, 0xFF, "Must be zero", HFILL }},
1996 { &hf_lisp_info_afi,
1997 { "AFI", "lisp.info.afi",
1998 FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Address Family Indicator", HFILL }},
1999 { &hf_lisp_loc,
2000 { "LOC", "lisp.loc",
2001 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2002 { &hf_lisp_loc_priority,
2003 { "Priority", "lisp.loc.priority",
2004 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2005 { &hf_lisp_loc_weight,
2006 { "Weight", "lisp.loc.weight",
2007 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2008 { &hf_lisp_loc_mpriority,
2009 { "Multicast Priority", "lisp.loc.multicast_priority",
2010 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2011 { &hf_lisp_loc_mweight,
2012 { "Multicast Weight", "lisp.loc.multicast_weight",
2013 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2014 { &hf_lisp_loc_flags,
2015 { "Flags", "lisp.loc.flags",
2016 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2017 { &hf_lisp_loc_flags_local,
2018 { "Local", "lisp.loc.flags.local",
2019 FT_BOOLEAN, 16, TFS(&tfs_set_notset), LOCAL_BIT_MASK, NULL, HFILL }},
2020 { &hf_lisp_loc_flags_probe,
2021 { "Probe", "lisp.loc.flags.probe",
2022 FT_BOOLEAN, 16, TFS(&tfs_set_notset), PROBE_BIT_MASK, NULL, HFILL }},
2023 { &hf_lisp_loc_flags_reach,
2024 { "Reach", "lisp.loc.flags.reach",
2025 FT_BOOLEAN, 16, TFS(&tfs_set_notset), REACH_BIT_MASK, NULL, HFILL }},
2026 { &hf_lisp_loc_flags_rsv,
2027 { "Reserved", "lisp.loc.flags.rsv",
2028 FT_UINT16, BASE_HEX, NULL, 0xFFF8, "Must be zero", HFILL }},
2029 { &hf_lisp_loc_afi,
2030 { "AFI", "lisp.loc.afi",
2031 FT_UINT16, BASE_DEC, VALS(lcaf_typevals), 0x0, NULL, HFILL }},
2032 { &hf_lisp_loc_locator,
2033 { "Locator", "lisp.loc.locator",
2034 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2035 { &hf_lisp_mapping,
2036 { "Mapping", "lisp.mapping",
2037 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2038 { &hf_lisp_mapping_ttl,
2039 { "Record TTL", "lisp.mapping.ttl",
2040 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2041 { &hf_lisp_mapping_loccnt,
2042 { "Locator Count", "lisp.mapping.loccnt",
2043 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2044 { &hf_lisp_mapping_eid_masklen,
2045 { "EID mask length", "lisp.mapping.eid.masklen",
2046 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2047 { &hf_lisp_mapping_act,
2048 { "Action", "lisp.mapping.act",
2049 FT_UINT16, BASE_DEC, VALS(mapping_actions), 0xE000, NULL, HFILL }},
2050 { &hf_lisp_mapping_auth,
2051 { "Authoritative bit", "lisp.mapping.auth",
2052 FT_BOOLEAN, 16, TFS(&tfs_set_notset), LISP_MAP_AUTH, NULL, HFILL }},
2053 { &hf_lisp_referral_incomplete,
2054 { "Incomplete", "lisp.referral.incomplete",
2055 FT_BOOLEAN, 16, TFS(&tfs_set_notset), REFERRAL_INCOMPLETE, NULL, HFILL }},
2056 { &hf_lisp_mapping_res1,
2057 { "Reserved", "lisp.mapping.res1",
2058 FT_UINT16, BASE_HEX, NULL, 0x07FF, NULL, HFILL }},
2059 { &hf_lisp_mapping_res2,
2060 { "Reserved", "lisp.mapping.res2",
2061 FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL }},
2062 { &hf_lisp_mapping_ver,
2063 { "Mapping Version", "lisp.mapping.ver",
2064 FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }},
2065 { &hf_lisp_referral_sigcnt,
2066 { "Signature Count", "lisp.referral.sigcnt",
2067 FT_UINT16, BASE_DEC, NULL, 0xF000, NULL, HFILL }},
2068 { &hf_lisp_mapping_eid_afi,
2069 { "EID prefix AFI", "lisp.mapping.eid.afi",
2070 FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, NULL, HFILL }},
2071 { &hf_lisp_mapping_eid,
2072 { "EID prefix", "lisp.mapping.eid",
2073 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2074 { &hf_lisp_ecm_flags_sec,
2075 { "S bit (LISP-SEC capable)", "lisp.ecm.flags.sec",
2076 FT_BOOLEAN, 32, TFS(&tfs_set_notset), ECM_FLAG_S, NULL, HFILL }},
2077 { &hf_lisp_ecm_flags_ddt,
2078 { "D bit (DDT-originated)", "lisp.ecm.flags.ddt",
2079 FT_BOOLEAN, 32, TFS(&tfs_set_notset), ECM_FLAG_D, NULL, HFILL }},
2080 { &hf_lisp_ecm_res,
2081 { "Reserved bits", "lisp.ecm.res",
2082 FT_UINT32, BASE_HEX, NULL, 0x03FFFFFF, NULL, HFILL }},
2083 { &hf_lisp_lcaf_res1,
2084 { "Reserved bits", "lisp.lcaf.res1",
2085 FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }},
2086 { &hf_lisp_lcaf_flags,
2087 { "Flags", "lisp.lcaf.flags",
2088 FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }},
2089 { &hf_lisp_lcaf_type,
2090 { "Type", "lisp.lcaf.type",
2091 FT_UINT8, BASE_DEC, VALS(lcaf_typevals), 0xFF, "LISP LCAF Type", HFILL }},
2092 { &hf_lisp_lcaf_res2,
2093 { "Reserved bits", "lisp.lcaf.res2",
2094 FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }},
2095 { &hf_lisp_lcaf_length,
2096 { "Length", "lisp.lcaf.length",
2097 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2098 { &hf_lisp_lcaf_iid,
2099 { "Instance ID", "lisp.lcaf.iid",
2100 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2101 { &hf_lisp_lcaf_natt_msport,
2102 { "MS UDP Port Number", "lisp.lcaf.natt.msport",
2103 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2104 { &hf_lisp_lcaf_natt_etrport,
2105 { "ETR UDP Port Number", "lisp.lcaf.natt.etrport",
2106 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2109 /* Setup protocol subtree array */
2110 static gint *ett[] = {
2111 &ett_lisp,
2112 &ett_lisp_mr,
2113 &ett_lisp_mreq_flags,
2114 &ett_lisp_mapping,
2115 &ett_lisp_itr,
2116 &ett_lisp_record,
2117 &ett_lisp_lcaf,
2118 &ett_lisp_loc,
2119 &ett_lisp_loc_flags,
2120 &ett_lisp_elp
2123 static ei_register_info ei[] = {
2124 { &ei_lisp_undecoded, { "lisp.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
2125 { &ei_lisp_unexpected_field, { "lisp.unexpected_field", PI_PROTOCOL, PI_ERROR, "Unexpected field", EXPFILL }},
2126 { &ei_lisp_lcaf_type, { "lisp.lcaf.type.invalid", PI_PROTOCOL, PI_ERROR, "LCAF type is not defined in draft-farinacci-lisp-lcaf-X", EXPFILL }},
2127 { &ei_lisp_expected_field, { "lisp.expected_field", PI_PROTOCOL, PI_ERROR, "Expecting field", EXPFILL }},
2130 expert_module_t* expert_lisp;
2132 /* Register the protocol name and description */
2133 proto_lisp = proto_register_protocol("Locator/ID Separation Protocol",
2134 "LISP Control", "lisp");
2136 /* Required function calls to register the header fields and subtrees used */
2137 proto_register_field_array(proto_lisp, hf, array_length(hf));
2138 proto_register_subtree_array(ett, array_length(ett));
2139 expert_lisp = expert_register_protocol(proto_lisp);
2140 expert_register_field_array(expert_lisp, ei, array_length(ei));
2142 /* Register dissector so that other dissectors can call it */
2143 lisp_handle = new_register_dissector("lisp", dissect_lisp, proto_lisp);
2148 * Simple form of proto_reg_handoff_lisp which can be used if there are
2149 * no prefs-dependent registration function calls.
2152 void
2153 proto_reg_handoff_lisp(void)
2155 dissector_add_uint("udp.port", LISP_CONTROL_PORT, lisp_handle);
2156 ipv4_handle = find_dissector("ip");
2157 ipv6_handle = find_dissector("ipv6");
2158 data_handle = find_dissector("data");
2162 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2164 * Local variables:
2165 * c-basic-offset: 4
2166 * tab-width: 8
2167 * indent-tabs-mode: nil
2168 * End:
2170 * vi: set shiftwidth=4 tabstop=8 expandtab:
2171 * :indentSize=4:tabSize=8:noTabs=true: