Ethereal-dev: [Ethereal-dev] Re: [Ethereal-users] SLPv2 support

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Brad Hards <bhards@xxxxxxxxxxxxxx>
Date: Sun, 29 Sep 2002 13:39:21 +1000
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sat, 28 Sep 2002 06:47, Ronnie Sahlberg wrote:
> Give it a try and post your patch to ethereal-dev,
> the people there can provide comments on how to
> improve it/clean it up.
First cut patch attached. I am a newbie to ethereal (even as a user), so I 
don't know if there are some tragic style or coding errors in this.

Feedback appreciated - please be gentle, this is my first time....

Brad

BTW: Is there some set of test files (eg in libpcap form) that I can 
contribute my tests to?

> aussie aussie aussie
oy oy oy - whatever.

- -- 
http://conf.linux.org.au. 22-25Jan2003. Perth, Aust. Tickets booked.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9lnXpW6pHgIdAuOMRAlRmAJ9eJ7Oo4zvOJ8LFEbP9++IpPEdVOwCgrav/
DihlN7d4V63pjo2FwbOPLB8=
=Y8mb
-----END PGP SIGNATURE-----
diff -Naur -x doc -x'*.1' -xtest1 -x 'ps*' -x 'register*' clean/ethereal-0.9.6/packet-srvloc.c ethereal-0.9.6/packet-srvloc.c
--- clean/ethereal-0.9.6/packet-srvloc.c	Fri Aug  9 12:34:37 2002
+++ ethereal-0.9.6/packet-srvloc.c	Sun Sep 29 12:31:42 2002
@@ -13,6 +13,8 @@
  * Copyright 1998 Gerald Combs
  *
  * Service Location Protocol is RFC 2165
+ * Service Location Protocol Version 2 is RFC 2608
+ *   - initial support by Brad Hards <bradh@xxxxxxxxxxxxx>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -48,6 +50,7 @@
 static int hf_srvloc_function = -1;
 static int hf_srvloc_flags = -1;
 static int hf_srvloc_error = -1;
+static int hf_srvloc_error_v2 = -1;
 
 static gint ett_srvloc = -1;
 static gint ett_srvloc_flags = -1;
@@ -67,9 +70,11 @@
 #define DAADVERT	8
 #define SRVTYPERQST	9
 #define	SRVTYPERPLY	10
+#define SAADVERT        11 /* SLPv2, section 8 */
 
 /* Create protocol header structure */
-
+/* bradh: looks like never used. */
+/* bradh: comment it out for now since it doesn't work for v2
 struct srvloc_hdr {
     guint8	version;
     guint8	function;
@@ -80,6 +85,7 @@
     guint16	encoding;
     guint16	xid;
 };
+*/
 
 /* List to resolve function numbers to names */
 
@@ -94,6 +100,7 @@
     { DAADVERT, "DA Advertisement" }, 
     { SRVTYPERQST, "Service Type Request" }, 
     { SRVTYPERPLY, "Service Type Reply" }, 
+    { SAADVERT, "SA Advertisement" }, /* v2 only */
     { 0, NULL }
 };
 
@@ -108,7 +115,12 @@
 #define FLAG_A		0x10
 #define FLAG_F		0x08
 
-/* Define Error Codes */
+/* it all changes for Version 2 */
+#define FLAG_O_V2       0x8000
+#define FLAG_F_V2       0x4000
+#define FLAG_R_V2       0x2000
+
+/* Define Error Codes  - Version 1*/
 
 #define SUCCESS		0
 #define LANG_NOT_SPTD	1
@@ -133,6 +145,42 @@
     { 0, NULL }
 };
 
