]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-lmp.c
CVE-2017-13040/MPTCP: Clean up printing DSS suboption.
[tcpdump] / print-lmp.c
index 53e62d18b34c122831c786c619df67362a7534b9..916a1d675b07fbfa71531ab9dbc15f6300abfdcf 100644 (file)
  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  * FOR A PARTICULAR PURPOSE.
  *
- * Support for the Link Management Protocol as per rfc 4204.
- *
- * Original code by Hannes Gredler ([email protected])
- * Support for LMP service discovery extensions (defined by UNI 1.0) added
- * by Manu Pathak ([email protected]), May 2005
+ * Original code by Hannes Gredler ([email protected])
+ * Support for LMP service discovery extensions (defined by OIF UNI 1.0)
+ * added by Manu Pathak ([email protected]), May 2005
  */
 
+/* \summary: Link Management Protocol (LMP) printer */
+
+/* specification: RFC 4204 */
+/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -351,6 +354,73 @@ static const struct tok lmp_ctype_values[] = {
     { 0, NULL}
 };
 
+static int
+lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
+                            int total_subobj_len, int offset)
+{
+    int hexdump = FALSE;
+    int subobj_type, subobj_len;
+
+    union { /* int to float conversion buffer */
+        float f;
+        uint32_t i;
+    } bw;
+
+    while (total_subobj_len > 0 && hexdump == FALSE ) {
+       subobj_type = EXTRACT_8BITS(obj_tptr+offset);
+       subobj_len  = EXTRACT_8BITS(obj_tptr+offset+1);
+       ND_PRINT((ndo, "\n\t    Subobject, Type: %s (%u), Length: %u",
+               tok2str(lmp_data_link_subobj,
+                       "Unknown",
+                       subobj_type),
+                       subobj_type,
+                       subobj_len));
+       if (subobj_len < 4) {
+           ND_PRINT((ndo, " (too short)"));
+           break;
+       }
+       if ((subobj_len % 4) != 0) {
+           ND_PRINT((ndo, " (not a multiple of 4)"));
+           break;
+       }
+       if (total_subobj_len < subobj_len) {
+           ND_PRINT((ndo, " (goes past the end of the object)"));
+           break;
+       }
+       switch(subobj_type) {
+       case INT_SWITCHING_TYPE_SUBOBJ:
+           ND_PRINT((ndo, "\n\t      Switching Type: %s (%u)",
+               tok2str(gmpls_switch_cap_values,
+                       "Unknown",
+                       EXTRACT_8BITS(obj_tptr+offset+2)),
+               EXTRACT_8BITS(obj_tptr+offset+2)));
+           ND_PRINT((ndo, "\n\t      Encoding Type: %s (%u)",
+               tok2str(gmpls_encoding_values,
+                       "Unknown",
+                       EXTRACT_8BITS(obj_tptr+offset+3)),
+               EXTRACT_8BITS(obj_tptr+offset+3)));
+           bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
+           ND_PRINT((ndo, "\n\t      Min Reservable Bandwidth: %.3f Mbps",
+                bw.f*8/1000000));
+           bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
+           ND_PRINT((ndo, "\n\t      Max Reservable Bandwidth: %.3f Mbps",
+                bw.f*8/1000000));
+           break;
+       case WAVELENGTH_SUBOBJ:
+           ND_PRINT((ndo, "\n\t      Wavelength: %u",
+               EXTRACT_32BITS(obj_tptr+offset+4)));
+           break;
+       default:
+           /* Any Unknown Subobject ==> Exit loop */
+           hexdump=TRUE;
+           break;
+       }
+       total_subobj_len-=subobj_len;
+       offset+=subobj_len;
+    }
+    return (hexdump);
+}
+
 void
 lmp_print(netdissect_options *ndo,
           register const u_char *pptr, register u_int len)
