2 * Routines for SRVLOC (Service Location Protocol) packet dissection
3 * Copyright 1999, James Coe <jammer@cin.net>
5 * NOTE: This is Alpha software not all features have been verified yet.
6 * In particular I have not had an opportunity to see how it
7 * responds to SRVLOC over TCP.
9 * $Id: packet-srvloc.c,v 1.1 1999/12/07 06:09:58 guy Exp $
11 * Ethereal - Network traffic analyzer
12 * By Gerald Combs <gerald@unicom.net>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #ifdef HAVE_SYS_TYPES_H
38 # include <sys/types.h>
41 #ifdef HAVE_NETINET_IN_H
42 # include <netinet/in.h>
45 #ifdef NEED_SNPRINTF_H
51 # include "snprintf.h"
57 #include "packet-ipv6.h"
59 int proto_srvloc = -1;
60 int hf_srvloc_version = -1;
61 int hf_srvloc_function = -1;
62 int hf_srvloc_flags = -1;
63 int hf_srvloc_error = -1;
65 static gint ett_srvloc = -1;
67 /* Define function types */
78 #define SRVTYPERPLY 10
80 /* Create protocol header structure */
93 /* List to resolve function numbers to names */
95 static const value_string srvlocfunctionvals[] = {
96 { SRVREQ, "Service Request" },
97 { SRVRPLY, "Service Reply" },
98 { SRVREG, "Service Registration" },
99 { SRVDEREG, "Service Deregister" },
100 { SRVACK, "Service Acknowledge" },
101 { ATTRRQST, "Attribute Request" },
102 { ATTRRPLY, "Attribute Reply" },
103 { DAADVERT, "DA Advertisement" },
104 { SRVTYPERQST, "Service Type Request" },
105 { SRVTYPERPLY, "Service Type Reply" },
108 /* List to resolve flag values to names */
111 /* Define Error Codes */
114 #define LANG_NOT_SPTD 1
115 #define PROT_PARSE_ERR 2
117 #define SCOPE_NOT_SPTD 4
118 #define CHRSET_NOT_UND 5
119 #define AUTH_ABSENT 6
120 #define AUTH_FAILED 7
122 /* List to resolve error codes to names */
124 static const value_string srvloc_errs[] = {
125 { SUCCESS, "No Error" },
126 { LANG_NOT_SPTD, "Language not supported" },
127 { PROT_PARSE_ERR, "Protocol parse error" },
128 { INVLD_REG, "Invalid registration" },
129 { SCOPE_NOT_SPTD, "Scope not supported" },
130 { CHRSET_NOT_UND, "Character set not understood" },
131 { AUTH_ABSENT, "Authentication absent" },
132 { AUTH_FAILED, "Authentication failed" },
135 /* Packet dissection routine called by tcp & udp when port 427 detected */
138 dissect_srvloc(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
141 proto_tree *srvloc_tree;
142 struct srvloc_hdr srvloc_hdr;
146 if (check_col(fd, COL_PROTOCOL))
147 col_add_str(fd, COL_PROTOCOL, "SRVLOC");
149 if (check_col(fd, COL_INFO))
150 col_add_str(fd, COL_INFO, "Service Location Protocol");
153 ti = proto_tree_add_item(tree, proto_srvloc, offset, END_OF_FRAME, NULL);
154 srvloc_tree = proto_item_add_subtree(ti, ett_srvloc);
156 if ( END_OF_FRAME > sizeof(srvloc_hdr) ) {
157 memcpy( &srvloc_hdr, &pd[offset], sizeof(srvloc_hdr) );
158 srvloc_hdr.length = ntohs(srvloc_hdr.length);
159 srvloc_hdr.encoding = ntohs(srvloc_hdr.encoding);
160 srvloc_hdr.xid = ntohs(srvloc_hdr.xid);
161 proto_tree_add_item(srvloc_tree, hf_srvloc_version, offset, 1, srvloc_hdr.version);
162 proto_tree_add_item(srvloc_tree, hf_srvloc_function, offset + 1, 1, srvloc_hdr.function);
163 proto_tree_add_text(srvloc_tree, offset + 2, 2, "Length: %d",srvloc_hdr.length);
164 proto_tree_add_item(srvloc_tree, hf_srvloc_flags, offset + 4, 1, srvloc_hdr.flags);
165 proto_tree_add_text(srvloc_tree, offset + 4, 0, "Overflow %d... .xxx", (srvloc_hdr.flags & 0x80) >> 7 );
166 proto_tree_add_text(srvloc_tree, offset + 4, 0, "Monolingual .%d.. .xxx", (srvloc_hdr.flags & 0x40) >> 6 );
167 proto_tree_add_text(srvloc_tree, offset + 4, 0, "URL Authentication Present ..%d. .xxx", (srvloc_hdr.flags & 0x20) >> 5 );
168 proto_tree_add_text(srvloc_tree, offset + 4, 0, "Attribute Authentication Present ...%d .xxx", (srvloc_hdr.flags & 0x10) >> 4 );
169 proto_tree_add_text(srvloc_tree, offset + 4, 0, "Fresh Service Entry .... %dxxx", (srvloc_hdr.flags & 0x08) >> 3 );
170 proto_tree_add_text(srvloc_tree, offset + 5, 1, "Dialect: %d",srvloc_hdr.dialect);
171 proto_tree_add_text(srvloc_tree, offset + 6, 2, "Language: %s", format_text(srvloc_hdr.language,2));
172 proto_tree_add_text(srvloc_tree, offset + 8, 2, "Encoding: %d", srvloc_hdr.encoding);
173 proto_tree_add_text(srvloc_tree, offset + 10, 2, "Transaction ID: %d", srvloc_hdr.xid);
176 proto_tree_add_text(srvloc_tree, offset, END_OF_FRAME, "Invalid Packet: Length less than header.");
179 if (( srvloc_hdr.length - 12 ) == END_OF_FRAME ) {
180 switch (srvloc_hdr.function) {
182 proto_tree_add_text(srvloc_tree, offset, 0, "Service Request");
183 length = pntohs(&pd[offset]);
184 proto_tree_add_text(srvloc_tree, offset, 2, "Previous Response List Length: %d", length);
186 proto_tree_add_text(srvloc_tree, offset, length, "Previous Response List: %s", format_text(&pd[offset], length));
188 length = pntohs(&pd[offset]);
189 proto_tree_add_text(srvloc_tree, offset, 2, "Predicate length: %d", length);
191 proto_tree_add_text(srvloc_tree, offset, length, "Predicate: %s", format_text(&pd[offset], length));
196 proto_tree_add_text(srvloc_tree, offset, 0, "Service Reply");
197 proto_tree_add_item(srvloc_tree, hf_srvloc_error, offset, 2, pd[offset]);;
199 proto_tree_add_text(srvloc_tree, offset, 2, "URL Count: %d", pntohs(&pd[offset]));
201 for (count = pntohs(&pd[offset]) + 1; count > 0; count--, offset++) {
202 proto_tree_add_text(srvloc_tree, offset, 2, "URL lifetime: %d", pntohs(&pd[offset]));
204 length = pntohs(&pd[offset]);
205 proto_tree_add_text(srvloc_tree, offset, 2, "URL length: %d", length);
207 proto_tree_add_text(srvloc_tree, offset, length, "Service URL: %s", format_text(&pd[offset], length));
213 proto_tree_add_text(srvloc_tree, offset, 0, "Service Registration");
214 proto_tree_add_text(srvloc_tree, offset, 2, "URL lifetime: %d", pntohs(&pd[offset]));
216 length = pntohs(&pd[offset]);
217 proto_tree_add_text(srvloc_tree, offset, 2, "URL length: %d", length);
219 proto_tree_add_text(srvloc_tree, offset, length, "Service URL: %s", format_text(&pd[offset], length));
221 length = pntohs(&pd[offset]);
222 proto_tree_add_text(srvloc_tree, offset, 2, "Attribute List length: %d", length);
224 proto_tree_add_text(srvloc_tree, offset, length, "Attribute List: %s", format_text(&pd[offset], length));
229 proto_tree_add_text(srvloc_tree, offset, 0, "Service Deregister");
230 length = pntohs(&pd[offset]);
231 proto_tree_add_text(srvloc_tree, offset, 2, "URL length: %d", length);
233 proto_tree_add_text(srvloc_tree, offset, length, "Service URL: %s", format_text(&pd[offset], length));
235 length = pntohs(&pd[offset]);
236 proto_tree_add_text(srvloc_tree, offset, 2, "Attribute List length: %d", length);
238 proto_tree_add_text(srvloc_tree, offset, length, "Attribute List: %s", format_text(&pd[offset], length));
243 proto_tree_add_text(srvloc_tree, offset, 0, "Service Acknowledge");
244 proto_tree_add_item(srvloc_tree, hf_srvloc_error, offset, 2, pd[offset]);;
249 proto_tree_add_text(srvloc_tree, offset, 0, "Attribute Request");
250 length = pntohs(&pd[offset]);
251 proto_tree_add_text(srvloc_tree, offset, 2, "Previous Response List Length: %d", length);
253 proto_tree_add_text(srvloc_tree, offset, length, "Previous Response List: %s", format_text(&pd[offset], length));
255 length = pntohs(&pd[offset]);
256 proto_tree_add_text(srvloc_tree, offset, 2, "URL length: %d", length);
258 proto_tree_add_text(srvloc_tree, offset, length, "Service URL: %s", format_text(&pd[offset], length));
260 length = pntohs(&pd[offset]);
261 proto_tree_add_text(srvloc_tree, offset, 2, "Scope List Length: %d", length);
263 proto_tree_add_text(srvloc_tree, offset, length, "Scope Response List: %s", format_text(&pd[offset], length));
265 length = pntohs(&pd[offset]);
266 proto_tree_add_text(srvloc_tree, offset, 2, "Attribute List length: %d", length);
268 proto_tree_add_text(srvloc_tree, offset, length, "Attribute List: %s", format_text(&pd[offset], length));
273 proto_tree_add_text(srvloc_tree, offset, 0, "Attribute Reply");
274 proto_tree_add_item(srvloc_tree, hf_srvloc_error, offset, 2, pd[offset]);;
276 length = pntohs(&pd[offset]);
277 proto_tree_add_text(srvloc_tree, offset, 2, "Attribute List length: %d", length);
279 proto_tree_add_text(srvloc_tree, offset, length, "Attribute List: %s", format_text(&pd[offset], length));
284 proto_tree_add_text(srvloc_tree, offset, 0, "DA Advertisement");
285 proto_tree_add_item(srvloc_tree, hf_srvloc_error, offset, 2, pd[offset]);;
287 length = pntohs(&pd[offset]);
288 proto_tree_add_text(srvloc_tree, offset, 2, "URL length: %d", length);
290 proto_tree_add_text(srvloc_tree, offset, length, "Service URL: %s", format_text(&pd[offset], length));
292 length = pntohs(&pd[offset]);
293 proto_tree_add_text(srvloc_tree, offset, 2, "Scope List Length: %d", length);
295 proto_tree_add_text(srvloc_tree, offset, length, "Scope Response List: %s", format_text(&pd[offset], length));
300 proto_tree_add_text(srvloc_tree, offset, 0, "Service Type Request");
301 length = pntohs(&pd[offset]);
302 proto_tree_add_text(srvloc_tree, offset, 2, "Previous Response List Length: %d", length);
304 proto_tree_add_text(srvloc_tree, offset, length, "Previous Response List: %s", format_text(&pd[offset], length));
306 length = pntohs(&pd[offset]);
307 proto_tree_add_text(srvloc_tree, offset, 2, "Naming Authority List length: %d", length);
309 proto_tree_add_text(srvloc_tree, offset, length, "Naming Authority List: %s", format_text(&pd[offset], length));
311 length = pntohs(&pd[offset]);
312 proto_tree_add_text(srvloc_tree, offset, 2, "Scope List Length: %d", length);
314 proto_tree_add_text(srvloc_tree, offset, length, "Scope Response List: %s", format_text(&pd[offset], length));
319 proto_tree_add_text(srvloc_tree, offset, 0, "Service Type Reply");
320 proto_tree_add_item(srvloc_tree, hf_srvloc_error, offset, 2, pd[offset]);;
322 proto_tree_add_text(srvloc_tree, offset, 2, "Service Type Count: %d", pntohs(&pd[offset]));
324 for (count = pntohs(&pd[offset]) + 1; count > 0; count--, offset++) {
325 length = pntohs(&pd[offset]);
326 proto_tree_add_text(srvloc_tree, offset, 2, "Service Type List length: %d", length);
328 proto_tree_add_text(srvloc_tree, offset, length, "Service Type List: %s", format_text(&pd[offset], length));
334 proto_tree_add_text(srvloc_tree, offset, END_OF_FRAME, "Unknown Function Type");
336 } else { proto_tree_add_text(srvloc_tree, offset, END_OF_FRAME,"Invalid packet: Bad length value");
341 /* Register protocol with Ethereal. */
344 proto_register_srvloc(void)
346 static hf_register_info hf[] = {
347 { &hf_srvloc_version,
348 { "Version", "srvloc.version",
349 FT_UINT8, BASE_DEC, NULL, 0x0,
353 {&hf_srvloc_function,
354 {"Function", "srvloc.function",
355 FT_UINT8, BASE_DEC, VALS(srvlocfunctionvals), 0x0,
360 {"Flags", "srvloc.flags",
361 FT_UINT8, BASE_HEX, NULL, 0x0,
366 {"Error Code", "srvloc.err",
367 FT_UINT8, BASE_DEC, VALS(srvloc_errs), 0x0,
372 static gint *ett[] = {
376 proto_srvloc = proto_register_protocol("Service Location Protocol", "srvloc");
377 proto_register_field_array(proto_srvloc, hf, array_length(hf));
378 proto_register_subtree_array(ett, array_length(ett));