+/* Define Error Codes for Version 2 */
+
+#define LANGUAGE_NOT_SUPPORTED 	1 
+#define PARSE_ERROR 		2
+#define INVALID_REGISTRATION	3
+#define SCOPE_NOT_SUPPORTED	4
+#define AUTHENTICATION_UNKNOWN	5
+#define AUTHENTICATION_ABSENT	6
+#define AUTHENTICATION_FAILED	7
+#define VER_NOT_SUPPORTED	9
+#define INTERNAL_ERROR		10
+#define DA_BUSY_NOW		11
+#define OPTION_NOT_UNDERSTOOD	12
+#define INVALID_UPDATE		13
+#define MSG_NOT_SUPPORTED	14
+#define REFRESH_REJECTED	15
+
+static const value_string srvloc_errs_v2[] = {
+    { SUCCESS, "No Error" },
+    { LANGUAGE_NOT_SUPPORTED, "There is data for the service type in the scope in the AttrRqst or SrvRqst, but not in the requested language." },
+    { PARSE_ERROR, "The message fails to obey SLP syntax." },
+    { INVALID_REGISTRATION, "The SrvReg has problems -- e.g., a zero lifetime or an omitted Language Tag." },
+    { SCOPE_NOT_SUPPORTED, "The SLP message did not include a scope in its <scope-list> supported by the SA or DA." },
+    { AUTHENTICATION_UNKNOWN, "The DA or SA receives a request for an unsupported SLP SPI." },
+    { AUTHENTICATION_ABSENT, "The DA expected URL and ATTR authentication in the SrvReg and did not receive it."},
+    { AUTHENTICATION_FAILED, "The DA detected an authentication error in an Authentication block."},
+    { VER_NOT_SUPPORTED, "Unsupported version number in message header." },
+    { INTERNAL_ERROR, "The DA (or SA) is too sick to respond." },
+    { DA_BUSY_NOW, "UA or SA SHOULD retry, using exponential back off." },
+    { OPTION_NOT_UNDERSTOOD, "The DA (or SA) received an unknown option from the mandatory range."},
+    { INVALID_UPDATE, "The DA received a SrvReg without FRESH set, for an unregistered service or with inconsistent Service Types." },
+    { MSG_NOT_SUPPORTED, "The SA received an AttrRqst or SrvTypeRqst and does not support it." },
+    { REFRESH_REJECTED, "The SA sent a SrvReg or partial SrvDereg to a DA more frequently than the DA's min-refresh-interval."},
+    { 0, NULL }
+};
+
 /*
  * Character encodings.
  * This is a small subset of what's in
@@ -203,6 +251,49 @@
     return offset;
 }
 
+/* SLPv2 version - Needs to be fixed to match RFC2608 sect 9.2*/
+static int
+dissect_authblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+    struct tm *stamp;
+    time_t seconds;
+    guint16 length;
+    
+    proto_tree_add_text(tree, tvb, offset, 2, "Block Structure Desciptor: 0x%x",
+			tvb_get_ntohs(tvb, offset));
+    proto_tree_add_text(tree, tvb, offset+2, 2, "Authentication Block Length: %u",
+			tvb_get_ntohs(tvb, offset + 2));
+
+    seconds = tvb_get_ntohl(tvb, offset+4) - 2208988800ul;
+    stamp = gmtime(&seconds);
+    if (stamp != NULL) {
+	proto_tree_add_text(tree, tvb, offset, 8,
+			    "Timestamp: %04d-%02d-%02d %02d:%02d:%02d UTC",
+			    stamp->tm_year + 1900, stamp->tm_mon + 1,
+			    stamp->tm_mday, stamp->tm_hour, stamp->tm_min,
+			    stamp->tm_sec);
+    } else {
+      proto_tree_add_text(tree, tvb, offset, 4, "Timestamp not representable");
+    }
+    length = tvb_get_ntohs(tvb, offset + 8);
+    proto_tree_add_text(tree, tvb, offset + 8, 2, "SLP SPI length: %u",
+			length);
+    offset += 10;
+    proto_tree_add_text(tree, tvb, offset, length, "SLP SPIk: %s",
+			tvb_format_text(tvb, offset, length));
+    offset += length;
+    /* add code in here to handle Structured Authentication Block */
+    return offset;
+}
+
+static int
+dissect_attrauthblk_v2(tvbuff_t *tvb, int offset, proto_tree *tree)
+{
+    tvb=tvb; tree=tree; /* silence gcc for now */
+    /* add code in here to handle attribute authentication */
+    return offset;
+}
+
 /* Packet dissection routine called by tcp & udp when port 427 detected */
 
 static void
@@ -214,9 +305,10 @@
     guint8 version;
     guint8 function;
     guint16 encoding;
