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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
46 #include <epan/packet.h>
47 #include <epan/strutil.h>
48 #include <epan/prefs.h>
49 #include <epan/wmem/wmem.h>
50 #include "packet-tcp.h"
51 #include <epan/expert.h>
53 static gboolean srvloc_desegment
= TRUE
;
54 static int proto_srvloc
= -1;
55 static int hf_srvloc_version
= -1;
56 static int hf_srvloc_function
= -1;
57 static int hf_srvloc_pktlen
= -1;
58 static int hf_srvloc_xid
= -1;
59 static int hf_srvloc_langtaglen
= -1;
60 static int hf_srvloc_langtag
= -1;
61 static int hf_srvloc_nextextoff
= -1;
62 static int hf_srvloc_flags_v1
= -1;
63 static int hf_srvloc_flags_v1_overflow
= -1;
64 static int hf_srvloc_flags_v1_monolingual
= -1;
65 static int hf_srvloc_flags_v1_url_auth
= -1;
66 static int hf_srvloc_flags_v1_attribute_auth
= -1;
67 static int hf_srvloc_flags_v1_fresh
= -1;
68 static int hf_srvloc_error
= -1;
69 static int hf_srvloc_flags_v2
= -1;
70 static int hf_srvloc_flags_v2_overflow
= -1;
71 static int hf_srvloc_flags_v2_fresh
= -1;
72 static int hf_srvloc_flags_v2_reqmulti
= -1;
73 static int hf_srvloc_error_v2
= -1;
74 static int hf_srvloc_daadvert_timestamp
= -1;
75 static int hf_srvloc_daadvert_urllen
= -1;
76 static int hf_srvloc_daadvert_url
= -1;
77 static int hf_srvloc_daadvert_scopelistlen
= -1;
78 static int hf_srvloc_daadvert_scopelist
= -1;
79 static int hf_srvloc_daadvert_attrlistlen
= -1;
80 static int hf_srvloc_daadvert_attrlist
= -1;
81 static int hf_srvloc_daadvert_slpspilen
= -1;
82 static int hf_srvloc_daadvert_slpspi
= -1;
83 static int hf_srvloc_daadvert_authcount
= -1;
84 static int hf_srvloc_srvreq_prlistlen
= -1;
85 static int hf_srvloc_srvreq_prlist
= -1;
86 static int hf_srvloc_srvreq_srvtypelen
= -1;
87 static int hf_srvloc_srvreq_srvtypelist
= -1;
88 static int hf_srvloc_srvreq_scopelistlen
= -1;
89 static int hf_srvloc_srvreq_scopelist
= -1;
90 static int hf_srvloc_srvreq_predicatelen
= -1;
91 static int hf_srvloc_srvreq_predicate
= -1;
92 static int hf_srvloc_srvreq_slpspilen
= -1;
93 static int hf_srvloc_srvreq_slpspi
= -1;
94 static int hf_srvloc_srvrply_urlcount
= -1;
95 static int hf_srvloc_srvreg_attrlistlen
= -1;
96 static int hf_srvloc_srvreg_attrlist
= -1;
97 static int hf_srvloc_srvreg_attrauthcount
= -1;
98 static int hf_srvloc_srvreg_srvtypelen
= -1;
99 static int hf_srvloc_srvreg_srvtype
= -1;
100 static int hf_srvloc_srvreg_scopelistlen
= -1;
101 static int hf_srvloc_srvreg_scopelist
= -1;
102 static int hf_srvloc_srvdereg_scopelistlen
= -1;
103 static int hf_srvloc_srvdereg_scopelist
= -1;
104 static int hf_srvloc_srvdereg_taglistlen
= -1;
105 static int hf_srvloc_srvdereg_taglist
= -1;
106 static int hf_srvloc_attrreq_prlistlen
= -1;
107 static int hf_srvloc_attrreq_prlist
= -1;
108 static int hf_srvloc_attrreq_urllen
= -1;
109 static int hf_srvloc_attrreq_url
= -1;
110 static int hf_srvloc_attrreq_scopelistlen
= -1;
111 static int hf_srvloc_attrreq_scopelist
= -1;
112 static int hf_srvloc_attrreq_attrlistlen
= -1;
113 static int hf_srvloc_attrreq_attrlist
= -1;
114 static int hf_srvloc_attrreq_taglistlen
= -1;
115 static int hf_srvloc_attrreq_taglist
= -1;
116 static int hf_srvloc_attrreq_slpspilen
= -1;
117 static int hf_srvloc_attrreq_slpspi
= -1;
118 static int hf_srvloc_attrrply_attrlistlen
= -1;
119 static int hf_srvloc_attrrply_attrlist
= -1;
120 static int hf_srvloc_attrrply_attrauthcount
= -1;
121 static int hf_srvloc_srvtypereq_prlistlen
= -1;
122 static int hf_srvloc_srvtypereq_prlist
= -1;
123 static int hf_srvloc_srvtypereq_nameauthlistlen
= -1;
124 static int hf_srvloc_srvtypereq_nameauthlistlenall
= -1;
125 static int hf_srvloc_srvtypereq_nameauthlist
= -1;
126 static int hf_srvloc_srvtypereq_scopelistlen
= -1;
127 static int hf_srvloc_srvtypereq_scopelist
= -1;
128 static int hf_srvloc_srvtyperply_srvtypelen
= -1;
129 static int hf_srvloc_srvtyperply_srvtype
= -1;
130 static int hf_srvloc_srvtyperply_srvtypelistlen
= -1;
131 static int hf_srvloc_srvtyperply_srvtypelist
= -1;
132 static int hf_srvloc_saadvert_urllen
= -1;
133 static int hf_srvloc_saadvert_url
= -1;
134 static int hf_srvloc_saadvert_scopelistlen
= -1;
135 static int hf_srvloc_saadvert_scopelist
= -1;
136 static int hf_srvloc_saadvert_attrlistlen
= -1;
137 static int hf_srvloc_saadvert_attrlist
= -1;
138 static int hf_srvloc_saadvert_authcount
= -1;
139 static int hf_srvloc_authblkv2_bsd
= -1;
140 static int hf_srvloc_authblkv2_len
= -1;
141 static int hf_srvloc_authblkv2_timestamp
= -1;
142 static int hf_srvloc_authblkv2_slpspilen
= -1;
143 static int hf_srvloc_authblkv2_slpspi
= -1;
144 static int hf_srvloc_url_reserved
= -1;
145 static int hf_srvloc_url_lifetime
= -1;
146 static int hf_srvloc_url_urllen
= -1;
147 static int hf_srvloc_url_url
= -1;
148 static int hf_srvloc_url_numauths
= -1;
149 static int hf_srvloc_add_ref_ip
= -1;
150 static int hf_srvloc_srvrply_svcname
= -1;
153 static gint ett_srvloc
= -1;
154 static gint ett_srvloc_attr
= -1;
155 static gint ett_srvloc_flags
= -1;
157 static expert_field ei_srvloc_error
= EI_INIT
;
158 static expert_field ei_srvloc_error_v2
= EI_INIT
;
159 static expert_field ei_srvloc_function_unknown
= EI_INIT
;
161 static const true_false_string tfs_srvloc_flags_overflow
= {
162 "Message will not fit in datagram",
163 "Message will fit in a datagram"
165 static const true_false_string tfs_srvloc_flags_v1_monolingual
= {
166 "Only responses in specified language will be accepted",
167 "Responses in any language will be accepted"
169 static const true_false_string tfs_srvloc_flags_v1_url_auth
= {
170 "URL Authentication Block is present",
171 "URL Authentication Block is absent"
173 static const true_false_string tfs_srvloc_flags_v1_attribute_auth
= {
174 "Attribute Authentication Block is present",
175 "Attribute Authentication Block is absent"
177 static const true_false_string tfs_srvloc_flags_fresh
= {
178 "New Service Registration",
179 "Not a new Service Registration"
181 static const true_false_string tfs_srvloc_flags_v2_reqmulti
= {
182 "Multicast (or broadcast) request",
183 "Not multicast or broadcast"
186 #define TCP_PORT_SRVLOC 427
187 #define UDP_PORT_SRVLOC 427
189 /* Define function types */
199 #define SRVTYPERQST 9
200 #define SRVTYPERPLY 10
201 #define SAADVERT 11 /* SLPv2, section 8 */
203 /* Create protocol header structure */
205 /* bradh: looks like never used. */
206 /* bradh: comment it out for now since it doesn't work for v2
219 /* List to resolve function numbers to names */
221 static const value_string srvloc_functions
[] = {
222 { SRVREQ
, "Service Request" },
223 { SRVRPLY
, "Service Reply" },
224 { SRVREG
, "Service Registration" },
225 { SRVDEREG
, "Service Deregister" },
226 { SRVACK
, "Service Acknowledge" },
227 { ATTRRQST
, "Attribute Request" },
228 { ATTRRPLY
, "Attribute Reply" },
229 { DAADVERT
, "DA Advertisement" },
230 { SRVTYPERQST
, "Service Type Request" },
231 { SRVTYPERPLY
, "Service Type Reply" },
232 { SAADVERT
, "SA Advertisement" }, /* v2 only */
236 /* List to resolve flag values to names */
239 /* Define flag masks */
247 /* it all changes for Version 2 */
248 #define FLAG_O_V2 0x8000
249 #define FLAG_F_V2 0x4000
250 #define FLAG_R_V2 0x2000
252 /* Define Error Codes - Version 1*/
255 #define LANG_NOT_SPTD 1
256 #define PROT_PARSE_ERR 2
258 #define SCOPE_NOT_SPTD 4
259 #define CHRSET_NOT_UND 5
260 #define AUTH_ABSENT 6
261 #define AUTH_FAILED 7
263 /* List to resolve error codes to names */
265 static const value_string srvloc_errs
[] = {
266 { SUCCESS
, "No Error" },
267 { LANG_NOT_SPTD
, "Language not supported" },
268 { PROT_PARSE_ERR
, "Protocol parse error" },
269 { INVLD_REG
, "Invalid registration" },
270 { SCOPE_NOT_SPTD
, "Scope not supported" },
271 { CHRSET_NOT_UND
, "Character set not understood" },
272 { AUTH_ABSENT
, "Authentication absent" },
273 { AUTH_FAILED
, "Authentication failed" },
277 /* Define Error Codes for Version 2 */
279 #define LANGUAGE_NOT_SUPPORTED 1
280 #define PARSE_ERROR 2
281 #define INVALID_REGISTRATION 3
282 #define SCOPE_NOT_SUPPORTED 4
283 #define AUTHENTICATION_UNKNOWN 5
284 #define AUTHENTICATION_ABSENT 6
285 #define AUTHENTICATION_FAILED 7
286 #define VER_NOT_SUPPORTED 9
287 #define INTERNAL_ERROR 10
288 #define DA_BUSY_NOW 11
289 #define OPTION_NOT_UNDERSTOOD 12
290 #define INVALID_UPDATE 13
291 #define MSG_NOT_SUPPORTED 14
292 #define REFRESH_REJECTED 15
294 static const value_string srvloc_errs_v2
[] = {
295 { SUCCESS
, "No Error" },
296 { LANGUAGE_NOT_SUPPORTED
, "No data in the requested language" },
297 { PARSE_ERROR
, "The message fails to obey SLP syntax." },
298 { INVALID_REGISTRATION
, "The SrvReg has problems" },
299 { SCOPE_NOT_SUPPORTED
, "Scope list not supported" },
300 { AUTHENTICATION_UNKNOWN
, "Unsupported SLP SPI." },
301 { AUTHENTICATION_ABSENT
, "URL and ATTR authentication not provided"},
302 { AUTHENTICATION_FAILED
, "Authentication error"},
303 { VER_NOT_SUPPORTED
, "Unsupported version number in message header" },
304 { INTERNAL_ERROR
, "The DA (or SA) is too sick to respond" },
305 { DA_BUSY_NOW
, "UA or SA SHOULD retry" },
306 { OPTION_NOT_UNDERSTOOD
, "Unknown option from the mandatory range"},
307 { INVALID_UPDATE
, "Invalid SrvReg" },
308 { MSG_NOT_SUPPORTED
, "No support for AttrRqst or SrvTypeRqst" },
309 { REFRESH_REJECTED
, "SrvReg sent too soon"},
314 * Character encodings.
315 * This is a small subset of what's in
317 * http://www.iana.org/assignments/character-sets
319 * XXX - we should do something useful with this, i.e. properly
320 * handle strings based on the character set they're in.
322 * XXX - what does "properly handle strings" mean? How do we know
323 * what character set the terminal can handle (for tty-based code)
324 * or the GUI can handle (for GUI code)?
326 * XXX - the Wireshark core really should be what does all the
327 * character set handling for strings, and it should be stuck with
328 * the task of figuring out how to properly handle them.
330 #define CHARSET_ASCII 3
331 #define CHARSET_ISO_10646_UTF_1 27
332 #define CHARSET_ISO_646_BASIC 28
333 #define CHARSET_ISO_646_IRV 30
334 #define CHARSET_ISO_8859_1 4
335 #define CHARSET_ISO_10646_UCS_2 1000 /* a/k/a Unicode */
336 #define CHARSET_UTF_7 1012
337 #define CHARSET_UTF_8 106
339 static const value_string charsets
[] = {
340 { CHARSET_ASCII
, "US-ASCII" },
341 { CHARSET_ISO_10646_UTF_1
, "ISO 10646 UTF-1" },
342 { CHARSET_ISO_646_BASIC
, "ISO 646 basic:1983" },
343 { CHARSET_ISO_646_IRV
, "ISO 646 IRV:1983" },
344 { CHARSET_ISO_8859_1
, "ISO 8859-1" },
345 { CHARSET_ISO_10646_UCS_2
, "Unicode" },
346 { CHARSET_UTF_7
, "UTF-7" },
347 { CHARSET_UTF_8
, "UTF-8" },
352 dissect_authblk(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
359 seconds
= tvb_get_ntohl(tvb
, offset
) - 2208988800ul;
360 stamp
= gmtime(&seconds
);
362 floatsec
= stamp
->tm_sec
+ tvb_get_ntohl(tvb
, offset
+ 4) / 4294967296.0;
363 proto_tree_add_text(tree
, tvb
, offset
, 8,
364 "Timestamp: %04d-%02d-%02d %02d:%02d:%07.4f UTC",
365 stamp
->tm_year
+ 1900, stamp
->tm_mon
+ 1,
366 stamp
->tm_mday
, stamp
->tm_hour
, stamp
->tm_min
,
369 proto_tree_add_text(tree
, tvb
, offset
, 8, "Timestamp not representable");
371 proto_tree_add_text(tree
, tvb
, offset
+ 8, 2, "Block Structure Descriptor: %u",
372 tvb_get_ntohs(tvb
, offset
+ 8));
373 length
= tvb_get_ntohs(tvb
, offset
+ 10);
374 proto_tree_add_text(tree
, tvb
, offset
+ 10, 2, "Authenticator length: %u",
377 proto_tree_add_text(tree
, tvb
, offset
, length
, "Authentication block: %s",
378 tvb_format_text(tvb
, offset
, length
));
383 /* SLPv2 version - Needs to be fixed to match RFC2608 sect 9.2*/
385 dissect_authblk_v2(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
390 proto_tree_add_item(tree
, hf_srvloc_authblkv2_bsd
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
391 proto_tree_add_item(tree
, hf_srvloc_authblkv2_len
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
393 ts
.secs
= tvb_get_ntohl(tvb
, offset
+ 4);
394 proto_tree_add_time(tree
, hf_srvloc_authblkv2_timestamp
, tvb
, offset
+4, 4, &ts
);
395 length
= tvb_get_ntohs(tvb
, offset
+ 8);
396 proto_tree_add_uint(tree
, hf_srvloc_authblkv2_slpspilen
, tvb
, offset
+ 8, 2, length
);
398 proto_tree_add_item(tree
, hf_srvloc_authblkv2_slpspi
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
400 /* add code in here to handle Structured Authentication Block */
405 dissect_attrauthblk_v2(tvbuff_t
*tvb _U_
, int offset
, proto_tree
*tree _U_
)
407 /* add code in here to handle attribute authentication */
412 add_v1_string(proto_tree
*tree
, int hf
, tvbuff_t
*tvb
, int offset
, int length
,
419 case CHARSET_ISO_10646_UCS_2
:
420 unicode_str
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, length
, ENC_BIG_ENDIAN
);
421 proto_tree_add_string(tree
, hf
, tvb
, offset
, length
,
426 /* XXX - need to support all the CHARSET_ values */
427 proto_tree_add_item(tree
, hf
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
433 * XXX - is this trying to guess the byte order?
435 * http://www.iana.org/assignments/character-sets
437 * says of ISO-10646-UCS-2, which has the code 1000 (this routine is used
438 * with CHARSET_ISO_10646_UCS_2, which is #defined to be 1000):
440 * this needs to specify network byte order: the standard
441 * does not specify (it is a 16-bit integer space)
443 * Does that mean that in SRVLOC, ISO-10646-UCS-2 is always big-endian?
444 * If so, can we just use "tvb_get_unicode_string()" and be
447 * XXX - this is also used with CHARSET_UTF_8. Is that a cut-and-pasteo?
450 unicode_to_bytes(tvbuff_t
*tvb
, int offset
, int length
, gboolean endianness
)
452 const guint8
*ascii_text
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, length
);
454 guint8 c_char
, c_char1
;
457 /* XXX - Is this the correct behavior? */
462 byte_array
= (guint8
*)wmem_alloc(wmem_packet_scope(), length
*2 + 1);
463 for (i
= length
; i
> 0; i
--) {
464 c_char
= ascii_text
[i
];
467 c_char1
= ascii_text
[i
];
470 c_char1
= ascii_text
[i
];
472 byte_array
[j
] = c_char1
;
474 byte_array
[j
] = c_char
;
481 byte_array
= (guint8
*)wmem_alloc(wmem_packet_scope(), length
+ 1);
482 for (i
= 0; i
< length
; i
++) {
483 c_char
= ascii_text
[i
];
485 byte_array
[j
] = c_char
;
496 * Format of x-x-x-xxxxxxxx. Each of these entries represents the service binding to UDP, TCP, or IPX.
497 * The first digit is the protocol family: 2 for TCP/UPD, 6 for IPX.
498 * The second digit is the socket type: 1 for socket stream (TCP), 2 for datagram (UDP and IPX).
499 * The third is the protocol: 6 for TCP, 17 for UDP, and 1000 for IPX.
500 * Last is the IP address, in hex, of the interface that is registered (or, in the case of IPX, an IPX network number).
502 * OpenSLP supports multiple attribute replies so we need to parse the attribute name and then decode accourdingly.
503 * We currently only parse the (non-utf8) attributes:
508 attr_list(proto_tree
*tree
, int hf
, tvbuff_t
*tvb
, int offset
, int length
,
511 const char *attr_type
;
512 int i
, svc
, ss
, type_len
, foffset
=offset
;
514 const guint8
*byte_value
;
516 proto_tree
*srvloc_tree
;
519 static const value_string srvloc_svc
[] = {
525 static const value_string srvloc_ss
[] = {
531 static const value_string srvloc_prot
[] = {
540 case CHARSET_ISO_10646_UCS_2
:
541 while (offset
+2<length
) {
543 /* If the length passed is longer then the actual payload then this must be an incomplete packet. */
544 if (tvb_length_remaining(tvb
, 4)<length
) {
545 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.");
546 proto_tree_add_text(tree
, tvb
, offset
, -1, "Note: Protocol dissection is aborted due to packet overflow. See overflow flag.");
549 /* Parse the attribute name */
550 tmp
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, length
-offset
, ENC_BIG_ENDIAN
);
551 type_len
= (int)strcspn(tmp
, "=");
552 attr_type
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, type_len
*2, ENC_BIG_ENDIAN
);
553 proto_tree_add_string(tree
, hf
, tvb
, offset
, type_len
*2, attr_type
);
554 offset
+= (type_len
*2)+2;
555 if (strcmp(attr_type
, "svcname-ws")==0) {
556 /* This is the attribute svcname */
557 tmp
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, length
-offset
, ENC_BIG_ENDIAN
);
558 type_len
= (int)strcspn(tmp
, ")");
559 add_v1_string(tree
, hf_srvloc_srvrply_svcname
, tvb
, offset
, type_len
*2, encoding
);
560 offset
+= (type_len
*2)+4;
562 } else if (strcmp(attr_type
, "svcaddr-ws")==0) {
563 /* This is the attribute svcaddr */
565 for (foffset
= offset
; foffset
<length
; foffset
+= 2) {
567 ti
= proto_tree_add_text(tree
, tvb
, foffset
, -1, "Item %d", i
);
568 srvloc_tree
= proto_item_add_subtree(ti
, ett_srvloc_attr
);
570 svc
= tvb_get_guint8(tvb
, foffset
+1);
571 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+1, 1,
572 "Service Type: %s", val_to_str_const(svc
, srvloc_svc
, "Unknown"));
573 ss
= tvb_get_guint8(tvb
, foffset
+5);
574 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+5, 1,
575 "Communication Type: %s", val_to_str_const(ss
, srvloc_ss
, "Unknown"));
578 if (tvb_get_guint8(tvb
, foffset
)==54) { /* TCP */
579 prot
= tvb_get_guint8(tvb
, foffset
);
580 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 1,
581 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
586 byte_value
= unicode_to_bytes(tvb
, foffset
, 4, FALSE
); /* UDP */
587 prot
= (guint32
)strtoul(byte_value
, NULL
, 10);
588 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 4,
589 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
595 byte_value
= unicode_to_bytes(tvb
, foffset
, 8, FALSE
); /* IPX */
596 prot
= (guint32
)strtoul(byte_value
, NULL
, 10);
597 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 8,
598 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
602 byte_value
= unicode_to_bytes(tvb
, foffset
, 16, TRUE
); /* IP Address */
603 sscanf(byte_value
,"%x",&prot
);
604 proto_tree_add_ipv4(srvloc_tree
, hf_srvloc_add_ref_ip
, tvb
, foffset
+2, 16, prot
);
605 byte_value
= unicode_to_bytes(tvb
, foffset
+18, 8, FALSE
); /* Port */
606 sscanf(byte_value
,"%x",&prot
);
607 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+18, 8, "Port: %d", prot
);
611 byte_value
= unicode_to_bytes(tvb
, foffset
+2, 16, FALSE
); /* IPX Network Address */
612 sscanf(byte_value
,"%x",&prot
);
613 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+2, 16, "Network: %s", byte_value
);
614 byte_value
= unicode_to_bytes(tvb
, foffset
+18, 24, FALSE
); /* IPX Node Address */
615 sscanf(byte_value
,"%x",&prot
);
616 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+18, 24, "Node: %s", byte_value
);
617 byte_value
= unicode_to_bytes(tvb
, foffset
+42, 8, FALSE
); /* Socket */
618 sscanf(byte_value
,"%x",&prot
);
619 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+42, 8, "Socket: %s", byte_value
);
627 /* If there are no more supported attributes available then abort dissection */
628 if (strcmp(attr_type
, "svcaddr-ws")!=0 && strcmp(attr_type
, "svcname-ws")!=0 && strcmp(attr_type
, "")!=0) {
635 type_len
= (int)strcspn(tvb_get_string(wmem_packet_scope(), tvb
, offset
, length
), "=");
636 attr_type
= unicode_to_bytes(tvb
, offset
+1, type_len
-1, FALSE
);
637 proto_tree_add_string(tree
, hf
, tvb
, offset
+1, type_len
-1, attr_type
);
639 for (foffset
= offset
+ (type_len
); foffset
<length
; foffset
++) {
641 ti
= proto_tree_add_text(tree
, tvb
, foffset
, -1, "Item %d", i
);
642 srvloc_tree
= proto_item_add_subtree(ti
, ett_srvloc_attr
);
644 svc
= tvb_get_guint8(tvb
, foffset
+1);
645 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+1, 1,
646 "Service Type: %s", val_to_str_const(svc
, srvloc_svc
, "Unknown"));
647 ss
= tvb_get_guint8(tvb
, foffset
+3);
648 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+3, 1,
649 "Communication Type: %s", val_to_str_const(ss
, srvloc_ss
, "Unknown"));
652 if (tvb_get_guint8(tvb
, foffset
)==54) { /* TCP */
653 prot
= tvb_get_guint8(tvb
, foffset
);
654 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 1,
655 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
661 byte_value
= unicode_to_bytes(tvb
, foffset
, 2, FALSE
); /* UDP */
662 prot
= (guint32
)strtoul(byte_value
, NULL
, 10);
663 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 2,
664 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
670 byte_value
= unicode_to_bytes(tvb
, foffset
, 4, FALSE
); /* IPX */
671 prot
= (guint32
)strtoul(byte_value
, NULL
, 10);
672 proto_tree_add_text(srvloc_tree
, tvb
, foffset
, 4,
673 "Protocol: %s", val_to_str_const(prot
, srvloc_prot
, "Unknown"));
677 byte_value
= unicode_to_bytes(tvb
, foffset
, 8, TRUE
); /* IP Address */
678 sscanf(byte_value
,"%x",&prot
);
679 proto_tree_add_ipv4(srvloc_tree
, hf_srvloc_add_ref_ip
, tvb
, foffset
+1, 8, prot
);
680 byte_value
= unicode_to_bytes(tvb
, foffset
+9, 4, FALSE
); /* Port */
681 sscanf(byte_value
,"%x",&prot
);
682 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+9, 4, "Port: %d", prot
);
686 byte_value
= unicode_to_bytes(tvb
, foffset
+1, 8, FALSE
); /* IPX Network Address */
687 sscanf(byte_value
,"%x",&prot
);
688 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+1, 8, "Network: %s", byte_value
);
689 byte_value
= unicode_to_bytes(tvb
, foffset
+9, 12, FALSE
); /* IPX Node Address */
690 sscanf(byte_value
,"%x",&prot
);
691 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+9, 12, "Node: %s", byte_value
);
692 byte_value
= unicode_to_bytes(tvb
, foffset
+21, 4, FALSE
); /* Socket */
693 sscanf(byte_value
,"%x",&prot
);
694 proto_tree_add_text(srvloc_tree
, tvb
, foffset
+21, 4, "Socket: %s", byte_value
);
703 /* XXX - need to handle specific encodings */
704 proto_tree_add_item(tree
, hf
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
710 attr_list2(proto_tree
*tree
, int hf
, tvbuff_t
*tvb
, int offset
, int length
, guint16 encoding _U_
)
717 proto_tree
*attr_tree
;
719 /* if we were to decode:
720 * For slp, these 9 characters: (),\!<=>~ and 0x00-1F, 0x7f are reserved and must be escaped in the form \HH
723 /* create a sub tree for attributes */
724 /* XXX - is this always ASCII, or what? */
725 ti
= proto_tree_add_item(tree
, hf
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
726 attr_tree
= proto_item_add_subtree(ti
, ett_srvloc_attr
);
728 /* this will ensure there is a terminating null */
729 start
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, length
);
736 cnt
++; /* Attribute count */
738 proto_tree_add_text(attr_tree
, tvb
, offset
, x
, "Item %d: %s", cnt
, start
);
741 /* reset string length */
745 /* increment and get next */
750 /* display anything remaining */
753 proto_tree_add_text(attr_tree
, tvb
, offset
, x
, "Item %d: %s", cnt
, start
);
758 dissect_url_entry_v1(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
759 guint16 encoding
, guint16 flags
)
763 proto_tree_add_item(tree
, hf_srvloc_url_lifetime
, tvb
, offset
, 2,
766 url_len
= tvb_get_ntohs(tvb
, offset
);
767 proto_tree_add_uint(tree
, hf_srvloc_url_urllen
, tvb
, offset
, 2,
770 add_v1_string(tree
, hf_srvloc_url_url
, tvb
, offset
, url_len
, encoding
);
772 if ( (flags
& FLAG_U
) == FLAG_U
)
773 offset
= dissect_authblk(tvb
, offset
, tree
);
778 dissect_url_entry_v2(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
784 reserved
= tvb_get_guint8(tvb
, offset
);
785 proto_tree_add_uint(tree
, hf_srvloc_url_reserved
, tvb
, offset
, 1,
788 proto_tree_add_item(tree
, hf_srvloc_url_lifetime
, tvb
, offset
, 2,
791 url_len
= tvb_get_ntohs(tvb
, offset
);
792 proto_tree_add_uint(tree
, hf_srvloc_url_urllen
, tvb
, offset
, 2,
795 proto_tree_add_item(tree
, hf_srvloc_url_url
, tvb
, offset
, url_len
, ENC_ASCII
|ENC_NA
);
797 num_auths
= tvb_get_guint8(tvb
, offset
);
798 proto_tree_add_uint(tree
, hf_srvloc_url_numauths
, tvb
, offset
, 1,
801 while (num_auths
> 0) {
802 offset
= dissect_authblk_v2(tvb
, offset
, tree
);
808 /* Packet dissection routine called by tcp & udp when port 427 detected */
811 dissect_srvloc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
815 proto_tree
*srvloc_tree
, *srvloc_flags
;
819 guint32 length
; /* three bytes needed for v2 */
820 guint16 flags
; /* two byes needed for v2 */
822 guint32 next_ext_off
; /* three bytes, v2 only */
823 guint16 lang_tag_len
;
825 proto_item
*expert_item
;
826 guint16 expert_status
;
828 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SRVLOC");
830 col_clear(pinfo
->cinfo
, COL_INFO
);
832 version
= tvb_get_guint8(tvb
, offset
);
833 function
= tvb_get_guint8(tvb
, offset
+ 1);
835 col_add_str(pinfo
->cinfo
, COL_INFO
,
836 val_to_str(function
, srvloc_functions
, "Unknown Function (%u)"));
838 ti
= proto_tree_add_item(tree
, proto_srvloc
, tvb
, offset
, -1, ENC_NA
);
839 srvloc_tree
= proto_item_add_subtree(ti
, ett_srvloc
);
841 proto_tree_add_uint(srvloc_tree
, hf_srvloc_version
, tvb
, offset
, 1,
843 proto_tree_add_uint(srvloc_tree
, hf_srvloc_function
, tvb
, offset
+ 1, 1,
846 length
= tvb_get_ntohs(tvb
, offset
+ 2);
847 proto_tree_add_uint(srvloc_tree
, hf_srvloc_pktlen
, tvb
, offset
+ 2, 2,
849 flags
= tvb_get_guint8(tvb
, offset
+ 4);
850 tf
= proto_tree_add_uint(srvloc_tree
, hf_srvloc_flags_v1
, tvb
, offset
+ 4, 1,
852 srvloc_flags
= proto_item_add_subtree(tf
, ett_srvloc_flags
);
853 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v1_overflow
,
854 tvb
, offset
+4, 1, flags
);
855 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v1_monolingual
,
856 tvb
, offset
+4, 1, flags
);
857 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v1_url_auth
,
858 tvb
, offset
+4, 1, flags
);
859 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v1_attribute_auth
,
860 tvb
, offset
+4, 1, flags
);
861 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v1_fresh
,
862 tvb
, offset
+4, 1, flags
);
863 proto_tree_add_text(srvloc_tree
, tvb
, offset
+ 5, 1, "Dialect: %u",
864 tvb_get_guint8(tvb
, offset
+ 5));
865 proto_tree_add_text(srvloc_tree
, tvb
, offset
+ 6, 2, "Language: %s",
866 tvb_format_text(tvb
, offset
+ 6, 2));
867 encoding
= tvb_get_ntohs(tvb
, offset
+ 8);
868 proto_tree_add_text(srvloc_tree
, tvb
, offset
+ 8, 2, "Encoding: %u (%s)",
870 val_to_str_const(encoding
, charsets
, "Unknown"));
871 proto_tree_add_text(srvloc_tree
, tvb
, offset
+ 10, 2, "Transaction ID: %u",
872 tvb_get_ntohs(tvb
, offset
+ 10));
873 /* added echo of XID to info colomn by Greg Morris 0ct 14, 2005 */
874 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", V1 Transaction ID - %u", tvb_get_ntohs(tvb
, offset
+ 10));
881 length
= tvb_get_ntohs(tvb
, offset
);
882 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_prlistlen
, tvb
, offset
, 2, length
);
884 add_v1_string(srvloc_tree
, hf_srvloc_srvreq_prlist
, tvb
, offset
, length
, encoding
);
886 length
= tvb_get_ntohs(tvb
, offset
);
887 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_predicatelen
, tvb
, offset
, 2, length
);
889 add_v1_string(srvloc_tree
, hf_srvloc_srvreq_predicate
, tvb
, offset
, length
, encoding
);
894 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
895 expert_status
= tvb_get_ntohs(tvb
, offset
);
896 if (expert_status
!=0) {
897 expert_add_info_format(pinfo
, expert_item
, &ei_srvloc_error
, "Error: %s", val_to_str(expert_status
, srvloc_errs
, "Unknown SRVLOC Error (0x%02x)"));
900 count
= tvb_get_ntohs(tvb
, offset
);
901 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvrply_urlcount
, tvb
, offset
, 2, count
);
904 offset
= dissect_url_entry_v1(tvb
, offset
, srvloc_tree
,
911 offset
= dissect_url_entry_v1(tvb
, offset
, srvloc_tree
, encoding
,
913 length
= tvb_get_ntohs(tvb
, offset
);
914 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreg_attrlistlen
, tvb
, offset
, 2, length
);
916 add_v1_string(srvloc_tree
, hf_srvloc_srvreg_attrlist
, tvb
, offset
, length
, encoding
);
918 if ( (flags
& FLAG_A
) == FLAG_A
)
919 offset
= dissect_authblk(tvb
, offset
, srvloc_tree
);
923 length
= tvb_get_ntohs(tvb
, offset
);
924 proto_tree_add_uint(tree
, hf_srvloc_url_urllen
, tvb
, offset
, 2, length
);
926 add_v1_string(tree
, hf_srvloc_url_url
, tvb
, offset
, length
, encoding
);
928 if ( (flags
& FLAG_U
) == FLAG_U
)
929 offset
= dissect_authblk(tvb
, offset
, srvloc_tree
);
930 length
= tvb_get_ntohs(tvb
, offset
);
931 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvdereg_taglistlen
, tvb
, offset
, 2, length
);
933 add_v1_string(srvloc_tree
, hf_srvloc_srvdereg_taglist
, tvb
, offset
, length
, encoding
);
936 * XXX - this was there before, but RFC 2165 doesn't speak
937 * of there being an attribute authentication block in
938 * a Service Deregister message. Is that a post-RFC-2165
941 if ( (flags
& FLAG_A
) == FLAG_A
)
942 offset
= dissect_authblk(tvb
, offset
, srvloc_tree
);
946 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
947 expert_status
= tvb_get_ntohs(tvb
, offset
);
948 if (expert_status
!=0) {
949 expert_add_info_format(pinfo
, expert_item
, &ei_srvloc_error
, "Error: %s", val_to_str(expert_status
, srvloc_errs
, "Unknown SRVLOC Error (0x%02x)"));
955 length
= tvb_get_ntohs(tvb
, offset
);
956 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_prlistlen
, tvb
, offset
, 2, length
);
958 add_v1_string(srvloc_tree
, hf_srvloc_attrreq_prlist
, tvb
, offset
, length
, encoding
);
960 length
= tvb_get_ntohs(tvb
, offset
);
961 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_urllen
, tvb
, offset
, 2, length
);
963 add_v1_string(srvloc_tree
, hf_srvloc_attrreq_url
, tvb
, offset
, length
, encoding
);
965 length
= tvb_get_ntohs(tvb
, offset
);
966 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_scopelistlen
, tvb
, offset
, 2, length
);
968 add_v1_string(srvloc_tree
, hf_srvloc_attrreq_scopelist
, tvb
, offset
, length
, encoding
);
970 length
= tvb_get_ntohs(tvb
, offset
);
971 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_attrlistlen
, tvb
, offset
, 2, length
);
973 add_v1_string(srvloc_tree
, hf_srvloc_attrreq_attrlist
, tvb
, offset
, length
, encoding
);
978 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
979 expert_status
= tvb_get_ntohs(tvb
, offset
);
980 if (expert_status
!=0) {
981 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)"));
984 length
= tvb_get_ntohs(tvb
, offset
);
985 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrrply_attrlistlen
, tvb
, offset
, 2, length
);
988 attr_list(srvloc_tree
, hf_srvloc_attrrply_attrlist
, tvb
, offset
, length
, encoding
);
990 if ( (flags
& FLAG_A
) == FLAG_A
)
991 offset
= dissect_authblk(tvb
, offset
, srvloc_tree
);
996 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
997 expert_status
= tvb_get_ntohs(tvb
, offset
);
998 if (expert_status
!=0) {
999 expert_add_info_format(pinfo
, expert_item
, &ei_srvloc_error
, "Error: %s", val_to_str(expert_status
, srvloc_errs
, "Unknown SRVLOC Error (0x%02x)"));
1002 length
= tvb_get_ntohs(tvb
, offset
);
1003 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_urllen
, tvb
, offset
, 2, length
);
1005 add_v1_string(srvloc_tree
, hf_srvloc_daadvert_url
, tvb
, offset
, length
, encoding
);
1007 length
= tvb_get_ntohs(tvb
, offset
);
1008 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_scopelistlen
, tvb
, offset
, 2, length
);
1010 add_v1_string(srvloc_tree
, hf_srvloc_daadvert_scopelist
, tvb
, offset
, length
, encoding
);
1015 length
= tvb_get_ntohs(tvb
, offset
);
1016 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_prlistlen
, tvb
, offset
, 2, length
);
1018 add_v1_string(srvloc_tree
, hf_srvloc_srvtypereq_prlist
, tvb
, offset
, length
, encoding
);
1020 length
= tvb_get_ntohs(tvb
, offset
);
1021 /* Updated by Greg Morris on 1-30-04 */
1022 if (0xFFFF == length
) {
1023 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlistlenall
, tvb
, offset
, 2, length
);
1028 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlistlen
, tvb
, offset
, 2, length
);
1030 add_v1_string(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlist
, tvb
, offset
, length
, encoding
);
1033 length
= tvb_get_ntohs(tvb
, offset
);
1034 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_scopelistlen
, tvb
, offset
, 2, length
);
1036 add_v1_string(srvloc_tree
, hf_srvloc_srvtypereq_scopelist
, tvb
, offset
, length
, encoding
);
1041 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1042 expert_status
= tvb_get_ntohs(tvb
, offset
);
1043 if (expert_status
!=0) {
1044 expert_add_info_format(pinfo
, expert_item
, &ei_srvloc_error
, "Error: %s", val_to_str(expert_status
, srvloc_errs
, "Unknown SRVLOC Error (0x%02x)"));
1047 count
= tvb_get_ntohs(tvb
, offset
);
1048 proto_tree_add_text(srvloc_tree
, tvb
, offset
, 2, "Service Type Count: %u",
1052 length
= tvb_get_ntohs(tvb
, offset
);
1053 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtyperply_srvtypelen
, tvb
, offset
, 2, length
);
1055 add_v1_string(srvloc_tree
, hf_srvloc_srvtyperply_srvtype
, tvb
, offset
, length
, encoding
);
1062 proto_tree_add_expert_format(srvloc_tree
, pinfo
, &ei_srvloc_function_unknown
,
1063 tvb
, offset
, -1, "Unknown Function Type: %d", function
);
1066 else { /* Version 2 */
1067 length
= tvb_get_ntoh24(tvb
, offset
+ 2);
1068 proto_tree_add_uint(srvloc_tree
, hf_srvloc_pktlen
, tvb
, offset
+ 2, 3,
1070 flags
= tvb_get_ntohs(tvb
, offset
+ 5);
1071 tf
= proto_tree_add_uint(srvloc_tree
, hf_srvloc_flags_v2
, tvb
, offset
+ 5, 2,
1073 srvloc_flags
= proto_item_add_subtree(tf
, ett_srvloc_flags
);
1074 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v2_overflow
,
1075 tvb
, offset
+5, 1, flags
);
1076 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v2_fresh
,
1077 tvb
, offset
+5, 1, flags
);
1078 proto_tree_add_boolean(srvloc_flags
, hf_srvloc_flags_v2_reqmulti
,
1079 tvb
, offset
+5, 1, flags
);
1081 next_ext_off
= tvb_get_ntoh24(tvb
, offset
+ 7);
1082 proto_tree_add_uint(srvloc_tree
, hf_srvloc_nextextoff
, tvb
, offset
+ 7, 3,
1084 proto_tree_add_uint(srvloc_tree
, hf_srvloc_xid
, tvb
, offset
+ 10, 2,
1085 tvb_get_ntohs(tvb
, offset
+ 10));
1086 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", V2 XID - %u", tvb_get_ntohs(tvb
, offset
+ 10));
1087 lang_tag_len
= tvb_get_ntohs(tvb
, offset
+ 12);
1088 proto_tree_add_uint(srvloc_tree
, hf_srvloc_langtaglen
, tvb
, offset
+ 12, 2, lang_tag_len
);
1089 proto_tree_add_item(srvloc_tree
, hf_srvloc_langtag
, tvb
, offset
+ 14, lang_tag_len
, ENC_ASCII
|ENC_NA
);
1090 offset
+= 14+lang_tag_len
;
1094 case SRVREQ
: /* RFC2608 8.1 */
1095 length
= tvb_get_ntohs(tvb
, offset
);
1096 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_prlistlen
, tvb
, offset
, 2, length
);
1099 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreq_prlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1102 length
= tvb_get_ntohs(tvb
, offset
);
1103 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_srvtypelen
, tvb
, offset
, 2, length
);
1106 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreq_srvtypelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1109 length
= tvb_get_ntohs(tvb
, offset
);
1110 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_scopelistlen
, tvb
, offset
, 2, length
);
1113 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreq_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1116 length
= tvb_get_ntohs(tvb
, offset
);
1117 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_predicatelen
, tvb
, offset
, 2, length
);
1120 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreq_predicate
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1123 length
= tvb_get_ntohs(tvb
, offset
);
1124 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreq_slpspilen
, tvb
, offset
, 2, length
);
1127 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreq_slpspi
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1132 case SRVRPLY
: /* RFC2608 8.2 */
1133 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1134 expert_status
= tvb_get_ntohs(tvb
, offset
);
1135 if (expert_status
!=0) {
1136 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)"));
1139 count
= tvb_get_ntohs(tvb
, offset
);
1140 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvrply_urlcount
, tvb
, offset
, 2, count
);
1143 offset
= dissect_url_entry_v2(tvb
, offset
, srvloc_tree
);
1148 case SRVREG
: /* RFC2608 8.3 */
1149 offset
= dissect_url_entry_v2(tvb
, offset
, srvloc_tree
);
1150 length
= tvb_get_ntohs(tvb
, offset
);
1151 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreg_srvtypelen
, tvb
, offset
, 2, length
);
1154 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreg_srvtype
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1157 length
= tvb_get_ntohs(tvb
, offset
);
1158 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreg_scopelistlen
, tvb
, offset
, 2, length
);
1161 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvreg_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1164 length
= tvb_get_ntohs(tvb
, offset
);
1165 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreg_attrlistlen
, tvb
, offset
, 2, length
);
1168 attr_list2(srvloc_tree
, hf_srvloc_srvreg_attrlist
, tvb
, offset
, length
, CHARSET_UTF_8
);
1171 count
= tvb_get_guint8(tvb
, offset
);
1172 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvreg_attrauthcount
, tvb
, offset
, 1, count
);
1175 offset
= dissect_attrauthblk_v2(tvb
, offset
, srvloc_tree
);
1180 case SRVDEREG
: /* RFC2608 10.6 */
1181 length
= tvb_get_ntohs(tvb
, offset
);
1182 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvdereg_scopelistlen
, tvb
, offset
, 2, length
);
1185 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvdereg_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1188 offset
= dissect_url_entry_v2(tvb
, offset
, srvloc_tree
);
1189 length
= tvb_get_ntohs(tvb
, offset
);
1190 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvdereg_taglistlen
, tvb
, offset
, 2, length
);
1193 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvdereg_taglist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1198 case SRVACK
: /* RFC2608 8.4 */
1199 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1200 expert_status
= tvb_get_ntohs(tvb
, offset
);
1201 if (expert_status
!=0) {
1202 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)"));
1207 case ATTRRQST
: /* RFC2608 10.3*/
1208 length
= tvb_get_ntohs(tvb
, offset
);
1209 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_prlistlen
, tvb
, offset
, 2, length
);
1212 proto_tree_add_item(srvloc_tree
, hf_srvloc_attrreq_prlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1215 length
= tvb_get_ntohs(tvb
, offset
);
1216 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_urllen
, tvb
, offset
, 2, length
);
1219 proto_tree_add_item(srvloc_tree
, hf_srvloc_attrreq_url
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1222 length
= tvb_get_ntohs(tvb
, offset
);
1223 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_scopelistlen
, tvb
, offset
, 2, length
);
1226 proto_tree_add_item(srvloc_tree
, hf_srvloc_attrreq_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1229 length
= tvb_get_ntohs(tvb
, offset
);
1230 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_taglistlen
, tvb
, offset
, 2, length
);
1233 proto_tree_add_item(srvloc_tree
, hf_srvloc_attrreq_taglist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1236 length
= tvb_get_ntohs(tvb
, offset
);
1237 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrreq_slpspilen
, tvb
, offset
, 2, length
);
1240 proto_tree_add_item(srvloc_tree
, hf_srvloc_attrreq_slpspi
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1245 case ATTRRPLY
: /* RFC2608 10.4 */
1246 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1247 expert_status
= tvb_get_ntohs(tvb
, offset
);
1248 if (expert_status
!=0) {
1249 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)"));
1252 length
= tvb_get_ntohs(tvb
, offset
);
1253 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrrply_attrlistlen
, tvb
, offset
, 2, length
);
1256 attr_list2(srvloc_tree
, hf_srvloc_attrrply_attrlist
, tvb
, offset
, length
, CHARSET_UTF_8
);
1259 count
= tvb_get_guint8(tvb
, offset
);
1260 proto_tree_add_uint(srvloc_tree
, hf_srvloc_attrrply_attrauthcount
, tvb
, offset
, 1, count
);
1263 offset
= dissect_attrauthblk_v2(tvb
, offset
, srvloc_tree
);
1268 case DAADVERT
: /* RCC 2608 8.5 */
1269 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1270 expert_status
= tvb_get_ntohs(tvb
, offset
);
1271 if (expert_status
!=0) {
1272 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)"));
1276 ts
.secs
= tvb_get_ntohl(tvb
, offset
);
1277 proto_tree_add_time(srvloc_tree
, hf_srvloc_daadvert_timestamp
, tvb
, offset
, 4,
1280 length
= tvb_get_ntohs(tvb
, offset
);
1281 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_urllen
, tvb
, offset
, 2, length
);
1284 proto_tree_add_item(srvloc_tree
, hf_srvloc_daadvert_url
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1287 length
= tvb_get_ntohs(tvb
, offset
);
1288 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_scopelistlen
, tvb
, offset
, 2, length
);
1291 proto_tree_add_item(srvloc_tree
, hf_srvloc_daadvert_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1294 length
= tvb_get_ntohs(tvb
, offset
);
1295 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_attrlistlen
, tvb
, offset
, 2, length
);
1298 proto_tree_add_item(srvloc_tree
, hf_srvloc_daadvert_attrlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1301 length
= tvb_get_ntohs(tvb
, offset
);
1302 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_slpspilen
, tvb
, offset
, 2, length
);
1305 proto_tree_add_item(srvloc_tree
, hf_srvloc_daadvert_slpspi
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1308 count
= tvb_get_guint8(tvb
, offset
);
1309 proto_tree_add_uint(srvloc_tree
, hf_srvloc_daadvert_authcount
, tvb
, offset
, 1, count
);
1312 offset
= dissect_authblk_v2(tvb
, offset
, srvloc_tree
);
1317 case SRVTYPERQST
: /* RFC2608 10.1 */
1318 length
= tvb_get_ntohs(tvb
, offset
);
1319 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_prlistlen
, tvb
, offset
, 2, length
);
1322 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvtypereq_prlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1325 length
= tvb_get_ntohs(tvb
, offset
);
1326 if (0xFFFF == length
) {
1327 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlistlenall
, tvb
, offset
, 2, length
);
1330 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlistlen
, tvb
, offset
, 2, length
);
1333 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvtypereq_nameauthlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1337 length
= tvb_get_ntohs(tvb
, offset
);
1338 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtypereq_scopelistlen
, tvb
, offset
, 2, length
);
1341 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvtypereq_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1346 case SRVTYPERPLY
: /* rfc2608 10.2 */
1347 expert_item
= proto_tree_add_item(srvloc_tree
, hf_srvloc_error_v2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1348 expert_status
= tvb_get_ntohs(tvb
, offset
);
1349 if (expert_status
!=0) {
1350 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)"));
1353 length
= tvb_get_ntohs(tvb
, offset
);
1354 proto_tree_add_uint(srvloc_tree
, hf_srvloc_srvtyperply_srvtypelistlen
, tvb
, offset
, 2, length
);
1357 proto_tree_add_item(srvloc_tree
, hf_srvloc_srvtyperply_srvtypelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1362 case SAADVERT
: /* rfc2608 10.2 */
1363 length
= tvb_get_ntohs(tvb
, offset
);
1364 proto_tree_add_uint(srvloc_tree
, hf_srvloc_saadvert_urllen
, tvb
, offset
, 2, length
);
1367 proto_tree_add_item(srvloc_tree
, hf_srvloc_saadvert_url
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1370 length
= tvb_get_ntohs(tvb
, offset
);
1371 proto_tree_add_uint(srvloc_tree
, hf_srvloc_saadvert_scopelistlen
, tvb
, offset
, 2, length
);
1374 proto_tree_add_item(srvloc_tree
, hf_srvloc_saadvert_scopelist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1377 length
= tvb_get_ntohs(tvb
, offset
);
1378 proto_tree_add_uint(srvloc_tree
, hf_srvloc_saadvert_attrlistlen
, tvb
, offset
, 2, length
);
1381 proto_tree_add_item(srvloc_tree
, hf_srvloc_saadvert_attrlist
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
1384 count
= tvb_get_guint8(tvb
, offset
);
1385 proto_tree_add_uint(srvloc_tree
, hf_srvloc_saadvert_authcount
, tvb
, offset
, 1, length
);
1388 offset
= dissect_authblk_v2(tvb
, offset
, srvloc_tree
);
1394 proto_tree_add_expert_format(srvloc_tree
, pinfo
, &ei_srvloc_function_unknown
,
1395 tvb
, offset
, -1, "Unknown Function Type: %d", function
);
1402 get_srvloc_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
1405 * Get the length of the SRVLOC packet.
1406 * It starts at offset+2, but it's 2 bytes in SLPv1 and 3 bytes
1409 if (tvb_get_guint8(tvb
, offset
) == 2)
1410 return tvb_get_ntoh24(tvb
, offset
+ 2);
1412 return tvb_get_ntohs(tvb
, offset
+ 2);
1416 dissect_srvloc_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1418 proto_tree
*srvloc_tree
= NULL
;
1421 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SRVLOC");
1423 col_clear(pinfo
->cinfo
, COL_INFO
);
1426 ti
= proto_tree_add_item(tree
, proto_srvloc
, tvb
, 0, -1, ENC_NA
);
1427 srvloc_tree
= proto_item_add_subtree(ti
, ett_srvloc
);
1429 dissect_srvloc(tvb
, pinfo
, srvloc_tree
, NULL
);
1430 return tvb_length(tvb
);
1434 dissect_srvloc_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1437 * XXX - in SLPv1, the fixed length need only be 4, as the length
1438 * is 2 bytes long; however, it must be 5 for SLPv2, as the length
1439 * is 3 bytes long, and there's probably no harm in asking for 5
1440 * bytes, as even SLPv1 packets start with a 12-byte header,
1441 * and if the packet has a length that's 4 or less, it's bogus,
1442 * and we can't handle a length < 4 anyway.
1444 tcp_dissect_pdus(tvb
, pinfo
, tree
, srvloc_desegment
, 5, get_srvloc_pdu_len
,
1445 dissect_srvloc_pdu
, data
);
1446 return tvb_length(tvb
);
1449 /* Register protocol with Wireshark. */
1452 proto_register_srvloc(void)
1454 static hf_register_info hf
[] = {
1455 /* Helper functions for the Version 1 Header*/
1457 {"Error Code", "srvloc.err",
1458 FT_UINT16
, BASE_DEC
, VALS(srvloc_errs
), 0x0,
1462 /* Helper function for the Version 2 Header */
1463 {&hf_srvloc_error_v2
,
1464 {"Error Code", "srvloc.errv2",
1465 FT_UINT16
, BASE_DEC
, VALS(srvloc_errs_v2
), 0x0,
1469 {"XID", "srvloc.xid",
1470 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
1471 "Transaction ID", HFILL
}
1473 {&hf_srvloc_langtag
,
1474 {"Lang Tag", "srvloc.langtag",
1475 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1478 {&hf_srvloc_langtaglen
,
1479 {"Lang Tag Len", "srvloc.langtaglen",
1480 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1483 {&hf_srvloc_nextextoff
,
1484 {"Next Extension Offset", "srvloc.nextextoff",
1485 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
1489 /* Helper functions for URL and URL Entry parsing - both versions */
1490 {&hf_srvloc_url_reserved
,
1491 {"Reserved", "srvloc.url.reserved",
1492 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1494 {&hf_srvloc_url_lifetime
,
1495 {"URL lifetime", "srvloc.url.lifetime",
1496 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1498 {&hf_srvloc_url_urllen
,
1499 {"URL Length", "srvloc.url.urllen",
1500 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1502 {&hf_srvloc_url_url
,
1503 {"URL", "srvloc.url.url",
1504 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
1506 {&hf_srvloc_url_numauths
,
1507 {"Num Auths", "srvloc.url.numauths",
1508 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1511 /* Helper functions for the common header fields */
1512 {&hf_srvloc_function
,
1513 {"Function", "srvloc.function",
1514 FT_UINT8
, BASE_DEC
, VALS(srvloc_functions
), 0x0,
1519 {"Packet Length", "srvloc.pktlen",
1520 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
1524 { &hf_srvloc_version
,
1525 { "Version", "srvloc.version",
1526 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1530 {&hf_srvloc_flags_v1
,
1531 {"Flags", "srvloc.flags_v1",
1532 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1536 { &hf_srvloc_flags_v1_overflow
,
1537 { "Overflow", "srvloc.flags_v1.overflow.", FT_BOOLEAN
, 8,
1538 TFS(&tfs_srvloc_flags_overflow
), FLAG_O
, "Can whole packet fit into a datagram?", HFILL
}},
1540 { &hf_srvloc_flags_v1_monolingual
,
1541 { "Monolingual", "srvloc.flags_v1.monolingual", FT_BOOLEAN
, 8,
1542 TFS(&tfs_srvloc_flags_v1_monolingual
), FLAG_M
, "Can whole packet fit into a datagram?", HFILL
}},
1544 { &hf_srvloc_flags_v1_url_auth
,
1545 { "URL Authentication", "srvloc.flags_v1.url_auth", FT_BOOLEAN
, 8,
1546 TFS(&tfs_srvloc_flags_v1_url_auth
), FLAG_U
, "Can whole packet fit into a datagram?", HFILL
}},
1548 { &hf_srvloc_flags_v1_attribute_auth
,
1549 { "Attribute Authentication", "srvloc.flags_v1.attribute_auth", FT_BOOLEAN
, 8,
1550 TFS(&tfs_srvloc_flags_v1_attribute_auth
), FLAG_A
, "Can whole packet fit into a datagram?", HFILL
}},
1552 { &hf_srvloc_flags_v1_fresh
,
1553 { "Fresh Registration", "srvloc.flags_v1.fresh", FT_BOOLEAN
, 8,
1554 TFS(&tfs_srvloc_flags_fresh
), FLAG_F
, "Is this a new registration?", HFILL
}},
1556 {&hf_srvloc_flags_v2
,
1557 {"Flags", "srvloc.flags_v2",
1558 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1562 { &hf_srvloc_flags_v2_overflow
,
1563 { "Overflow", "srvloc.flags_v2.overflow", FT_BOOLEAN
, 16,
1564 TFS(&tfs_srvloc_flags_overflow
), FLAG_O_V2
, "Can whole packet fit into a datagram?", HFILL
}},
1566 { &hf_srvloc_flags_v2_fresh
,
1567 { "Fresh Registration", "srvloc.flags_v2.fresh", FT_BOOLEAN
, 16,
1568 TFS(&tfs_srvloc_flags_fresh
), FLAG_F_V2
, "Is this a new registration?", HFILL
}},
1570 { &hf_srvloc_flags_v2_reqmulti
,
1571 { "Multicast requested", "srvloc.flags_v2.reqmulti", FT_BOOLEAN
, 16,
1572 TFS(&tfs_srvloc_flags_v2_reqmulti
), FLAG_R_V2
, "Do we want multicast?", HFILL
}},
1574 /* collection of helper functions for dissect_authblk_v2 */
1575 { &hf_srvloc_authblkv2_bsd
,
1576 { "BSD", "srvloc.authblkv2_bsd", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1577 "Block Structure Descriptor", HFILL
}
1579 { &hf_srvloc_authblkv2_len
,
1580 { "Length", "srvloc.authblkv2_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1581 "Length of Authentication Block", HFILL
}
1583 { &hf_srvloc_authblkv2_timestamp
,
1584 { "Timestamp", "srvloc.authblkv2.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
1585 NULL
, 0, "Timestamp on Authentication Block", HFILL
}
1587 { &hf_srvloc_authblkv2_slpspilen
,
1588 { "SLP SPI Length", "srvloc.authblkv2.slpspilen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1589 "Length of the SLP SPI", HFILL
}
1591 { &hf_srvloc_authblkv2_slpspi
,
1592 { "SLP SPI", "srvloc.authblkv2.slpspi", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1596 /* collection of helper functions for Service Request */
1597 { &hf_srvloc_srvreq_prlistlen
,
1598 { "Previous Response List Length", "srvloc.srvreq.prlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1599 "Length of Previous Response List", HFILL
}
1601 { &hf_srvloc_srvreq_prlist
,
1602 { "Previous Response List", "srvloc.srvreq.prlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1605 { &hf_srvloc_srvreq_srvtypelen
,
1606 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1607 "Length of Service Type List", HFILL
}
1609 { &hf_srvloc_srvreq_srvtypelist
,
1610 { "Service Type List", "srvloc.srvreq.srvtypelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1613 { &hf_srvloc_srvreq_scopelistlen
,
1614 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1615 "Length of the Scope List", HFILL
}
1617 { &hf_srvloc_srvreq_scopelist
,
1618 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1621 { &hf_srvloc_srvreq_predicatelen
,
1622 { "Predicate Length", "srvloc.srvreq.predicatelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1623 "Length of the Predicate", HFILL
}
1625 { &hf_srvloc_srvreq_predicate
,
1626 { "Predicate", "srvloc.srvreq.predicate", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1629 { &hf_srvloc_srvreq_slpspilen
,
1630 { "SLP SPI Length", "srvloc.srvreq.slpspilen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1631 "Length of the SLP SPI", HFILL
}
1633 { &hf_srvloc_srvreq_slpspi
,
1634 { "SLP SPI", "srvloc.srvreq.slpspi", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1638 /* Helper function for Service Request */
1639 { &hf_srvloc_srvrply_urlcount
,
1640 { "Number of URLs", "srvloc.srvreq.urlcount", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1644 /* Helper functions for Service Registration */
1645 { &hf_srvloc_srvreg_srvtypelen
,
1646 { "Service Type Length", "srvloc.srvreq.srvtypelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1649 { &hf_srvloc_srvreg_srvtype
,
1650 { "Service Type", "srvloc.srvreq.srvtype", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1653 { &hf_srvloc_srvreg_scopelistlen
,
1654 { "Scope List Length", "srvloc.srvreq.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1657 { &hf_srvloc_srvreg_scopelist
,
1658 { "Scope List", "srvloc.srvreq.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1661 { &hf_srvloc_srvreg_attrlistlen
,
1662 { "Attribute List Length", "srvloc.srvreq.attrlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1665 { &hf_srvloc_srvreg_attrlist
,
1666 { "Attribute List", "srvloc.srvreq.attrlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1669 { &hf_srvloc_srvreg_attrauthcount
,
1670 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1671 "Number of Attribute Authentication Blocks", HFILL
}
1674 /* Helper functions for Service Deregistration */
1675 { &hf_srvloc_srvdereg_scopelistlen
,
1676 { "Scope List Length", "srvloc.srvdereq.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1679 { &hf_srvloc_srvdereg_scopelist
,
1680 { "Scope List", "srvloc.srvdereq.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1683 { &hf_srvloc_srvdereg_taglistlen
,
1684 { "Tag List Length", "srvloc.srvdereq.taglistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1687 { &hf_srvloc_srvdereg_taglist
,
1688 { "Tag List", "srvloc.srvdereq.taglist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1693 /* collection of helper functions for Attribute Request */
1694 { &hf_srvloc_attrreq_prlistlen
,
1695 { "Previous Response List Length", "srvloc.attrreq.prlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1696 "Length of Previous Response List", HFILL
}
1698 { &hf_srvloc_attrreq_prlist
,
1699 { "Previous Response List", "srvloc.attrreq.prlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1702 { &hf_srvloc_attrreq_urllen
,
1703 { "URL Length", "srvloc.attrreq.urllen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1706 { &hf_srvloc_attrreq_url
,
1707 { "Service URL", "srvloc.attrreq.url", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1708 "URL of service", HFILL
}
1710 { &hf_srvloc_attrreq_scopelistlen
,
1711 { "Scope List Length", "srvloc.attrreq.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1712 "Length of the Scope List", HFILL
}
1714 { &hf_srvloc_attrreq_scopelist
,
1715 { "Scope List", "srvloc.attrreq.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1718 { &hf_srvloc_attrreq_attrlistlen
,
1719 { "Attribute List Length", "srvloc.attrreq.attrlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1722 { &hf_srvloc_attrreq_attrlist
,
1723 { "Attribute List", "srvloc.attrreq.attrlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1726 { &hf_srvloc_attrreq_taglistlen
,
1727 { "Tag List Length", "srvloc.attrreq.taglistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1730 { &hf_srvloc_attrreq_taglist
,
1731 { "Tag List", "srvloc.attrreq.taglist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1734 { &hf_srvloc_attrreq_slpspilen
,
1735 { "SLP SPI Length", "srvloc.attrreq.slpspilen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1736 "Length of the SLP SPI", HFILL
}
1738 { &hf_srvloc_attrreq_slpspi
,
1739 { "SLP SPI", "srvloc.attrreq.slpspi", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1743 /* collection of helper functions for Attribute Reply */
1744 { &hf_srvloc_attrrply_attrlistlen
,
1745 { "Attribute List Length", "srvloc.attrrply.attrlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1746 "Length of Attribute List", HFILL
}
1748 { &hf_srvloc_attrrply_attrlist
,
1749 { "Attribute List", "srvloc.attrrply.attrlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1752 { &hf_srvloc_attrrply_attrauthcount
,
1753 { "Attr Auths", "srvloc.srvreq.attrauthcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1754 "Number of Attribute Authentication Blocks", HFILL
}
1757 /* collection of helper functions for DA Advertisement */
1758 { &hf_srvloc_daadvert_timestamp
,
1759 { "DAADVERT Timestamp", "srvloc.daadvert.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
1760 NULL
, 0, "Timestamp on DA Advert", HFILL
}
1762 { &hf_srvloc_daadvert_urllen
,
1763 { "URL Length", "srvloc.daadvert.urllen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1766 { &hf_srvloc_daadvert_url
,
1767 { "URL", "srvloc.daadvert.url", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1770 { &hf_srvloc_daadvert_scopelistlen
,
1771 { "Scope List Length", "srvloc.daadvert.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1772 "Length of the Scope List", HFILL
}
1774 { &hf_srvloc_daadvert_scopelist
,
1775 { "Scope List", "srvloc.daadvert.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1778 { &hf_srvloc_daadvert_attrlistlen
,
1779 { "Attribute List Length", "srvloc.daadvert.attrlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1782 { &hf_srvloc_daadvert_attrlist
,
1783 { "Attribute List", "srvloc.daadvert.attrlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1786 { &hf_srvloc_daadvert_slpspilen
,
1787 { "SLP SPI Length", "srvloc.daadvert.slpspilen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1788 "Length of the SLP SPI", HFILL
}
1790 { &hf_srvloc_daadvert_slpspi
,
1791 { "SLP SPI", "srvloc.daadvert.slpspi", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1794 { &hf_srvloc_daadvert_authcount
,
1795 { "Auths", "srvloc.daadvert.authcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1796 "Number of Authentication Blocks", HFILL
}
1799 /* collection of helper functions for Service Type Request */
1800 { &hf_srvloc_srvtypereq_prlistlen
,
1801 { "Previous Response List Length", "srvloc.srvtypereq.prlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1802 "Length of Previous Response List", HFILL
}
1804 { &hf_srvloc_srvtypereq_prlist
,
1805 { "Previous Response List", "srvloc.srvtypereq.prlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1808 { &hf_srvloc_srvtypereq_nameauthlistlen
,
1809 { "Naming Authority List Length", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1810 "Length of the Naming Authority List", HFILL
}
1812 { &hf_srvloc_srvtypereq_nameauthlistlenall
,
1813 { "Naming Authority List Length (All Naming Authorities)", "srvloc.srvtypereq.nameauthlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1814 "Length of the Naming Authority List", HFILL
}
1816 { &hf_srvloc_srvtypereq_nameauthlist
,
1817 { "Naming Authority List", "srvloc.srvtypereq.nameauthlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1820 { &hf_srvloc_srvtypereq_scopelistlen
,
1821 { "Scope List Length", "srvloc.srvtypereq.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1822 "Length of the Scope List", HFILL
}
1824 { &hf_srvloc_srvtypereq_scopelist
,
1825 { "Scope List", "srvloc.srvtypereq.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1829 /* collection of helper functions for Service Type Replies */
1830 { &hf_srvloc_srvtyperply_srvtypelen
,
1831 { "Service Type Length", "srvloc.srvtypereq.srvtypelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1832 "Length of the Service Type", HFILL
}
1834 { &hf_srvloc_srvtyperply_srvtype
,
1835 { "Service Type", "srvloc.srvtyperply.srvtype", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1838 { &hf_srvloc_srvtyperply_srvtypelistlen
,
1839 { "Service Type List Length", "srvloc.srvtypereq.srvtypelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1840 "Length of the Service Type List", HFILL
}
1842 { &hf_srvloc_srvtyperply_srvtypelist
,
1843 { "Service Type List", "srvloc.srvtyperply.srvtypelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1847 /* collection of helper functions for SA Advertisement */
1848 { &hf_srvloc_saadvert_urllen
,
1849 { "URL Length", "srvloc.saadvert.urllen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1852 { &hf_srvloc_saadvert_url
,
1853 { "URL", "srvloc.saadvert.url", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1856 { &hf_srvloc_saadvert_scopelistlen
,
1857 { "Scope List Length", "srvloc.saadvert.scopelistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1858 "Length of the Scope List", HFILL
}
1860 { &hf_srvloc_saadvert_scopelist
,
1861 { "Scope List", "srvloc.saadvert.scopelist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1864 { &hf_srvloc_saadvert_attrlistlen
,
1865 { "Attribute List Length", "srvloc.saadvert.attrlistlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1868 { &hf_srvloc_saadvert_attrlist
,
1869 { "Attribute List", "srvloc.saadvert.attrlist", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1872 { &hf_srvloc_saadvert_authcount
,
1873 { "Auths", "srvloc.saadvert.authcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1874 "Number of Authentication Blocks", HFILL
}
1876 { &hf_srvloc_add_ref_ip
,
1877 { "IP Address", "srvloc.list.ipaddr", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1878 "IP Address of SLP server", HFILL
}
1880 { &hf_srvloc_srvrply_svcname
,
1881 { "Service Name Value", "srvloc.srvrply.svcname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1886 static gint
*ett
[] = {
1891 static ei_register_info ei
[] = {
1892 { &ei_srvloc_error
, { "srvloc.err.expert", PI_RESPONSE_CODE
, PI_ERROR
, "Error", EXPFILL
}},
1893 { &ei_srvloc_error_v2
, { "srvloc.errv2.expert", PI_RESPONSE_CODE
, PI_ERROR
, "Error", EXPFILL
}},
1894 { &ei_srvloc_function_unknown
, { "srvloc.function.unknown", PI_RESPONSE_CODE
, PI_ERROR
, "Unknown Function Type", EXPFILL
}},
1897 module_t
*srvloc_module
;
1898 expert_module_t
* expert_srvloc
;
1900 proto_srvloc
= proto_register_protocol("Service Location Protocol",
1901 "SRVLOC", "srvloc");
1902 proto_register_field_array(proto_srvloc
, hf
, array_length(hf
));
1903 proto_register_subtree_array(ett
, array_length(ett
));
1904 expert_srvloc
= expert_register_protocol(proto_srvloc
);
1905 expert_register_field_array(expert_srvloc
, ei
, array_length(ei
));
1906 srvloc_module
= prefs_register_protocol(proto_srvloc
, NULL
);
1907 prefs_register_bool_preference(srvloc_module
, "desegment_tcp",
1908 "Reassemble SRVLOC messages spanning multiple TCP segments",
1909 "Whether the SRVLOC dissector should reassemble messages spanning multiple TCP segments. "
1910 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1915 proto_reg_handoff_srvloc(void)
1917 dissector_handle_t srvloc_handle
, srvloc_tcp_handle
;
1918 srvloc_handle
= new_create_dissector_handle(dissect_srvloc
, proto_srvloc
);
1919 dissector_add_uint("udp.port", UDP_PORT_SRVLOC
, srvloc_handle
);
1920 srvloc_tcp_handle
= new_create_dissector_handle(dissect_srvloc_tcp
,
1922 dissector_add_uint("tcp.port", TCP_PORT_SRVLOC
, srvloc_tcp_handle
);