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