-    guint16 length;
-    guint8 flags;
+    guint32 length; /* three bytes needed for v2 */
+    guint16 flags; /* two byes needed for v2 */
     guint32 count;
+    guint32 next_ext_off; /* three bytes, v2 only */
 
     if (check_col(pinfo->cinfo, COL_PROTOCOL))
         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SRVLOC");
@@ -239,31 +331,32 @@
                             version);
         proto_tree_add_uint(srvloc_tree, hf_srvloc_function, tvb, offset + 1, 1,
                             function);
-        length = tvb_get_ntohs(tvb, offset + 2);
-        proto_tree_add_text(srvloc_tree, tvb, offset + 2, 2, "Length: %u",
-                            length);
-        flags = tvb_get_guint8(tvb, offset + 4);
-        tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags, tvb, offset + 4, 1,
-                                 flags);
-        srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
-        proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Overflow                          %d... .xxx", (flags & FLAG_O) >> 7 );
-        proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Monolingual                       .%d.. .xxx", (flags & FLAG_M) >> 6 );
-        proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "URL Authentication Present        ..%d. .xxx", (flags & FLAG_U) >> 5 );
-        proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Attribute Authentication Present  ...%d .xxx", (flags & FLAG_A) >> 4 );
-        proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Fresh Service Entry               .... %dxxx", (flags & FLAG_F) >> 3 );
-        proto_tree_add_text(srvloc_tree, tvb, offset + 5, 1, "Dialect: %u",
-                            tvb_get_guint8(tvb, offset + 5));
-        proto_tree_add_text(srvloc_tree, tvb, offset + 6, 2, "Language: %s",
-                            tvb_format_text(tvb, offset + 6, 2));
-        encoding = tvb_get_ntohs(tvb, offset + 8);
-        proto_tree_add_text(srvloc_tree, tvb, offset + 8, 2, "Encoding: %u (%s)",
-                            encoding,
-                            val_to_str(encoding, charsets, "Unknown"));
-        proto_tree_add_text(srvloc_tree, tvb, offset + 10, 2, "Transaction ID: %u",
-                            tvb_get_ntohs(tvb, offset + 10));
-        offset += 12;
+	if (version < 2) {
+	    length = tvb_get_ntohs(tvb, offset + 2);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 2, 2, "Length: %u",
+				length);
+	    flags = tvb_get_guint8(tvb, offset + 4);
+	    tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags, tvb, offset + 4, 1,
+				     flags);
+	    srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Overflow                          %d... .xxx", (flags & FLAG_O) >> 7 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Monolingual                       .%d.. .xxx", (flags & FLAG_M) >> 6 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "URL Authentication Present        ..%d. .xxx", (flags & FLAG_U) >> 5 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Attribute Authentication Present  ...%d .xxx", (flags & FLAG_A) >> 4 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 4, 0, "Fresh Service Entry               .... %dxxx", (flags & FLAG_F) >> 3 );
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 5, 1, "Dialect: %u",
+				tvb_get_guint8(tvb, offset + 5));
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 6, 2, "Language: %s",
+				tvb_format_text(tvb, offset + 6, 2));
+	    encoding = tvb_get_ntohs(tvb, offset + 8);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 8, 2, "Encoding: %u (%s)",
+				encoding,
+				val_to_str(encoding, charsets, "Unknown"));
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 10, 2, "Transaction ID: %u",
+				tvb_get_ntohs(tvb, offset + 10));
+	    offset += 12;
         
