]> The Tcpdump Group git mirrors - tcpdump/commitdiff
add support for printing of tc,tc-lq,hello,hna and mid messages
authorhannes <hannes>
Wed, 28 Mar 2007 07:34:55 +0000 (07:34 +0000)
committerhannes <hannes>
Wed, 28 Mar 2007 07:34:55 +0000 (07:34 +0000)
print-olsr.c

index 7fe4fb3db6a48174d049046f2d94f9125cda2383..174a51eac9437ff1f18d1d6d61b121c5d3a03096 100644 (file)
@@ -29,7 +29,7 @@
 #include "interface.h"
 #include "addrtoname.h"
 #include "extract.h"           
-#include "nlpid.h"
+#include "ip.h"
 
 /*
  * RFC 3626 common header
@@ -98,18 +98,29 @@ struct olsr_msg {
     u_int8_t msg_seq[2];
 };
 
-struct olsr_hello_lq {
+struct olsr_hello {
     u_int8_t res[2];
     u_int8_t htime;
     u_int8_t will;
 };
 
-struct olsr_hello_lq_link {
+struct olsr_hello_link {
     u_int8_t link_code;
     u_int8_t res;
     u_int8_t len[2];
 };
 
+struct olsr_tc {
+    u_int8_t ans_seq[2];
+    u_int8_t res[2];
+};
+
+struct olsr_hna {
+    u_int8_t network[4];
+    u_int8_t mask[4];
+};
+
+
 #define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3)
 #define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2)
 
@@ -128,7 +139,7 @@ static struct tok olsr_neighbor_type_values[] = {
     { 0, NULL}
 };
 
-struct olsr_hello_lq_neighbor {
+struct olsr_lq_neighbor {
     u_int8_t neighbor[4];
     u_int8_t link_quality;
     u_int8_t neighbor_link_quality;
@@ -137,24 +148,73 @@ struct olsr_hello_lq_neighbor {
 
 /*
  * macro to convert the 8-bit mantissa/exponent to a double float
- * taken from olsr.org code.
+ * taken from olsr.org.
  */
 #define VTIME_SCALE_FACTOR    0.0625
 #define ME_TO_DOUBLE(me) \
   (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F)))
 
+/*
+ * print a neighbor list with LQ extensions.
+ */
+static void
+olsr_print_lq_neighbor (const u_char *msg_data, u_int hello_len)
+{
+    struct olsr_lq_neighbor *lq_neighbor;
+
+    while (hello_len >= sizeof(struct olsr_lq_neighbor)) {
+
+        lq_neighbor = (struct olsr_lq_neighbor *)msg_data;
+
+        printf("\n\t      neighbor %s, link-quality %.2lf%%"
+               ", neighbor-link-quality %.2lf%%",
+               ipaddr_string(lq_neighbor->neighbor),
+               ((double)lq_neighbor->link_quality/2.55),
+               ((double)lq_neighbor->neighbor_link_quality/2.55));
+
+        msg_data += sizeof(struct olsr_lq_neighbor);
+        hello_len -= sizeof(struct olsr_lq_neighbor);
+    }
+}
+
+/*
+ * print a neighbor list.
+ */
+static void
+olsr_print_neighbor (const u_char *msg_data, u_int hello_len)
+{
+    int neighbor;
+
+    printf("\n\t      neighbor\n\t\t");
+    neighbor = 1;
+
+    while (hello_len >= sizeof(struct in_addr)) {
+
+        /* print 4 neighbors per line */
+
+        printf("%s%s", ipaddr_string(msg_data),
+               neighbor % 4 == 0 ? "\n\t\t" : " ");
+
+        msg_data += sizeof(struct in_addr);
+        hello_len -= sizeof(struct in_addr);
+    }
+}
+
+
 void
 olsr_print (const u_char *pptr, u_int length)
 {
     union {
         const struct olsr_common *common;
         const struct olsr_msg *msg;
-        const struct olsr_hello_lq *hello_lq;
-        const struct olsr_hello_lq_link *hello_lq_link;
-        const struct olsr_hello_lq_neighbor *hello_lq_neighbor;
+        const struct olsr_hello *hello;
+        const struct olsr_hello_link *hello_link;
+        const struct olsr_lq_neighbor *lq_neighbor;
+        const struct olsr_tc *tc;
+        const struct olsr_hna *hna;
     } ptr;
 
-    u_int msg_type, msg_len, msg_tlen, hello_len;
+    u_int msg_type, msg_len, msg_tlen, hello_len, prefix;
     u_int8_t link_type, neighbor_type;
     const u_char *tptr, *msg_data;
 
@@ -213,52 +273,99 @@ olsr_print (const u_char *pptr, u_int length)
         msg_data = tptr + sizeof(struct olsr_msg);
 
         switch (msg_type) {
+        case OLSR_HELLO_MSG:
         case OLSR_HELLO_LQ_MSG:
-            ptr.hello_lq = (struct olsr_hello_lq *)msg_data;
+            if (!TTEST2(*msg_data, sizeof(struct olsr_hello))) 
+                goto trunc;
+
+            ptr.hello = (struct olsr_hello *)msg_data;
             printf("\n\t  hello-time %.3lfs, MPR willingness %u",
-                   ME_TO_DOUBLE(ptr.hello_lq->htime),
-                   ptr.hello_lq->will);
-            msg_data += sizeof(struct olsr_hello_lq);
-            msg_tlen -= sizeof(struct olsr_hello_lq);
+                   ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will);
+            msg_data += sizeof(struct olsr_hello);
+            msg_tlen -= sizeof(struct olsr_hello);
 
-            while (msg_tlen >= sizeof(struct olsr_hello_lq_link)) {
+            while (msg_tlen >= sizeof(struct olsr_hello_link)) {
 
                 /*
                  * link-type.
                  */
-                ptr.hello_lq_link = (struct olsr_hello_lq_link *)msg_data;
+                if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link)))        
+                    goto trunc;
+
+                ptr.hello_link = (struct olsr_hello_link *)msg_data;
 
