2 * Routines for SRVLOC (Service Location Protocol) packet dissection
3 * Copyright 1999, James Coe <jammer@cin.net>
4 * Copyright 2002, Brad Hards
5 * Updated for TCP segments by Greg Morris <gmorris@novell.com>
6 * Copyright 2003, Greg Morris
8 * NOTE: This is Alpha software not all features have been verified yet.
9 * In particular I have not had an opportunity to see how it
10 * responds to SRVLOC over TCP.
12 * $Id: packet-srvloc.c,v 1.46 2004/02/28 22:56:36 guy Exp $
14 * Ethereal - Network traffic analyzer
15 * By Gerald Combs <gerald@ethereal.com>
16 * Copyright 1998 Gerald Combs
18 * Service Location Protocol is RFC 2165
19 * Service Location Protocol Version 2 is RFC 2608
20 * - partial support by Brad Hards <bradh@frogmouth.net>
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
48 #include <epan/packet.h>
49 #include <epan/strutil.h>
51 #include "packet-tcp.h"
52 #include "reassemble.h"
54 static gboolean srvloc_desegment = TRUE;
55 static int proto_srvloc = -1;
56 static int hf_srvloc_version = -1;
57 static int hf_srvloc_function = -1;
58 static int hf_srvloc_pktlen = -1;
59 static int hf_srvloc_xid = -1;
60 static int hf_srvloc_langtaglen = -1;
61 static int hf_srvloc_langtag = -1;
62 static int hf_srvloc_nextextoff = -1;
63 static int hf_srvloc_flags_v1 = -1;
64 static int hf_srvloc_flags_v1_overflow = -1;
65 static int hf_srvloc_flags_v1_monolingual = -1;
66 static int hf_srvloc_flags_v1_url_auth = -1;
67 static int hf_srvloc_flags_v1_attribute_auth = -1;
68 static int hf_srvloc_flags_v1_fresh = -1;
69 static int hf_srvloc_error = -1;
70 static int hf_srvloc_flags_v2 = -1;
71 static int hf_srvloc_flags_v2_overflow = -1;
72 static int hf_srvloc_flags_v2_fresh = -1;
73 static int hf_srvloc_flags_v2_reqmulti = -1;
74 static int hf_srvloc_error_v2 = -1;
75 static int hf_srvloc_daadvert_timestamp = -1;
76 static int hf_srvloc_daadvert_urllen = -1;
77 static int hf_srvloc_daadvert_url = -1;
78 static int hf_srvloc_daadvert_scopelistlen = -1;
79 static int hf_srvloc_daadvert_scopelist = -1;
80 static int hf_srvloc_daadvert_attrlistlen = -1;
81 static int hf_srvloc_daadvert_attrlist = -1;
82 static int hf_srvloc_daadvert_slpspilen = -1;
83 static int hf_srvloc_daadvert_slpspi = -1;
84 static int hf_srvloc_daadvert_authcount = -1;
85 static int hf_srvloc_srvreq_prlistlen = -1;
86 static int hf_srvloc_srvreq_prlist = -1;
87 static int hf_srvloc_srvreq_srvtypelen = -1;
88 static int hf_srvloc_srvreq_srvtypelist = -1;
89 static int hf_srvloc_srvreq_scopelistlen = -1;
90 static int hf_srvloc_srvreq_scopelist = -1;
91 static int hf_srvloc_srvreq_predicatelen = -1;
92 static int hf_srvloc_srvreq_predicate = -1;
93 static int hf_srvloc_srvreq_slpspilen = -1;
94 static int hf_srvloc_srvreq_slpspi = -1;
95 static int hf_srvloc_srvrply_urlcount = -1;
96 static int hf_srvloc_srvreg_attrlistlen = -1;
97 static int hf_srvloc_srvreg_attrlist = -1;
98 static int hf_srvloc_srvreg_attrauthcount = -1;
99 static int hf_srvloc_srvreg_srvtypelen = -1;
100 static int hf_srvloc_srvreg_srvtype = -1;
101 static int hf_srvloc_srvreg_scopelistlen = -1;
102 static int hf_srvloc_srvreg_scopelist = -1;
103 static int hf_srvloc_srvdereg_scopelistlen = -1;
104 static int hf_srvloc_srvdereg_scopelist = -1;
105 static int hf_srvloc_srvdereg_taglistlen = -1;
106 static int hf_srvloc_srvdereg_taglist = -1;
107 static int hf_srvloc_attrreq_prlistlen = -1;
108 static int hf_srvloc_attrreq_prlist = -1;
109 static int hf_srvloc_attrreq_urllen = -1;
110 static int hf_srvloc_attrreq_url = -1;
111 static int hf_srvloc_attrreq_scopelistlen = -1;
112 static int hf_srvloc_attrreq_scopelist = -1;
113 static int hf_srvloc_attrreq_attrlistlen = -1;
114 static int hf_srvloc_attrreq_attrlist = -1;
115 static int hf_srvloc_attrreq_taglistlen = -1;
116 static int hf_srvloc_attrreq_taglist = -1;
117 static int hf_srvloc_attrreq_slpspilen = -1;
118 static int hf_srvloc_attrreq_slpspi = -1;
119 static int hf_srvloc_attrrply_attrlistlen = -1;
120 static int hf_srvloc_attrrply_attrlist = -1;
121 static int hf_srvloc_attrrply_attrauthcount = -1;
122 static int hf_srvloc_srvtypereq_prlistlen = -1;
123 static int hf_srvloc_srvtypereq_prlist = -1;
124 static int hf_srvloc_srvtypereq_nameauthlistlen = -1;
125 static int hf_srvloc_srvtypereq_nameauthlistlenall = -1;
126 static int hf_srvloc_srvtypereq_nameauthlist = -1;
127 static int hf_srvloc_srvtypereq_scopelistlen = -1;
128 static int hf_srvloc_srvtypereq_scopelist = -1;
129 static int hf_srvloc_srvtyperply_srvtypelen = -1;
130 static int hf_srvloc_srvtyperply_srvtype = -1;
131 static int hf_srvloc_srvtyperply_srvtypelistlen = -1;
132 static int hf_srvloc_srvtyperply_srvtypelist = -1;
133 static int hf_srvloc_saadvert_urllen = -1;
134 static int hf_srvloc_saadvert_url = -1;
135 static int hf_srvloc_saadvert_scopelistlen = -1;
136 static int hf_srvloc_saadvert_scopelist = -1;
137 static int hf_srvloc_saadvert_attrlistlen = -1;
138 static int hf_srvloc_saadvert_attrlist = -1;
139 static int hf_srvloc_saadvert_authcount = -1;
140 static int hf_srvloc_authblkv2_bsd = -1;
141 static int hf_srvloc_authblkv2_len = -1;
142 static int hf_srvloc_authblkv2_timestamp = -1;
143 static int hf_srvloc_authblkv2_slpspilen = -1;
144 static int hf_srvloc_authblkv2_slpspi = -1;
145 static int hf_srvloc_url_reserved = -1;
146 static int hf_srvloc_url_lifetime = -1;
147 static int hf_srvloc_url_urllen = -1;
148 static int hf_srvloc_url_url = -1;
149 static int hf_srvloc_url_numauths = -1;
150 static int hf_srvloc_add_ref_ip = -1;
153 static gint ett_srvloc = -1;
154 static gint ett_srvloc_flags = -1;
157 static const true_false_string tfs_srvloc_flags_overflow = {
158 "Message will not fit in datagram",
159 "Message will fit in a datagram"
161 static const true_false_string tfs_srvloc_flags_v1_monolingual = {
162 "Only responses in specified language will be accepted",
163 "Responses in any language will be accepted"
165 static const true_false_string tfs_srvloc_flags_v1_url_auth = {
166 "URL Authentication Block is present",
167 "URL Authentication Block is absent"
169 static const true_false_string tfs_srvloc_flags_v1_attribute_auth = {
170 "Attribute Authentication Block is present",
171 "Attribute Authentication Block is absent"
173 static const true_false_string tfs_srvloc_flags_fresh = {
174 "New Service Registration",
175 "Not a new Service Registration"
177 static const true_false_string tfs_srvloc_flags_v2_reqmulti = {
178 "Multicast (or broadcast) request",
179 "Not multicast or broadcast"
182 #define TCP_PORT_SRVLOC 427
183 #define UDP_PORT_SRVLOC 427
185 /* Define function types */
195 #define SRVTYPERQST 9
196 #define SRVTYPERPLY 10
197 #define SAADVERT 11 /* SLPv2, section 8 */
199 /* Create protocol header structure */
201 /* bradh: looks like never used. */
202 /* bradh: comment it out for now since it doesn't work for v2
215 /* List to resolve function numbers to names */
217 static const value_string srvloc_functions[] = {
218 { SRVREQ, "Service Request" },
219 { SRVRPLY, "Service Reply" },
220 { SRVREG, "Service Registration" },
221 { SRVDEREG, "Service Deregister" },
222 { SRVACK, "Service Acknowledge" },
223 { ATTRRQST, "Attribute Request" },
224 { ATTRRPLY, "Attribute Reply" },
225 { DAADVERT, "DA Advertisement" },
226 { SRVTYPERQST, "Service Type Request" },
227 { SRVTYPERPLY, "Service Type Reply" },
228 { SAADVERT, "SA Advertisement" }, /* v2 only */
232 /* List to resolve flag values to names */
235 /* Define flag masks */
243 /* it all changes for Version 2 */
244 #define FLAG_O_V2 0x8000
245 #define FLAG_F_V2 0x4000
246 #define FLAG_R_V2 0x2000
248 /* Define Error Codes - Version 1*/
251 #define LANG_NOT_SPTD 1
252 #define PROT_PARSE_ERR 2
254 #define SCOPE_NOT_SPTD 4
255 #define CHRSET_NOT_UND 5
256 #define AUTH_ABSENT 6
257 #define AUTH_FAILED 7
259 /* List to resolve error codes to names */
261 static const value_string srvloc_errs[] = {
262 { SUCCESS, "No Error" },
263 { LANG_NOT_SPTD, "Language not supported" },
264 { PROT_PARSE_ERR, "Protocol parse error" },
265 { INVLD_REG, "Invalid registration" },
266 { SCOPE_NOT_SPTD, "Scope not supported" },
267 { CHRSET_NOT_UND, "Character set not understood" },
268 { AUTH_ABSENT, "Authentication absent" },
269 { AUTH_FAILED, "Authentication failed" },
273 /* Define Error Codes for Version 2 */
275 #define LANGUAGE_NOT_SUPPORTED 1
276 #define PARSE_ERROR 2
277 #define INVALID_REGISTRATION 3
278 #define SCOPE_NOT_SUPPORTED 4
279 #define AUTHENTICATION_UNKNOWN 5
280 #define AUTHENTICATION_ABSENT 6
281 #define AUTHENTICATION_FAILED 7
282 #define VER_NOT_SUPPORTED 9
283 #define INTERNAL_ERROR 10
284 #define DA_BUSY_NOW 11
285 #define OPTION_NOT_UNDERSTOOD 12
286 #define INVALID_UPDATE 13
287 #define MSG_NOT_SUPPORTED 14
288 #define REFRESH_REJECTED 15
290 static const value_string srvloc_errs_v2[] = {
291 { SUCCESS, "No Error" },
292 { LANGUAGE_NOT_SUPPORTED, "No data in the requested language" },
293 { PARSE_ERROR, "The message fails to obey SLP syntax." },
294 { INVALID_REGISTRATION, "The SrvReg has problems" },
295 { SCOPE_NOT_SUPPORTED, "Scope list not supported" },
296 { AUTHENTICATION_UNKNOWN, "Unsupported SLP SPI." },
297 { AUTHENTICATION_ABSENT, "URL and ATTR authentication not provided"},
298 { AUTHENTICATION_FAILED, "Authentication error"},
299 { VER_NOT_SUPPORTED, "Unsupported version number in message header" },
300 { INTERNAL_ERROR, "The DA (or SA) is too sick to respond" },
301 { DA_BUSY_NOW, "UA or SA SHOULD retry" },
302 { OPTION_NOT_UNDERSTOOD, "Unknown option from the mandatory range"},
303 { INVALID_UPDATE, "Invalid SrvReg" },
304 { MSG_NOT_SUPPORTED, "No support for AttrRqst or SrvTypeRqst" },
305 { REFRESH_REJECTED, "SrvReg sent too soon"},
310 * Character encodings.
311 * This is a small subset of what's in
313 * http://www.iana.org/assignments/character-sets
315 * XXX - we should do something useful with this, i.e. properly
316 * handle strings based on the character set they're in.
318 * XXX - what does "properly handle strings" mean? How do we know
319 * what character set the terminal can handle (for tty-based code)
320 * or the GUI can handle (for GUI code)?
322 * XXX - the Ethereal core really should be what does all the
323 * character set handling for strings, and it should be stuck with
324 * the task of figuring out how to properly handle them.
326 #define CHARSET_ASCII 3
327 #define CHARSET_ISO_10646_UTF_1 27
328 #define CHARSET_ISO_646_BASIC 28
329 #define CHARSET_ISO_646_IRV 30
330 #define CHARSET_ISO_8859_1 4
331 #define CHARSET_ISO_10646_UCS_2 1000 /* a/k/a Unicode */
332 #define CHARSET_UTF_7 1012
333 #define CHARSET_UTF_8 106
335 static const value_string charsets[] = {
336 { CHARSET_ASCII, "US-ASCII" },
337 { CHARSET_ISO_10646_UTF_1, "ISO 10646 UTF-1" },
338 { CHARSET_ISO_646_BASIC, "ISO 646 basic:1983" },
339 { CHARSET_ISO_646_IRV, "ISO 646 IRV:1983" },
340 { CHARSET_ISO_8859_1, "ISO 8859-1" },
341 { CHARSET_ISO_10646_UCS_2, "Unicode" },
342 { CHARSET_UTF_7, "UTF-7" },
343 { CHARSET_UTF_8, "UTF-8" },
348 dissect_authblk(tvbuff_t *tvb, int offset, proto_tree *tree)
355 seconds = tvb_get_ntohl(tvb, offset) - 2208988800ul;
356 stamp = gmtime(&seconds);
358 floatsec = stamp->tm_sec + tvb_get_ntohl(tvb, offset + 4) / 4294967296.0;
359 proto_tree_add_text(tree, tvb, offset, 8,
360 "Timestamp: %04d-%02d-%02d %02d:%02d:%07.4f UTC",
361 stamp->tm_year + 1900, stamp->tm_mon + 1,
362 stamp->tm_mday, stamp->tm_hour, stamp->tm_min,
365 proto_tree_add_text(tree, tvb, offset, 8, "Timestamp not representable");
367 proto_tree_add_text(tree, tvb, offset + 8, 2, "Block Structure Desciptor: %u",
368 tvb_get_ntohs(tvb, offset + 8));
369 length = tvb_get_ntohs(tvb, offset + 10);
370 proto_tree_add_text(tree, tvb, offset + 10, 2, "Authenticator length: %u",
373 proto_tree_add_text(tree, tvb, offset, length, "Authentication block: %s",
374 tvb_format_text(tvb, offset, length));
379 /* SLPv2 version - Needs to be fixed to match RFC2608 sect 9.2*/
381 dissect_authblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
385 proto_tree_add_item(tree, hf_srvloc_authblkv2_bsd, tvb, offset, 2, FALSE);
386 proto_tree_add_item(tree, hf_srvloc_authblkv2_len, tvb, offset+2, 2, FALSE);
387 proto_tree_add_item(tree, hf_srvloc_authblkv2_timestamp, tvb, offset+4, 4, FALSE);
388 length = tvb_get_ntohs(tvb, offset + 8);
389 proto_tree_add_uint(tree, hf_srvloc_authblkv2_slpspilen, tvb, offset + 8, 2, length);
391 proto_tree_add_item(tree, hf_srvloc_authblkv2_slpspi, tvb, offset, length, TRUE);
393 /* add code in here to handle Structured Authentication Block */
398 dissect_attrauthblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
400 tvb=tvb; tree=tree; /* silence gcc for now */
401 /* add code in here to handle attribute authentication */
406 add_v1_string(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length,
413 case CHARSET_ISO_10646_UCS_2:
414 unicode_str = tvb_fake_unicode(tvb, offset, length/2, FALSE);
415 proto_tree_add_string(tree, hf, tvb, offset, length,
421 proto_tree_add_item(tree, hf, tvb, offset, length, TRUE);
427 unicode_to_bytes(tvbuff_t *tvb, int offset, int length, gboolean endianness)
429 const char *ascii_text = tvb_get_ptr(tvb, offset, length);
431 guint8 c_char, c_char1;
432 static guint8 byte_array[255];
435 for (i = length; i > 0; i--) {
436 c_char = ascii_text[i];
439 c_char1 = ascii_text[i];
442 c_char1 = ascii_text[i];
444 byte_array[j] = c_char1;
446 byte_array[j] = c_char;
453 for (i = 0; i < length; i++) {
454 c_char = ascii_text[i];
456 byte_array[j] = c_char;
467 * Format of x-x-x-xxxxxxxx. Each of these entries represents the service binding to UDP, TCP, or IPX.
468 * The first digit is the protocol family: 2 for TCP/UPD, 6 for IPX.
469 * The second digit is the socket type: 1 for socket stream (TCP), 2 for datagram (UDP and IPX).
470 * The third is the protocol: 6 for TCP, 17 for UDP, and 1000 for IPX.
471 * Last is the IP address, in hex, of the interface that is registered (or, in the case of IPX, an IPX network number).
474 attr_list(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length,
478 int i, svc, ss, type_len, foffset=offset;
482 proto_tree *srvloc_tree;
484 static const value_string srvloc_svc[] = {
490 static const value_string srvloc_ss[] = {
496 static const value_string srvloc_prot[] = {
505 case CHARSET_ISO_10646_UCS_2:
507 type_len = strcspn(tvb_fake_unicode(tvb, offset, length/2, FALSE), "=");
508 attr_type = tvb_fake_unicode(tvb, offset+2, type_len-1, FALSE);
509 proto_tree_add_string(tree, hf, tvb, offset, type_len*2, attr_type);
511 for (foffset = offset + ((type_len*2)+2); foffset<length; foffset += 2) {
513 ti = proto_tree_add_text(tree, tvb, foffset, -1, "Item %d", i);
514 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
516 svc = tvb_get_guint8(tvb, foffset+1);
517 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 1,
518 "Service Type: %s", val_to_str(svc, srvloc_svc, "Unknown"));
519 ss = tvb_get_guint8(tvb, foffset+5);
520 proto_tree_add_text(srvloc_tree, tvb, foffset+5, 1,
521 "Communication Type: %s", val_to_str(ss, srvloc_ss, "Unknown"));
524 if (tvb_get_guint8(tvb, foffset)==54) { /* TCP */
525 prot = tvb_get_guint8(tvb, foffset);
526 proto_tree_add_text(srvloc_tree, tvb, foffset, 1,
527 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
532 byte_value = unicode_to_bytes(tvb, foffset, 4, FALSE); /* UDP */
533 prot = atol(byte_value);
534 proto_tree_add_text(srvloc_tree, tvb, foffset, 4,
535 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
541 byte_value = unicode_to_bytes(tvb, foffset, 8, FALSE); /* IPX */
542 prot = atol(byte_value);
543 proto_tree_add_text(srvloc_tree, tvb, foffset, 8,
544 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
548 byte_value = unicode_to_bytes(tvb, foffset, 16, TRUE); /* IP Address */
549 sscanf(byte_value,"%x",&prot);
550 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+2, 16, prot);
551 byte_value = unicode_to_bytes(tvb, foffset+18, 8, FALSE); /* Port */
552 sscanf(byte_value,"%x",&prot);
553 proto_tree_add_text(srvloc_tree, tvb, foffset+18, 8, "Port: %d", prot);
557 byte_value = unicode_to_bytes(tvb, foffset+2, 16, FALSE); /* IPX Network Address */
558 sscanf(byte_value,"%x",&prot);
559 proto_tree_add_text(srvloc_tree, tvb, foffset+2, 16, "Network: %s", byte_value);
560 byte_value = unicode_to_bytes(tvb, foffset+18, 24, FALSE); /* IPX Node Address */
561 sscanf(byte_value,"%x",&prot);
562 proto_tree_add_text(srvloc_tree, tvb, foffset+18, 24, "Node: %s", byte_value);
563 byte_value = unicode_to_bytes(tvb, foffset+42, 8, FALSE); /* Socket */
564 sscanf(byte_value,"%x",&prot);
565 proto_tree_add_text(srvloc_tree, tvb, foffset+42, 8, "Socket: %s", byte_value);
573 type_len = strcspn(tvb_get_ptr(tvb, offset, length), "=");
574 attr_type = unicode_to_bytes(tvb, offset+1, type_len-1, FALSE);
575 proto_tree_add_string(tree, hf, tvb, offset+1, type_len-1, attr_type);
577 for (foffset = offset + (type_len); foffset<length; foffset++) {
579 ti = proto_tree_add_text(tree, tvb, foffset, -1, "Item %d", i);
580 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
582 svc = tvb_get_guint8(tvb, foffset+1);
583 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 1,
584 "Service Type: %s", val_to_str(svc, srvloc_svc, "Unknown"));
585 ss = tvb_get_guint8(tvb, foffset+3);
586 proto_tree_add_text(srvloc_tree, tvb, foffset+3, 1,
587 "Communication Type: %s", val_to_str(ss, srvloc_ss, "Unknown"));
590 if (tvb_get_guint8(tvb, foffset)==54) { /* TCP */
591 prot = tvb_get_guint8(tvb, foffset);
592 proto_tree_add_text(srvloc_tree, tvb, foffset, 1,
593 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
599 byte_value = unicode_to_bytes(tvb, foffset, 2, FALSE); /* UDP */
600 prot = atol(byte_value);
601 proto_tree_add_text(srvloc_tree, tvb, foffset, 2,
602 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
608 byte_value = unicode_to_bytes(tvb, foffset, 4, FALSE); /* IPX */
609 prot = atol(byte_value);
610 proto_tree_add_text(srvloc_tree, tvb, foffset, 4,
611 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
615 byte_value = unicode_to_bytes(tvb, foffset, 8, TRUE); /* IP Address */
616 sscanf(byte_value,"%x",&prot);
617 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+1, 8, prot);
618 byte_value = unicode_to_bytes(tvb, foffset+9, 4, FALSE); /* Port */
619 sscanf(byte_value,"%x",&prot);
620 proto_tree_add_text(srvloc_tree, tvb, foffset+9, 4, "Port: %d", prot);
624 byte_value = unicode_to_bytes(tvb, foffset+1, 8, FALSE); /* IPX Network Address */
625 sscanf(byte_value,"%x",&prot);
626 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 8, "Network: %s", byte_value);
627 byte_value = unicode_to_bytes(tvb, foffset+9, 12, FALSE); /* IPX Node Address */
628 sscanf(byte_value,"%x",&prot);
629 proto_tree_add_text(srvloc_tree, tvb, foffset+9, 12, "Node: %s", byte_value);
630 byte_value = unicode_to_bytes(tvb, foffset+21, 4, FALSE); /* Socket */
631 sscanf(byte_value,"%x",&prot);
632 proto_tree_add_text(srvloc_tree, tvb, foffset+21, 4, "Socket: %s", byte_value);
641 proto_tree_add_item(tree, hf, tvb, offset, length, TRUE);
647 dissect_url_entry_v1(tvbuff_t *tvb, int offset, proto_tree *tree,
648 guint16 encoding, guint16 flags)
652 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
655 url_len = tvb_get_ntohs(tvb, offset);
656 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
659 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, url_len, encoding);
661 if ( (flags & FLAG_U) == FLAG_U )
662 offset = dissect_authblk(tvb, offset, tree);
667 dissect_url_entry_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
673 reserved = tvb_get_guint8(tvb, offset);
674 proto_tree_add_uint(tree, hf_srvloc_url_reserved, tvb, offset, 1,
677 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
680 url_len = tvb_get_ntohs(tvb, offset);
681 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
684 proto_tree_add_item(tree, hf_srvloc_url_url, tvb, offset, url_len, TRUE);
686 num_auths = tvb_get_guint8(tvb, offset);
687 proto_tree_add_uint(tree, hf_srvloc_url_numauths, tvb, offset, 1,
690 while (num_auths > 0) {
691 offset = dissect_authblk_v2(tvb, offset, tree);
697 /* Packet dissection routine called by tcp & udp when port 427 detected */
700 dissect_srvloc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
704 proto_tree *srvloc_tree, *srvloc_flags;
708 guint32 length; /* three bytes needed for v2 */
709 guint16 flags; /* two byes needed for v2 */
711 guint32 next_ext_off; /* three bytes, v2 only */
712 guint16 lang_tag_len;
715 if (check_col(pinfo->cinfo, COL_PROTOCOL))
716 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
718 if (check_col(pinfo->cinfo, COL_INFO))
719 col_clear(pinfo->cinfo, COL_INFO);
721 version = tvb_get_guint8(tvb, offset);
722 function = tvb_get_guint8(tvb, offset + 1);
724 if (check_col(pinfo->cinfo, COL_INFO))
725 col_add_str(pinfo->cinfo, COL_INFO,
726 val_to_str(function, srvloc_functions, "Unknown Function (%u)"));
729 ti = proto_tree_add_item(tree, proto_srvloc, tvb, offset, -1, FALSE);
730 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
732 proto_tree_add_uint(srvloc_tree, hf_srvloc_version, tvb, offset, 1,
734 proto_tree_add_uint(srvloc_tree, hf_srvloc_function, tvb, offset + 1, 1,
737 length = tvb_get_ntohs(tvb, offset + 2);
738 proto_tree_add_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 2,
740 flags = tvb_get_guint8(tvb, offset + 4);
741 tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags_v1, tvb, offset + 4, 1,
743 srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
744 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_overflow,
745 tvb, offset+4, 1, flags);
746 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_monolingual,
747 tvb, offset+4, 1, flags);
748 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_url_auth,
749 tvb, offset+4, 1, flags);
750 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_attribute_auth,
751 tvb, offset+4, 1, flags);
752 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_fresh,
753 tvb, offset+4, 1, flags);
754 proto_tree_add_text(srvloc_tree, tvb, offset + 5, 1, "Dialect: %u",
755 tvb_get_guint8(tvb, offset + 5));
756 proto_tree_add_text(srvloc_tree, tvb, offset + 6, 2, "Language: %s",
757 tvb_format_text(tvb, offset + 6, 2));
758 encoding = tvb_get_ntohs(tvb, offset + 8);
759 proto_tree_add_text(srvloc_tree, tvb, offset + 8, 2, "Encoding: %u (%s)",
761 val_to_str(encoding, charsets, "Unknown"));
762 proto_tree_add_text(srvloc_tree, tvb, offset + 10, 2, "Transaction ID: %u",
763 tvb_get_ntohs(tvb, offset + 10));
768 length = tvb_get_ntohs(tvb, offset);
769 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
771 add_v1_string(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, encoding);
773 length = tvb_get_ntohs(tvb, offset);
774 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
776 add_v1_string(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, encoding);
781 proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
783 count = tvb_get_ntohs(tvb, offset);
784 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
787 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree,
794 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree, encoding,
796 length = tvb_get_ntohs(tvb, offset);
797 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
799 add_v1_string(srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, encoding);
801 if ( (flags & FLAG_A) == FLAG_A )
802 offset = dissect_authblk(tvb, offset, srvloc_tree);
806 length = tvb_get_ntohs(tvb, offset);
807 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2, length);
809 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, length, encoding);
811 if ( (flags & FLAG_U) == FLAG_U )
812 offset = dissect_authblk(tvb, offset, srvloc_tree);
813 length = tvb_get_ntohs(tvb, offset);
814 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
816 add_v1_string(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, encoding);
819 * XXX - this was there before, but RFC 2165 doesn't speak
820 * of there being an attribute authentication block in
821 * a Service Deregister message. Is that a post-RFC-2165
824 if ( (flags & FLAG_A) == FLAG_A )
825 offset = dissect_authblk(tvb, offset, srvloc_tree);
829 proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
834 length = tvb_get_ntohs(tvb, offset);
835 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
837 add_v1_string(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, encoding);
839 length = tvb_get_ntohs(tvb, offset);
840 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
842 add_v1_string(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, encoding);
844 length = tvb_get_ntohs(tvb, offset);
845 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
847 add_v1_string(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, encoding);
849 length = tvb_get_ntohs(tvb, offset);
850 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_attrlistlen, tvb, offset, 2, length);
852 add_v1_string(srvloc_tree, hf_srvloc_attrreq_attrlist, tvb, offset, length, encoding);
857 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
859 length = tvb_get_ntohs(tvb, offset);
860 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
863 attr_list(srvloc_tree, hf_srvloc_attrrply_attrlist, tvb, offset, length, encoding);
865 if ( (flags & FLAG_A) == FLAG_A )
866 offset = dissect_authblk(tvb, offset, srvloc_tree);
871 proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
873 length = tvb_get_ntohs(tvb, offset);
874 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
876 add_v1_string(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, encoding);
878 length = tvb_get_ntohs(tvb, offset);
879 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
881 add_v1_string(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, encoding);
886 length = tvb_get_ntohs(tvb, offset);
887 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
889 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, encoding);
891 length = tvb_get_ntohs(tvb, offset);
892 /* Updated by Greg Morris on 1-30-04 */
893 if (0xFFFF == length) {
894 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
899 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
901 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, encoding);
904 length = tvb_get_ntohs(tvb, offset);
905 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
907 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, encoding);
912 proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
914 count = tvb_get_ntohs(tvb, offset);
915 proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Service Type Count: %u",
919 length = tvb_get_ntohs(tvb, offset);
920 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelen, tvb, offset, 2, length);
922 add_v1_string(srvloc_tree, hf_srvloc_srvtyperply_srvtype, tvb, offset, length, encoding);
929 proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
932 else { /* Version 2 */
933 length = tvb_get_ntoh24(tvb, offset + 2);
934 proto_tree_add_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 3,
936 flags = tvb_get_ntohs(tvb, offset + 5);
937 tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags_v2, tvb, offset + 5, 2,
939 srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
940 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_overflow,
941 tvb, offset+5, 1, flags);
942 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_fresh,
943 tvb, offset+5, 1, flags);
944 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_reqmulti,
945 tvb, offset+5, 1, flags);
947 next_ext_off = tvb_get_ntoh24(tvb, offset + 7);
948 proto_tree_add_uint(srvloc_tree, hf_srvloc_nextextoff, tvb, offset + 7, 3,
950 proto_tree_add_uint(srvloc_tree, hf_srvloc_xid, tvb, offset + 10, 2,
951 tvb_get_ntohs(tvb, offset + 10));
952 lang_tag_len = tvb_get_ntohs(tvb, offset + 12);
953 proto_tree_add_uint(srvloc_tree, hf_srvloc_langtaglen, tvb, offset + 12, 2, lang_tag_len);
954 proto_tree_add_item(srvloc_tree, hf_srvloc_langtag, tvb, offset + 14, lang_tag_len, TRUE);
955 offset += 14+lang_tag_len;
958 case SRVREQ: /* RFC2608 8.1 */
959 length = tvb_get_ntohs(tvb, offset);
960 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
962 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, TRUE);
964 length = tvb_get_ntohs(tvb, offset);
965 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_srvtypelen, tvb, offset, 2, length);
967 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_srvtypelist, tvb, offset, length, TRUE);
969 length = tvb_get_ntohs(tvb, offset);
970 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_scopelistlen, tvb, offset, 2, length);
972 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_scopelist, tvb, offset, length, TRUE);
974 length = tvb_get_ntohs(tvb, offset);
975 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
977 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, TRUE);
979 length = tvb_get_ntohs(tvb, offset);
980 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_slpspilen, tvb, offset, 2, length);
982 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_slpspi, tvb, offset, length, TRUE);
986 case SRVRPLY: /* RFC2608 8.2 */
987 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
989 count = tvb_get_ntohs(tvb, offset);
990 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
993 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
998 case SRVREG: /* RFC2608 8.3 */
999 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1000 length = tvb_get_ntohs(tvb, offset);
1001 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_srvtypelen, tvb, offset, 2, length);
1003 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_srvtype, tvb, offset, length, TRUE);
1005 length = tvb_get_ntohs(tvb, offset);
1006 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_scopelistlen, tvb, offset, 2, length);
1008 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_scopelist, tvb, offset, length, TRUE);
1010 length = tvb_get_ntohs(tvb, offset);
1011 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
1013 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, TRUE);
1015 count = tvb_get_guint8(tvb, offset);
1016 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrauthcount, tvb, offset, 1, count);
1019 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1024 case SRVDEREG: /* RFC2608 10.6 */
1025 length = tvb_get_ntohs(tvb, offset);
1026 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_scopelistlen, tvb, offset, 2, length);
1028 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_scopelist, tvb, offset, length, TRUE);
1030 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1031 length = tvb_get_ntohs(tvb, offset);
1032 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
1034 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, TRUE);
1038 case SRVACK: /* RFC2608 8.4 */
1039 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1043 case ATTRRQST: /* RFC2608 10.3*/
1044 length = tvb_get_ntohs(tvb, offset);
1045 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
1047 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, TRUE);
1049 length = tvb_get_ntohs(tvb, offset);
1050 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
1052 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, TRUE);
1054 length = tvb_get_ntohs(tvb, offset);
1055 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
1057 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, TRUE);
1059 length = tvb_get_ntohs(tvb, offset);
1060 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_taglistlen, tvb, offset, 2, length);
1062 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_taglist, tvb, offset, length, TRUE);
1064 length = tvb_get_ntohs(tvb, offset);
1065 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_slpspilen, tvb, offset, 2, length);
1067 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_slpspi, tvb, offset, length, TRUE);
1071 case ATTRRPLY: /* RFC2608 10.4 */
1072 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1074 length = tvb_get_ntohs(tvb, offset);
1075 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
1078 attr_list(srvloc_tree, hf_srvloc_attrrply_attrlist, tvb, offset, length, CHARSET_UTF_8);
1080 count = tvb_get_guint8(tvb, offset);
1081 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrauthcount, tvb, offset, 1, count);
1084 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1090 case DAADVERT: /* RCC 2608 8.5 */
1091 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1094 ts.secs = tvb_get_ntohl(tvb, offset);
1095 proto_tree_add_time(srvloc_tree, hf_srvloc_daadvert_timestamp, tvb, offset, 4,
1098 length = tvb_get_ntohs(tvb, offset);
1099 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
1101 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, TRUE);
1103 length = tvb_get_ntohs(tvb, offset);
1104 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
1106 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, TRUE);
1108 length = tvb_get_ntohs(tvb, offset);
1109 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_attrlistlen, tvb, offset, 2, length);
1111 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_attrlist, tvb, offset, length, TRUE);
1113 length = tvb_get_ntohs(tvb, offset);
1114 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_slpspilen, tvb, offset, 2, length);
1116 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_slpspi, tvb, offset, length, TRUE);
1118 count = tvb_get_guint8(tvb, offset);
1119 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_authcount, tvb, offset, 1, count);
1122 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1127 case SRVTYPERQST: /* RFC2608 10.1 */
1128 length = tvb_get_ntohs(tvb, offset);
1129 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
1131 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, TRUE);
1133 length = tvb_get_ntohs(tvb, offset);
1134 if (0xFFFF == length) {
1135 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
1138 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
1140 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, TRUE);
1143 length = tvb_get_ntohs(tvb, offset);
1144 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
1146 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, TRUE);
1150 case SRVTYPERPLY: /* rfc2608 10.2 */
1151 proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1153 length = tvb_get_ntohs(tvb, offset);
1154 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelistlen, tvb, offset, 2, length);
1156 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtyperply_srvtypelist, tvb, offset, length, TRUE);
1159 case SAADVERT: /* rfc2608 10.2 */
1160 length = tvb_get_ntohs(tvb, offset);
1161 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_urllen, tvb, offset, 2,
1164 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_url, tvb, offset, length, TRUE);
1166 length = tvb_get_ntohs(tvb, offset);
1167 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_scopelistlen, tvb, offset, 2, length);
1169 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_scopelist, tvb, offset, length, TRUE);
1171 length = tvb_get_ntohs(tvb, offset);
1172 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_attrlistlen, tvb, offset, 2, length);
1174 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_attrlist, tvb, offset, length, TRUE);
1176 count = tvb_get_guint8(tvb, offset);
1177 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_authcount, tvb, offset, 1, length);
1180 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1186 proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
1193 get_srvloc_pdu_len(tvbuff_t *tvb, int offset)
1196 * Get the length of the SRVLOC packet.
1197 * It starts at offset+2, but it's 2 bytes in SLPv1 and 3 bytes
1200 if (tvb_get_guint8(tvb, offset) == 2)
1201 return tvb_get_ntoh24(tvb, offset + 2);
1203 return tvb_get_ntohs(tvb, offset + 2);
1207 dissect_srvloc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1209 proto_tree *srvloc_tree = NULL;
1212 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1213 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
1215 if (check_col(pinfo->cinfo, COL_INFO))
1216 col_clear(pinfo->cinfo, COL_INFO);
1219 ti = proto_tree_add_item(tree, proto_srvloc, tvb, 0, -1, FALSE);
1220 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
1222 dissect_srvloc(tvb, pinfo, srvloc_tree);
1226 dissect_srvloc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1229 * XXX - in SLPv1, the fixed length need only be 4, as the length
1230 * is 2 bytes long; however, it must be 5 for SLPv2, as the length
1231 * is 3 bytes long, and there's probably no harm in asking for 5
1232 * bytes, as even SLPv1 packets start with a 12-byte header,
1233 * and if the packet has a length that's 4 or less, it's bogus,
1234 * and we can't handle a length < 4 anyway.
1236 tcp_dissect_pdus(tvb, pinfo, tree, srvloc_desegment, 5, get_srvloc_pdu_len,
1237 dissect_srvloc_pdu);
1240 /* Register protocol with Ethereal. */
1243 proto_register_srvloc(void)
1245 static hf_register_info hf[] = {
1246 /* Helper functions for the Version 1 Header*/
1248 {"Error Code", "srvloc.err",
1249 FT_UINT16, BASE_DEC, VALS(srvloc_errs), 0x0,
1253 /* Helper function for the Version 2 Header */
1254 {&hf_srvloc_error_v2,
1255 {"Error Code", "srvloc.errv2",
1256 FT_UINT16, BASE_DEC, VALS(srvloc_errs_v2), 0x0,
1260 {"XID", "srvloc.xid",
1261 FT_UINT24, BASE_DEC, NULL, 0x0,
1262 "Transaction ID", HFILL }
1264 {&hf_srvloc_langtag,
1265 {"Lang Tag", "srvloc.langtag",
1266 FT_STRING, BASE_NONE, NULL, 0x0,
1269 {&hf_srvloc_langtaglen,
1270 {"Lang Tag Len", "srvloc.langtaglen",
1271 FT_UINT16, BASE_DEC, NULL, 0x0,
1274 {&hf_srvloc_nextextoff,
1275 {"Next Extension Offset", "srvloc.nextextoff",
1276 FT_UINT24, BASE_DEC, NULL, 0x0,
1280 /* Helper functions for URL and URL Entry parsing - both versions */
1281 {&hf_srvloc_url_reserved,
1282 {"Reserved", "srvloc.url.reserved",
1283 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
1285 {&hf_srvloc_url_lifetime,
1286 {"URL lifetime", "srvloc.url.lifetime",
1287 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1289 {&hf_srvloc_url_urllen,
1290 {"URL Length", "srvloc.url.urllen",
1291 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1293 {&hf_srvloc_url_url,
1294 {"URL", "srvloc.url.url",
1295 FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }
1297 {&hf_srvloc_url_numauths,
1298 {"Num Auths", "srvloc.url.numauths",
1299 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
1302 /* Helper functions for the common header fields */
1303 {&hf_srvloc_function,
1304 {"Function", "srvloc.function",
1305 FT_UINT8, BASE_DEC, VALS(srvloc_functions), 0x0,
1310 {"Packet Length", "srvloc.pktlen",
1311 FT_UINT24, BASE_DEC, NULL, 0x0,
1315 { &hf_srvloc_version,
1316 { "Version", "srvloc.version",
1317 FT_UINT8, BASE_DEC, NULL, 0x0,
1321 {&hf_srvloc_flags_v1,
1322 {"Flags", "srvloc.flags_v1",
1323 FT_UINT8, BASE_HEX, NULL, 0x0,
1327 { &hf_srvloc_flags_v1_overflow,
1328 { "Overflow", "srvloc.flags_v1.overflow.", FT_BOOLEAN, 8,
1329 TFS(&tfs_srvloc_flags_overflow), FLAG_O, "Can whole packet fit into a datagram?", HFILL }},
1331 { &hf_srvloc_flags_v1_monolingual,
1332 { "Monolingual", "srvloc.flags_v1.monolingual", FT_BOOLEAN, 8,
1333 TFS(&tfs_srvloc_flags_v1_monolingual), FLAG_M, "Can whole packet fit into a datagram?", HFILL }},
1335 { &hf_srvloc_flags_v1_url_auth,
1336 { "URL Authentication", "srvloc.flags_v1.url_auth", FT_BOOLEAN, 8,
1337 TFS(&tfs_srvloc_flags_v1_url_auth), FLAG_U, "Can whole packet fit into a datagram?", HFILL }},
1339 { &hf_srvloc_flags_v1_attribute_auth,
1340 { "Attribute Authentication", "srvloc.flags_v1.attribute_auth", FT_BOOLEAN, 8,
1341 TFS(&tfs_srvloc_flags_v1_attribute_auth), FLAG_A, "Can whole packet fit into a datagram?", HFILL }},
1343 { &hf_srvloc_flags_v1_fresh,
1344 { "Fresh Registration", "srvloc.flags_v1.fresh", FT_BOOLEAN, 8,
1345 TFS(&tfs_srvloc_flags_fresh), FLAG_F, "Is this a new registration?", HFILL }},
1347 {&hf_srvloc_flags_v2,
1348 {"Flags", "srvloc.flags_v2",
1349 FT_UINT16, BASE_HEX, NULL, 0x0,
1353 { &hf_srvloc_flags_v2_overflow,
1354 { "Overflow", "srvloc.flags_v2.overflow", FT_BOOLEAN, 16,
1355 TFS(&tfs_srvloc_flags_overflow), FLAG_O_V2, "Can whole packet fit into a datagram?", HFILL }},
1357 { &hf_srvloc_flags_v2_fresh,
1358 { "Fresh Registration", "srvloc.flags_v2.fresh", FT_BOOLEAN, 16,
1359 TFS(&tfs_srvloc_flags_fresh), FLAG_F_V2, "Is this a new registration?", HFILL }},
1361 { &hf_srvloc_flags_v2_reqmulti,
1362 { "Multicast requested", "srvloc.flags_v2.reqmulti", FT_BOOLEAN, 16,
1363 TFS(&tfs_srvloc_flags_v2_reqmulti), FLAG_R_V2, "Do we want multicast?", HFILL }},
1365 /* collection of helper functions for dissect_authblk_v2 */
1366 { &hf_srvloc_authblkv2_bsd,
1367 { "BSD", "srvloc.authblkv2_bsd", FT_UINT16, BASE_HEX, NULL, 0x0,
1368 "Block Structure Descriptor", HFILL}
1370 { &hf_srvloc_authblkv2_len,
1371 { "Length", "srvloc.authblkv2_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1372 "Length of Authentication Block", HFILL}
1374 { &hf_srvloc_authblkv2_timestamp,
1375 { "Timestamp", "srvloc.authblkv2.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
1376 NULL, 0, "Timestamp on Authentication Block", HFILL }
1378 { &hf_srvloc_authblkv2_slpspilen,
1379 { "SLP SPI Length", "srvloc.authblkv2.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1380 "Length of the SLP SPI", HFILL}
1382 { &hf_srvloc_authblkv2_slpspi,
1383 { "SLP SPI", "srvloc.authblkv2.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1387 /* collection of helper functions for Service Request */
1388 { &hf_srvloc_srvreq_prlistlen,
1389 { "Previous Response List Length", "srvloc.srvreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1390 "Length of Previous Response List", HFILL}
1392 { &hf_srvloc_srvreq_prlist,
1393 { "Previous Response List", "srvloc.srvreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1394 "Previous Response List", HFILL}
1396 { &hf_srvloc_srvreq_srvtypelen,
1397 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1398 "Length of Service Type List", HFILL}
1400 { &hf_srvloc_srvreq_srvtypelist,
1401 { "Service Type List", "srvloc.srvreq.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1404 { &hf_srvloc_srvreq_scopelistlen,
1405 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1406 "Length of the Scope List", HFILL}
1408 { &hf_srvloc_srvreq_scopelist,
1409 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1412 { &hf_srvloc_srvreq_predicatelen,
1413 { "Predicate Length", "srvloc.srvreq.predicatelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1414 "Length of the Predicate", HFILL}
1416 { &hf_srvloc_srvreq_predicate,
1417 { "Predicate", "srvloc.srvreq.predicate", FT_STRING, BASE_NONE, NULL, 0x0,
1420 { &hf_srvloc_srvreq_slpspilen,
1421 { "SLP SPI Length", "srvloc.srvreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1422 "Length of the SLP SPI", HFILL}
1424 { &hf_srvloc_srvreq_slpspi,
1425 { "SLP SPI", "srvloc.srvreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1429 /* Helper function for Service Request */
1430 { &hf_srvloc_srvrply_urlcount,
1431 { "Number of URLs", "srvloc.srvreq.urlcount", FT_UINT16, BASE_DEC, NULL, 0x0,
1435 /* Helper functions for Service Registration */
1436 { &hf_srvloc_srvreg_srvtypelen,
1437 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1440 { &hf_srvloc_srvreg_srvtype,
1441 { "Service Type", "srvloc.srvreq.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1444 { &hf_srvloc_srvreg_scopelistlen,
1445 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1448 { &hf_srvloc_srvreg_scopelist,
1449 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1452 { &hf_srvloc_srvreg_attrlistlen,
1453 { "Attribute List Length", "srvloc.srvreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1456 { &hf_srvloc_srvreg_attrlist,
1457 { "Attribute List", "srvloc.srvreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1460 { &hf_srvloc_srvreg_attrauthcount,
1461 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1462 "Number of Attribute Authentication Blocks", HFILL}
1465 /* Helper functions for Service Deregistration */
1466 { &hf_srvloc_srvdereg_scopelistlen,
1467 { "Scope List Length", "srvloc.srvdereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1470 { &hf_srvloc_srvdereg_scopelist,
1471 { "Scope List", "srvloc.srvdereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1474 { &hf_srvloc_srvdereg_taglistlen,
1475 { "Tag List Length", "srvloc.srvdereq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1478 { &hf_srvloc_srvdereg_taglist,
1479 { "Tag List", "srvloc.srvdereq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1484 /* collection of helper functions for Attribute Request */
1485 { &hf_srvloc_attrreq_prlistlen,
1486 { "Previous Response List Length", "srvloc.attrreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1487 "Length of Previous Response List", HFILL}
1489 { &hf_srvloc_attrreq_prlist,
1490 { "Previous Response List", "srvloc.attrreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1491 "Previous Response List", HFILL}
1493 { &hf_srvloc_attrreq_urllen,
1494 { "URL Length", "srvloc.attrreq.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1497 { &hf_srvloc_attrreq_url,
1498 { "Service URL", "srvloc.attrreq.url", FT_STRING, BASE_NONE, NULL, 0x0,
1499 "URL of service", HFILL}
1501 { &hf_srvloc_attrreq_scopelistlen,
1502 { "Scope List Length", "srvloc.attrreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1503 "Length of the Scope List", HFILL}
1505 { &hf_srvloc_attrreq_scopelist,
1506 { "Scope List", "srvloc.attrreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1509 { &hf_srvloc_attrreq_attrlistlen,
1510 { "Attribute List Length", "srvloc.attrreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1513 { &hf_srvloc_attrreq_attrlist,
1514 { "Attribute List", "srvloc.attrreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1517 { &hf_srvloc_attrreq_taglistlen,
1518 { "Tag List Length", "srvloc.attrreq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1521 { &hf_srvloc_attrreq_taglist,
1522 { "Tag List", "srvloc.attrreq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1525 { &hf_srvloc_attrreq_slpspilen,
1526 { "SLP SPI Length", "srvloc.attrreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1527 "Length of the SLP SPI", HFILL}
1529 { &hf_srvloc_attrreq_slpspi,
1530 { "SLP SPI", "srvloc.attrreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1534 /* collection of helper functions for Attribute Reply */
1535 { &hf_srvloc_attrrply_attrlistlen,
1536 { "Attribute List Length", "srvloc.attrrply.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1537 "Length of Attribute List", HFILL}
1539 { &hf_srvloc_attrrply_attrlist,
1540 { "Attribute List", "srvloc.attrrply.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1543 { &hf_srvloc_attrrply_attrauthcount,
1544 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1545 "Number of Attribute Authentication Blocks", HFILL}
1548 /* collection of helper functions for DA Advertisement */
1549 { &hf_srvloc_daadvert_timestamp,
1550 { "DAADVERT Timestamp", "srvloc.daadvert.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
1551 NULL, 0, "Timestamp on DA Advert", HFILL }
1553 { &hf_srvloc_daadvert_urllen,
1554 { "URL Length", "srvloc.daadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1557 { &hf_srvloc_daadvert_url,
1558 { "URL", "srvloc.daadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1561 { &hf_srvloc_daadvert_scopelistlen,
1562 { "Scope List Length", "srvloc.daadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1563 "Length of the Scope List", HFILL}
1565 { &hf_srvloc_daadvert_scopelist,
1566 { "Scope List", "srvloc.daadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1569 { &hf_srvloc_daadvert_attrlistlen,
1570 { "Attribute List Length", "srvloc.daadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1573 { &hf_srvloc_daadvert_attrlist,
1574 { "Attribute List", "srvloc.daadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1577 { &hf_srvloc_daadvert_slpspilen,
1578 { "SLP SPI Length", "srvloc.daadvert.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1579 "Length of the SLP SPI", HFILL}
1581 { &hf_srvloc_daadvert_slpspi,
1582 { "SLP SPI", "srvloc.daadvert.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1585 { &hf_srvloc_daadvert_authcount,
1586 { "Auths", "srvloc.daadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1587 "Number of Authentication Blocks", HFILL}
1590 /* collection of helper functions for Service Type Request */
1591 { &hf_srvloc_srvtypereq_prlistlen,
1592 { "Previous Response List Length", "srvloc.srvtypereq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1593 "Length of Previous Response List", HFILL}
1595 { &hf_srvloc_srvtypereq_prlist,
1596 { "Previous Response List", "srvloc.srvtypereq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1597 "Previous Response List", HFILL}
1599 { &hf_srvloc_srvtypereq_nameauthlistlen,
1600 { "Naming Authority List Length", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1601 "Length of the Naming Authority List", HFILL}
1603 { &hf_srvloc_srvtypereq_nameauthlistlenall,
1604 { "Naming Authority List Length (All Naming Authorities)", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1605 "Length of the Naming Authority List", HFILL}
1607 { &hf_srvloc_srvtypereq_nameauthlist,
1608 { "Naming Authority List", "srvloc.srvtypereq.nameauthlist", FT_STRING, BASE_NONE, NULL, 0x0,
1611 { &hf_srvloc_srvtypereq_scopelistlen,
1612 { "Scope List Length", "srvloc.srvtypereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1613 "Length of the Scope List", HFILL}
1615 { &hf_srvloc_srvtypereq_scopelist,
1616 { "Scope List", "srvloc.srvtypereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1620 /* collection of helper functions for Service Type Replies */
1621 { &hf_srvloc_srvtyperply_srvtypelen,
1622 { "Service Type Length", "srvloc.srvtypereq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1623 "Length of the Service Type", HFILL}
1625 { &hf_srvloc_srvtyperply_srvtype,
1626 { "Service Type", "srvloc.srvtyperply.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1629 { &hf_srvloc_srvtyperply_srvtypelistlen,
1630 { "Service Type List Length", "srvloc.srvtypereq.srvtypelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1631 "Length of the Service Type List", HFILL}
1633 { &hf_srvloc_srvtyperply_srvtypelist,
1634 { "Service Type List", "srvloc.srvtyperply.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1638 /* collection of helper functions for SA Advertisement */
1639 { &hf_srvloc_saadvert_urllen,
1640 { "URL Length", "srvloc.saadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1643 { &hf_srvloc_saadvert_url,
1644 { "URL", "srvloc.saadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1647 { &hf_srvloc_saadvert_scopelistlen,
1648 { "Scope List Length", "srvloc.saadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1649 "Length of the Scope List", HFILL}
1651 { &hf_srvloc_saadvert_scopelist,
1652 { "Scope List", "srvloc.saadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1655 { &hf_srvloc_saadvert_attrlistlen,
1656 { "Attribute List Length", "srvloc.saadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1659 { &hf_srvloc_saadvert_attrlist,
1660 { "Attribute List", "srvloc.saadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1663 { &hf_srvloc_saadvert_authcount,
1664 { "Auths", "srvloc.saadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1665 "Number of Authentication Blocks", HFILL}
1667 { &hf_srvloc_add_ref_ip,
1668 { "IP Address", "srvloc.list.ipaddr", FT_IPv4, BASE_DEC, NULL, 0x0,
1669 "IP Address of SLP server", HFILL}
1673 static gint *ett[] = {
1677 module_t *srvloc_module;
1679 proto_srvloc = proto_register_protocol("Service Location Protocol",
1680 "SRVLOC", "srvloc");
1681 proto_register_field_array(proto_srvloc, hf, array_length(hf));
1682 proto_register_subtree_array(ett, array_length(ett));
1683 srvloc_module = prefs_register_protocol(proto_srvloc, NULL);
1684 prefs_register_bool_preference(srvloc_module, "desegment_tcp",
1685 "Desegment all SRVLOC messages spanning multiple TCP segments",
1686 "Whether the SRVLOC dissector should desegment all messages spanning multiple TCP segments",
1691 proto_reg_handoff_srvloc(void)
1693 dissector_handle_t srvloc_handle, srvloc_tcp_handle;
1694 srvloc_handle = create_dissector_handle(dissect_srvloc, proto_srvloc);
1695 dissector_add("udp.port", UDP_PORT_SRVLOC, srvloc_handle);
1696 srvloc_tcp_handle = create_dissector_handle(dissect_srvloc_tcp,
1698 dissector_add("tcp.port", TCP_PORT_SRVLOC, srvloc_tcp_handle);