@@ -358,10 +428,10 @@ lmp_print(netdissect_options *ndo,
     const struct lmp_common_header *lmp_com_header;
     const struct lmp_object_header *lmp_obj_header;
     const u_char *tptr,*obj_tptr;
-    int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
+    u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
     int hexdump;
-    int offset,subobj_type,subobj_len,total_subobj_len;
-    int link_type;
+    u_int offset;
+    u_int link_type;
 
     union { /* int to float conversion buffer */
         float f;
@@ -399,6 +469,14 @@ lmp_print(netdissect_options *ndo,
            tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
            bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
            tlen));
+    if (tlen < sizeof(const struct lmp_common_header)) {
+        ND_PRINT((ndo, " (too short)"));
+        return;
+    }
+    if (tlen > len) {
+        ND_PRINT((ndo, " (too long)"));
+        tlen = len;
+    }
 
     tptr+=sizeof(const struct lmp_common_header);
     tlen-=sizeof(const struct lmp_common_header);
@@ -411,9 +489,6 @@ lmp_print(netdissect_options *ndo,
         lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
         lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
 
-        if(lmp_obj_len % 4 || lmp_obj_len < 4)
-            return;
-
         ND_PRINT((ndo, "\n\t  %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
                tok2str(lmp_obj_values,
                        "Unknown",
@@ -426,6 +501,15 @@ lmp_print(netdissect_options *ndo,
                (lmp_obj_header->ctype)&0x80 ? "" : "non-",
                lmp_obj_len));
 
+        if (lmp_obj_len < 4) {
+            ND_PRINT((ndo, " (too short)"));
+            return;
+        }
+        if ((lmp_obj_len % 4) != 0) {
+            ND_PRINT((ndo, " (not a multiple of 4)"));
+            return;
+        }
+
         obj_tptr=tptr+sizeof(struct lmp_object_header);
         obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
 
@@ -439,6 +523,10 @@ lmp_print(netdissect_options *ndo,
             switch(lmp_obj_ctype) {
             case LMP_CTYPE_LOC:
             case LMP_CTYPE_RMT:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Control Channel ID: %u (0x%08x)",
                        EXTRACT_32BITS(obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
@@ -454,20 +542,30 @@ lmp_print(netdissect_options *ndo,
             switch(lmp_obj_ctype) {
             case LMP_CTYPE_IPV4_LOC:
             case LMP_CTYPE_IPV4_RMT:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    IPv4 Link ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
                 break;
-#ifdef INET6
             case LMP_CTYPE_IPV6_LOC:
             case LMP_CTYPE_IPV6_RMT:
+                if (obj_tlen != 16) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    IPv6 Link ID: %s (0x%08x)",
                        ip6addr_string(ndo, obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
                 break;
-#endif
             case LMP_CTYPE_UNMD_LOC:
             case LMP_CTYPE_UNMD_RMT:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Link ID: %u (0x%08x)",
                        EXTRACT_32BITS(obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
@@ -480,11 +578,19 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_MESSAGE_ID:
             switch(lmp_obj_ctype) {
             case LMP_CTYPE_1:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Message ID: %u (0x%08x)",
                        EXTRACT_32BITS(obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
                 break;
             case LMP_CTYPE_2:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Message ID Ack: %u (0x%08x)",
                        EXTRACT_32BITS(obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
@@ -498,6 +604,10 @@ lmp_print(netdissect_options *ndo,
             switch(lmp_obj_ctype) {
             case LMP_CTYPE_LOC:
             case LMP_CTYPE_RMT:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Node ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr),
                        EXTRACT_32BITS(obj_tptr)));
@@ -511,6 +621,10 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_CONFIG:
             switch(lmp_obj_ctype) {
             case LMP_CTYPE_HELLO_CONFIG:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Hello Interval: %u\n\t    Hello Dead Interval: %u",
                        EXTRACT_16BITS(obj_tptr),
                        EXTRACT_16BITS(obj_tptr+2)));
@@ -524,6 +638,10 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_HELLO:
             switch(lmp_obj_ctype) {
            case LMP_CTYPE_HELLO:
+                if (obj_tlen != 8) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Tx Seq: %u, Rx Seq: %u",
                        EXTRACT_32BITS(obj_tptr),
                        EXTRACT_32BITS(obj_tptr+4)));
@@ -535,13 +653,17 @@ lmp_print(netdissect_options *ndo,
             break;
 
         case LMP_OBJ_TE_LINK:
+           switch(lmp_obj_ctype) {
+           case LMP_CTYPE_IPV4:
+                if (obj_tlen != 12) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                ND_PRINT((ndo, "\n\t    Flags: [%s]",
-               bittok2str(lmp_obj_te_link_flag_values,
+                   bittok2str(lmp_obj_te_link_flag_values,
                        "none",
-                       EXTRACT_16BITS(obj_tptr)>>8)));
+                       EXTRACT_8BITS(obj_tptr))));
 
-           switch(lmp_obj_ctype) {
-           case LMP_CTYPE_IPV4:
                ND_PRINT((ndo, "\n\t    Local Link-ID: %s (0x%08x)"
                       "\n\t    Remote Link-ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr+4),
@@ -550,24 +672,58 @@ lmp_print(netdissect_options *ndo,
                        EXTRACT_32BITS(obj_tptr+8)));
                break;
 
-#ifdef INET6
            case LMP_CTYPE_IPV6:
-#endif
+                if (obj_tlen != 36) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
+               ND_PRINT((ndo, "\n\t    Flags: [%s]",
+                   bittok2str(lmp_obj_te_link_flag_values,
+                       "none",
+                       EXTRACT_8BITS(obj_tptr))));
+
+               ND_PRINT((ndo, "\n\t    Local Link-ID: %s (0x%08x)"
+                      "\n\t    Remote Link-ID: %s (0x%08x)",
+                       ip6addr_string(ndo, obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+4),
+                       ip6addr_string(ndo, obj_tptr+20),
+                       EXTRACT_32BITS(obj_tptr+20)));
+                break;
+
            case LMP_CTYPE_UNMD:
+                if (obj_tlen != 12) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
+               ND_PRINT((ndo, "\n\t    Flags: [%s]",
+                   bittok2str(lmp_obj_te_link_flag_values,
+                       "none",
+                       EXTRACT_8BITS(obj_tptr))));
+
+               ND_PRINT((ndo, "\n\t    Local Link-ID: %u (0x%08x)"
+                      "\n\t    Remote Link-ID: %u (0x%08x)",
+                       EXTRACT_32BITS(obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+8),
+                       EXTRACT_32BITS(obj_tptr+8)));
+               break;
+
             default:
                 hexdump=TRUE;
             }
             break;
 
         case LMP_OBJ_DATA_LINK:
-               ND_PRINT((ndo, "\n\t    Flags: [%s]",
-               bittok2str(lmp_obj_data_link_flag_values,
-                       "none",
-                       EXTRACT_16BITS(obj_tptr)>>8)));
-
            switch(lmp_obj_ctype) {
            case LMP_CTYPE_IPV4:
-           case LMP_CTYPE_UNMD:
+                if (obj_tlen < 12) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
+               ND_PRINT((ndo, "\n\t    Flags: [%s]",
+                   bittok2str(lmp_obj_data_link_flag_values,
+                       "none",
+                       EXTRACT_8BITS(obj_tptr))));
                 ND_PRINT((ndo, "\n\t    Local Interface ID: %s (0x%08x)"
                        "\n\t    Remote Interface ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr+4),
@@ -575,53 +731,50 @@ lmp_print(netdissect_options *ndo,
                        ipaddr_string(ndo, obj_tptr+8),
                        EXTRACT_32BITS(obj_tptr+8)));
 
-               total_subobj_len = lmp_obj_len - 16;
-               offset = 12;
-               while (total_subobj_len > 0 && hexdump == FALSE ) {
-                       subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
-                       subobj_len  = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
-                       ND_PRINT((ndo, "\n\t    Subobject, Type: %s (%u), Length: %u",
-                               tok2str(lmp_data_link_subobj,
-                                       "Unknown",
-                                       subobj_type),
-                                       subobj_type,
-                                       subobj_len));
-                       switch(subobj_type) {
-                       case INT_SWITCHING_TYPE_SUBOBJ:
-                               ND_PRINT((ndo, "\n\t      Switching Type: %s (%u)",
-                                       tok2str(gmpls_switch_cap_values,
-                                               "Unknown",
-                                               EXTRACT_16BITS(obj_tptr+offset+2)>>8),
-                                       EXTRACT_16BITS(obj_tptr+offset+2)>>8));
-                               ND_PRINT((ndo, "\n\t      Encoding Type: %s (%u)",
-                                       tok2str(gmpls_encoding_values,
-                                               "Unknown",
-                                               EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
-                                       EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF));
-                               bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
-                               ND_PRINT((ndo, "\n\t      Min Reservable Bandwidth: %.3f Mbps",
-                                       bw.f*8/1000000));
-                               bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
-                               ND_PRINT((ndo, "\n\t      Max Reservable Bandwidth: %.3f Mbps",
-                                       bw.f*8/1000000));
-                               break;
-                       case WAVELENGTH_SUBOBJ:
-                               ND_PRINT((ndo, "\n\t      Wavelength: %u",
-                                       EXTRACT_32BITS(obj_tptr+offset+4)));
-                               break;
-                       default:
-                               /* Any Unknown Subobject ==> Exit loop */
-                               hexdump=TRUE;
-                               break;
-                       }
-                       total_subobj_len-=subobj_len;
-                       offset+=subobj_len;
-               }
-
+               if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+                   hexdump=TRUE;
                break;
-#ifdef INET6
+
            case LMP_CTYPE_IPV6:
-#endif
+                if (obj_tlen < 36) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
+               ND_PRINT((ndo, "\n\t    Flags: [%s]",
+                   bittok2str(lmp_obj_data_link_flag_values,
+                       "none",
+                       EXTRACT_8BITS(obj_tptr))));
+                ND_PRINT((ndo, "\n\t    Local Interface ID: %s (0x%08x)"
+                       "\n\t    Remote Interface ID: %s (0x%08x)",
+                       ip6addr_string(ndo, obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+4),
+                       ip6addr_string(ndo, obj_tptr+20),
+                       EXTRACT_32BITS(obj_tptr+20)));
+
+               if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
+                   hexdump=TRUE;
+               break;
+
+           case LMP_CTYPE_UNMD:
+                if (obj_tlen < 12) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
+               ND_PRINT((ndo, "\n\t    Flags: [%s]",
+                   bittok2str(lmp_obj_data_link_flag_values,
+                       "none",
+                       EXTRACT_8BITS(obj_tptr))));
+                ND_PRINT((ndo, "\n\t    Local Interface ID: %u (0x%08x)"
+                       "\n\t    Remote Interface ID: %u (0x%08x)",
+                       EXTRACT_32BITS(obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+4),
+                       EXTRACT_32BITS(obj_tptr+8),
+                       EXTRACT_32BITS(obj_tptr+8)));
+
+               if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+                   hexdump=TRUE;
+               break;
+
             default:
                 hexdump=TRUE;
             }
@@ -630,6 +783,10 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_VERIFY_BEGIN:
            switch(lmp_obj_ctype) {
             case LMP_CTYPE_1:
+                if (obj_tlen != 20) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                ND_PRINT((ndo, "\n\t    Flags: %s",
                bittok2str(lmp_obj_begin_verify_flag_values,
                        "none",
@@ -658,6 +815,10 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_VERIFY_BEGIN_ACK:
            switch(lmp_obj_ctype) {
             case LMP_CTYPE_1:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Verify Dead Interval: %u"
                        "\n\t    Verify Transport Response: %u",
                        EXTRACT_16BITS(obj_tptr),
@@ -672,6 +833,10 @@ lmp_print(netdissect_options *ndo,
        case LMP_OBJ_VERIFY_ID:
            switch(lmp_obj_ctype) {
             case LMP_CTYPE_1:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                 ND_PRINT((ndo, "\n\t    Verify ID: %u",
                        EXTRACT_32BITS(obj_tptr)));
                 break;
@@ -684,19 +849,20 @@ lmp_print(netdissect_options *ndo,
        case LMP_OBJ_CHANNEL_STATUS:
             switch(lmp_obj_ctype) {
            case LMP_CTYPE_IPV4:
-           case LMP_CTYPE_UNMD:
                offset = 0;
                /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
-               while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+               while (offset+8 <= obj_tlen) {
                        ND_PRINT((ndo, "\n\t    Interface ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr+offset),
                        EXTRACT_32BITS(obj_tptr+offset)));
 
-                       ND_PRINT((ndo, "\n\t\t    Active: %s (%u)",             (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+                       ND_PRINT((ndo, "\n\t\t    Active: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
                                                "Allocated" : "Non-allocated",
                                (EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
 
-                       ND_PRINT((ndo, "\n\t\t    Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+                       ND_PRINT((ndo, "\n\t\t    Direction: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
                                                "Transmit" : "Receive",
                                (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
 
@@ -708,9 +874,61 @@ lmp_print(netdissect_options *ndo,
                        offset+=8;
                }
                 break;
-#ifdef INET6
+
            case LMP_CTYPE_IPV6:
-#endif
+               offset = 0;
+               /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
+               while (offset+20 <= obj_tlen) {
+                       ND_PRINT((ndo, "\n\t    Interface ID: %s (0x%08x)",
+                       ip6addr_string(ndo, obj_tptr+offset),
+                       EXTRACT_32BITS(obj_tptr+offset)));
+
+                       ND_PRINT((ndo, "\n\t\t    Active: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ?
+                                               "Allocated" : "Non-allocated",
+                               (EXTRACT_32BITS(obj_tptr+offset+16)>>31)));
+
+                       ND_PRINT((ndo, "\n\t\t    Direction: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ?
+                                               "Transmit" : "Receive",
+                               (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1));
+
+                       ND_PRINT((ndo, "\n\t\t    Channel Status: %s (%u)",
+                                       tok2str(lmp_obj_channel_status_values,
+                                       "Unknown",
+                                       EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF),
+                       EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF));
+                       offset+=20;
+               }
+                break;
+
+           case LMP_CTYPE_UNMD:
+               offset = 0;
+               /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
+               while (offset+8 <= obj_tlen) {
+                       ND_PRINT((ndo, "\n\t    Interface ID: %u (0x%08x)",
+                       EXTRACT_32BITS(obj_tptr+offset),
+                       EXTRACT_32BITS(obj_tptr+offset)));
+
+                       ND_PRINT((ndo, "\n\t\t    Active: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+                                               "Allocated" : "Non-allocated",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
+
+                       ND_PRINT((ndo, "\n\t\t    Direction: %s (%u)",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+                                               "Transmit" : "Receive",
+                               (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
+
+                       ND_PRINT((ndo, "\n\t\t    Channel Status: %s (%u)",
+                                       tok2str(lmp_obj_channel_status_values,
+                                       "Unknown",
+                                       EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
+                       EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF));
+                       offset+=8;
+               }
+                break;
+
             default:
                 hexdump=TRUE;
             }
@@ -719,18 +937,35 @@ lmp_print(netdissect_options *ndo,
        case LMP_OBJ_CHANNEL_STATUS_REQ:
             switch(lmp_obj_ctype) {
            case LMP_CTYPE_IPV4:
-           case LMP_CTYPE_UNMD:
                offset = 0;
-               while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+               while (offset+4 <= obj_tlen) {
                        ND_PRINT((ndo, "\n\t    Interface ID: %s (0x%08x)",
                        ipaddr_string(ndo, obj_tptr+offset),
                        EXTRACT_32BITS(obj_tptr+offset)));
                        offset+=4;
                }
                 break;
-#ifdef INET6
+
            case LMP_CTYPE_IPV6:
-#endif
+               offset = 0;
+               while (offset+16 <= obj_tlen) {
+                       ND_PRINT((ndo, "\n\t    Interface ID: %s (0x%08x)",
+                       ip6addr_string(ndo, obj_tptr+offset),
+                       EXTRACT_32BITS(obj_tptr+offset)));
+                       offset+=16;
+               }
+                break;
+
+           case LMP_CTYPE_UNMD:
+               offset = 0;
+               while (offset+4 <= obj_tlen) {
+                       ND_PRINT((ndo, "\n\t    Interface ID: %u (0x%08x)",
+                       EXTRACT_32BITS(obj_tptr+offset),
+                       EXTRACT_32BITS(obj_tptr+offset)));
+                       offset+=4;
+               }
+                break;
+
            default:
                 hexdump=TRUE;
             }
@@ -739,6 +974,10 @@ lmp_print(netdissect_options *ndo,
         case LMP_OBJ_ERROR_CODE:
            switch(lmp_obj_ctype) {
             case LMP_CTYPE_BEGIN_VERIFY_ERROR:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                ND_PRINT((ndo, "\n\t    Error Code: %s",
                bittok2str(lmp_obj_begin_verify_error_values,
                        "none",
@@ -746,6 +985,10 @@ lmp_print(netdissect_options *ndo,
                 break;
 
             case LMP_CTYPE_LINK_SUMMARY_ERROR:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                ND_PRINT((ndo, "\n\t    Error Code: %s",
                bittok2str(lmp_obj_link_summary_error_values,
                        "none",
@@ -759,51 +1002,60 @@ lmp_print(netdissect_options *ndo,
        case LMP_OBJ_SERVICE_CONFIG:
            switch (lmp_obj_ctype) {
            case LMP_CTYPE_SERVICE_CONFIG_SP:
-
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
                ND_PRINT((ndo, "\n\t Flags: %s",
                       bittok2str(lmp_obj_service_config_sp_flag_values,
                                  "none",
-                                 EXTRACT_16BITS(obj_tptr)>>8)));
+                                 EXTRACT_8BITS(obj_tptr))));
 
                ND_PRINT((ndo, "\n\t  UNI Version: %u",
-                      EXTRACT_16BITS(obj_tptr) & 0x00FF));
+                      EXTRACT_8BITS(obj_tptr+1)));
 
                break;
 
             case LMP_CTYPE_SERVICE_CONFIG_CPSA:
+                if (obj_tlen != 16) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
 
-               link_type = EXTRACT_16BITS(obj_tptr)>>8;
+               link_type = EXTRACT_8BITS(obj_tptr);
 
                ND_PRINT((ndo, "\n\t Link Type: %s (%u)",
                       tok2str(lmp_sd_service_config_cpsa_link_type_values,
                               "Unknown", link_type),
                       link_type));
 
-               if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
+               switch (link_type) {
+               case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
                    ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
                           tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
                                   "Unknown",
-                                  EXTRACT_16BITS(obj_tptr) & 0x00FF),
-                          EXTRACT_16BITS(obj_tptr) & 0x00FF));
-               }
+                                  EXTRACT_8BITS(obj_tptr+1)),
+                          EXTRACT_8BITS(obj_tptr+1)));
+                   break;
 
-               if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
+               case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
                    ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
                           tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
                                   "Unknown",
-                                  EXTRACT_16BITS(obj_tptr) & 0x00FF),
-                          EXTRACT_16BITS(obj_tptr) & 0x00FF));
+                                  EXTRACT_8BITS(obj_tptr+1)),
+                          EXTRACT_8BITS(obj_tptr+1)));
+                   break;
                }
 
                ND_PRINT((ndo, "\n\t Transparency: %s",
                       bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
                                  "none",
-                                 EXTRACT_16BITS(obj_tptr+2)>>8)));
+                                 EXTRACT_8BITS(obj_tptr+2))));
 
                ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
                       bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
                                  "none",
-                                 EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)));
+                                 EXTRACT_8BITS(obj_tptr+3))));
 
                ND_PRINT((ndo, "\n\t Minimum NCC: %u",
                       EXTRACT_16BITS(obj_tptr+4)));
@@ -824,6 +1076,10 @@ lmp_print(netdissect_options *ndo,
                break;
 
            case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
+                if (obj_tlen != 8) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
 
                ND_PRINT((ndo, "\n\t Transparency Flags: %s",
                       bittok2str(
@@ -835,22 +1091,26 @@ lmp_print(netdissect_options *ndo,
                       bittok2str(
                           lmp_obj_service_config_nsa_tcm_flag_values,
                           "none",
-                          EXTRACT_16BITS(obj_tptr+6) & 0x00FF)));
+                          EXTRACT_8BITS(obj_tptr+7))));
 
                break;
 
            case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
+                if (obj_tlen != 4) {
+                    ND_PRINT((ndo, " (not correct for object)"));
+                    break;
+                }
 
                ND_PRINT((ndo, "\n\t Diversity: Flags: %s",
                       bittok2str(
                           lmp_obj_service_config_nsa_network_diversity_flag_values,
                           "none",
-                          EXTRACT_16BITS(obj_tptr+2) & 0x00FF)));
+                          EXTRACT_8BITS(obj_tptr+3))));
                break;
 
            default:
                hexdump = TRUE;
-           };
+           }
 
        break;