-                hello_len = EXTRACT_16BITS(ptr.hello_lq_link->len);
-                link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_lq_link->link_code);
-                neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_lq_link->link_code);
+                hello_len = EXTRACT_16BITS(ptr.hello_link->len);
+                link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code);
+                neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code);
 
                 printf("\n\t    link-type %s, neighbor-type %s, len %u",
                        tok2str(olsr_link_type_values, "Unknown", link_type),
                        tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type),
                        hello_len);
 
-                msg_data += sizeof(struct olsr_hello_lq_link);
-                msg_tlen -= sizeof(struct olsr_hello_lq_link);
+                msg_data += sizeof(struct olsr_hello_link);
+                msg_tlen -= sizeof(struct olsr_hello_link);
+                hello_len -= sizeof(struct olsr_hello_link);
 
-                hello_len -= sizeof(struct olsr_hello_lq_link);
-                while (hello_len >= sizeof(struct olsr_hello_lq_neighbor)) {
+                if (msg_type == OLSR_HELLO_MSG) {
+                    olsr_print_neighbor(msg_data, hello_len);
+                } else {
+                    olsr_print_lq_neighbor(msg_data, hello_len);
+                }
+
+                msg_data += hello_len;
+                msg_tlen -= hello_len;
+            }
+            break;
 
-                    /*
-                     * neighbor.
-                     */
-                    ptr.hello_lq_neighbor =
-                        (struct olsr_hello_lq_neighbor *)msg_data;
+        case OLSR_TC_MSG:
+        case OLSR_TC_LQ_MSG:
+            if (!TTEST2(*msg_data, sizeof(struct olsr_tc)))    
+                goto trunc;
+
+            ptr.tc = (struct olsr_tc *)msg_data;
+            printf("\n\t    advertised neighbor seq 0x%04x",
+                   EXTRACT_16BITS(ptr.tc->ans_seq));
+            msg_data += sizeof(struct olsr_tc);
+            msg_tlen -= sizeof(struct olsr_tc);
+
+            if (msg_type == OLSR_TC_MSG) {
+                olsr_print_neighbor(msg_data, msg_tlen);
+            } else {
+                olsr_print_lq_neighbor(msg_data, msg_tlen);
+            }
+            break;
 
-                    printf("\n\t      neighbor %s, link-quality %.2lf%%"
-                           ", neighbor-link-quality %.2lf%%",
-                           ipaddr_string(ptr.hello_lq_neighbor->neighbor),
-                           ((double)ptr.hello_lq_neighbor->link_quality/2.55),
-                           ((double)ptr.hello_lq_neighbor->neighbor_link_quality/2.55));
+        case OLSR_MID_MSG:
+            if (!TTEST2(*msg_data, sizeof(struct in_addr)))    
+                goto trunc;
 
-                    msg_data += sizeof(struct olsr_hello_lq_neighbor);
-                    msg_tlen -= sizeof(struct olsr_hello_lq_neighbor);                
-                    hello_len -= sizeof(struct olsr_hello_lq_neighbor);
-                }
+            while (msg_tlen >= sizeof(struct in_addr)) {
+                printf("\n\t  interface address %s", ipaddr_string(msg_data));
+                msg_data += sizeof(struct in_addr);
+                msg_tlen -= sizeof(struct in_addr);
+            }
+            break;
+
+        case OLSR_HNA_MSG:
+            prefix = 1;
+            printf("\n\t  advertised networks\n\t    ");
+            while (msg_tlen >= sizeof(struct olsr_hna)) {
+                if (!TTEST2(*msg_data, sizeof(struct olsr_hna)))       
+                    goto trunc;
+
+                ptr.hna = (struct olsr_hna *)msg_data;
+
+                /* print 4 prefixes per line */
+
+                printf("%s/%u%s",
+                       ipaddr_string(ptr.hna->network),
+                       mask2plen(EXTRACT_32BITS(ptr.hna->mask)),                       
+                       prefix % 4 == 0 ? "\n\t    " : " ");
+
+                msg_data += sizeof(struct olsr_hna);
+                msg_tlen -= sizeof(struct olsr_hna);
+                prefix ++;
             }
             break;
 
@@ -267,13 +374,8 @@ olsr_print (const u_char *pptr, u_int length)
              * you are welcome to contribute code ;-)
              */
 
-        case OLSR_HELLO_MSG:
-        case OLSR_TC_MSG:
-        case OLSR_MID_MSG:
-        case OLSR_HNA_MSG:
         case OLSR_POWERINFO_MSG:
         case OLSR_NAMESERVICE_MSG:
-        case OLSR_TC_LQ_MSG:
         default:
            print_unknown_data(msg_data, "\n\t    ", msg_tlen);
             break;