-        switch (function) {
+	    switch (function) {
             case SRVREQ:
                 proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Request");
                 length = tvb_get_ntohs(tvb, offset);
@@ -280,8 +373,8 @@
                 proto_tree_add_text(srvloc_tree, tvb, offset, length, "Predicate: %s",
                                     tvb_format_text(tvb, offset, length));
                 offset += length;
-            break;
-            
+		break;
+		
             case SRVRPLY:
                 proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Reply");
                 proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
@@ -394,7 +487,7 @@
             
             case ATTRRPLY:
                 proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Attribute Reply");
-                proto_tree_add_item(srvloc_tree, hf_srvloc_error, tvb, offset, 2, FALSE);
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
                 offset += 2;
                 length = tvb_get_ntohs(tvb, offset);
                 proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Attribute List length: %u",
@@ -474,8 +567,379 @@
 
             default:
                 proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
-        };
-    };
+	    };
+	}
+	else { /* Version 2 */
+	    length = tvb_get_ntoh24(tvb, offset + 2);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 2, 3, "Length: %u", length);
+
+	    flags = tvb_get_ntohs(tvb, offset + 5);
+	    tf = proto_tree_add_uint(srvloc_tree, hf_srvloc_flags, tvb, offset + 5, 2,
+				     flags);
+	    srvloc_flags = proto_item_add_subtree(tf, ett_srvloc_flags);
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 5, 0, "Overflow               %d..x xxxx",
+				(flags & FLAG_O_V2) >> 15 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 5, 0, "Fresh Service Entry    .%d.x xxxx",
+				(flags & FLAG_F_V2) >> 14 );
+	    proto_tree_add_text(srvloc_flags, tvb, offset + 5, 0, "Request Multicast      ..%dx xxxx",
+				(flags & FLAG_R_V2) >> 13 );
+
+	    next_ext_off = tvb_get_ntoh24(tvb, offset + 7);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 7, 3, "Next Extension offset: %u", next_ext_off);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 10, 2, "Transaction ID: %u",
+				tvb_get_ntohs(tvb, offset + 10));
+	    length = tvb_get_ntohs(tvb, offset + 12);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 12, 2, "Language Tag Length: %u", length);
+	    proto_tree_add_text(srvloc_tree, tvb, offset + 14, length, "Language Tag: %s",
+				tvb_format_text(tvb, offset + 14, length));
+	    offset += 14+length;
+
+	    switch (function) {
+            case SRVREQ: /* RFC2608 8.1 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Request");
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Previous Response List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Previous Response List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Service Type Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service Type: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Scope List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+		offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Predicate length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Predicate: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "SLP SPI length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "SLP SPI: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		break;
+		
+            case SRVRPLY: /* RFC2608 8.2 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Reply");
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
+                offset += 2;
+                count = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL Count: %u",
+                                    count);
+                offset += 2;
+                while (count > 0) {
+		    proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Reserved: 0x%x",
+					tvb_get_guint8(tvb, offset));
+		    offset += 1;
+                    proto_tree_add_text(srvloc_tree, tvb, offset, 2, "  URL lifetime: %u",
+                                        tvb_get_ntohs(tvb, offset));
+                    offset += 2;
+                    length = tvb_get_ntohs(tvb, offset);
+                    proto_tree_add_text(srvloc_tree, tvb, offset, 2, "  URL length: %u",
+                                        length);
+                    offset += 2;
+                    proto_tree_add_text(srvloc_tree, tvb, offset, length, "  Service URL: %s",
+                                        tvb_format_text(tvb, offset, length));
+                    offset += length;
+                    length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+                    proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of URL auths: %u",
+                                        length);
+                    offset += 1;
+		    while (length > 0) {
+			offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
+			length--;
+		    }
+                    count--;
+                };
+            break;
+
+            case SRVREG: /* RFC2608 8.3 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Registration");
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "Reserved: 0x%x",
+				    tvb_get_guint8(tvb, offset));
+		offset += 1;
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL lifetime: %u",
+                                    tvb_get_ntohs(tvb, offset));
+                offset += 2;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service URL: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of URL auths: %u",
+				    length);
+		offset += 1;
+		while (length > 0) {
+		    offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
+		    length--;
+		}
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Length of service type string: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service type: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Length of scope-list string: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Attribute List length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Attribute List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of Attr auths: %u",
+				    length);
+		offset += 1;
+		while (length > 0) {
+		    offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
+		    length--;
+		}
+		break;
+
+            case SRVDEREG: /* RFC2608 10.6 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Deregister");
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Length of scope-list string: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service URL: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Tag List length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Tag List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		break;
+            
+            case SRVACK: /* RFC2608 8.4 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Acknowledge");
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
+                offset += 2;
+            break;
+
+            case ATTRRQST: /* RFC2608 10.3*/
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Attribute Request");
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Previous Response List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Previous Response List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service URL: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Scope List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Tag  List length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Tag List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "SLP SPI length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "SLP SPI: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+            break;
+
+            case ATTRRPLY: /* RFC2608 10.4 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Attribute Reply");
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
+                offset += 2;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Attribute List length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Attribute List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of Attr auths: %u",
+				    length);
+		offset += 1;
+		while (length > 0) {
+		    offset = dissect_attrauthblk_v2(tvb, offset, srvloc_tree);
+		    length--;
+		}
+            break;
+            
+            case DAADVERT: /* RCC 2608 8.5 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "DA Advertisement");
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
+                offset += 2;
+		proto_tree_add_text(srvloc_tree, tvb, offset, 4, "DA Stateless Boot Timestamp: %u",
+				    tvb_get_ntohl(tvb, offset));
+		offset += 4;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service URL: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Scope List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Attr List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Attr List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "SLP SPI Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "SLP SPI: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+		length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of auth blocks: %u",
+				    length);
+		offset += 1;
+		while (length > 0) {
+		    offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
+		    length--;
+		}
+            break;
+
+            case SRVTYPERQST: /* RFC2608 10.1 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Type Request");
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Previous Response List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Previous Response List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Naming Authority List length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Naming Authority List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+                length = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Scope List Length: %u",
+                                    length);
+                offset += 2;
+                proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+                                    tvb_format_text(tvb, offset, length));
+                offset += length;
+            break;
+
+	    case SRVTYPERPLY: /* rfc2608 10.2 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "Service Type Reply");
+                proto_tree_add_item(srvloc_tree, hf_srvloc_error_v2, tvb, offset, 2, FALSE);
+                offset += 2;
+                count = tvb_get_ntohs(tvb, offset);
+                proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Service Type Count: %u",
+                                    count);
+                offset += 2;
+                while (count > 0) {
+                    length = tvb_get_ntohs(tvb, offset);
+                    proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Service Type List length: %u",
+                                        length);
+                    offset += 2;
+                    proto_tree_add_text(srvloc_tree, tvb, offset, length, "Service Type List: %s",
+                                        tvb_format_text(tvb, offset, length));
+                    offset += length;
+                    count--;
+                };
+            break;
+
+	    case SAADVERT: /* rfc2608 10.2 */
+                proto_tree_add_text(srvloc_tree, tvb, offset, 0, "SA Advertisement");
+		length = tvb_get_ntohs(tvb, offset);
+		proto_tree_add_text(srvloc_tree, tvb, offset, 2, "URL length: %u",
+				    length);
+		offset += 2;
+		proto_tree_add_text(srvloc_tree, tvb, offset, length, "URL: %s",
+				    tvb_format_text(tvb, offset, length));
+		offset += length;
+		proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Scope List length: %u",
+				    length);
+		offset += 2;
+		proto_tree_add_text(srvloc_tree, tvb, offset, length, "Scope List: %s",
+				    tvb_format_text(tvb, offset, length));
+		offset += length;
+		length = tvb_get_ntohs(tvb, offset);
+		proto_tree_add_text(srvloc_tree, tvb, offset, 2, "Attribute List length: %u",
+				    length);
+		offset += 2;
+		proto_tree_add_text(srvloc_tree, tvb, offset, length, "Attribute length: %s",
+				    tvb_format_text(tvb, offset, length));
+		offset += length;
+		length = tvb_get_guint8(tvb, offset); /* really a count, naming abuse */
+		proto_tree_add_text(srvloc_tree, tvb, offset, 1, "  Number of auth blocks: %u",
+				    length);
+		offset += 1;
+		while (length > 0) {
+		    offset = dissect_authblk_v2(tvb, offset, srvloc_tree);
+		    length--;
+		}
+		break;
+
+            default:
+                proto_tree_add_text(srvloc_tree, tvb, offset, -1, "Unknown Function Type");
+	    };
+	};
+    }
 }
 
 /* Register protocol with Ethereal. */
@@ -507,6 +971,13 @@
             FT_UINT16, BASE_DEC, VALS(srvloc_errs), 0x0,
             "", HFILL }
         },
+
+        {&hf_srvloc_error_v2,
+            {"Error Code", "srvloc.errv2",
+            FT_UINT16, BASE_DEC, VALS(srvloc_errs_v2), 0x0,
+            "", HFILL }
+        },
+
     };
                   
     static gint *ett[] = {