Allow filter names and expressions of arbitrary length, and, in the
[metze/wireshark/wip.git] / packet-ldp.c
1 /* packet-ldp.c
2  * Routines for ldp packet disassembly
3  *
4  * $Id: packet-ldp.c,v 1.14 2001/01/25 06:14:14 guy Exp $
5  * 
6  * Copyright (c) November 2000 by Richard Sharpe <rsharpe@ns.aus.com>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs
10  * Copyright 1999 Gerald Combs
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #ifdef HAVE_NETINET_IN_H
35 #include <netinet/in.h>
36 #endif
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <ctype.h>
41 #include <time.h>
42 #include <glib.h>
43 #include <string.h>
44 #include "packet.h"
45 #include "resolv.h"
46 #include "prefs.h"
47
48 #define TCP_PORT_LDP 646
49 #define UDP_PORT_LDP 646
50
51 void proto_reg_handoff_ldp(void);
52
53 static int proto_ldp = -1;
54
55 /* Delete the following if you do not use it, or add to it if you need */
56 static int hf_ldp_req = -1;
57 static int hf_ldp_rsp = -1;
58 static int hf_ldp_version = -1;
59 static int hf_ldp_pdu_len = -1;
60 static int hf_ldp_lsr = -1;
61 static int hf_ldp_ls_id = -1;
62 static int hf_ldp_msg_type = -1;
63 static int hf_ldp_msg_len = -1;
64 static int hf_ldp_msg_id = -1;
65 static int hf_ldp_tlv_value = -1;
66 static int hf_ldp_tlv_type = -1;
67 static int hf_ldp_tlv_len = -1;
68 static int hf_ldp_tlv_val_hold = -1;
69 static int hf_ldp_tlv_val_target = -1;
70 static int hf_ldp_tlv_val_request = -1;
71 static int hf_ldp_tlv_val_res = -1;
72 static int hf_ldp_tlv_config_seqno = -1;
73 static int hf_ldp_tlv_fec_wc = -1;
74 static int hf_ldp_tlv_fec_af = -1;
75 static int hf_ldp_tlv_fec_len = -1;
76 static int hf_ldp_tlv_fec_pfval = -1;
77 static int hf_ldp_tlv_generic_label = -1;
78
79 static int ett_ldp = -1;
80 static int ett_ldp_header = -1;
81 static int ett_ldp_ldpid = -1;
82 static int ett_ldp_message = -1;
83 static int ett_ldp_tlv = -1;
84 static int ett_ldp_tlv_val = -1;
85 static int ett_ldp_fec = -1;
86
87 static int tcp_port = 0;
88 static int udp_port = 0;
89
90 /* Add your functions here */
91
92 static int global_ldp_tcp_port = TCP_PORT_LDP;
93 static int global_ldp_udp_port = UDP_PORT_LDP;
94
95 /*
96  * The following define all the TLV types I know about
97  */
98
99 #define TLV_FEC                    0x0100
100 #define TLV_ADDRESS_LIST           0x0101
101 #define TLV_HOP_COUNT              0x0103
102 #define TLV_PATH_VECTOR            0x0104
103 #define TLV_GENERIC_LABEL          0x0200
104 #define TLV_ATM_LABEL              0x0201
105 #define TLV_FRAME_LABEL            0x0202
106 #define TLV_STATUS                 0x0300
107 #define TLV_EXTENDED_STATUS        0x0301
108 #define TLV_RETURNED_PDU           0x0302
109 #define TLV_RETURNED_MESSAGE       0x0303
110 #define TLV_COMMON_HELLO_PARMS     0x0400
111 #define TLV_IPV4_TRANSPORT_ADDRESS 0x0401
112 #define TLV_CONFIGURATION_SEQNO    0x0402
113 #define TLV_IPV6_TRANSPORT_ADDRESS 0x0403
114 #define TLV_COMMON_SESSION_PARMS   0x0500
115 #define TLV_ATM_SESSION_PARMS      0x0501
116 #define TLV_FRAME_RELAY_SESSION_PARMS 0x0502
117 #define TLV_LABEL_REQUEST_MESSAGE_ID 0x0600
118
119 #define TLV_VENDOR_PRIVATE_START   0x3E00
120 #define TLV_VENDOR_PROVATE_END     0x3EFF
121 #define TLV_EXPERIMENTAL_START     0x3F00
122 #define TLV_EXPERIMENTAL_END       0x3FFF
123
124 static const value_string tlv_type_names[] = { 
125   { TLV_FEC,                       "Forwarding Equivalence Classes" },
126   { TLV_ADDRESS_LIST,              "Address List"},
127   { TLV_HOP_COUNT,                 "Hop Count"},
128   { TLV_PATH_VECTOR,               "Path Vector"},
129   { TLV_GENERIC_LABEL,             "Generic Label"},
130   { TLV_ATM_LABEL,                 "Frame Label"},
131   { TLV_STATUS,                    "Status"},
132   { TLV_EXTENDED_STATUS,           "Extended Status"},
133   { TLV_RETURNED_PDU,              "Returned PDU"},
134   { TLV_RETURNED_MESSAGE,          "Returned Message"},
135   { TLV_COMMON_HELLO_PARMS,        "Common Hello Parameters"},
136   { TLV_IPV4_TRANSPORT_ADDRESS,    "IPv4 Transport Address"},
137   { TLV_CONFIGURATION_SEQNO,       "Configuration Sequence Number"},
138   { TLV_IPV6_TRANSPORT_ADDRESS,    "IPv6 Transport Address"},
139   { TLV_COMMON_SESSION_PARMS,      "Common Session Parameters"},
140   { TLV_ATM_SESSION_PARMS,         "ATM Session Parameters"},
141   { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters"},
142   { TLV_LABEL_REQUEST_MESSAGE_ID,  "Label Request Message ID"},
143   { 0, NULL}
144 };
145
146 /*
147  * The following define all the message types I know about
148  */
149
150 #define LDP_NOTIFICATION       0x0001
151 #define LDP_HELLO              0x0100
152 #define LDP_INITIALIZATION     0x0200
153 #define LDP_KEEPALIVE          0x0201
154 #define LDP_ADDRESS            0x0300
155 #define LDP_ADDRESS_WITHDRAWAL 0x0301
156 #define LDP_LABEL_MAPPING      0x0400
157 #define LDP_LABEL_REQUEST      0x0401
158 #define LDP_LABEL_WITHDRAWAL   0x0402
159 #define LDP_LABEL_RELEASE      0x0403
160 #define LDP_LABEL_ABORT_REQUEST 0x0404
161 #define LDP_VENDOR_PRIVATE_START 0x3E00
162 #define LDP_VENDOR_PRIVATE_END   0x3EFF
163 #define LDP_EXPERIMENTAL_MESSAGE_START 0x3F00
164 #define LDP_EXPERIMENTAL_MESSAGE_END   0x3FFF
165
166 static const value_string ldp_message_types[] = {
167   {LDP_NOTIFICATION,             "Notification"},
168   {LDP_HELLO,                    "Hello"},
169   {LDP_INITIALIZATION,           "Initialization"},
170   {LDP_KEEPALIVE,                "Keep Alive"},
171   {LDP_ADDRESS,                  "Address"},
172   {LDP_ADDRESS_WITHDRAWAL,       "Address Withdrawal"},
173   {LDP_LABEL_MAPPING,            "Label Mapping"},
174   {LDP_LABEL_REQUEST,            "Label Request"},
175   {LDP_LABEL_WITHDRAWAL,         "Label Withdrawal"},
176   {LDP_LABEL_RELEASE,            "Label Release"},
177   {LDP_LABEL_ABORT_REQUEST,      "Label Abort Request"},
178   {0, NULL}
179 };
180
181 static const true_false_string hello_targeted_vals = {
182   "Targeted Hello",
183   "Link Hello"
184 };
185
186 static const value_string fec_types[] = {
187   {1, "Wildcard FEC"},
188   {2, "Prefix FEC"},
189   {3, "Host Address FEC"},
190   {0, NULL}
191 };
192
193 static const value_string fec_af_types[] = {
194   {0, "Reserved"},
195   {1, "IP (IPv4)"},
196   {2, "IP6 (IPv6)"},
197   {3, "NSAP"},
198   {4, "HDLC (8-bit multidrop)"},
199   {5, "BBN 1822"},
200   {6, "802"},
201   {10, "X.121 (X.25, Frame Relay)"},
202   {11, "IPX"},
203   {12, "Appletalk"},
204   {0, NULL}
205 };
206
207 static const true_false_string hello_requested_vals = {
208   "Source requests periodic hellos",
209   "Source does not request periodic hellos"
210 };
211
212 /* Dissect the common hello params */
213
214 void dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
215 {
216   proto_tree *ti = NULL, *val_tree = NULL;
217
218   if (tree) {
219
220     ti = proto_tree_add_bytes(tree, hf_ldp_tlv_value, tvb, offset, rem,
221                               tvb_get_ptr(tvb, offset, rem));
222
223     val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
224
225     proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
226
227     proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
228     proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
229     proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
230   }
231
232 }
233
234 /* Dissect a TLV and return the number of bytes consumed ... */
235
236 int dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
237 {
238   guint16 message = tvb_get_ntohs(tvb, offset),
239           length = tvb_get_ntohs(tvb, offset + 2),
240           pad = 0, fec_len = 0;
241   proto_tree *ti = NULL, *tlv_tree = NULL;
242
243   /* Hmmm, check for illegal alignment padding */
244
245   if (message == 0x00) {
246
247     proto_tree_add_text(tree, tvb, offset, 2, "Illegal Padding: %04X", message);
248     offset += 2; pad = 2;
249     message = tvb_get_ntohs(tvb, offset);
250     length = tvb_get_ntohs(tvb, offset + 2);
251
252   }
253
254   length = MIN(length, rem);  /* Don't go haywire if a problem ... */
255
256   if (tree) {
257
258     /* FIXME: Account for vendor and special messages */
259
260     ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
261                              val_to_str(message, tlv_type_names, "Unknown TLV type (0x%04X)"));
262
263     tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
264
265     proto_tree_add_item(tlv_tree, hf_ldp_tlv_type, tvb, offset, 2, FALSE);
266
267     proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
268
269     switch (message) {
270
271     case TLV_FEC:  /* Process an FEC */
272
273       offset += 4;  /* Skip the TLV header */
274
275       fec_len = length;
276
277       while (fec_len > 0) {
278         proto_tree *fec_tree = NULL;
279
280
281         switch (tvb_get_guint8(tvb, offset)) {
282         case 1:   /* Wild Card */
283
284           proto_tree_add_item(tlv_tree, hf_ldp_tlv_fec_wc, tvb, offset, 4, FALSE);
285           fec_len -= 4;
286
287           offset += 4;
288
289           break;
290
291         case 2:   /* Prefix    */
292
293           /* Add a subtree for this ... */
294
295           ti = proto_tree_add_text(tlv_tree, tvb, offset, 8, "Prefix FEC Element");
296
297           fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
298
299           proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
300
301           offset += 1;
302
303           /* XXX - the address family length should be extracted and used to
304              dissect the prefix field. */
305           proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
306           offset += 2;
307
308
309           proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
310
311           offset += 1;
312
313           proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_pfval, tvb, offset, 4, FALSE);
314
315           fec_len -= 8;
316
317           break;
318
319         case 3:   /* Host address */
320
321           /* XXX - write me. */
322
323           fec_len -= 8;
324
325           offset += 8;
326
327           break;
328
329         default:  /* Unknown */
330
331           /* XXX - do all FEC's have a length that's a multiple of 4? */
332           /* Hmmm, don't think so. Will check. RJS. */
333
334           fec_len -= 4;
335
336           offset += 4;
337
338           break;
339
340         }
341
342       }
343
344       break;;
345
346     case TLV_GENERIC_LABEL:
347
348       proto_tree_add_item(tlv_tree, hf_ldp_tlv_generic_label, tvb, offset + 4, 4, FALSE);
349
350       break;
351
352     case TLV_COMMON_HELLO_PARMS:
353
354       dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
355       break;
356
357     case TLV_CONFIGURATION_SEQNO:
358
359       proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
360       break;
361
362     default:
363       proto_tree_add_bytes(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4, 
364                            length, tvb_get_ptr(tvb, offset + 4, length));
365
366       break;
367     }
368
369   }
370
371   return length + pad + 4;  /* Length of the value field + header */
372
373 }
374
375 /* 
376  * Each of these routines dissect the relevant messages, but the msg header 
377  * has already been dissected.
378  */
379
380 void
381 dissect_ldp_notification(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
382 {
383   guint rem = length, cc = 0;
384
385   while (rem > 0) {
386
387     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
388     offset += cc;
389
390   }
391
392 }
393
394 /* Dissect a Hello Message ... */
395 void
396 dissect_ldp_hello(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
397 {
398   guint rem = length, cc = 0;
399
400   while (rem > 0) {
401
402     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
403     offset += cc;
404
405   }
406
407 }
408
409 void
410 dissect_ldp_initialization(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
411 {
412   guint rem = length, cc = 0;
413
414   while (rem > 0) {
415
416     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
417     offset += cc;
418
419   }
420
421 }
422
423 void
424 dissect_ldp_keepalive(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
425 {
426   guint rem = length, cc = 0;
427
428   while (rem > 0) {
429
430     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
431     offset += cc;
432
433   }
434
435 }
436
437 void
438 dissect_ldp_address(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
439 {
440   guint rem = length, cc = 0;
441
442   while (rem > 0) {
443
444     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
445     offset += cc;
446
447   }
448
449 }
450
451 void
452 dissect_ldp_address_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
453 {
454   guint rem = length, cc = 0;
455
456   while (rem > 0) {
457
458     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
459     offset += cc;
460
461   }
462
463 }
464
465 void
466 dissect_ldp_label_mapping(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
467 {
468   guint rem = length, cc = 0;
469
470   while (rem > 0) {
471
472     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
473     offset += cc;
474
475   }
476
477 }
478
479 void
480 dissect_ldp_label_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
481 {
482   guint rem = length, cc = 0;
483
484   while (rem > 0) {
485
486     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
487     offset += cc;
488
489   }
490
491 }
492
493 void
494 dissect_ldp_label_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
495 {
496   guint rem = length, cc = 0;
497
498   while (rem > 0) {
499
500     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
501     offset += cc;
502
503   }
504
505 }
506
507 void
508 dissect_ldp_label_release(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
509 {
510   guint rem = length, cc = 0;
511
512   while (rem > 0) {
513
514     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
515     offset += cc;
516
517   }
518
519 }
520
521 void
522 dissect_ldp_label_abort_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
523 {
524   guint rem = length, cc = 0;
525
526   while (rem > 0) {
527
528     rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
529     offset += cc;
530
531   }
532
533 }
534
535 static void
536 dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
537 {
538   proto_tree     *ldp_tree = NULL, 
539                  *ti = NULL,
540                  *hdr_tree = NULL, *ldpid_tree = NULL;
541   int            offset = 0, msg_cnt = 0;
542   guint16        ldp_message = 0;
543
544   if (check_col(pinfo->fd, COL_PROTOCOL))
545     col_add_str(pinfo->fd, COL_PROTOCOL, "LDP");
546   if (check_col(pinfo->fd, COL_INFO))
547     col_clear(pinfo->fd, COL_INFO);
548
549   if (tree) {  /* Build the tree info ..., this is wrong! FIXME */
550
551     ti = proto_tree_add_item(tree, proto_ldp, tvb, offset,
552                              tvb_length_remaining(tvb, offset), FALSE);
553     ldp_tree = proto_item_add_subtree(ti, ett_ldp);
554
555     ti = proto_tree_add_text(ldp_tree, tvb, 0, 10, "Header");
556
557     hdr_tree = proto_item_add_subtree(ti, ett_ldp_header);
558
559     proto_tree_add_item(hdr_tree, hf_ldp_version, tvb, offset, 2, FALSE);
560
561     offset += 2;
562
563     proto_tree_add_item(hdr_tree, hf_ldp_pdu_len, tvb, offset, 2, FALSE);
564
565     offset += 2;
566
567     ti = proto_tree_add_text(hdr_tree, tvb, offset, 6, "LDP Identifier");
568
569     ldpid_tree = proto_item_add_subtree(ti, ett_ldp_ldpid);
570
571     proto_tree_add_item(ldpid_tree, hf_ldp_lsr, tvb, offset, 4, FALSE);
572
573     offset += 4;
574
575     proto_tree_add_item(ldpid_tree, hf_ldp_ls_id, tvb, offset, 2, FALSE);
576
577     offset += 2;
578
579   }
580
581   offset = 10;
582
583   while (tvb_length_remaining(tvb, offset) > 0) { /* Dissect a message */
584
585     guint msg_len;
586
587     ldp_message = tvb_get_ntohs(tvb, offset) & 0x7FFF; /* Get the message type */
588
589     msg_len = tvb_get_ntohs(tvb, offset + 2);
590
591     if (check_col(pinfo->fd, COL_INFO)) {  /* Check the type ... */
592
593       if (msg_cnt > 0) 
594         col_append_fstr(pinfo->fd, COL_INFO, ", %s",
595                         val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
596       else
597         col_add_fstr(pinfo->fd, COL_INFO, "%s", 
598                      val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
599
600     }
601
602     msg_cnt++;
603
604     if (tree) {
605
606       proto_tree *ti = NULL, *msg_tree = NULL;
607
608       /* FIXME: Account for vendor and experimental messages */
609
610       ti = proto_tree_add_text(ldp_tree, tvb, offset, msg_len + 4, "%s",
611                                val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
612
613       msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
614
615       proto_tree_add_item(msg_tree, hf_ldp_msg_type, tvb, offset, 2, FALSE);
616
617       proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset + 2, 2, FALSE);
618
619       proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset + 4, 4, FALSE);
620
621       switch (ldp_message) {
622
623       case LDP_NOTIFICATION:
624
625         dissect_ldp_notification(tvb, offset + 8, pinfo, msg_tree, msg_len - 4); 
626
627         break;
628
629       case LDP_HELLO:
630
631         dissect_ldp_hello(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
632
633         break;
634
635       case LDP_INITIALIZATION:
636
637         dissect_ldp_initialization(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
638
639         break;
640
641       case LDP_KEEPALIVE:
642
643         dissect_ldp_keepalive(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
644
645         break;
646
647       case LDP_ADDRESS:
648
649         dissect_ldp_address(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
650
651         break;
652
653       case LDP_ADDRESS_WITHDRAWAL:
654
655         dissect_ldp_address_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
656
657         break;
658
659       case LDP_LABEL_MAPPING:
660
661         dissect_ldp_label_mapping(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
662
663         break;
664
665       case LDP_LABEL_REQUEST:
666
667         dissect_ldp_label_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
668
669         break;
670
671       case LDP_LABEL_WITHDRAWAL:
672
673         dissect_ldp_label_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
674
675         break;
676
677       case LDP_LABEL_RELEASE:
678
679         dissect_ldp_label_release(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
680
681         break;
682
683       case LDP_LABEL_ABORT_REQUEST:
684
685         dissect_ldp_label_abort_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
686
687         break;
688
689       default:
690
691         /* Some sort of unknown message, treat as undissected data */
692
693         break;
694
695       }
696     
697     }
698
699     offset += msg_len + 4;
700
701   }
702 }
703
704 /* Register all the bits needed with the filtering engine */
705
706 void 
707 proto_register_ldp(void)
708 {
709   static hf_register_info hf[] = {
710     { &hf_ldp_req,
711       /* Change the following to the type you need */
712       { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "" }},
713
714     { &hf_ldp_rsp,
715       { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "" }},
716
717     { &hf_ldp_version,
718       { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number" }},
719
720     { &hf_ldp_pdu_len,
721       { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length"}},
722
723     { &hf_ldp_lsr,
724       { "LSR ID", "ldp.hdr.ldpid.lsr", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID"}},
725
726     { &hf_ldp_ls_id,
727       { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID"}},
728
729     { &hf_ldp_msg_type,
730       { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x0, "LDP message type"}},
731
732     { &hf_ldp_msg_len,
733       { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)"}},
734
735     { &hf_ldp_msg_id, 
736       { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID"}},
737
738     { &hf_ldp_tlv_type, 
739       { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x0, "TLV Type Field"}},
740
741     { &hf_ldp_tlv_len,
742       {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field"}},
743
744     { &hf_ldp_tlv_value,
745       { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes"}},
746
747     { &hf_ldp_tlv_val_hold,
748       { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time"}},
749
750     { &hf_ldp_tlv_val_target,
751       { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 8, TFS(&hello_targeted_vals), 0x80, "Hello Common Parameters Targeted Bit"}},
752
753     { &hf_ldp_tlv_val_request,
754       { "Hello Requested", "ldp,msg.tlv.hello.requested", FT_BOOLEAN, 8, TFS(&hello_requested_vals), 0x40, "Hello Common Parameters Hello Requested Bit" }},
755  
756     { &hf_ldp_tlv_val_res,
757       { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field"}},
758
759     { &hf_ldp_tlv_config_seqno,
760       { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_HEX, NULL, 0x0, "Hello COnfiguration Sequence Number"}},
761
762     { &hf_ldp_tlv_fec_wc,
763       { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types"}},
764
765     { &hf_ldp_tlv_fec_af,
766       { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(fec_af_types), 0x0, "Forwarding Equivalence Class Element Address Family"}},
767
768     { &hf_ldp_tlv_fec_len,
769       { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length"}},
770
771     { &hf_ldp_tlv_fec_pfval,
772       { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_UINT32, BASE_HEX, NULL, 0x0, "Forwarding Equivalence Class Element Prefix"}},
773
774     { &hf_ldp_tlv_generic_label,
775       { "Generic Label", "ldp.msg.tlv.label", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Mapping Generic Label"}},
776
777   };
778   static gint *ett[] = {
779     &ett_ldp,
780     &ett_ldp_header,
781     &ett_ldp_ldpid,
782     &ett_ldp_message,
783     &ett_ldp_tlv,
784     &ett_ldp_tlv_val,
785     &ett_ldp_fec,
786   };
787   module_t *ldp_module; 
788
789   proto_ldp = proto_register_protocol("Label Distribution Protocol",
790                                        "LDP", "ldp");
791
792   proto_register_field_array(proto_ldp, hf, array_length(hf));
793   proto_register_subtree_array(ett, array_length(ett));
794
795   /* Register our configuration options for , particularly our port */
796
797   ldp_module = prefs_register_protocol(proto_ldp, proto_reg_handoff_ldp);
798
799   prefs_register_uint_preference(ldp_module, "tcp.port", "LDP TCP Port",
800                                  "Set the port for  messages (if other"
801                                  " than the default of 646)",
802                                  10, &global_ldp_tcp_port);
803
804   prefs_register_uint_preference(ldp_module, "udp.port", "LDP UDP Port",
805                                  "Set the port for  messages (if other"
806                                  " than the default of 646)",
807                                  10, &global_ldp_udp_port);
808
809 }
810
811 /* The registration hand-off routine */
812 void
813 proto_reg_handoff_ldp(void)
814 {
815   static int ldp_prefs_initialized = FALSE;
816
817   if (ldp_prefs_initialized) {
818
819     dissector_delete("tcp.port", tcp_port, dissect_ldp);
820     dissector_delete("udp.port", udp_port, dissect_ldp);
821
822   }
823   else {
824
825     ldp_prefs_initialized = TRUE;
826
827   }
828
829   /* Set our port number for future use */
830
831   tcp_port = global_ldp_tcp_port;
832   udp_port = global_ldp_udp_port;
833
834   dissector_add("tcp.port", global_ldp_tcp_port, dissect_ldp, proto_ldp);
835   dissector_add("udp.port", global_ldp_udp_port, dissect_ldp, proto_ldp);
836
837 }