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.
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
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>
50 #include <epan/prefs.h>
51 #include <epan/emem.h>
52 #include "packet-tcp.h"
53 #include <epan/reassemble.h>
54 #include <epan/expert.h>
56 static proto_item *expert_item = NULL;
57 static guint16 expert_status = 0;
58 static gboolean srvloc_desegment = TRUE;
59 static int proto_srvloc = -1;
60 static int hf_srvloc_version = -1;
61 static int hf_srvloc_function = -1;
62 static int hf_srvloc_pktlen = -1;
63 static int hf_srvloc_xid = -1;
64 static int hf_srvloc_langtaglen = -1;
65 static int hf_srvloc_langtag = -1;
66 static int hf_srvloc_nextextoff = -1;
67 static int hf_srvloc_flags_v1 = -1;
68 static int hf_srvloc_flags_v1_overflow = -1;
69 static int hf_srvloc_flags_v1_monolingual = -1;
70 static int hf_srvloc_flags_v1_url_auth = -1;
71 static int hf_srvloc_flags_v1_attribute_auth = -1;
72 static int hf_srvloc_flags_v1_fresh = -1;
73 static int hf_srvloc_error = -1;
74 static int hf_srvloc_flags_v2 = -1;
75 static int hf_srvloc_flags_v2_overflow = -1;
76 static int hf_srvloc_flags_v2_fresh = -1;
77 static int hf_srvloc_flags_v2_reqmulti = -1;
78 static int hf_srvloc_error_v2 = -1;
79 static int hf_srvloc_daadvert_timestamp = -1;
80 static int hf_srvloc_daadvert_urllen = -1;
81 static int hf_srvloc_daadvert_url = -1;
82 static int hf_srvloc_daadvert_scopelistlen = -1;
83 static int hf_srvloc_daadvert_scopelist = -1;
84 static int hf_srvloc_daadvert_attrlistlen = -1;
85 static int hf_srvloc_daadvert_attrlist = -1;
86 static int hf_srvloc_daadvert_slpspilen = -1;
87 static int hf_srvloc_daadvert_slpspi = -1;
88 static int hf_srvloc_daadvert_authcount = -1;
89 static int hf_srvloc_srvreq_prlistlen = -1;
90 static int hf_srvloc_srvreq_prlist = -1;
91 static int hf_srvloc_srvreq_srvtypelen = -1;
92 static int hf_srvloc_srvreq_srvtypelist = -1;
93 static int hf_srvloc_srvreq_scopelistlen = -1;
94 static int hf_srvloc_srvreq_scopelist = -1;
95 static int hf_srvloc_srvreq_predicatelen = -1;
96 static int hf_srvloc_srvreq_predicate = -1;
97 static int hf_srvloc_srvreq_slpspilen = -1;
98 static int hf_srvloc_srvreq_slpspi = -1;
99 static int hf_srvloc_srvrply_urlcount = -1;
100 static int hf_srvloc_srvreg_attrlistlen = -1;
101 static int hf_srvloc_srvreg_attrlist = -1;
102 static int hf_srvloc_srvreg_attrauthcount = -1;
103 static int hf_srvloc_srvreg_srvtypelen = -1;
104 static int hf_srvloc_srvreg_srvtype = -1;
105 static int hf_srvloc_srvreg_scopelistlen = -1;
106 static int hf_srvloc_srvreg_scopelist = -1;
107 static int hf_srvloc_srvdereg_scopelistlen = -1;
108 static int hf_srvloc_srvdereg_scopelist = -1;
109 static int hf_srvloc_srvdereg_taglistlen = -1;
110 static int hf_srvloc_srvdereg_taglist = -1;
111 static int hf_srvloc_attrreq_prlistlen = -1;
112 static int hf_srvloc_attrreq_prlist = -1;
113 static int hf_srvloc_attrreq_urllen = -1;
114 static int hf_srvloc_attrreq_url = -1;
115 static int hf_srvloc_attrreq_scopelistlen = -1;
116 static int hf_srvloc_attrreq_scopelist = -1;
117 static int hf_srvloc_attrreq_attrlistlen = -1;
118 static int hf_srvloc_attrreq_attrlist = -1;
119 static int hf_srvloc_attrreq_taglistlen = -1;
120 static int hf_srvloc_attrreq_taglist = -1;
121 static int hf_srvloc_attrreq_slpspilen = -1;
122 static int hf_srvloc_attrreq_slpspi = -1;
123 static int hf_srvloc_attrrply_attrlistlen = -1;
124 static int hf_srvloc_attrrply_attrlist = -1;
125 static int hf_srvloc_attrrply_attrauthcount = -1;
126 static int hf_srvloc_srvtypereq_prlistlen = -1;
127 static int hf_srvloc_srvtypereq_prlist = -1;
128 static int hf_srvloc_srvtypereq_nameauthlistlen = -1;
129 static int hf_srvloc_srvtypereq_nameauthlistlenall = -1;
130 static int hf_srvloc_srvtypereq_nameauthlist = -1;
131 static int hf_srvloc_srvtypereq_scopelistlen = -1;
132 static int hf_srvloc_srvtypereq_scopelist = -1;
133 static int hf_srvloc_srvtyperply_srvtypelen = -1;
134 static int hf_srvloc_srvtyperply_srvtype = -1;
135 static int hf_srvloc_srvtyperply_srvtypelistlen = -1;
136 static int hf_srvloc_srvtyperply_srvtypelist = -1;
137 static int hf_srvloc_saadvert_urllen = -1;
138 static int hf_srvloc_saadvert_url = -1;
139 static int hf_srvloc_saadvert_scopelistlen = -1;
140 static int hf_srvloc_saadvert_scopelist = -1;
141 static int hf_srvloc_saadvert_attrlistlen = -1;
142 static int hf_srvloc_saadvert_attrlist = -1;
143 static int hf_srvloc_saadvert_authcount = -1;
144 static int hf_srvloc_authblkv2_bsd = -1;
145 static int hf_srvloc_authblkv2_len = -1;
146 static int hf_srvloc_authblkv2_timestamp = -1;
147 static int hf_srvloc_authblkv2_slpspilen = -1;
148 static int hf_srvloc_authblkv2_slpspi = -1;
149 static int hf_srvloc_url_reserved = -1;
150 static int hf_srvloc_url_lifetime = -1;
151 static int hf_srvloc_url_urllen = -1;
152 static int hf_srvloc_url_url = -1;
153 static int hf_srvloc_url_numauths = -1;
154 static int hf_srvloc_add_ref_ip = -1;
155 static int hf_srvloc_srvrply_svcname = -1;
158 static gint ett_srvloc = -1;
159 static gint ett_srvloc_attr = -1;
160 static gint ett_srvloc_flags = -1;
163 static const true_false_string tfs_srvloc_flags_overflow = {
164 "Message will not fit in datagram",
165 "Message will fit in a datagram"
167 static const true_false_string tfs_srvloc_flags_v1_monolingual = {
168 "Only responses in specified language will be accepted",
169 "Responses in any language will be accepted"
171 static const true_false_string tfs_srvloc_flags_v1_url_auth = {
172 "URL Authentication Block is present",
173 "URL Authentication Block is absent"
175 static const true_false_string tfs_srvloc_flags_v1_attribute_auth = {
176 "Attribute Authentication Block is present",
177 "Attribute Authentication Block is absent"
179 static const true_false_string tfs_srvloc_flags_fresh = {
180 "New Service Registration",
181 "Not a new Service Registration"
183 static const true_false_string tfs_srvloc_flags_v2_reqmulti = {
184 "Multicast (or broadcast) request",
185 "Not multicast or broadcast"
188 #define TCP_PORT_SRVLOC 427
189 #define UDP_PORT_SRVLOC 427
191 /* Define function types */
201 #define SRVTYPERQST 9
202 #define SRVTYPERPLY 10
203 #define SAADVERT 11 /* SLPv2, section 8 */
205 /* Create protocol header structure */
207 /* bradh: looks like never used. */
208 /* bradh: comment it out for now since it doesn't work for v2
221 /* List to resolve function numbers to names */
223 static const value_string srvloc_functions[] = {
224 { SRVREQ, "Service Request" },
225 { SRVRPLY, "Service Reply" },
226 { SRVREG, "Service Registration" },
227 { SRVDEREG, "Service Deregister" },
228 { SRVACK, "Service Acknowledge" },
229 { ATTRRQST, "Attribute Request" },
230 { ATTRRPLY, "Attribute Reply" },
231 { DAADVERT, "DA Advertisement" },
232 { SRVTYPERQST, "Service Type Request" },
233 { SRVTYPERPLY, "Service Type Reply" },
234 { SAADVERT, "SA Advertisement" }, /* v2 only */
238 /* List to resolve flag values to names */
241 /* Define flag masks */
249 /* it all changes for Version 2 */
250 #define FLAG_O_V2 0x8000
251 #define FLAG_F_V2 0x4000
252 #define FLAG_R_V2 0x2000
254 /* Define Error Codes - Version 1*/
257 #define LANG_NOT_SPTD 1
258 #define PROT_PARSE_ERR 2
260 #define SCOPE_NOT_SPTD 4
261 #define CHRSET_NOT_UND 5
262 #define AUTH_ABSENT 6
263 #define AUTH_FAILED 7
265 /* List to resolve error codes to names */
267 static const value_string srvloc_errs[] = {
268 { SUCCESS, "No Error" },
269 { LANG_NOT_SPTD, "Language not supported" },
270 { PROT_PARSE_ERR, "Protocol parse error" },
271 { INVLD_REG, "Invalid registration" },
272 { SCOPE_NOT_SPTD, "Scope not supported" },
273 { CHRSET_NOT_UND, "Character set not understood" },
274 { AUTH_ABSENT, "Authentication absent" },
275 { AUTH_FAILED, "Authentication failed" },
279 /* Define Error Codes for Version 2 */
281 #define LANGUAGE_NOT_SUPPORTED 1
282 #define PARSE_ERROR 2
283 #define INVALID_REGISTRATION 3
284 #define SCOPE_NOT_SUPPORTED 4
285 #define AUTHENTICATION_UNKNOWN 5
286 #define AUTHENTICATION_ABSENT 6
287 #define AUTHENTICATION_FAILED 7
288 #define VER_NOT_SUPPORTED 9
289 #define INTERNAL_ERROR 10
290 #define DA_BUSY_NOW 11
291 #define OPTION_NOT_UNDERSTOOD 12
292 #define INVALID_UPDATE 13
293 #define MSG_NOT_SUPPORTED 14
294 #define REFRESH_REJECTED 15
296 static const value_string srvloc_errs_v2[] = {
297 { SUCCESS, "No Error" },
298 { LANGUAGE_NOT_SUPPORTED, "No data in the requested language" },
299 { PARSE_ERROR, "The message fails to obey SLP syntax." },
300 { INVALID_REGISTRATION, "The SrvReg has problems" },
301 { SCOPE_NOT_SUPPORTED, "Scope list not supported" },
302 { AUTHENTICATION_UNKNOWN, "Unsupported SLP SPI." },
303 { AUTHENTICATION_ABSENT, "URL and ATTR authentication not provided"},
304 { AUTHENTICATION_FAILED, "Authentication error"},
305 { VER_NOT_SUPPORTED, "Unsupported version number in message header" },
306 { INTERNAL_ERROR, "The DA (or SA) is too sick to respond" },
307 { DA_BUSY_NOW, "UA or SA SHOULD retry" },
308 { OPTION_NOT_UNDERSTOOD, "Unknown option from the mandatory range"},
309 { INVALID_UPDATE, "Invalid SrvReg" },
310 { MSG_NOT_SUPPORTED, "No support for AttrRqst or SrvTypeRqst" },
311 { REFRESH_REJECTED, "SrvReg sent too soon"},
316 * Character encodings.
317 * This is a small subset of what's in
319 * http://www.iana.org/assignments/character-sets
321 * XXX - we should do something useful with this, i.e. properly
322 * handle strings based on the character set they're in.
324 * XXX - what does "properly handle strings" mean? How do we know
325 * what character set the terminal can handle (for tty-based code)
326 * or the GUI can handle (for GUI code)?
328 * XXX - the Wireshark core really should be what does all the
329 * character set handling for strings, and it should be stuck with
330 * the task of figuring out how to properly handle them.
332 #define CHARSET_ASCII 3
333 #define CHARSET_ISO_10646_UTF_1 27
334 #define CHARSET_ISO_646_BASIC 28
335 #define CHARSET_ISO_646_IRV 30
336 #define CHARSET_ISO_8859_1 4
337 #define CHARSET_ISO_10646_UCS_2 1000 /* a/k/a Unicode */
338 #define CHARSET_UTF_7 1012
339 #define CHARSET_UTF_8 106
341 static const value_string charsets[] = {
342 { CHARSET_ASCII, "US-ASCII" },
343 { CHARSET_ISO_10646_UTF_1, "ISO 10646 UTF-1" },
344 { CHARSET_ISO_646_BASIC, "ISO 646 basic:1983" },
345 { CHARSET_ISO_646_IRV, "ISO 646 IRV:1983" },
346 { CHARSET_ISO_8859_1, "ISO 8859-1" },
347 { CHARSET_ISO_10646_UCS_2, "Unicode" },
348 { CHARSET_UTF_7, "UTF-7" },
349 { CHARSET_UTF_8, "UTF-8" },
354 dissect_authblk(tvbuff_t *tvb, int offset, proto_tree *tree)
361 seconds = tvb_get_ntohl(tvb, offset) - 2208988800ul;
362 stamp = gmtime(&seconds);
364 floatsec = stamp->tm_sec + tvb_get_ntohl(tvb, offset + 4) / 4294967296.0;
365 proto_tree_add_text(tree, tvb, offset, 8,
366 "Timestamp: %04d-%02d-%02d %02d:%02d:%07.4f UTC",
367 stamp->tm_year + 1900, stamp->tm_mon + 1,
368 stamp->tm_mday, stamp->tm_hour, stamp->tm_min,
371 proto_tree_add_text(tree, tvb, offset, 8, "Timestamp not representable");
373 proto_tree_add_text(tree, tvb, offset + 8, 2, "Block Structure Desciptor: %u",
374 tvb_get_ntohs(tvb, offset + 8));
375 length = tvb_get_ntohs(tvb, offset + 10);
376 proto_tree_add_text(tree, tvb, offset + 10, 2, "Authenticator length: %u",
379 proto_tree_add_text(tree, tvb, offset, length, "Authentication block: %s",
380 tvb_format_text(tvb, offset, length));
385 /* SLPv2 version - Needs to be fixed to match RFC2608 sect 9.2*/
387 dissect_authblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
392 proto_tree_add_item(tree, hf_srvloc_authblkv2_bsd, tvb, offset, 2, FALSE);
393 proto_tree_add_item(tree, hf_srvloc_authblkv2_len, tvb, offset+2, 2, FALSE);
395 ts.secs = tvb_get_ntohl(tvb, offset + 4);
396 proto_tree_add_time(tree, hf_srvloc_authblkv2_timestamp, tvb, offset+4, 4, &ts);
397 length = tvb_get_ntohs(tvb, offset + 8);
398 proto_tree_add_uint(tree, hf_srvloc_authblkv2_slpspilen, tvb, offset + 8, 2, length);
400 proto_tree_add_item(tree, hf_srvloc_authblkv2_slpspi, tvb, offset, length, TRUE);
402 /* add code in here to handle Structured Authentication Block */
407 dissect_attrauthblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
409 tvb=tvb; tree=tree; /* silence gcc for now */
410 /* add code in here to handle attribute authentication */
415 add_v1_string(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length,
422 case CHARSET_ISO_10646_UCS_2:
423 unicode_str = tvb_get_ephemeral_faked_unicode(tvb, offset, length/2, FALSE);
424 proto_tree_add_string(tree, hf, tvb, offset, length,
429 proto_tree_add_item(tree, hf, tvb, offset, length, TRUE);
435 * XXX - is this trying to guess the byte order?
437 * http://www.iana.org/assignments/character-sets
439 * says of ISO-10646-UCS-2, which has the code 1000 (this routine is used
440 * with CHARSET_ISO_10646_UCS_2, which is #defined to be 1000):
442 * this needs to specify network byte order: the standard
443 * does not specify (it is a 16-bit integer space)
445 * Does that mean that in SRVLOC, ISO-10646-UCS-2 is always big-endian?
446 * If so, can we just use "tvb_get_ephemeral_faked_unicode()" and be
449 * XXX - this is also used with CHARSET_UTF_8. Is that a cut-and-pasteo?
452 unicode_to_bytes(tvbuff_t *tvb, int offset, int length, gboolean endianness)
454 const char *ascii_text = tvb_get_ptr(tvb, offset, length);
456 guint8 c_char, c_char1;
459 /* XXX - Is this the correct behavior? */
464 byte_array = ep_alloc(length*2 + 1);
465 for (i = length; i > 0; i--) {
466 c_char = ascii_text[i];
469 c_char1 = ascii_text[i];
472 c_char1 = ascii_text[i];
474 byte_array[j] = c_char1;
476 byte_array[j] = c_char;
483 byte_array = ep_alloc(length + 1);
484 for (i = 0; i < length; i++) {
485 c_char = ascii_text[i];
487 byte_array[j] = c_char;
498 * Format of x-x-x-xxxxxxxx. Each of these entries represents the service binding to UDP, TCP, or IPX.
499 * The first digit is the protocol family: 2 for TCP/UPD, 6 for IPX.
500 * The second digit is the socket type: 1 for socket stream (TCP), 2 for datagram (UDP and IPX).
501 * The third is the protocol: 6 for TCP, 17 for UDP, and 1000 for IPX.
502 * Last is the IP address, in hex, of the interface that is registered (or, in the case of IPX, an IPX network number).
504 * OpenSLP supports multiple attribute replies so we need to parse the attribute name and then decode accourdingly.
505 * We currently only parse the (non-utf8) attributes:
510 attr_list(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length,
514 int i, svc, ss, type_len, foffset=offset;
518 proto_tree *srvloc_tree;
521 static const value_string srvloc_svc[] = {
527 static const value_string srvloc_ss[] = {
533 static const value_string srvloc_prot[] = {
542 case CHARSET_ISO_10646_UCS_2:
543 while (offset+2<length) {
545 /* If the length passed is longer then the actual payload then this must be an incomplete packet. */
546 if (tvb_length_remaining(tvb, 4)<length) {
547 proto_tree_add_text(tree, tvb, offset, -1, "Status: Too much data to pass inside this protocol. Resubmit request using a streaming protocol like TCP.");
548 proto_tree_add_text(tree, tvb, offset, -1, "Note: Protocol dissection is aborted due to packet overflow. See overflow flag.");
551 /* Parse the attribute name */
552 tmp = tvb_get_ephemeral_faked_unicode(tvb, offset, (length-offset)/2, FALSE);
553 type_len = strcspn(tmp, "=");
554 attr_type = tvb_get_ephemeral_faked_unicode(tvb, offset, type_len, FALSE);
555 proto_tree_add_string(tree, hf, tvb, offset, type_len*2, attr_type);
556 offset += (type_len*2)+2;
557 /* If this is the attribute svcname */
558 if (strcmp(attr_type, "svcname-ws")==0) {
559 tmp = tvb_get_ephemeral_faked_unicode(tvb, offset, (length-offset)/2, FALSE);
560 type_len = strcspn(tmp, ")");
561 add_v1_string(tree, hf_srvloc_srvrply_svcname, tvb, offset, type_len*2, encoding);
562 offset += (type_len*2)+4;
563 strcpy(attr_type, "\0");
565 /* If this is the attribute svcaddr */
566 if (strcmp(attr_type, "svcaddr-ws")==0) {
568 for (foffset = offset; foffset<length; foffset += 2) {
570 ti = proto_tree_add_text(tree, tvb, foffset, -1, "Item %d", i);
571 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc_attr);
573 svc = tvb_get_guint8(tvb, foffset+1);
574 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 1,
575 "Service Type: %s", val_to_str(svc, srvloc_svc, "Unknown"));
576 ss = tvb_get_guint8(tvb, foffset+5);
577 proto_tree_add_text(srvloc_tree, tvb, foffset+5, 1,
578 "Communication Type: %s", val_to_str(ss, srvloc_ss, "Unknown"));
581 if (tvb_get_guint8(tvb, foffset)==54) { /* TCP */
582 prot = tvb_get_guint8(tvb, foffset);
583 proto_tree_add_text(srvloc_tree, tvb, foffset, 1,
584 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
589 byte_value = unicode_to_bytes(tvb, foffset, 4, FALSE); /* UDP */
590 prot = atol(byte_value);
591 proto_tree_add_text(srvloc_tree, tvb, foffset, 4,
592 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
598 byte_value = unicode_to_bytes(tvb, foffset, 8, FALSE); /* IPX */
599 prot = atol(byte_value);
600 proto_tree_add_text(srvloc_tree, tvb, foffset, 8,
601 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
605 byte_value = unicode_to_bytes(tvb, foffset, 16, TRUE); /* IP Address */
606 sscanf(byte_value,"%x",&prot);
607 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+2, 16, prot);
608 byte_value = unicode_to_bytes(tvb, foffset+18, 8, FALSE); /* Port */
609 sscanf(byte_value,"%x",&prot);
610 proto_tree_add_text(srvloc_tree, tvb, foffset+18, 8, "Port: %d", prot);
614 byte_value = unicode_to_bytes(tvb, foffset+2, 16, FALSE); /* IPX Network Address */
615 sscanf(byte_value,"%x",&prot);
616 proto_tree_add_text(srvloc_tree, tvb, foffset+2, 16, "Network: %s", byte_value);
617 byte_value = unicode_to_bytes(tvb, foffset+18, 24, FALSE); /* IPX Node Address */
618 sscanf(byte_value,"%x",&prot);
619 proto_tree_add_text(srvloc_tree, tvb, foffset+18, 24, "Node: %s", byte_value);
620 byte_value = unicode_to_bytes(tvb, foffset+42, 8, FALSE); /* Socket */
621 sscanf(byte_value,"%x",&prot);
622 proto_tree_add_text(srvloc_tree, tvb, foffset+42, 8, "Socket: %s", byte_value);
628 strcpy(attr_type, "\0");
630 /* If there are no more supported attributes available then abort dissection */
631 if (strcmp(attr_type, "svcaddr-ws")!=0 && strcmp(attr_type, "svcname-ws")!=0 && strcmp(attr_type, "\0")!=0) {
638 type_len = strcspn(tvb_get_ptr(tvb, offset, length), "=");
639 attr_type = unicode_to_bytes(tvb, offset+1, type_len-1, FALSE);
640 proto_tree_add_string(tree, hf, tvb, offset+1, type_len-1, attr_type);
642 for (foffset = offset + (type_len); foffset<length; foffset++) {
644 ti = proto_tree_add_text(tree, tvb, foffset, -1, "Item %d", i);
645 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc_attr);
647 svc = tvb_get_guint8(tvb, foffset+1);
648 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 1,
649 "Service Type: %s", val_to_str(svc, srvloc_svc, "Unknown"));
650 ss = tvb_get_guint8(tvb, foffset+3);
651 proto_tree_add_text(srvloc_tree, tvb, foffset+3, 1,
652 "Communication Type: %s", val_to_str(ss, srvloc_ss, "Unknown"));
655 if (tvb_get_guint8(tvb, foffset)==54) { /* TCP */
656 prot = tvb_get_guint8(tvb, foffset);
657 proto_tree_add_text(srvloc_tree, tvb, foffset, 1,
658 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
664 byte_value = unicode_to_bytes(tvb, foffset, 2, FALSE); /* UDP */
665 prot = atol(byte_value);
666 proto_tree_add_text(srvloc_tree, tvb, foffset, 2,
667 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
673 byte_value = unicode_to_bytes(tvb, foffset, 4, FALSE); /* IPX */
674 prot = atol(byte_value);
675 proto_tree_add_text(srvloc_tree, tvb, foffset, 4,
676 "Protocol: %s", val_to_str(prot, srvloc_prot, "Unknown"));
680 byte_value = unicode_to_bytes(tvb, foffset, 8, TRUE); /* IP Address */
681 sscanf(byte_value,"%x",&prot);
682 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+1, 8, prot);
683 byte_value = unicode_to_bytes(tvb, foffset+9, 4, FALSE); /* Port */
684 sscanf(byte_value,"%x",&prot);
685 proto_tree_add_text(srvloc_tree, tvb, foffset+9, 4, "Port: %d", prot);
689 byte_value = unicode_to_bytes(tvb, foffset+1, 8, FALSE); /* IPX Network Address */
690 sscanf(byte_value,"%x",&prot);
691 proto_tree_add_text(srvloc_tree, tvb, foffset+1, 8, "Network: %s", byte_value);
692 byte_value = unicode_to_bytes(tvb, foffset+9, 12, FALSE); /* IPX Node Address */
693 sscanf(byte_value,"%x",&prot);
694 proto_tree_add_text(srvloc_tree, tvb, foffset+9, 12, "Node: %s", byte_value);
695 byte_value = unicode_to_bytes(tvb, foffset+21, 4, FALSE); /* Socket */
696 sscanf(byte_value,"%x",&prot);
697 proto_tree_add_text(srvloc_tree, tvb, foffset+21, 4, "Socket: %s", byte_value);
706 proto_tree_add_item(tree, hf, tvb, offset, length, TRUE);
712 attr_list2(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length, guint16 encoding _U_)
719 proto_tree *attr_tree;
721 /* if we were to decode:
722 * For slp, these 9 characters: (),\!<=>~ and 0x00-1F, 0x7f are reserved and must be escaped in the form \HH
725 /* create a sub tree for attributes */
726 ti = proto_tree_add_item(tree, hf, tvb, offset, length, TRUE);
727 attr_tree = proto_item_add_subtree(ti, ett_srvloc_attr);
729 /* this will ensure there is a terminating null */
730 start = tvb_get_ephemeral_string(tvb, offset, length);
737 cnt++; /* Attribute count */
739 proto_tree_add_text(attr_tree, tvb, offset, x, "Item %d: %s", cnt, start);
742 /* reset string length */
746 /* increment and get next */
751 /* display anything remaining */
754 proto_tree_add_text(attr_tree, tvb, offset, x, "Item %d: %s", cnt, start);
759 dissect_url_entry_v1(tvbuff_t *tvb, int offset, proto_tree *tree,
760 guint16 encoding, guint16 flags)
764 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
767 url_len = tvb_get_ntohs(tvb, offset);
768 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
771 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, url_len, encoding);
773 if ( (flags & FLAG_U) == FLAG_U )
774 offset = dissect_authblk(tvb, offset, tree);
779 dissect_url_entry_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
785 reserved = tvb_get_guint8(tvb, offset);
786 proto_tree_add_uint(tree, hf_srvloc_url_reserved, tvb, offset, 1,
789 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
792 url_len = tvb_get_ntohs(tvb, offset);
793 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
796 proto_tree_add_item(tree, hf_srvloc_url_url, tvb, offset, url_len, TRUE);
798 num_auths = tvb_get_guint8(tvb, offset);
799 proto_tree_add_uint(tree, hf_srvloc_url_numauths, tvb, offset, 1,
802 while (num_auths > 0) {
803 offset = dissect_authblk_v2(tvb, offset, tree);
809 /* Packet dissection routine called by tcp & udp when port 427 detected */
812 dissect_srvloc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
816 proto_tree *srvloc_tree, *srvloc_flags;
820 guint32 length; /* three bytes needed for v2 */
821 guint16 flags; /* two byes needed for v2 */
823 guint32 next_ext_off; /* three bytes, v2 only */
824 guint16 lang_tag_len;
827 if (check_col(pinfo->cinfo, COL_PROTOCOL))
828 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
830 if (check_col(pinfo->cinfo, COL_INFO))
831 col_clear(pinfo->cinfo, COL_INFO);
833 version = tvb_get_guint8(tvb, offset);
834 function = tvb_get_guint8(tvb, offset + 1);
836 if (check_col(pinfo->cinfo, COL_INFO))
837 col_add_str(pinfo->cinfo, COL_INFO,
838 val_to_str(function, srvloc_functions, "Unknown Function (%u)"));
841 ti = proto_tree_add_item(tree, proto_srvloc, tvb, offset, -1, FALSE);
842 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
844 proto_tree_add_uint(srvloc_tree, hf_srvloc_version, tvb, offset, 1,
846 proto_tree_add_uint(srvloc_tree, hf_srvloc_function, tvb, offset + 1, 1,
849 length = tvb_get_ntohs(tvb, offset + 2);
850 proto_tree_add_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 2,
852 flags = tvb_get_guint8(tvb, offset + 4);
853 tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags_v1, tvb, offset + 4, 1,
855 srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
856 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_overflow,
857 tvb, offset+4, 1, flags);
858 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_monolingual,
859 tvb, offset+4, 1, flags);
860 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_url_auth,
861 tvb, offset+4, 1, flags);
862 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_attribute_auth,
863 tvb, offset+4, 1, flags);
864 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v1_fresh,
865 tvb, offset+4, 1, flags);
866 proto_tree_add_text(srvloc_tree, tvb, offset + 5, 1, "Dialect: %u",
867 tvb_get_guint8(tvb, offset + 5));
868 proto_tree_add_text(srvloc_tree, tvb, offset + 6, 2, "Language: %s",
869 tvb_format_text(tvb, offset + 6, 2));
870 encoding = tvb_get_ntohs(tvb, offset + 8);
871 proto_tree_add_text(srvloc_tree, tvb, offset + 8, 2, "Encoding: %u (%s)",
873 val_to_str(encoding, charsets, "Unknown"));
874 proto_tree_add_text(srvloc_tree, tvb, offset + 10, 2, "Transaction ID: %u",
875 tvb_get_ntohs(tvb, offset + 10));
876 /* added echo of XID to info colomn by Greg Morris 0ct 14, 2005 */
877 if (check_col(pinfo->cinfo, COL_INFO))
878 col_append_fstr(pinfo->cinfo, COL_INFO, ", V1 Transaction ID - %u", tvb_get_ntohs(tvb, offset + 10));
884 length = tvb_get_ntohs(tvb, offset);
885 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
887 add_v1_string(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, encoding);
889 length = tvb_get_ntohs(tvb, offset);
890 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
892 add_v1_string(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, encoding);
897 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
898 expert_status = tvb_get_ntohs(tvb, offset);
899 if (expert_status!=0) {
900 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
903 count = tvb_get_ntohs(tvb, offset);
904 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
907 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree,
914 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree, encoding,
916 length = tvb_get_ntohs(tvb, offset);
917 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
919 add_v1_string(srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, encoding);
921 if ( (flags & FLAG_A) == FLAG_A )
922 offset = dissect_authblk(tvb, offset, srvloc_tree);
926 length = tvb_get_ntohs(tvb, offset);
927 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2, length);
929 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, length, encoding);
931 if ( (flags & FLAG_U) == FLAG_U )
932 offset = dissect_authblk(tvb, offset, srvloc_tree);
933 length = tvb_get_ntohs(tvb, offset);
934 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
936 add_v1_string(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, encoding);
939 * XXX - this was there before, but RFC 2165 doesn't speak
940 * of there being an attribute authentication block in
941 * a Service Deregister message. Is that a post-RFC-2165
944 if ( (flags & FLAG_A) == FLAG_A )
945 offset = dissect_authblk(tvb, offset, srvloc_tree);
949 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
950 expert_status = tvb_get_ntohs(tvb, offset);
951 if (expert_status!=0) {
952 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
958 length = tvb_get_ntohs(tvb, offset);
959 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
961 add_v1_string(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, encoding);
963 length = tvb_get_ntohs(tvb, offset);
964 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
966 add_v1_string(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, encoding);
968 length = tvb_get_ntohs(tvb, offset);
969 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
971 add_v1_string(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, encoding);
973 length = tvb_get_ntohs(tvb, offset);
974 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_attrlistlen, tvb, offset, 2, length);
976 add_v1_string(srvloc_tree, hf_srvloc_attrreq_attrlist, tvb, offset, length, encoding);
981 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
982 expert_status = tvb_get_ntohs(tvb, offset);
983 if (expert_status!=0) {
984 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
987 length = tvb_get_ntohs(tvb, offset);
988 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
991 attr_list(srvloc_tree, hf_srvloc_attrrply_attrlist, tvb, offset, length, encoding);
993 if ( (flags & FLAG_A) == FLAG_A )
994 offset = dissect_authblk(tvb, offset, srvloc_tree);
999 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
1000 expert_status = tvb_get_ntohs(tvb, offset);
1001 if (expert_status!=0) {
1002 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
1005 length = tvb_get_ntohs(tvb, offset);
1006 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
1008 add_v1_string(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, encoding);
1010 length = tvb_get_ntohs(tvb, offset);
1011 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
1013 add_v1_string(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, encoding);
1018 length = tvb_get_ntohs(tvb, offset);
1019 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
1021 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, encoding);
1023 length = tvb_get_ntohs(tvb, offset);
1024 /* Updated by Greg Morris on 1-30-04 */
1025 if (0xFFFF == length) {
1026 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
1031 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
1033 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, encoding);
1036 length = tvb_get_ntohs(tvb, offset);
1037 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
1039 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, encoding);
1044 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
1045 expert_status = tvb_get_ntohs(tvb, offset);
1046 if (expert_status!=0) {
1047 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
1050 count = tvb_get_ntohs(tvb, offset);
1051 proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Service Type Count: %u",
1055 length = tvb_get_ntohs(tvb, offset);
1056 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelen, tvb, offset, 2, length);
1058 add_v1_string(srvloc_tree, hf_srvloc_srvtyperply_srvtype, tvb, offset, length, encoding);
1065 expert_item = proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
1066 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Unknown Function Type: %d", function);
1069 else { /* Version 2 */
1070 length = tvb_get_ntoh24(tvb, offset + 2);
1071 proto_tree_add_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 3,
1073 flags = tvb_get_ntohs(tvb, offset + 5);
1074 tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags_v2, tvb, offset + 5, 2,
1076 srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
1077 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_overflow,
1078 tvb, offset+5, 1, flags);
1079 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_fresh,
1080 tvb, offset+5, 1, flags);
1081 proto_tree_add_boolean(srvloc_flags, hf_srvloc_flags_v2_reqmulti,
1082 tvb, offset+5, 1, flags);
1084 next_ext_off = tvb_get_ntoh24(tvb, offset + 7);
1085 proto_tree_add_uint(srvloc_tree, hf_srvloc_nextextoff, tvb, offset + 7, 3,
1087 proto_tree_add_uint(srvloc_tree, hf_srvloc_xid, tvb, offset + 10, 2,
1088 tvb_get_ntohs(tvb, offset + 10));
1089 if (check_col(pinfo->cinfo, COL_INFO))
1090 col_append_fstr(pinfo->cinfo, COL_INFO, ", V2 XID - %u", tvb_get_ntohs(tvb, offset + 10));
1091 lang_tag_len = tvb_get_ntohs(tvb, offset + 12);
1092 proto_tree_add_uint(srvloc_tree, hf_srvloc_langtaglen, tvb, offset + 12, 2, lang_tag_len);
1093 proto_tree_add_item(srvloc_tree, hf_srvloc_langtag, tvb, offset + 14, lang_tag_len, TRUE);
1094 offset += 14+lang_tag_len;
1097 case SRVREQ: /* RFC2608 8.1 */
1098 length = tvb_get_ntohs(tvb, offset);
1099 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
1102 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, TRUE);
1105 length = tvb_get_ntohs(tvb, offset);
1106 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_srvtypelen, tvb, offset, 2, length);
1109 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_srvtypelist, tvb, offset, length, TRUE);
1112 length = tvb_get_ntohs(tvb, offset);
1113 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_scopelistlen, tvb, offset, 2, length);
1116 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_scopelist, tvb, offset, length, TRUE);
1119 length = tvb_get_ntohs(tvb, offset);
1120 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
1123 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, TRUE);
1126 length = tvb_get_ntohs(tvb, offset);
1127 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_slpspilen, tvb, offset, 2, length);
1130 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_slpspi, tvb, offset, length, TRUE);
1135 case SRVRPLY: /* RFC2608 8.2 */
1136 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1137 expert_status = tvb_get_ntohs(tvb, offset);
1138 if (expert_status!=0) {
1139 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1142 count = tvb_get_ntohs(tvb, offset);
1143 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
1146 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1151 case SRVREG: /* RFC2608 8.3 */
1152 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1153 length = tvb_get_ntohs(tvb, offset);
1154 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_srvtypelen, tvb, offset, 2, length);
1157 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_srvtype, tvb, offset, length, TRUE);
1160 length = tvb_get_ntohs(tvb, offset);
1161 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_scopelistlen, tvb, offset, 2, length);
1164 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_scopelist, tvb, offset, length, TRUE);
1167 length = tvb_get_ntohs(tvb, offset);
1168 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
1171 attr_list2(srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, CHARSET_UTF_8);
1174 count = tvb_get_guint8(tvb, offset);
1175 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrauthcount, tvb, offset, 1, count);
1178 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1183 case SRVDEREG: /* RFC2608 10.6 */
1184 length = tvb_get_ntohs(tvb, offset);
1185 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_scopelistlen, tvb, offset, 2, length);
1188 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_scopelist, tvb, offset, length, TRUE);
1191 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1192 length = tvb_get_ntohs(tvb, offset);
1193 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
1196 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, TRUE);
1201 case SRVACK: /* RFC2608 8.4 */
1202 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1203 expert_status = tvb_get_ntohs(tvb, offset);
1204 if (expert_status!=0) {
1205 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1210 case ATTRRQST: /* RFC2608 10.3*/
1211 length = tvb_get_ntohs(tvb, offset);
1212 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
1215 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, TRUE);
1218 length = tvb_get_ntohs(tvb, offset);
1219 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
1222 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, TRUE);
1225 length = tvb_get_ntohs(tvb, offset);
1226 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
1229 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, TRUE);
1232 length = tvb_get_ntohs(tvb, offset);
1233 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_taglistlen, tvb, offset, 2, length);
1236 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_taglist, tvb, offset, length, TRUE);
1239 length = tvb_get_ntohs(tvb, offset);
1240 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_slpspilen, tvb, offset, 2, length);
1243 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_slpspi, tvb, offset, length, TRUE);
1248 case ATTRRPLY: /* RFC2608 10.4 */
1249 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1250 expert_status = tvb_get_ntohs(tvb, offset);
1251 if (expert_status!=0) {
1252 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1255 length = tvb_get_ntohs(tvb, offset);
1256 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
1259 attr_list2(srvloc_tree, hf_srvloc_attrrply_attrlist, tvb, offset, length, CHARSET_UTF_8);
1261 count = tvb_get_guint8(tvb, offset);
1262 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrauthcount, tvb, offset, 1, count);
1265 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1271 case DAADVERT: /* RCC 2608 8.5 */
1272 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1273 expert_status = tvb_get_ntohs(tvb, offset);
1274 if (expert_status!=0) {
1275 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1279 ts.secs = tvb_get_ntohl(tvb, offset);
1280 proto_tree_add_time(srvloc_tree, hf_srvloc_daadvert_timestamp, tvb, offset, 4,
1283 length = tvb_get_ntohs(tvb, offset);
1284 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
1287 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, TRUE);
1290 length = tvb_get_ntohs(tvb, offset);
1291 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
1294 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, TRUE);
1297 length = tvb_get_ntohs(tvb, offset);
1298 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_attrlistlen, tvb, offset, 2, length);
1301 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_attrlist, tvb, offset, length, TRUE);
1304 length = tvb_get_ntohs(tvb, offset);
1305 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_slpspilen, tvb, offset, 2, length);
1308 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_slpspi, tvb, offset, length, TRUE);
1311 count = tvb_get_guint8(tvb, offset);
1312 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_authcount, tvb, offset, 1, count);
1315 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1320 case SRVTYPERQST: /* RFC2608 10.1 */
1321 length = tvb_get_ntohs(tvb, offset);
1322 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
1325 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, TRUE);
1328 length = tvb_get_ntohs(tvb, offset);
1329 if (0xFFFF == length) {
1330 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
1333 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
1336 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, TRUE);
1340 length = tvb_get_ntohs(tvb, offset);
1341 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
1344 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, TRUE);
1349 case SRVTYPERPLY: /* rfc2608 10.2 */
1350 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
1351 expert_status = tvb_get_ntohs(tvb, offset);
1352 if (expert_status!=0) {
1353 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1356 length = tvb_get_ntohs(tvb, offset);
1357 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelistlen, tvb, offset, 2, length);
1360 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtyperply_srvtypelist, tvb, offset, length, TRUE);
1365 case SAADVERT: /* rfc2608 10.2 */
1366 length = tvb_get_ntohs(tvb, offset);
1367 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_urllen, tvb, offset, 2, length);
1370 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_url, tvb, offset, length, TRUE);
1373 length = tvb_get_ntohs(tvb, offset);
1374 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_scopelistlen, tvb, offset, 2, length);
1377 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_scopelist, tvb, offset, length, TRUE);
1380 length = tvb_get_ntohs(tvb, offset);
1381 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_attrlistlen, tvb, offset, 2, length);
1384 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_attrlist, tvb, offset, length, TRUE);
1387 count = tvb_get_guint8(tvb, offset);
1388 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_authcount, tvb, offset, 1, length);
1391 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1397 expert_item = proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
1398 expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "Unknown Function Type: %d", function);
1405 get_srvloc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1408 * Get the length of the SRVLOC packet.
1409 * It starts at offset+2, but it's 2 bytes in SLPv1 and 3 bytes
1412 if (tvb_get_guint8(tvb, offset) == 2)
1413 return tvb_get_ntoh24(tvb, offset + 2);
1415 return tvb_get_ntohs(tvb, offset + 2);
1419 dissect_srvloc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1421 proto_tree *srvloc_tree = NULL;
1424 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1425 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
1427 if (check_col(pinfo->cinfo, COL_INFO))
1428 col_clear(pinfo->cinfo, COL_INFO);
1431 ti = proto_tree_add_item(tree, proto_srvloc, tvb, 0, -1, FALSE);
1432 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
1434 dissect_srvloc(tvb, pinfo, srvloc_tree);
1438 dissect_srvloc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1441 * XXX - in SLPv1, the fixed length need only be 4, as the length
1442 * is 2 bytes long; however, it must be 5 for SLPv2, as the length
1443 * is 3 bytes long, and there's probably no harm in asking for 5
1444 * bytes, as even SLPv1 packets start with a 12-byte header,
1445 * and if the packet has a length that's 4 or less, it's bogus,
1446 * and we can't handle a length < 4 anyway.
1448 tcp_dissect_pdus(tvb, pinfo, tree, srvloc_desegment, 5, get_srvloc_pdu_len,
1449 dissect_srvloc_pdu);
1452 /* Register protocol with Wireshark. */
1455 proto_register_srvloc(void)
1457 static hf_register_info hf[] = {
1458 /* Helper functions for the Version 1 Header*/
1460 {"Error Code", "srvloc.err",
1461 FT_UINT16, BASE_DEC, VALS(srvloc_errs), 0x0,
1465 /* Helper function for the Version 2 Header */
1466 {&hf_srvloc_error_v2,
1467 {"Error Code", "srvloc.errv2",
1468 FT_UINT16, BASE_DEC, VALS(srvloc_errs_v2), 0x0,
1472 {"XID", "srvloc.xid",
1473 FT_UINT24, BASE_DEC, NULL, 0x0,
1474 "Transaction ID", HFILL }
1476 {&hf_srvloc_langtag,
1477 {"Lang Tag", "srvloc.langtag",
1478 FT_STRING, BASE_NONE, NULL, 0x0,
1481 {&hf_srvloc_langtaglen,
1482 {"Lang Tag Len", "srvloc.langtaglen",
1483 FT_UINT16, BASE_DEC, NULL, 0x0,
1486 {&hf_srvloc_nextextoff,
1487 {"Next Extension Offset", "srvloc.nextextoff",
1488 FT_UINT24, BASE_DEC, NULL, 0x0,
1492 /* Helper functions for URL and URL Entry parsing - both versions */
1493 {&hf_srvloc_url_reserved,
1494 {"Reserved", "srvloc.url.reserved",
1495 FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
1497 {&hf_srvloc_url_lifetime,
1498 {"URL lifetime", "srvloc.url.lifetime",
1499 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1501 {&hf_srvloc_url_urllen,
1502 {"URL Length", "srvloc.url.urllen",
1503 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
1505 {&hf_srvloc_url_url,
1506 {"URL", "srvloc.url.url",
1507 FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }
1509 {&hf_srvloc_url_numauths,
1510 {"Num Auths", "srvloc.url.numauths",
1511 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
1514 /* Helper functions for the common header fields */
1515 {&hf_srvloc_function,
1516 {"Function", "srvloc.function",
1517 FT_UINT8, BASE_DEC, VALS(srvloc_functions), 0x0,
1522 {"Packet Length", "srvloc.pktlen",
1523 FT_UINT24, BASE_DEC, NULL, 0x0,
1527 { &hf_srvloc_version,
1528 { "Version", "srvloc.version",
1529 FT_UINT8, BASE_DEC, NULL, 0x0,
1533 {&hf_srvloc_flags_v1,
1534 {"Flags", "srvloc.flags_v1",
1535 FT_UINT8, BASE_HEX, NULL, 0x0,
1539 { &hf_srvloc_flags_v1_overflow,
1540 { "Overflow", "srvloc.flags_v1.overflow.", FT_BOOLEAN, 8,
1541 TFS(&tfs_srvloc_flags_overflow), FLAG_O, "Can whole packet fit into a datagram?", HFILL }},
1543 { &hf_srvloc_flags_v1_monolingual,
1544 { "Monolingual", "srvloc.flags_v1.monolingual", FT_BOOLEAN, 8,
1545 TFS(&tfs_srvloc_flags_v1_monolingual), FLAG_M, "Can whole packet fit into a datagram?", HFILL }},
1547 { &hf_srvloc_flags_v1_url_auth,
1548 { "URL Authentication", "srvloc.flags_v1.url_auth", FT_BOOLEAN, 8,
1549 TFS(&tfs_srvloc_flags_v1_url_auth), FLAG_U, "Can whole packet fit into a datagram?", HFILL }},
1551 { &hf_srvloc_flags_v1_attribute_auth,
1552 { "Attribute Authentication", "srvloc.flags_v1.attribute_auth", FT_BOOLEAN, 8,
1553 TFS(&tfs_srvloc_flags_v1_attribute_auth), FLAG_A, "Can whole packet fit into a datagram?", HFILL }},
1555 { &hf_srvloc_flags_v1_fresh,
1556 { "Fresh Registration", "srvloc.flags_v1.fresh", FT_BOOLEAN, 8,
1557 TFS(&tfs_srvloc_flags_fresh), FLAG_F, "Is this a new registration?", HFILL }},
1559 {&hf_srvloc_flags_v2,
1560 {"Flags", "srvloc.flags_v2",
1561 FT_UINT16, BASE_HEX, NULL, 0x0,
1565 { &hf_srvloc_flags_v2_overflow,
1566 { "Overflow", "srvloc.flags_v2.overflow", FT_BOOLEAN, 16,
1567 TFS(&tfs_srvloc_flags_overflow), FLAG_O_V2, "Can whole packet fit into a datagram?", HFILL }},
1569 { &hf_srvloc_flags_v2_fresh,
1570 { "Fresh Registration", "srvloc.flags_v2.fresh", FT_BOOLEAN, 16,
1571 TFS(&tfs_srvloc_flags_fresh), FLAG_F_V2, "Is this a new registration?", HFILL }},
1573 { &hf_srvloc_flags_v2_reqmulti,
1574 { "Multicast requested", "srvloc.flags_v2.reqmulti", FT_BOOLEAN, 16,
1575 TFS(&tfs_srvloc_flags_v2_reqmulti), FLAG_R_V2, "Do we want multicast?", HFILL }},
1577 /* collection of helper functions for dissect_authblk_v2 */
1578 { &hf_srvloc_authblkv2_bsd,
1579 { "BSD", "srvloc.authblkv2_bsd", FT_UINT16, BASE_HEX, NULL, 0x0,
1580 "Block Structure Descriptor", HFILL}
1582 { &hf_srvloc_authblkv2_len,
1583 { "Length", "srvloc.authblkv2_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1584 "Length of Authentication Block", HFILL}
1586 { &hf_srvloc_authblkv2_timestamp,
1587 { "Timestamp", "srvloc.authblkv2.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
1588 NULL, 0, "Timestamp on Authentication Block", HFILL }
1590 { &hf_srvloc_authblkv2_slpspilen,
1591 { "SLP SPI Length", "srvloc.authblkv2.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1592 "Length of the SLP SPI", HFILL}
1594 { &hf_srvloc_authblkv2_slpspi,
1595 { "SLP SPI", "srvloc.authblkv2.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1599 /* collection of helper functions for Service Request */
1600 { &hf_srvloc_srvreq_prlistlen,
1601 { "Previous Response List Length", "srvloc.srvreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1602 "Length of Previous Response List", HFILL}
1604 { &hf_srvloc_srvreq_prlist,
1605 { "Previous Response List", "srvloc.srvreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1606 "Previous Response List", HFILL}
1608 { &hf_srvloc_srvreq_srvtypelen,
1609 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1610 "Length of Service Type List", HFILL}
1612 { &hf_srvloc_srvreq_srvtypelist,
1613 { "Service Type List", "srvloc.srvreq.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1616 { &hf_srvloc_srvreq_scopelistlen,
1617 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1618 "Length of the Scope List", HFILL}
1620 { &hf_srvloc_srvreq_scopelist,
1621 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1624 { &hf_srvloc_srvreq_predicatelen,
1625 { "Predicate Length", "srvloc.srvreq.predicatelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1626 "Length of the Predicate", HFILL}
1628 { &hf_srvloc_srvreq_predicate,
1629 { "Predicate", "srvloc.srvreq.predicate", FT_STRING, BASE_NONE, NULL, 0x0,
1632 { &hf_srvloc_srvreq_slpspilen,
1633 { "SLP SPI Length", "srvloc.srvreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1634 "Length of the SLP SPI", HFILL}
1636 { &hf_srvloc_srvreq_slpspi,
1637 { "SLP SPI", "srvloc.srvreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1641 /* Helper function for Service Request */
1642 { &hf_srvloc_srvrply_urlcount,
1643 { "Number of URLs", "srvloc.srvreq.urlcount", FT_UINT16, BASE_DEC, NULL, 0x0,
1647 /* Helper functions for Service Registration */
1648 { &hf_srvloc_srvreg_srvtypelen,
1649 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1652 { &hf_srvloc_srvreg_srvtype,
1653 { "Service Type", "srvloc.srvreq.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1656 { &hf_srvloc_srvreg_scopelistlen,
1657 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1660 { &hf_srvloc_srvreg_scopelist,
1661 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1664 { &hf_srvloc_srvreg_attrlistlen,
1665 { "Attribute List Length", "srvloc.srvreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1668 { &hf_srvloc_srvreg_attrlist,
1669 { "Attribute List", "srvloc.srvreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1672 { &hf_srvloc_srvreg_attrauthcount,
1673 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1674 "Number of Attribute Authentication Blocks", HFILL}
1677 /* Helper functions for Service Deregistration */
1678 { &hf_srvloc_srvdereg_scopelistlen,
1679 { "Scope List Length", "srvloc.srvdereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1682 { &hf_srvloc_srvdereg_scopelist,
1683 { "Scope List", "srvloc.srvdereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1686 { &hf_srvloc_srvdereg_taglistlen,
1687 { "Tag List Length", "srvloc.srvdereq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1690 { &hf_srvloc_srvdereg_taglist,
1691 { "Tag List", "srvloc.srvdereq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1696 /* collection of helper functions for Attribute Request */
1697 { &hf_srvloc_attrreq_prlistlen,
1698 { "Previous Response List Length", "srvloc.attrreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1699 "Length of Previous Response List", HFILL}
1701 { &hf_srvloc_attrreq_prlist,
1702 { "Previous Response List", "srvloc.attrreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1703 "Previous Response List", HFILL}
1705 { &hf_srvloc_attrreq_urllen,
1706 { "URL Length", "srvloc.attrreq.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1709 { &hf_srvloc_attrreq_url,
1710 { "Service URL", "srvloc.attrreq.url", FT_STRING, BASE_NONE, NULL, 0x0,
1711 "URL of service", HFILL}
1713 { &hf_srvloc_attrreq_scopelistlen,
1714 { "Scope List Length", "srvloc.attrreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1715 "Length of the Scope List", HFILL}
1717 { &hf_srvloc_attrreq_scopelist,
1718 { "Scope List", "srvloc.attrreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1721 { &hf_srvloc_attrreq_attrlistlen,
1722 { "Attribute List Length", "srvloc.attrreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1725 { &hf_srvloc_attrreq_attrlist,
1726 { "Attribute List", "srvloc.attrreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1729 { &hf_srvloc_attrreq_taglistlen,
1730 { "Tag List Length", "srvloc.attrreq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1733 { &hf_srvloc_attrreq_taglist,
1734 { "Tag List", "srvloc.attrreq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1737 { &hf_srvloc_attrreq_slpspilen,
1738 { "SLP SPI Length", "srvloc.attrreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1739 "Length of the SLP SPI", HFILL}
1741 { &hf_srvloc_attrreq_slpspi,
1742 { "SLP SPI", "srvloc.attrreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1746 /* collection of helper functions for Attribute Reply */
1747 { &hf_srvloc_attrrply_attrlistlen,
1748 { "Attribute List Length", "srvloc.attrrply.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1749 "Length of Attribute List", HFILL}
1751 { &hf_srvloc_attrrply_attrlist,
1752 { "Attribute List", "srvloc.attrrply.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1755 { &hf_srvloc_attrrply_attrauthcount,
1756 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1757 "Number of Attribute Authentication Blocks", HFILL}
1760 /* collection of helper functions for DA Advertisement */
1761 { &hf_srvloc_daadvert_timestamp,
1762 { "DAADVERT Timestamp", "srvloc.daadvert.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
1763 NULL, 0, "Timestamp on DA Advert", HFILL }
1765 { &hf_srvloc_daadvert_urllen,
1766 { "URL Length", "srvloc.daadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1769 { &hf_srvloc_daadvert_url,
1770 { "URL", "srvloc.daadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1773 { &hf_srvloc_daadvert_scopelistlen,
1774 { "Scope List Length", "srvloc.daadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1775 "Length of the Scope List", HFILL}
1777 { &hf_srvloc_daadvert_scopelist,
1778 { "Scope List", "srvloc.daadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1781 { &hf_srvloc_daadvert_attrlistlen,
1782 { "Attribute List Length", "srvloc.daadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1785 { &hf_srvloc_daadvert_attrlist,
1786 { "Attribute List", "srvloc.daadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1789 { &hf_srvloc_daadvert_slpspilen,
1790 { "SLP SPI Length", "srvloc.daadvert.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1791 "Length of the SLP SPI", HFILL}
1793 { &hf_srvloc_daadvert_slpspi,
1794 { "SLP SPI", "srvloc.daadvert.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1797 { &hf_srvloc_daadvert_authcount,
1798 { "Auths", "srvloc.daadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1799 "Number of Authentication Blocks", HFILL}
1802 /* collection of helper functions for Service Type Request */
1803 { &hf_srvloc_srvtypereq_prlistlen,
1804 { "Previous Response List Length", "srvloc.srvtypereq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1805 "Length of Previous Response List", HFILL}
1807 { &hf_srvloc_srvtypereq_prlist,
1808 { "Previous Response List", "srvloc.srvtypereq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1809 "Previous Response List", HFILL}
1811 { &hf_srvloc_srvtypereq_nameauthlistlen,
1812 { "Naming Authority List Length", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1813 "Length of the Naming Authority List", HFILL}
1815 { &hf_srvloc_srvtypereq_nameauthlistlenall,
1816 { "Naming Authority List Length (All Naming Authorities)", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1817 "Length of the Naming Authority List", HFILL}
1819 { &hf_srvloc_srvtypereq_nameauthlist,
1820 { "Naming Authority List", "srvloc.srvtypereq.nameauthlist", FT_STRING, BASE_NONE, NULL, 0x0,
1823 { &hf_srvloc_srvtypereq_scopelistlen,
1824 { "Scope List Length", "srvloc.srvtypereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1825 "Length of the Scope List", HFILL}
1827 { &hf_srvloc_srvtypereq_scopelist,
1828 { "Scope List", "srvloc.srvtypereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1832 /* collection of helper functions for Service Type Replies */
1833 { &hf_srvloc_srvtyperply_srvtypelen,
1834 { "Service Type Length", "srvloc.srvtypereq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1835 "Length of the Service Type", HFILL}
1837 { &hf_srvloc_srvtyperply_srvtype,
1838 { "Service Type", "srvloc.srvtyperply.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1841 { &hf_srvloc_srvtyperply_srvtypelistlen,
1842 { "Service Type List Length", "srvloc.srvtypereq.srvtypelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1843 "Length of the Service Type List", HFILL}
1845 { &hf_srvloc_srvtyperply_srvtypelist,
1846 { "Service Type List", "srvloc.srvtyperply.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1850 /* collection of helper functions for SA Advertisement */
1851 { &hf_srvloc_saadvert_urllen,
1852 { "URL Length", "srvloc.saadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1855 { &hf_srvloc_saadvert_url,
1856 { "URL", "srvloc.saadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1859 { &hf_srvloc_saadvert_scopelistlen,
1860 { "Scope List Length", "srvloc.saadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1861 "Length of the Scope List", HFILL}
1863 { &hf_srvloc_saadvert_scopelist,
1864 { "Scope List", "srvloc.saadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1867 { &hf_srvloc_saadvert_attrlistlen,
1868 { "Attribute List Length", "srvloc.saadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1871 { &hf_srvloc_saadvert_attrlist,
1872 { "Attribute List", "srvloc.saadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1875 { &hf_srvloc_saadvert_authcount,
1876 { "Auths", "srvloc.saadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1877 "Number of Authentication Blocks", HFILL}
1879 { &hf_srvloc_add_ref_ip,
1880 { "IP Address", "srvloc.list.ipaddr", FT_IPv4, BASE_DEC, NULL, 0x0,
1881 "IP Address of SLP server", HFILL}
1883 { &hf_srvloc_srvrply_svcname,
1884 { "Service Name Value", "srvloc.srvrply.svcname", FT_STRING, BASE_NONE, NULL, 0x0,
1889 static gint *ett[] = {
1894 module_t *srvloc_module;
1896 proto_srvloc = proto_register_protocol("Service Location Protocol",
1897 "SRVLOC", "srvloc");
1898 proto_register_field_array(proto_srvloc, hf, array_length(hf));
1899 proto_register_subtree_array(ett, array_length(ett));
1900 srvloc_module = prefs_register_protocol(proto_srvloc, NULL);
1901 prefs_register_bool_preference(srvloc_module, "desegment_tcp",
1902 "Reassemble SRVLOC messages spanning multiple TCP segments",
1903 "Whether the SRVLOC dissector should reassemble messages spanning multiple TCP segments. "
1904 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1909 proto_reg_handoff_srvloc(void)
1911 dissector_handle_t srvloc_handle, srvloc_tcp_handle;
1912 srvloc_handle = create_dissector_handle(dissect_srvloc, proto_srvloc);
1913 dissector_add("udp.port", UDP_PORT_SRVLOC, srvloc_handle);
1914 srvloc_tcp_handle = create_dissector_handle(dissect_srvloc_tcp,
1916 dissector_add("tcp.port", TCP_PORT_SRVLOC, srvloc_tcp_handle);