Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-srvloc.c
blob8e32cfde32b3b68888607726cb868f5bc0befb75
1 /* packet-srvloc.c
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 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * Service Location Protocol is RFC 2165
17 * Service Location Protocol Version 2 is RFC 2608
18 * - partial support by Brad Hards <bradh@frogmouth.net>
20 * SPDX-License-Identifier: GPL-2.0-or-later
23 #include "config.h"
25 #include <stdlib.h> /* for strtoul() */
27 #include <epan/packet.h>
28 #include <epan/prefs.h>
29 #include "packet-tcp.h"
30 #include <epan/expert.h>
31 #include <epan/tfs.h>
32 #include <wsutil/array.h>
34 void proto_register_srvloc(void);
35 void proto_reg_handoff_srvloc(void);
37 static dissector_handle_t srvloc_handle;
38 static dissector_handle_t srvloc_tcp_handle;
40 static bool srvloc_desegment = true;
41 static int proto_srvloc;
42 static int hf_srvloc_version;
43 static int hf_srvloc_function;
44 static int hf_srvloc_pktlen;
45 static int hf_srvloc_xid;
46 static int hf_srvloc_langtaglen;
47 static int hf_srvloc_langtag;
48 static int hf_srvloc_nextextoff;
49 static int hf_srvloc_flags_v1;
50 static int hf_srvloc_flags_v1_overflow;
51 static int hf_srvloc_flags_v1_monolingual;
52 static int hf_srvloc_flags_v1_url_auth;
53 static int hf_srvloc_flags_v1_attribute_auth;
54 static int hf_srvloc_flags_v1_fresh;
55 static int hf_srvloc_error;
56 static int hf_srvloc_flags_v2;
57 static int hf_srvloc_flags_v2_overflow;
58 static int hf_srvloc_flags_v2_fresh;
59 static int hf_srvloc_flags_v2_reqmulti;
60 static int hf_srvloc_error_v2;
61 static int hf_srvloc_daadvert_timestamp;
62 static int hf_srvloc_daadvert_urllen;
63 static int hf_srvloc_daadvert_url;
64 static int hf_srvloc_daadvert_scopelistlen;
65 static int hf_srvloc_daadvert_scopelist;
66 static int hf_srvloc_daadvert_attrlistlen;
67 static int hf_srvloc_daadvert_attrlist;
68 static int hf_srvloc_daadvert_slpspilen;
69 static int hf_srvloc_daadvert_slpspi;
70 static int hf_srvloc_daadvert_authcount;
71 static int hf_srvloc_srvreq_prlistlen;
72 static int hf_srvloc_srvreq_prlist;
73 static int hf_srvloc_srvreq_srvtypelen;
74 static int hf_srvloc_srvreq_srvtypelist;
75 static int hf_srvloc_srvreq_scopelistlen;
76 static int hf_srvloc_srvreq_scopelist;
77 static int hf_srvloc_srvreq_predicatelen;
78 static int hf_srvloc_srvreq_predicate;
79 static int hf_srvloc_srvreq_slpspilen;
80 static int hf_srvloc_srvreq_slpspi;
81 static int hf_srvloc_srvrply_urlcount;
82 static int hf_srvloc_srvreg_attrlistlen;
83 static int hf_srvloc_srvreg_attrlist;
84 static int hf_srvloc_srvreg_attrauthcount;
85 static int hf_srvloc_srvreg_srvtypelen;
86 static int hf_srvloc_srvreg_srvtype;
87 static int hf_srvloc_srvreg_scopelistlen;
88 static int hf_srvloc_srvreg_scopelist;
89 static int hf_srvloc_srvdereg_scopelistlen;
90 static int hf_srvloc_srvdereg_scopelist;
91 static int hf_srvloc_srvdereg_taglistlen;
92 static int hf_srvloc_srvdereg_taglist;
93 static int hf_srvloc_attrreq_prlistlen;
94 static int hf_srvloc_attrreq_prlist;
95 static int hf_srvloc_attrreq_urllen;
96 static int hf_srvloc_attrreq_url;
97 static int hf_srvloc_attrreq_scopelistlen;
98 static int hf_srvloc_attrreq_scopelist;
99 static int hf_srvloc_attrreq_attrlistlen;
100 static int hf_srvloc_attrreq_attrlist;
101 static int hf_srvloc_attrreq_taglistlen;
102 static int hf_srvloc_attrreq_taglist;
103 static int hf_srvloc_attrreq_slpspilen;
104 static int hf_srvloc_attrreq_slpspi;
105 static int hf_srvloc_attrrply_attrlistlen;
106 static int hf_srvloc_attrrply_attrlist;
107 static int hf_srvloc_attrrply_attrauthcount;
108 static int hf_srvloc_srvtypereq_prlistlen;
109 static int hf_srvloc_srvtypereq_prlist;
110 static int hf_srvloc_srvtypereq_nameauthlistlen;
111 static int hf_srvloc_srvtypereq_nameauthlistlenall;
112 static int hf_srvloc_srvtypereq_nameauthlist;
113 static int hf_srvloc_srvtypereq_scopelistlen;
114 static int hf_srvloc_srvtypereq_scopelist;
115 static int hf_srvloc_srvtyperply_srvtypelen;
116 static int hf_srvloc_srvtyperply_srvtype;
117 static int hf_srvloc_srvtyperply_srvtypelistlen;
118 static int hf_srvloc_srvtyperply_srvtypelist;
119 static int hf_srvloc_saadvert_urllen;
120 static int hf_srvloc_saadvert_url;
121 static int hf_srvloc_saadvert_scopelistlen;
122 static int hf_srvloc_saadvert_scopelist;
123 static int hf_srvloc_saadvert_attrlistlen;
124 static int hf_srvloc_saadvert_attrlist;
125 static int hf_srvloc_saadvert_authcount;
126 static int hf_srvloc_authblkv2_bsd;
127 static int hf_srvloc_authblkv2_len;
128 static int hf_srvloc_authblkv2_timestamp;
129 static int hf_srvloc_authblkv2_slpspilen;
130 static int hf_srvloc_authblkv2_slpspi;
131 static int hf_srvloc_url_reserved;
132 static int hf_srvloc_url_lifetime;
133 static int hf_srvloc_url_urllen;
134 static int hf_srvloc_url_url;
135 static int hf_srvloc_url_numauths;
136 static int hf_srvloc_add_ref_ip;
137 static int hf_srvloc_srvrply_svcname;
138 /* Generated from convert_proto_tree_add_text.pl */
139 static int hf_srvloc_timestamp;
140 static int hf_srvloc_authentication_block;
141 static int hf_srvloc_transaction_id;
142 static int hf_srvloc_block_structure_descriptor;
143 static int hf_srvloc_communication_type;
144 static int hf_srvloc_language;
145 static int hf_srvloc_socket;
146 static int hf_srvloc_encoding;
147 static int hf_srvloc_node;
148 static int hf_srvloc_item;
149 static int hf_srvloc_service_type;
150 static int hf_srvloc_network;
151 static int hf_srvloc_service_type_count;
152 static int hf_srvloc_dialect;
153 static int hf_srvloc_authenticator_length;
154 static int hf_srvloc_protocol;
155 static int hf_srvloc_port;
158 static int ett_srvloc;
159 static int ett_srvloc_attr;
160 static int ett_srvloc_flags;
162 static expert_field ei_srvloc_error;
163 static expert_field ei_srvloc_error_v2;
164 static expert_field ei_srvloc_function_unknown;
165 static expert_field ei_srvloc_malformed;
167 static const true_false_string tfs_srvloc_flags_overflow = {
168 "Message will not fit in datagram",
169 "Message will fit in a datagram"
171 static const true_false_string tfs_srvloc_flags_v1_monolingual = {
172 "Only responses in specified language will be accepted",
173 "Responses in any language will be accepted"
175 static const true_false_string tfs_srvloc_flags_v1_url_auth = {
176 "URL Authentication Block is present",
177 "URL Authentication Block is absent"
179 static const true_false_string tfs_srvloc_flags_v1_attribute_auth = {
180 "Attribute Authentication Block is present",
181 "Attribute Authentication Block is absent"
183 static const true_false_string tfs_srvloc_flags_fresh = {
184 "New Service Registration",
185 "Not a new Service Registration"
187 static const true_false_string tfs_srvloc_flags_v2_reqmulti = {
188 "Multicast (or broadcast) request",
189 "Not multicast or broadcast"
192 #define TCP_PORT_SRVLOC 427
193 #define UDP_PORT_SRVLOC 427
195 /* Define function types */
197 #define SRVREQ 1
198 #define SRVRPLY 2
199 #define SRVREG 3
200 #define SRVDEREG 4
201 #define SRVACK 5
202 #define ATTRRQST 6
203 #define ATTRRPLY 7
204 #define DAADVERT 8
205 #define SRVTYPERQST 9
206 #define SRVTYPERPLY 10
207 #define SAADVERT 11 /* SLPv2, section 8 */
209 /* Create protocol header structure */
211 /* bradh: looks like never used. */
212 /* bradh: comment it out for now since it doesn't work for v2
213 struct srvloc_hdr {
214 uint8_t version;
215 uint8_t function;
216 uint16_t length;
217 uint8_t flags;
218 uint8_t dialect;
219 unsigned char language[2];
220 uint16_t encoding;
221 uint16_t xid;
225 /* List to resolve function numbers to names */
227 static const value_string srvloc_functions[] = {
228 { SRVREQ, "Service Request" },
229 { SRVRPLY, "Service Reply" },
230 { SRVREG, "Service Registration" },
231 { SRVDEREG, "Service Deregister" },
232 { SRVACK, "Service Acknowledge" },
233 { ATTRRQST, "Attribute Request" },
234 { ATTRRPLY, "Attribute Reply" },
235 { DAADVERT, "DA Advertisement" },
236 { SRVTYPERQST, "Service Type Request" },
237 { SRVTYPERPLY, "Service Type Reply" },
238 { SAADVERT, "SA Advertisement" }, /* v2 only */
239 { 0, NULL }
242 /* List to resolve flag values to names */
245 /* Define flag masks */
247 #define FLAG_O 0x80
248 #define FLAG_M 0x40
249 #define FLAG_U 0x20
250 #define FLAG_A 0x10
251 #define FLAG_F 0x08
253 /* it all changes for Version 2 */
254 #define FLAG_O_V2 0x8000
255 #define FLAG_F_V2 0x4000
256 #define FLAG_R_V2 0x2000
258 /* Define Error Codes - Version 1*/
260 #define SUCCESS 0
261 #define LANG_NOT_SPTD 1
262 #define PROT_PARSE_ERR 2
263 #define INVLD_REG 3
264 #define SCOPE_NOT_SPTD 4
265 #define CHRSET_NOT_UND 5
266 #define AUTH_ABSENT 6
267 #define AUTH_FAILED 7
269 /* List to resolve error codes to names */
271 static const value_string srvloc_errs[] = {
272 { SUCCESS, "No Error" },
273 { LANG_NOT_SPTD, "Language not supported" },
274 { PROT_PARSE_ERR, "Protocol parse error" },
275 { INVLD_REG, "Invalid registration" },
276 { SCOPE_NOT_SPTD, "Scope not supported" },
277 { CHRSET_NOT_UND, "Character set not understood" },
278 { AUTH_ABSENT, "Authentication absent" },
279 { AUTH_FAILED, "Authentication failed" },
280 { 0, NULL }
283 /* Define Error Codes for Version 2 */
285 #define LANGUAGE_NOT_SUPPORTED 1
286 #define PARSE_ERROR 2
287 #define INVALID_REGISTRATION 3
288 #define SCOPE_NOT_SUPPORTED 4
289 #define AUTHENTICATION_UNKNOWN 5
290 #define AUTHENTICATION_ABSENT 6
291 #define AUTHENTICATION_FAILED 7
292 #define VER_NOT_SUPPORTED 9
293 #define INTERNAL_ERROR 10
294 #define DA_BUSY_NOW 11
295 #define OPTION_NOT_UNDERSTOOD 12
296 #define INVALID_UPDATE 13
297 #define MSG_NOT_SUPPORTED 14
298 #define REFRESH_REJECTED 15
300 static const value_string srvloc_errs_v2[] = {
301 { SUCCESS, "No Error" },
302 { LANGUAGE_NOT_SUPPORTED, "No data in the requested language" },
303 { PARSE_ERROR, "The message fails to obey SLP syntax." },
304 { INVALID_REGISTRATION, "The SrvReg has problems" },
305 { SCOPE_NOT_SUPPORTED, "Scope list not supported" },
306 { AUTHENTICATION_UNKNOWN, "Unsupported SLP SPI." },
307 { AUTHENTICATION_ABSENT, "URL and ATTR authentication not provided"},
308 { AUTHENTICATION_FAILED, "Authentication error"},
309 { VER_NOT_SUPPORTED, "Unsupported version number in message header" },
310 { INTERNAL_ERROR, "The DA (or SA) is too sick to respond" },
311 { DA_BUSY_NOW, "UA or SA SHOULD retry" },
312 { OPTION_NOT_UNDERSTOOD, "Unknown option from the mandatory range"},
313 { INVALID_UPDATE, "Invalid SrvReg" },
314 { MSG_NOT_SUPPORTED, "No support for AttrRqst or SrvTypeRqst" },
315 { REFRESH_REJECTED, "SrvReg sent too soon"},
316 { 0, NULL }
320 * Character encodings.
321 * This is a small subset of what's in
323 * http://www.iana.org/assignments/character-sets
325 * XXX - we should do something useful with this, i.e. properly
326 * handle strings based on the character set they're in.
328 * XXX - what does "properly handle strings" mean? How do we know
329 * what character set the terminal can handle (for tty-based code)
330 * or the GUI can handle (for GUI code)?
332 * XXX - the Wireshark core really should be what does all the
333 * character set handling for strings, and it should be stuck with
334 * the task of figuring out how to properly handle them.
336 #define CHARSET_ASCII 3
337 #define CHARSET_ISO_10646_UTF_1 27
338 #define CHARSET_ISO_646_BASIC 28
339 #define CHARSET_ISO_646_IRV 30
340 #define CHARSET_ISO_8859_1 4
341 #define CHARSET_ISO_10646_UCS_2 1000 /* a/k/a Unicode */
342 #define CHARSET_UTF_7 1012
343 #define CHARSET_UTF_8 106
345 static const value_string charsets[] = {
346 { CHARSET_ASCII, "US-ASCII" },
347 { CHARSET_ISO_10646_UTF_1, "ISO 10646 UTF-1" },
348 { CHARSET_ISO_646_BASIC, "ISO 646 basic:1983" },
349 { CHARSET_ISO_646_IRV, "ISO 646 IRV:1983" },
350 { CHARSET_ISO_8859_1, "ISO 8859-1" },
351 { CHARSET_ISO_10646_UCS_2, "Unicode" },
352 { CHARSET_UTF_7, "UTF-7" },
353 { CHARSET_UTF_8, "UTF-8" },
354 { 0, NULL }
357 static int
358 dissect_authblk(tvbuff_t *tvb, int offset, proto_tree *tree)
360 uint16_t length;
362 proto_tree_add_item(tree, hf_srvloc_timestamp, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
363 proto_tree_add_item(tree, hf_srvloc_block_structure_descriptor, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
364 length = tvb_get_ntohs(tvb, offset + 10);
365 proto_tree_add_item(tree, hf_srvloc_authenticator_length, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
366 offset += 12;
367 proto_tree_add_item(tree, hf_srvloc_authentication_block, tvb, offset, length, ENC_NA|ENC_ASCII);
368 offset += length;
369 return offset;
372 /* SLPv2 version - Needs to be fixed to match RFC2608 sect 9.2*/
373 static int
374 dissect_authblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
376 uint16_t length;
378 proto_tree_add_item(tree, hf_srvloc_authblkv2_bsd, tvb, offset, 2, ENC_BIG_ENDIAN);
379 proto_tree_add_item(tree, hf_srvloc_authblkv2_len, tvb, offset+2, 2, ENC_BIG_ENDIAN);
380 proto_tree_add_item(tree, hf_srvloc_authblkv2_timestamp, tvb, offset+4, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
381 length = tvb_get_ntohs(tvb, offset + 8);
382 proto_tree_add_uint(tree, hf_srvloc_authblkv2_slpspilen, tvb, offset + 8, 2, length);
383 offset += 10;
384 proto_tree_add_item(tree, hf_srvloc_authblkv2_slpspi, tvb, offset, length, ENC_ASCII);
385 offset += length;
386 /* add code in here to handle Structured Authentication Block */
387 return offset;
390 static int
391 dissect_attrauthblk_v2(tvbuff_t *tvb _U_, int offset, proto_tree *tree _U_)
393 /* add code in here to handle attribute authentication */
394 return offset;
397 static void
398 add_v1_string(proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length,
399 uint16_t encoding)
401 switch (encoding) {
403 case CHARSET_ISO_10646_UCS_2:
404 proto_tree_add_item(tree, hf, tvb, offset, length, ENC_UCS_2|ENC_BIG_ENDIAN);
405 break;
407 default:
408 /* XXX - need to support all the CHARSET_ values */
409 proto_tree_add_item(tree, hf, tvb, offset, length, ENC_ASCII|ENC_NA);
410 break;
415 * XXX - is this trying to guess the byte order?
417 * http://www.iana.org/assignments/character-sets
419 * says of ISO-10646-UCS-2, which has the code 1000 (this routine is used
420 * with CHARSET_ISO_10646_UCS_2, which is #defined to be 1000):
422 * this needs to specify network byte order: the standard
423 * does not specify (it is a 16-bit integer space)
425 * Does that mean that in SRVLOC, ISO-10646-UCS-2 is always big-endian?
426 * If so, can we just use "tvb_get_string_enc()" and be
427 * done with it?
429 * XXX - this is also used with CHARSET_UTF_8. Is that a cut-and-pasteo?
431 static const uint8_t*
432 unicode_to_bytes(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, bool endianness)
434 const uint8_t *ascii_text = tvb_get_string_enc(scope, tvb, offset, length, ENC_ASCII);
435 int i, j = 0;
436 uint8_t c_char, c_char1;
437 uint8_t *byte_array;
439 /* XXX - Is this the correct behavior? */
440 if (length < 1)
441 return "";
443 if (endianness) {
444 byte_array = (uint8_t *)wmem_alloc(scope, length*2 + 1);
445 for (i = length; i > 0; i--) {
446 c_char = ascii_text[i];
447 if (c_char != 0) {
448 if (i == 0)
449 break;
450 i--;
451 c_char1 = ascii_text[i];
452 if (c_char1 == 0) {
453 if (i == 0)
454 break;
455 i--;
456 c_char1 = ascii_text[i];
458 byte_array[j] = c_char1;
459 j++;
460 byte_array[j] = c_char;
461 j++;
465 else
467 byte_array = (uint8_t *)wmem_alloc(scope, length + 1);
468 for (i = 0; i < length; i++) {
469 c_char = ascii_text[i];
470 if (c_char != 0) {
471 byte_array[j] = c_char;
472 j++;
477 byte_array[j]=0;
478 return byte_array;
482 * Format of x-x-x-xxxxxxxx. Each of these entries represents the service binding to UDP, TCP, or IPX.
483 * The first digit is the protocol family: 2 for TCP/UPD, 6 for IPX.
484 * The second digit is the socket type: 1 for socket stream (TCP), 2 for datagram (UDP and IPX).
485 * The third is the protocol: 6 for TCP, 17 for UDP, and 1000 for IPX.
486 * Last is the IP address, in hex, of the interface that is registered (or, in the case of IPX, an IPX network number).
488 * OpenSLP supports multiple attribute replies so we need to parse the attribute name and then decode accordingly.
489 * We currently only parse the (non-utf8) attributes:
490 * svcname
491 * svcaddr
493 static const value_string srvloc_svc[] = {
494 { 50, "TCP/UDP" },
495 { 54, "IPX" },
496 { 0, NULL }
499 static const value_string srvloc_ss[] = {
500 { 49, "Socket" },
501 { 50, "Datagram" },
502 { 0, NULL }
505 static const value_string srvloc_prot[] = {
506 { 54, "TCP" },
507 { 17, "UDP" },
508 { 1000, "IPX" },
509 { 0, NULL }
512 static void
513 attr_list(proto_tree *tree, packet_info* pinfo, int hf, tvbuff_t *tvb, int offset, int length,
514 uint16_t encoding)
516 const char *attr_type;
517 int i, svc, type_len, foffset=offset;
518 uint32_t prot;
519 const uint8_t *byte_value;
520 proto_tree *srvloc_tree;
521 proto_item *ti;
522 char *tmp;
524 switch (encoding) {
526 case CHARSET_ISO_10646_UCS_2:
527 while (offset+2<length) {
528 offset += 2;
529 /* If the length passed is longer then the actual payload then this must be an incomplete packet. */
530 if (tvb_reported_length_remaining(tvb, 4)<length) {
531 proto_tree_add_expert(tree, pinfo, &ei_srvloc_malformed, tvb, offset, -1);
532 break;
534 /* Parse the attribute name */
535 tmp = tvb_get_string_enc(pinfo->pool, tvb, offset, length-offset, ENC_UCS_2|ENC_BIG_ENDIAN);
536 type_len = (int)strcspn(tmp, "=");
537 attr_type = tvb_get_string_enc(pinfo->pool, tvb, offset, type_len*2, ENC_UCS_2|ENC_BIG_ENDIAN);
538 proto_tree_add_string(tree, hf, tvb, offset, type_len*2, attr_type);
539 offset += (type_len*2)+2;
540 if (strcmp(attr_type, "svcname-ws")==0) {
541 /* This is the attribute svcname */
542 tmp = tvb_get_string_enc(pinfo->pool, tvb, offset, length-offset, ENC_UCS_2|ENC_BIG_ENDIAN);
543 type_len = (int)strcspn(tmp, ")");
544 add_v1_string(tree, hf_srvloc_srvrply_svcname, tvb, offset, type_len*2, encoding);
545 offset += (type_len*2)+4;
546 attr_type = "";
547 } else if (strcmp(attr_type, "svcaddr-ws")==0) {
548 /* This is the attribute svcaddr */
549 i=1;
550 for (foffset = offset; foffset<length; foffset += 2) {
552 srvloc_tree = proto_tree_add_subtree_format(tree, tvb, foffset, -1, ett_srvloc_attr, NULL, "Item %d", i);
554 svc = tvb_get_uint8(tvb, foffset+1);
555 proto_tree_add_item(srvloc_tree, hf_srvloc_service_type, tvb, foffset+1, 1, ENC_NA);
556 proto_tree_add_item(srvloc_tree, hf_srvloc_communication_type, tvb, foffset+5, 1, ENC_NA);
557 foffset += 9;
558 if (svc == 50) {
559 if (tvb_get_uint8(tvb, foffset)==54) { /* TCP */
560 proto_tree_add_item(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 1, ENC_NA);
561 foffset += 2;
563 else
565 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 4, false); /* UDP */
566 prot = (uint32_t)strtoul(byte_value, NULL, 10);
567 proto_tree_add_uint(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 4, prot);
568 foffset += 4;
571 else
573 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 8, false); /* IPX */
574 prot = (uint32_t)strtoul(byte_value, NULL, 10);
575 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 4, prot);
576 proto_item_set_len(ti, 8);
577 foffset += 8;
579 if (svc == 50) {
580 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 16, true); /* IP Address */
581 prot = (uint32_t)strtoul(byte_value, NULL, 16);
582 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+2, 16, prot);
583 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+18, 8, false); /* Port */
584 prot = (uint32_t)strtoul(byte_value, NULL, 16);
585 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_port, tvb, foffset+18, 4, prot);
586 proto_item_set_len(ti, 8);
588 else
590 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+2, 16, false); /* IPX Network Address */
591 prot = (uint32_t)strtoul(byte_value, NULL, 16);
592 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_network, tvb, foffset+2, 4, prot);
593 proto_item_set_len(ti, 16);
594 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+18, 24, false); /* IPX Node Address */
595 prot = (uint32_t)strtoul(byte_value, NULL, 16);
596 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_node, tvb, foffset+18, 4, prot);
597 proto_item_set_len(ti, 24);
598 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+42, 8, false); /* Socket */
599 prot = (uint32_t)strtoul(byte_value, NULL, 16);
600 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_socket, tvb, foffset+42, 4, prot);
601 proto_item_set_len(ti, 8);
603 i++;
604 foffset += 57;
606 offset = foffset;
607 attr_type = "";
609 /* If there are no more supported attributes available then abort dissection */
610 if (strcmp(attr_type, "svcaddr-ws")!=0 && strcmp(attr_type, "svcname-ws")!=0 && strcmp(attr_type, "")!=0) {
611 break;
614 break;
616 case CHARSET_UTF_8:
617 type_len = (int)strcspn(tvb_get_string_enc(pinfo->pool, tvb, offset, length, ENC_ASCII), "=");
618 attr_type = unicode_to_bytes(pinfo->pool, tvb, offset+1, type_len-1, false);
619 proto_tree_add_string(tree, hf, tvb, offset+1, type_len-1, attr_type);
620 i=1;
621 for (foffset = offset + (type_len); foffset<length; foffset++) {
623 srvloc_tree = proto_tree_add_subtree_format(tree, tvb, foffset, -1, ett_srvloc_attr, NULL, "Item %d", i);
625 svc = tvb_get_uint8(tvb, foffset+1);
626 proto_tree_add_item(srvloc_tree, hf_srvloc_service_type, tvb, foffset+1, 1, ENC_NA);
627 proto_tree_add_item(srvloc_tree, hf_srvloc_communication_type, tvb, foffset+3, 1, ENC_NA);
628 foffset += 5;
629 if (svc == 50) {
630 if (tvb_get_uint8(tvb, foffset)==54) { /* TCP */
631 proto_tree_add_item(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 1, ENC_NA);
632 foffset += 1;
634 else
636 /* UDP */
637 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 2, false); /* UDP */
638 prot = (uint32_t)strtoul(byte_value, NULL, 10);
639 proto_tree_add_uint(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 2, prot);
640 foffset += 2;
643 else
645 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 4, false); /* IPX */
646 prot = (uint32_t)strtoul(byte_value, NULL, 10);
647 proto_tree_add_uint(srvloc_tree, hf_srvloc_protocol, tvb, foffset, 4, prot);
648 foffset += 4;
650 if (svc == 50) {
651 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset, 8, true); /* IP Address */
652 prot = (uint32_t)strtoul(byte_value, NULL, 16);
653 proto_tree_add_ipv4(srvloc_tree, hf_srvloc_add_ref_ip, tvb, foffset+1, 8, prot);
654 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+9, 4, false); /* Port */
655 prot = (uint32_t)strtoul(byte_value, NULL, 16);
656 proto_tree_add_uint(srvloc_tree, hf_srvloc_port, tvb, foffset+9, 4, prot);
658 else
660 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+1, 8, false); /* IPX Network Address */
661 prot = (uint32_t)strtoul(byte_value, NULL, 16);
662 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_network, tvb, foffset+1, 4, prot);
663 proto_item_set_len(ti, 8);
664 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+9, 12, false); /* IPX Node Address */
665 prot = (uint32_t)strtoul(byte_value, NULL, 16);
666 ti = proto_tree_add_uint(srvloc_tree, hf_srvloc_node, tvb, foffset+9, 4, prot);
667 proto_item_set_len(ti, 12);
668 byte_value = unicode_to_bytes(pinfo->pool, tvb, foffset+21, 4, false); /* Socket */
669 prot = (uint32_t)strtoul(byte_value, NULL, 16);
670 proto_tree_add_uint(srvloc_tree, hf_srvloc_socket, tvb, foffset+21, 4, prot);
672 i++;
673 foffset += 28;
675 break;
678 default:
679 /* XXX - need to handle specific encodings */
680 proto_tree_add_item(tree, hf, tvb, offset, length, ENC_ASCII|ENC_NA);
681 break;
685 static void
686 attr_list2(packet_info *pinfo, proto_tree *tree, int hf, tvbuff_t *tvb, int offset, int length, uint16_t encoding _U_)
688 uint8_t *start;
689 uint8_t c;
690 uint32_t x;
691 uint32_t cnt;
692 proto_item *ti;
693 proto_tree *attr_tree;
695 /* if we were to decode:
696 * For slp, these 9 characters: (),\!<=>~ and 0x00-1F, 0x7f are reserved and must be escaped in the form \HH
699 /* create a sub tree for attributes */
700 /* XXX - is this always ASCII, or what? */
701 ti = proto_tree_add_item(tree, hf, tvb, offset, length, ENC_ASCII|ENC_NA);
702 attr_tree = proto_item_add_subtree(ti, ett_srvloc_attr);
704 /* this will ensure there is a terminating null */
705 start = tvb_get_string_enc(pinfo->pool, tvb, offset, length, ENC_ASCII);
707 cnt = 0;
708 x = 0;
709 c = start[x];
710 while (c) {
711 if (c == ',') {
712 cnt++; /* Attribute count */
713 start[x] = 0;
714 proto_tree_add_string_format(attr_tree, hf_srvloc_item, tvb, offset, x, start, "Item %d: %s", cnt, start);
715 offset += x+1;
716 start += x+1;
717 /* reset string length */
718 x = 0;
719 c = start[x];
720 } else {
721 /* increment and get next */
722 x++;
723 c = start[x];
726 /* display anything remaining */
727 if (x) {
728 cnt++;
729 proto_tree_add_string_format(attr_tree, hf_srvloc_item, tvb, offset, x, start, "Item %d: %s", cnt, start);
733 static int
734 dissect_url_entry_v1(tvbuff_t *tvb, int offset, proto_tree *tree,
735 uint16_t encoding, uint16_t flags)
737 uint16_t url_len;
739 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
740 ENC_BIG_ENDIAN);
741 offset += 2;
742 url_len = tvb_get_ntohs(tvb, offset);
743 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
744 url_len);
745 offset += 2;
746 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, url_len, encoding);
747 offset += url_len;
748 if ( (flags & FLAG_U) == FLAG_U )
749 offset = dissect_authblk(tvb, offset, tree);
750 return offset;
753 static int
754 dissect_url_entry_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
756 uint8_t reserved;
757 uint16_t url_len;
758 uint8_t num_auths;
760 reserved = tvb_get_uint8(tvb, offset);
761 proto_tree_add_uint(tree, hf_srvloc_url_reserved, tvb, offset, 1,
762 reserved);
763 offset += 1;
764 proto_tree_add_item(tree, hf_srvloc_url_lifetime, tvb, offset, 2,
765 ENC_BIG_ENDIAN);
766 offset += 2;
767 url_len = tvb_get_ntohs(tvb, offset);
768 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2,
769 url_len);
770 offset += 2;
771 proto_tree_add_item(tree, hf_srvloc_url_url, tvb, offset, url_len, ENC_ASCII);
772 offset += url_len;
773 num_auths = tvb_get_uint8(tvb, offset);
774 proto_tree_add_uint(tree, hf_srvloc_url_numauths, tvb, offset, 1,
775 num_auths);
776 offset += 1;
777 while (num_auths > 0) {
778 offset = dissect_authblk_v2(tvb, offset, tree);
779 num_auths--;
781 return offset;
784 /* Packet dissection routine called by tcp & udp when port 427 detected */
786 static int
787 dissect_srvloc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
789 int offset = 0;
790 proto_item *ti;
791 proto_tree *srvloc_tree;
792 uint8_t version;
793 uint8_t function;
794 uint16_t encoding;
795 uint32_t length; /* three bytes needed for v2 */
796 uint16_t flags; /* two byes needed for v2 */
797 uint32_t count;
798 uint32_t next_ext_off; /* three bytes, v2 only */
799 uint16_t lang_tag_len;
800 proto_item *expert_item;
801 uint16_t expert_status;
803 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
805 col_clear(pinfo->cinfo, COL_INFO);
807 version = tvb_get_uint8(tvb, offset);
808 function = tvb_get_uint8(tvb, offset + 1);
810 col_add_str(pinfo->cinfo, COL_INFO,
811 val_to_str(function, srvloc_functions, "Unknown Function (%u)"));
813 ti = proto_tree_add_item(tree, proto_srvloc, tvb, offset, -1, ENC_NA);
814 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
816 proto_tree_add_uint(srvloc_tree, hf_srvloc_version, tvb, offset, 1,
817 version);
818 proto_tree_add_uint(srvloc_tree, hf_srvloc_function, tvb, offset + 1, 1,
819 function);
820 if (version < 2) {
821 static int * const v1_flags[] = {
822 &hf_srvloc_flags_v1_overflow,
823 &hf_srvloc_flags_v1_monolingual,
824 &hf_srvloc_flags_v1_url_auth,
825 &hf_srvloc_flags_v1_attribute_auth,
826 &hf_srvloc_flags_v1_fresh,
827 NULL
830 length = tvb_get_ntohs(tvb, offset + 2);
831 proto_tree_add_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 2,
832 length);
833 flags = tvb_get_uint8(tvb, offset + 4);
834 proto_tree_add_bitmask(srvloc_tree, tvb, offset + 4, hf_srvloc_flags_v1, ett_srvloc_flags, v1_flags, ENC_NA);
835 proto_tree_add_item(srvloc_tree, hf_srvloc_dialect, tvb, offset + 5, 1, ENC_NA);
836 proto_tree_add_item(srvloc_tree, hf_srvloc_language, tvb, offset + 6, 2, ENC_NA|ENC_ASCII);
837 encoding = tvb_get_ntohs(tvb, offset + 8);
838 proto_tree_add_item(srvloc_tree, hf_srvloc_encoding, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
839 proto_tree_add_item(srvloc_tree, hf_srvloc_transaction_id, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
840 /* added echo of XID to info column by Greg Morris 0ct 14, 2005 */
841 col_append_fstr(pinfo->cinfo, COL_INFO, ", V1 Transaction ID - %u", tvb_get_ntohs(tvb, offset + 10));
843 offset += 12;
845 switch (function) {
847 case SRVREQ:
848 length = tvb_get_ntohs(tvb, offset);
849 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
850 offset += 2;
851 add_v1_string(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, encoding);
852 offset += length;
853 length = tvb_get_ntohs(tvb, offset);
854 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
855 offset += 2;
856 add_v1_string(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, encoding);
857 offset += length;
858 break;
860 case SRVRPLY:
861 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, ENC_BIG_ENDIAN);
862 expert_status = tvb_get_ntohs(tvb, offset);
863 if (expert_status!=0) {
864 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
866 offset += 2;
867 count = tvb_get_ntohs(tvb, offset);
868 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
869 offset += 2;
870 while (count > 0) {
871 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree,
872 encoding, flags);
873 count--;
875 break;
877 case SRVREG:
878 offset = dissect_url_entry_v1(tvb, offset, srvloc_tree, encoding,
879 flags);
880 length = tvb_get_ntohs(tvb, offset);
881 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
882 offset += 2;
883 add_v1_string(srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, encoding);
884 offset += length;
885 if ( (flags & FLAG_A) == FLAG_A )
886 offset = dissect_authblk(tvb, offset, srvloc_tree);
887 break;
889 case SRVDEREG:
890 length = tvb_get_ntohs(tvb, offset);
891 proto_tree_add_uint(tree, hf_srvloc_url_urllen, tvb, offset, 2, length);
892 offset += 2;
893 add_v1_string(tree, hf_srvloc_url_url, tvb, offset, length, encoding);
894 offset += length;
895 if ( (flags & FLAG_U) == FLAG_U )
896 offset = dissect_authblk(tvb, offset, srvloc_tree);
897 length = tvb_get_ntohs(tvb, offset);
898 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
899 offset += 2;
900 add_v1_string(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, encoding);
901 offset += length;
903 * XXX - this was there before, but RFC 2165 doesn't speak
904 * of there being an attribute authentication block in
905 * a Service Deregister message. Is that a post-RFC-2165
906 * addition?
908 if ( (flags & FLAG_A) == FLAG_A )
909 offset = dissect_authblk(tvb, offset, srvloc_tree);
910 break;
912 case SRVACK:
913 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, ENC_BIG_ENDIAN);
914 expert_status = tvb_get_ntohs(tvb, offset);
915 if (expert_status!=0) {
916 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
918 offset += 2;
919 break;
921 case ATTRRQST:
922 length = tvb_get_ntohs(tvb, offset);
923 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
924 offset += 2;
925 add_v1_string(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, encoding);
926 offset += length;
927 length = tvb_get_ntohs(tvb, offset);
928 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
929 offset += 2;
930 add_v1_string(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, encoding);
931 offset += length;
932 length = tvb_get_ntohs(tvb, offset);
933 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
934 offset += 2;
935 add_v1_string(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, encoding);
936 offset += length;
937 length = tvb_get_ntohs(tvb, offset);
938 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_attrlistlen, tvb, offset, 2, length);
939 offset += 2;
940 add_v1_string(srvloc_tree, hf_srvloc_attrreq_attrlist, tvb, offset, length, encoding);
941 offset += length;
942 break;
944 case ATTRRPLY:
945 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
946 expert_status = tvb_get_ntohs(tvb, offset);
947 if (expert_status!=0) {
948 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
950 offset += 2;
951 length = tvb_get_ntohs(tvb, offset);
952 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
953 if (length > 0) {
954 offset += 2;
955 attr_list(srvloc_tree, pinfo, hf_srvloc_attrrply_attrlist, tvb, offset, length, encoding);
956 offset += length;
957 if ( (flags & FLAG_A) == FLAG_A )
958 offset = dissect_authblk(tvb, offset, srvloc_tree);
960 break;
962 case DAADVERT:
963 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, ENC_BIG_ENDIAN);
964 expert_status = tvb_get_ntohs(tvb, offset);
965 if (expert_status!=0) {
966 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
968 offset += 2;
969 length = tvb_get_ntohs(tvb, offset);
970 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
971 offset += 2;
972 add_v1_string(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, encoding);
973 offset += length;
974 length = tvb_get_ntohs(tvb, offset);
975 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
976 offset += 2;
977 add_v1_string(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, encoding);
978 offset += length;
979 break;
981 case SRVTYPERQST:
982 length = tvb_get_ntohs(tvb, offset);
983 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
984 offset += 2;
985 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, encoding);
986 offset += length;
987 length = tvb_get_ntohs(tvb, offset);
988 /* Updated by Greg Morris on 1-30-04 */
989 if (0xFFFF == length) {
990 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
991 offset += 2;
993 else
995 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
996 offset += 2;
997 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, encoding);
998 offset += length;
1000 length = tvb_get_ntohs(tvb, offset);
1001 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
1002 offset += 2;
1003 add_v1_string(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, encoding);
1004 offset += length;
1005 break;
1007 case SRVTYPERPLY:
1008 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, ENC_BIG_ENDIAN);
1009 expert_status = tvb_get_ntohs(tvb, offset);
1010 if (expert_status!=0) {
1011 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error, "Error: %s", val_to_str(expert_status, srvloc_errs, "Unknown SRVLOC Error (0x%02x)"));
1013 offset += 2;
1014 count = tvb_get_ntohs(tvb, offset);
1015 proto_tree_add_item(srvloc_tree, hf_srvloc_service_type_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1016 offset += 2;
1017 while (count > 0) {
1018 length = tvb_get_ntohs(tvb, offset);
1019 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelen, tvb, offset, 2, length);
1020 offset += 2;
1021 add_v1_string(srvloc_tree, hf_srvloc_srvtyperply_srvtype, tvb, offset, length, encoding);
1022 offset += length;
1023 count--;
1025 break;
1027 default:
1028 proto_tree_add_expert_format(srvloc_tree, pinfo, &ei_srvloc_function_unknown,
1029 tvb, offset, -1, "Unknown Function Type: %d", function);
1032 else { /* Version 2 */
1033 static int * const v2_flags[] = {
1034 &hf_srvloc_flags_v2_overflow,
1035 &hf_srvloc_flags_v2_fresh,
1036 &hf_srvloc_flags_v2_reqmulti,
1037 NULL
1040 proto_tree_add_item_ret_uint(srvloc_tree, hf_srvloc_pktlen, tvb, offset + 2, 3, ENC_BIG_ENDIAN, &length);
1041 proto_tree_add_bitmask(srvloc_tree, tvb, offset + 5, hf_srvloc_flags_v2, ett_srvloc_flags, v2_flags, ENC_BIG_ENDIAN);
1043 proto_tree_add_item_ret_uint(srvloc_tree, hf_srvloc_nextextoff, tvb, offset + 7, 3,
1044 ENC_BIG_ENDIAN, &next_ext_off);
1045 proto_tree_add_item(srvloc_tree, hf_srvloc_xid, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
1046 col_append_fstr(pinfo->cinfo, COL_INFO, ", V2 XID - %u", tvb_get_ntohs(tvb, offset + 10));
1047 lang_tag_len = tvb_get_ntohs(tvb, offset + 12);
1048 proto_tree_add_uint(srvloc_tree, hf_srvloc_langtaglen, tvb, offset + 12, 2, lang_tag_len);
1049 proto_tree_add_item(srvloc_tree, hf_srvloc_langtag, tvb, offset + 14, lang_tag_len, ENC_ASCII);
1050 offset += 14+lang_tag_len;
1052 switch (function) {
1054 case SRVREQ: /* RFC2608 8.1 */
1055 length = tvb_get_ntohs(tvb, offset);
1056 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_prlistlen, tvb, offset, 2, length);
1057 offset += 2;
1058 if (length) {
1059 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_prlist, tvb, offset, length, ENC_ASCII);
1060 offset += length;
1062 length = tvb_get_ntohs(tvb, offset);
1063 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_srvtypelen, tvb, offset, 2, length);
1064 offset += 2;
1065 if (length) {
1066 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_srvtypelist, tvb, offset, length, ENC_ASCII);
1067 offset += length;
1069 length = tvb_get_ntohs(tvb, offset);
1070 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_scopelistlen, tvb, offset, 2, length);
1071 offset += 2;
1072 if (length) {
1073 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_scopelist, tvb, offset, length, ENC_ASCII);
1074 offset += length;
1076 length = tvb_get_ntohs(tvb, offset);
1077 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_predicatelen, tvb, offset, 2, length);
1078 offset += 2;
1079 if (length) {
1080 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_predicate, tvb, offset, length, ENC_ASCII);
1081 offset += length;
1083 length = tvb_get_ntohs(tvb, offset);
1084 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreq_slpspilen, tvb, offset, 2, length);
1085 offset += 2;
1086 if (length) {
1087 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreq_slpspi, tvb, offset, length, ENC_ASCII);
1088 offset += length;
1090 break;
1092 case SRVRPLY: /* RFC2608 8.2 */
1093 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
1094 expert_status = tvb_get_ntohs(tvb, offset);
1095 if (expert_status!=0) {
1096 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error_v2, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1098 offset += 2;
1099 count = tvb_get_ntohs(tvb, offset);
1100 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvrply_urlcount, tvb, offset, 2, count);
1101 offset += 2;
1102 while (count > 0) {
1103 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1104 count--;
1106 break;
1108 case SRVREG: /* RFC2608 8.3 */
1109 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1110 length = tvb_get_ntohs(tvb, offset);
1111 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_srvtypelen, tvb, offset, 2, length);
1112 offset += 2;
1113 if (length) {
1114 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_srvtype, tvb, offset, length, ENC_ASCII);
1115 offset += length;
1117 length = tvb_get_ntohs(tvb, offset);
1118 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_scopelistlen, tvb, offset, 2, length);
1119 offset += 2;
1120 if (length) {
1121 proto_tree_add_item(srvloc_tree, hf_srvloc_srvreg_scopelist, tvb, offset, length, ENC_ASCII);
1122 offset += length;
1124 length = tvb_get_ntohs(tvb, offset);
1125 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrlistlen, tvb, offset, 2, length);
1126 offset += 2;
1127 if (length) {
1128 attr_list2(pinfo, srvloc_tree, hf_srvloc_srvreg_attrlist, tvb, offset, length, CHARSET_UTF_8);
1129 offset += length;
1131 count = tvb_get_uint8(tvb, offset);
1132 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvreg_attrauthcount, tvb, offset, 1, count);
1133 offset += 1;
1134 while (count > 0) {
1135 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1136 count--;
1138 break;
1140 case SRVDEREG: /* RFC2608 10.6 */
1141 length = tvb_get_ntohs(tvb, offset);
1142 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_scopelistlen, tvb, offset, 2, length);
1143 offset += 2;
1144 if (length) {
1145 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_scopelist, tvb, offset, length, ENC_ASCII);
1146 offset += length;
1148 offset = dissect_url_entry_v2(tvb, offset, srvloc_tree);
1149 length = tvb_get_ntohs(tvb, offset);
1150 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvdereg_taglistlen, tvb, offset, 2, length);
1151 offset += 2;
1152 if (length) {
1153 proto_tree_add_item(srvloc_tree, hf_srvloc_srvdereg_taglist, tvb, offset, length, ENC_ASCII);
1154 offset += length;
1156 break;
1158 case SRVACK: /* RFC2608 8.4 */
1159 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
1160 expert_status = tvb_get_ntohs(tvb, offset);
1161 if (expert_status!=0) {
1162 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error_v2, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1164 offset += 2;
1165 break;
1167 case ATTRRQST: /* RFC2608 10.3*/
1168 length = tvb_get_ntohs(tvb, offset);
1169 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_prlistlen, tvb, offset, 2, length);
1170 offset += 2;
1171 if (length) {
1172 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_prlist, tvb, offset, length, ENC_ASCII);
1173 offset += length;
1175 length = tvb_get_ntohs(tvb, offset);
1176 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_urllen, tvb, offset, 2, length);
1177 offset += 2;
1178 if (length) {
1179 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_url, tvb, offset, length, ENC_ASCII);
1180 offset += length;
1182 length = tvb_get_ntohs(tvb, offset);
1183 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_scopelistlen, tvb, offset, 2, length);
1184 offset += 2;
1185 if (length) {
1186 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_scopelist, tvb, offset, length, ENC_ASCII);
1187 offset += length;
1189 length = tvb_get_ntohs(tvb, offset);
1190 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_taglistlen, tvb, offset, 2, length);
1191 offset += 2;
1192 if (length) {
1193 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_taglist, tvb, offset, length, ENC_ASCII);
1194 offset += length;
1196 length = tvb_get_ntohs(tvb, offset);
1197 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrreq_slpspilen, tvb, offset, 2, length);
1198 offset += 2;
1199 if (length) {
1200 proto_tree_add_item(srvloc_tree, hf_srvloc_attrreq_slpspi, tvb, offset, length, ENC_ASCII);
1201 offset += length;
1203 break;
1205 case ATTRRPLY: /* RFC2608 10.4 */
1206 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
1207 expert_status = tvb_get_ntohs(tvb, offset);
1208 if (expert_status!=0) {
1209 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error_v2, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1211 offset += 2;
1212 length = tvb_get_ntohs(tvb, offset);
1213 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrlistlen, tvb, offset, 2, length);
1214 offset += 2;
1215 if (length) {
1216 attr_list2(pinfo, srvloc_tree, hf_srvloc_attrrply_attrlist, tvb, offset, length, CHARSET_UTF_8);
1217 offset += length;
1219 count = tvb_get_uint8(tvb, offset);
1220 proto_tree_add_uint(srvloc_tree, hf_srvloc_attrrply_attrauthcount, tvb, offset, 1, count);
1221 offset += 1;
1222 while (count > 0) {
1223 offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
1224 count--;
1226 break;
1228 case DAADVERT: /* RCC 2608 8.5 */
1229 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
1230 expert_status = tvb_get_ntohs(tvb, offset);
1231 if (expert_status!=0) {
1232 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error_v2, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1234 offset += 2;
1235 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_timestamp, tvb, offset, 4,
1236 ENC_TIME_SECS|ENC_BIG_ENDIAN);
1237 offset += 4;
1238 length = tvb_get_ntohs(tvb, offset);
1239 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_urllen, tvb, offset, 2, length);
1240 offset += 2;
1241 if (length) {
1242 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_url, tvb, offset, length, ENC_ASCII);
1243 offset += length;
1245 length = tvb_get_ntohs(tvb, offset);
1246 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_scopelistlen, tvb, offset, 2, length);
1247 offset += 2;
1248 if (length) {
1249 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_scopelist, tvb, offset, length, ENC_ASCII);
1250 offset += length;
1252 length = tvb_get_ntohs(tvb, offset);
1253 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_attrlistlen, tvb, offset, 2, length);
1254 offset += 2;
1255 if (length) {
1256 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_attrlist, tvb, offset, length, ENC_ASCII);
1257 offset += length;
1259 length = tvb_get_ntohs(tvb, offset);
1260 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_slpspilen, tvb, offset, 2, length);
1261 offset += 2;
1262 if (length) {
1263 proto_tree_add_item(srvloc_tree, hf_srvloc_daadvert_slpspi, tvb, offset, length, ENC_ASCII);
1264 offset += length;
1266 count = tvb_get_uint8(tvb, offset);
1267 proto_tree_add_uint(srvloc_tree, hf_srvloc_daadvert_authcount, tvb, offset, 1, count);
1268 offset += 1;
1269 while (count > 0) {
1270 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1271 count--;
1273 break;
1275 case SRVTYPERQST: /* RFC2608 10.1 */
1276 length = tvb_get_ntohs(tvb, offset);
1277 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_prlistlen, tvb, offset, 2, length);
1278 offset += 2;
1279 if (length) {
1280 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_prlist, tvb, offset, length, ENC_ASCII);
1281 offset += length;
1283 length = tvb_get_ntohs(tvb, offset);
1284 if (0xFFFF == length) {
1285 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlenall, tvb, offset, 2, length);
1286 offset += 2;
1287 } else {
1288 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_nameauthlistlen, tvb, offset, 2, length);
1289 offset += 2;
1290 if (length) {
1291 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_nameauthlist, tvb, offset, length, ENC_ASCII);
1292 offset += length;
1295 length = tvb_get_ntohs(tvb, offset);
1296 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtypereq_scopelistlen, tvb, offset, 2, length);
1297 offset += 2;
1298 if (length) {
1299 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtypereq_scopelist, tvb, offset, length, ENC_ASCII);
1300 offset += length;
1302 break;
1304 case SRVTYPERPLY: /* rfc2608 10.2 */
1305 expert_item = proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, ENC_BIG_ENDIAN);
1306 expert_status = tvb_get_ntohs(tvb, offset);
1307 if (expert_status!=0) {
1308 expert_add_info_format(pinfo, expert_item, &ei_srvloc_error_v2, "Error: %s", val_to_str(expert_status, srvloc_errs_v2, "Unknown SRVLOC Error (0x%02x)"));
1310 offset += 2;
1311 length = tvb_get_ntohs(tvb, offset);
1312 proto_tree_add_uint(srvloc_tree, hf_srvloc_srvtyperply_srvtypelistlen, tvb, offset, 2, length);
1313 offset += 2;
1314 if (length) {
1315 proto_tree_add_item(srvloc_tree, hf_srvloc_srvtyperply_srvtypelist, tvb, offset, length, ENC_ASCII);
1316 offset += length;
1318 break;
1320 case SAADVERT: /* rfc2608 10.2 */
1321 length = tvb_get_ntohs(tvb, offset);
1322 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_urllen, tvb, offset, 2, length);
1323 offset += 2;
1324 if (length) {
1325 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_url, tvb, offset, length, ENC_ASCII);
1326 offset += length;
1328 length = tvb_get_ntohs(tvb, offset);
1329 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_scopelistlen, tvb, offset, 2, length);
1330 offset += 2;
1331 if (length) {
1332 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_scopelist, tvb, offset, length, ENC_ASCII);
1333 offset += length;
1335 length = tvb_get_ntohs(tvb, offset);
1336 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_attrlistlen, tvb, offset, 2, length);
1337 offset += 2;
1338 if (length) {
1339 proto_tree_add_item(srvloc_tree, hf_srvloc_saadvert_attrlist, tvb, offset, length, ENC_ASCII);
1340 offset += length;
1342 count = tvb_get_uint8(tvb, offset);
1343 proto_tree_add_uint(srvloc_tree, hf_srvloc_saadvert_authcount, tvb, offset, 1, length);
1344 offset += 1;
1345 while (count > 0) {
1346 offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
1347 count--;
1349 break;
1351 default:
1352 proto_tree_add_expert_format(srvloc_tree, pinfo, &ei_srvloc_function_unknown,
1353 tvb, offset, -1, "Unknown Function Type: %d", function);
1356 return offset;
1359 static unsigned
1360 get_srvloc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1363 * Get the length of the SRVLOC packet.
1364 * It starts at offset+2, but it's 2 bytes in SLPv1 and 3 bytes
1365 * in SLPv2.
1367 if (tvb_get_uint8(tvb, offset) == 2)
1368 return tvb_get_ntoh24(tvb, offset + 2);
1369 else
1370 return tvb_get_ntohs(tvb, offset + 2);
1373 static int
1374 dissect_srvloc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1377 * XXX - in SLPv1, the fixed length need only be 4, as the length
1378 * is 2 bytes long; however, it must be 5 for SLPv2, as the length
1379 * is 3 bytes long, and there's probably no harm in asking for 5
1380 * bytes, as even SLPv1 packets start with a 12-byte header,
1381 * and if the packet has a length that's 4 or less, it's bogus,
1382 * and we can't handle a length < 4 anyway.
1384 tcp_dissect_pdus(tvb, pinfo, tree, srvloc_desegment, 5, get_srvloc_pdu_len,
1385 dissect_srvloc, data);
1386 return tvb_captured_length(tvb);
1389 /* Register protocol with Wireshark. */
1391 void
1392 proto_register_srvloc(void)
1394 static hf_register_info hf[] = {
1395 /* Helper functions for the Version 1 Header*/
1396 {&hf_srvloc_error,
1397 {"Error Code", "srvloc.err",
1398 FT_UINT16, BASE_DEC, VALS(srvloc_errs), 0x0,
1399 NULL, HFILL }
1402 /* Helper function for the Version 2 Header */
1403 {&hf_srvloc_error_v2,
1404 {"Error Code", "srvloc.errv2",
1405 FT_UINT16, BASE_DEC, VALS(srvloc_errs_v2), 0x0,
1406 NULL, HFILL }
1408 {&hf_srvloc_xid,
1409 {"XID", "srvloc.xid",
1410 FT_UINT24, BASE_DEC, NULL, 0x0,
1411 "Transaction ID", HFILL }
1413 {&hf_srvloc_langtag,
1414 {"Lang Tag", "srvloc.langtag",
1415 FT_STRING, BASE_NONE, NULL, 0x0,
1416 NULL, HFILL }
1418 {&hf_srvloc_langtaglen,
1419 {"Lang Tag Len", "srvloc.langtaglen",
1420 FT_UINT16, BASE_DEC, NULL, 0x0,
1421 NULL, HFILL }
1423 {&hf_srvloc_nextextoff,
1424 {"Next Extension Offset", "srvloc.nextextoff",
1425 FT_UINT24, BASE_DEC, NULL, 0x0,
1426 NULL, HFILL }
1429 /* Helper functions for URL and URL Entry parsing - both versions */
1430 {&hf_srvloc_url_reserved,
1431 {"Reserved", "srvloc.url.reserved",
1432 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1434 {&hf_srvloc_url_lifetime,
1435 {"URL lifetime", "srvloc.url.lifetime",
1436 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1438 {&hf_srvloc_url_urllen,
1439 {"URL Length", "srvloc.url.urllen",
1440 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1442 {&hf_srvloc_url_url,
1443 {"URL", "srvloc.url.url",
1444 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
1446 {&hf_srvloc_url_numauths,
1447 {"Num Auths", "srvloc.url.numauths",
1448 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1451 /* Helper functions for the common header fields */
1452 {&hf_srvloc_function,
1453 {"Function", "srvloc.function",
1454 FT_UINT8, BASE_DEC, VALS(srvloc_functions), 0x0,
1455 NULL, HFILL }
1458 {&hf_srvloc_pktlen,
1459 {"Packet Length", "srvloc.pktlen",
1460 FT_UINT24, BASE_DEC, NULL, 0x0,
1461 NULL, HFILL }
1464 { &hf_srvloc_version,
1465 { "Version", "srvloc.version",
1466 FT_UINT8, BASE_DEC, NULL, 0x0,
1467 NULL, HFILL }
1470 {&hf_srvloc_flags_v1,
1471 {"Flags", "srvloc.flags_v1",
1472 FT_UINT8, BASE_HEX, NULL, 0x0,
1473 NULL, HFILL }
1476 { &hf_srvloc_flags_v1_overflow,
1477 { "Overflow", "srvloc.flags_v1.overflow", FT_BOOLEAN, 8,
1478 TFS(&tfs_srvloc_flags_overflow), FLAG_O, "Can whole packet fit into a datagram?", HFILL }},
1480 { &hf_srvloc_flags_v1_monolingual,
1481 { "Monolingual", "srvloc.flags_v1.monolingual", FT_BOOLEAN, 8,
1482 TFS(&tfs_srvloc_flags_v1_monolingual), FLAG_M, "Can whole packet fit into a datagram?", HFILL }},
1484 { &hf_srvloc_flags_v1_url_auth,
1485 { "URL Authentication", "srvloc.flags_v1.url_auth", FT_BOOLEAN, 8,
1486 TFS(&tfs_srvloc_flags_v1_url_auth), FLAG_U, "Can whole packet fit into a datagram?", HFILL }},
1488 { &hf_srvloc_flags_v1_attribute_auth,
1489 { "Attribute Authentication", "srvloc.flags_v1.attribute_auth", FT_BOOLEAN, 8,
1490 TFS(&tfs_srvloc_flags_v1_attribute_auth), FLAG_A, "Can whole packet fit into a datagram?", HFILL }},
1492 { &hf_srvloc_flags_v1_fresh,
1493 { "Fresh Registration", "srvloc.flags_v1.fresh", FT_BOOLEAN, 8,
1494 TFS(&tfs_srvloc_flags_fresh), FLAG_F, "Is this a new registration?", HFILL }},
1496 {&hf_srvloc_flags_v2,
1497 {"Flags", "srvloc.flags_v2",
1498 FT_UINT16, BASE_HEX, NULL, 0x0,
1499 NULL, HFILL }
1502 { &hf_srvloc_flags_v2_overflow,
1503 { "Overflow", "srvloc.flags_v2.overflow", FT_BOOLEAN, 16,
1504 TFS(&tfs_srvloc_flags_overflow), FLAG_O_V2, "Can whole packet fit into a datagram?", HFILL }},
1506 { &hf_srvloc_flags_v2_fresh,
1507 { "Fresh Registration", "srvloc.flags_v2.fresh", FT_BOOLEAN, 16,
1508 TFS(&tfs_srvloc_flags_fresh), FLAG_F_V2, "Is this a new registration?", HFILL }},
1510 { &hf_srvloc_flags_v2_reqmulti,
1511 { "Multicast requested", "srvloc.flags_v2.reqmulti", FT_BOOLEAN, 16,
1512 TFS(&tfs_srvloc_flags_v2_reqmulti), FLAG_R_V2, "Do we want multicast?", HFILL }},
1514 /* collection of helper functions for dissect_authblk_v2 */
1515 { &hf_srvloc_authblkv2_bsd,
1516 { "BSD", "srvloc.authblkv2_bsd", FT_UINT16, BASE_HEX, NULL, 0x0,
1517 "Block Structure Descriptor", HFILL}
1519 { &hf_srvloc_authblkv2_len,
1520 { "Length", "srvloc.authblkv2_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1521 "Length of Authentication Block", HFILL}
1523 { &hf_srvloc_authblkv2_timestamp,
1524 { "Timestamp", "srvloc.authblkv2.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1525 NULL, 0, "Timestamp on Authentication Block", HFILL }
1527 { &hf_srvloc_authblkv2_slpspilen,
1528 { "SLP SPI Length", "srvloc.authblkv2.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1529 "Length of the SLP SPI", HFILL}
1531 { &hf_srvloc_authblkv2_slpspi,
1532 { "SLP SPI", "srvloc.authblkv2.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1533 NULL, HFILL}
1536 /* collection of helper functions for Service Request */
1537 { &hf_srvloc_srvreq_prlistlen,
1538 { "Previous Response List Length", "srvloc.srvreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1539 "Length of Previous Response List", HFILL}
1541 { &hf_srvloc_srvreq_prlist,
1542 { "Previous Response List", "srvloc.srvreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1543 NULL, HFILL}
1545 { &hf_srvloc_srvreq_srvtypelen,
1546 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1547 "Length of Service Type List", HFILL}
1549 { &hf_srvloc_srvreq_srvtypelist,
1550 { "Service Type List", "srvloc.srvreq.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1551 NULL, HFILL}
1553 { &hf_srvloc_srvreq_scopelistlen,
1554 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1555 "Length of the Scope List", HFILL}
1557 { &hf_srvloc_srvreq_scopelist,
1558 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1559 NULL, HFILL}
1561 { &hf_srvloc_srvreq_predicatelen,
1562 { "Predicate Length", "srvloc.srvreq.predicatelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1563 "Length of the Predicate", HFILL}
1565 { &hf_srvloc_srvreq_predicate,
1566 { "Predicate", "srvloc.srvreq.predicate", FT_STRING, BASE_NONE, NULL, 0x0,
1567 NULL, HFILL}
1569 { &hf_srvloc_srvreq_slpspilen,
1570 { "SLP SPI Length", "srvloc.srvreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1571 "Length of the SLP SPI", HFILL}
1573 { &hf_srvloc_srvreq_slpspi,
1574 { "SLP SPI", "srvloc.srvreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1575 NULL, HFILL}
1578 /* Helper function for Service Request */
1579 { &hf_srvloc_srvrply_urlcount,
1580 { "Number of URLs", "srvloc.srvreq.urlcount", FT_UINT16, BASE_DEC, NULL, 0x0,
1581 NULL, HFILL}
1584 /* Helper functions for Service Registration */
1585 { &hf_srvloc_srvreg_srvtypelen,
1586 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1587 NULL, HFILL}
1589 { &hf_srvloc_srvreg_srvtype,
1590 { "Service Type", "srvloc.srvreq.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1591 NULL, HFILL}
1593 { &hf_srvloc_srvreg_scopelistlen,
1594 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1595 NULL, HFILL}
1597 { &hf_srvloc_srvreg_scopelist,
1598 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1599 NULL, HFILL}
1601 { &hf_srvloc_srvreg_attrlistlen,
1602 { "Attribute List Length", "srvloc.srvreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1603 NULL, HFILL}
1605 { &hf_srvloc_srvreg_attrlist,
1606 { "Attribute List", "srvloc.srvreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1607 NULL, HFILL}
1609 { &hf_srvloc_srvreg_attrauthcount,
1610 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1611 "Number of Attribute Authentication Blocks", HFILL}
1614 /* Helper functions for Service Deregistration */
1615 { &hf_srvloc_srvdereg_scopelistlen,
1616 { "Scope List Length", "srvloc.srvdereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1617 NULL, HFILL}
1619 { &hf_srvloc_srvdereg_scopelist,
1620 { "Scope List", "srvloc.srvdereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1621 NULL, HFILL}
1623 { &hf_srvloc_srvdereg_taglistlen,
1624 { "Tag List Length", "srvloc.srvdereq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1625 NULL, HFILL}
1627 { &hf_srvloc_srvdereg_taglist,
1628 { "Tag List", "srvloc.srvdereq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1629 NULL, HFILL}
1633 /* collection of helper functions for Attribute Request */
1634 { &hf_srvloc_attrreq_prlistlen,
1635 { "Previous Response List Length", "srvloc.attrreq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1636 "Length of Previous Response List", HFILL}
1638 { &hf_srvloc_attrreq_prlist,
1639 { "Previous Response List", "srvloc.attrreq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1640 NULL, HFILL}
1642 { &hf_srvloc_attrreq_urllen,
1643 { "URL Length", "srvloc.attrreq.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1644 NULL, HFILL}
1646 { &hf_srvloc_attrreq_url,
1647 { "Service URL", "srvloc.attrreq.url", FT_STRING, BASE_NONE, NULL, 0x0,
1648 "URL of service", HFILL}
1650 { &hf_srvloc_attrreq_scopelistlen,
1651 { "Scope List Length", "srvloc.attrreq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1652 "Length of the Scope List", HFILL}
1654 { &hf_srvloc_attrreq_scopelist,
1655 { "Scope List", "srvloc.attrreq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1656 NULL, HFILL}
1658 { &hf_srvloc_attrreq_attrlistlen,
1659 { "Attribute List Length", "srvloc.attrreq.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1660 NULL, HFILL}
1662 { &hf_srvloc_attrreq_attrlist,
1663 { "Attribute List", "srvloc.attrreq.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1664 NULL, HFILL}
1666 { &hf_srvloc_attrreq_taglistlen,
1667 { "Tag List Length", "srvloc.attrreq.taglistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1668 NULL, HFILL}
1670 { &hf_srvloc_attrreq_taglist,
1671 { "Tag List", "srvloc.attrreq.taglist", FT_STRING, BASE_NONE, NULL, 0x0,
1672 NULL, HFILL}
1674 { &hf_srvloc_attrreq_slpspilen,
1675 { "SLP SPI Length", "srvloc.attrreq.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1676 "Length of the SLP SPI", HFILL}
1678 { &hf_srvloc_attrreq_slpspi,
1679 { "SLP SPI", "srvloc.attrreq.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1680 NULL, HFILL}
1683 /* collection of helper functions for Attribute Reply */
1684 { &hf_srvloc_attrrply_attrlistlen,
1685 { "Attribute List Length", "srvloc.attrrply.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1686 "Length of Attribute List", HFILL}
1688 { &hf_srvloc_attrrply_attrlist,
1689 { "Attribute List", "srvloc.attrrply.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1690 NULL, HFILL}
1692 { &hf_srvloc_attrrply_attrauthcount,
1693 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1694 "Number of Attribute Authentication Blocks", HFILL}
1697 /* collection of helper functions for DA Advertisement */
1698 { &hf_srvloc_daadvert_timestamp,
1699 { "DAADVERT Timestamp", "srvloc.daadvert.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1700 NULL, 0, "Timestamp on DA Advert", HFILL }
1702 { &hf_srvloc_daadvert_urllen,
1703 { "URL Length", "srvloc.daadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1704 NULL, HFILL}
1706 { &hf_srvloc_daadvert_url,
1707 { "URL", "srvloc.daadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1708 NULL, HFILL}
1710 { &hf_srvloc_daadvert_scopelistlen,
1711 { "Scope List Length", "srvloc.daadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1712 "Length of the Scope List", HFILL}
1714 { &hf_srvloc_daadvert_scopelist,
1715 { "Scope List", "srvloc.daadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1716 NULL, HFILL}
1718 { &hf_srvloc_daadvert_attrlistlen,
1719 { "Attribute List Length", "srvloc.daadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1720 NULL, HFILL}
1722 { &hf_srvloc_daadvert_attrlist,
1723 { "Attribute List", "srvloc.daadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1724 NULL, HFILL}
1726 { &hf_srvloc_daadvert_slpspilen,
1727 { "SLP SPI Length", "srvloc.daadvert.slpspilen", FT_UINT16, BASE_DEC, NULL, 0x0,
1728 "Length of the SLP SPI", HFILL}
1730 { &hf_srvloc_daadvert_slpspi,
1731 { "SLP SPI", "srvloc.daadvert.slpspi", FT_STRING, BASE_NONE, NULL, 0x0,
1732 NULL, HFILL}
1734 { &hf_srvloc_daadvert_authcount,
1735 { "Auths", "srvloc.daadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1736 "Number of Authentication Blocks", HFILL}
1739 /* collection of helper functions for Service Type Request */
1740 { &hf_srvloc_srvtypereq_prlistlen,
1741 { "Previous Response List Length", "srvloc.srvtypereq.prlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1742 "Length of Previous Response List", HFILL}
1744 { &hf_srvloc_srvtypereq_prlist,
1745 { "Previous Response List", "srvloc.srvtypereq.prlist", FT_STRING, BASE_NONE, NULL, 0x0,
1746 NULL, HFILL}
1748 { &hf_srvloc_srvtypereq_nameauthlistlen,
1749 { "Naming Authority List Length", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1750 "Length of the Naming Authority List", HFILL}
1752 { &hf_srvloc_srvtypereq_nameauthlistlenall,
1753 { "Naming Authority List Length (All Naming Authorities)", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1754 "Length of the Naming Authority List", HFILL}
1756 { &hf_srvloc_srvtypereq_nameauthlist,
1757 { "Naming Authority List", "srvloc.srvtypereq.nameauthlist", FT_STRING, BASE_NONE, NULL, 0x0,
1758 NULL, HFILL}
1760 { &hf_srvloc_srvtypereq_scopelistlen,
1761 { "Scope List Length", "srvloc.srvtypereq.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1762 "Length of the Scope List", HFILL}
1764 { &hf_srvloc_srvtypereq_scopelist,
1765 { "Scope List", "srvloc.srvtypereq.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1766 NULL, HFILL}
1769 /* collection of helper functions for Service Type Replies */
1770 { &hf_srvloc_srvtyperply_srvtypelen,
1771 { "Service Type Length", "srvloc.srvtypereq.srvtypelen", FT_UINT16, BASE_DEC, NULL, 0x0,
1772 "Length of the Service Type", HFILL}
1774 { &hf_srvloc_srvtyperply_srvtype,
1775 { "Service Type", "srvloc.srvtyperply.srvtype", FT_STRING, BASE_NONE, NULL, 0x0,
1776 NULL, HFILL}
1778 { &hf_srvloc_srvtyperply_srvtypelistlen,
1779 { "Service Type List Length", "srvloc.srvtypereq.srvtypelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1780 "Length of the Service Type List", HFILL}
1782 { &hf_srvloc_srvtyperply_srvtypelist,
1783 { "Service Type List", "srvloc.srvtyperply.srvtypelist", FT_STRING, BASE_NONE, NULL, 0x0,
1784 NULL, HFILL}
1787 /* collection of helper functions for SA Advertisement */
1788 { &hf_srvloc_saadvert_urllen,
1789 { "URL Length", "srvloc.saadvert.urllen", FT_UINT16, BASE_DEC, NULL, 0x0,
1790 NULL, HFILL}
1792 { &hf_srvloc_saadvert_url,
1793 { "URL", "srvloc.saadvert.url", FT_STRING, BASE_NONE, NULL, 0x0,
1794 NULL, HFILL}
1796 { &hf_srvloc_saadvert_scopelistlen,
1797 { "Scope List Length", "srvloc.saadvert.scopelistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1798 "Length of the Scope List", HFILL}
1800 { &hf_srvloc_saadvert_scopelist,
1801 { "Scope List", "srvloc.saadvert.scopelist", FT_STRING, BASE_NONE, NULL, 0x0,
1802 NULL, HFILL}
1804 { &hf_srvloc_saadvert_attrlistlen,
1805 { "Attribute List Length", "srvloc.saadvert.attrlistlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1806 NULL, HFILL}
1808 { &hf_srvloc_saadvert_attrlist,
1809 { "Attribute List", "srvloc.saadvert.attrlist", FT_STRING, BASE_NONE, NULL, 0x0,
1810 NULL, HFILL}
1812 { &hf_srvloc_saadvert_authcount,
1813 { "Auths", "srvloc.saadvert.authcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1814 "Number of Authentication Blocks", HFILL}
1816 { &hf_srvloc_add_ref_ip,
1817 { "IP Address", "srvloc.list.ipaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
1818 "IP Address of SLP server", HFILL}
1820 { &hf_srvloc_srvrply_svcname,
1821 { "Service Name Value", "srvloc.srvrply.svcname", FT_STRING, BASE_NONE, NULL, 0x0,
1822 NULL, HFILL}
1824 /* Generated from convert_proto_tree_add_text.pl */
1825 { &hf_srvloc_timestamp, { "Timestamp", "srvloc.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL }},
1826 { &hf_srvloc_block_structure_descriptor, { "Block Structure Descriptor", "srvloc.block_structure_descriptor", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1827 { &hf_srvloc_authenticator_length, { "Authenticator length", "srvloc.authenticator_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1828 { &hf_srvloc_authentication_block, { "Authentication block", "srvloc.authentication_block", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1829 { &hf_srvloc_service_type, { "Service Type", "srvloc.service_type", FT_UINT8, BASE_DEC, VALS(srvloc_svc), 0x0, NULL, HFILL }},
1830 { &hf_srvloc_communication_type, { "Communication Type", "srvloc.communication_type", FT_UINT8, BASE_DEC, VALS(srvloc_ss), 0x0, NULL, HFILL }},
1831 { &hf_srvloc_protocol, { "Protocol", "srvloc.protocol", FT_UINT32, BASE_DEC, VALS(srvloc_prot), 0x0, NULL, HFILL }},
1832 { &hf_srvloc_port, { "Port", "srvloc.port", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1833 { &hf_srvloc_network, { "Network", "srvloc.network", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1834 { &hf_srvloc_node, { "Node", "srvloc.node", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1835 { &hf_srvloc_socket, { "Socket", "srvloc.socket", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1836 { &hf_srvloc_item, { "Item", "srvloc.item", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1837 { &hf_srvloc_dialect, { "Dialect", "srvloc.dialect", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1838 { &hf_srvloc_language, { "Language", "srvloc.language", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1839 { &hf_srvloc_encoding, { "Encoding", "srvloc.encoding", FT_UINT16, BASE_DEC, VALS(charsets), 0x0, NULL, HFILL }},
1840 { &hf_srvloc_transaction_id, { "Transaction ID", "srvloc.transaction_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1841 { &hf_srvloc_service_type_count, { "Service Type Count", "srvloc.service_type_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1844 static int *ett[] = {
1845 &ett_srvloc,
1846 &ett_srvloc_attr,
1847 &ett_srvloc_flags,
1849 static ei_register_info ei[] = {
1850 { &ei_srvloc_error, { "srvloc.err.expert", PI_RESPONSE_CODE, PI_ERROR, "Error", EXPFILL }},
1851 { &ei_srvloc_error_v2, { "srvloc.errv2.expert", PI_RESPONSE_CODE, PI_ERROR, "Error", EXPFILL }},
1852 { &ei_srvloc_function_unknown, { "srvloc.function.unknown", PI_RESPONSE_CODE, PI_ERROR, "Unknown Function Type", EXPFILL }},
1853 { &ei_srvloc_malformed, { "srvloc.malformed", PI_MALFORMED, PI_ERROR, "Too much data to pass inside this protocol. Resubmit request using a streaming protocol like TCP. "
1854 "Protocol dissection is aborted due to packet overflow. See overflow flag.", EXPFILL }},
1857 module_t *srvloc_module;
1858 expert_module_t* expert_srvloc;
1860 proto_srvloc = proto_register_protocol("Service Location Protocol",
1861 "SRVLOC", "srvloc");
1862 proto_register_field_array(proto_srvloc, hf, array_length(hf));
1863 proto_register_subtree_array(ett, array_length(ett));
1864 srvloc_handle = register_dissector("srvloc", dissect_srvloc, proto_srvloc);
1865 srvloc_tcp_handle = register_dissector("srvloc.tcp", dissect_srvloc_tcp, proto_srvloc);
1866 expert_srvloc = expert_register_protocol(proto_srvloc);
1867 expert_register_field_array(expert_srvloc, ei, array_length(ei));
1868 srvloc_module = prefs_register_protocol(proto_srvloc, NULL);
1869 prefs_register_bool_preference(srvloc_module, "desegment_tcp",
1870 "Reassemble SRVLOC messages spanning multiple TCP segments",
1871 "Whether the SRVLOC dissector should reassemble messages spanning multiple TCP segments. "
1872 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1873 &srvloc_desegment);
1876 void
1877 proto_reg_handoff_srvloc(void)
1879 dissector_add_uint_with_preference("udp.port", UDP_PORT_SRVLOC, srvloc_handle);
1880 dissector_add_uint_with_preference("tcp.port", TCP_PORT_SRVLOC, srvloc_tcp_handle);
1884 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1886 * Local variables:
1887 * c-basic-offset: 4
1888 * tab-width: 8
1889 * indent-tabs-mode: nil
1890 * End:
1892 * vi: set shiftwidth=4 tabstop=8 expandtab:
1893 * :indentSize=4:tabSize=8:noTabs=true: