1b5bfcb5dSMax Laier /* 2b5bfcb5dSMax Laier * Copyright (c) 1998-2007 The TCPDUMP project 327df3f5dSRui Paulo * Copyright (c) 2009 Florian Forster 4b5bfcb5dSMax Laier * 5b5bfcb5dSMax Laier * Redistribution and use in source and binary forms, with or without 6b5bfcb5dSMax Laier * modification, are permitted provided that: (1) source code 7b5bfcb5dSMax Laier * distributions retain the above copyright notice and this paragraph 8b5bfcb5dSMax Laier * in its entirety, and (2) distributions including binary code include 9b5bfcb5dSMax Laier * the above copyright notice and this paragraph in its entirety in 10b5bfcb5dSMax Laier * the documentation or other materials provided with the distribution. 11b5bfcb5dSMax Laier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 12b5bfcb5dSMax Laier * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 13b5bfcb5dSMax Laier * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14b5bfcb5dSMax Laier * FOR A PARTICULAR PURPOSE. 15b5bfcb5dSMax Laier * 16*0bff6a5aSEd Maste * Original code by Hannes Gredler <hannes@gredler.at> 1727df3f5dSRui Paulo * IPv6 additions by Florian Forster <octo at verplant.org> 18b5bfcb5dSMax Laier */ 19b5bfcb5dSMax Laier 203340d773SGleb Smirnoff /* \summary: Optimized Link State Routing Protocol (OLSR) printer */ 213340d773SGleb Smirnoff 223340d773SGleb Smirnoff /* specification: RFC 3626 */ 233340d773SGleb Smirnoff 24b5bfcb5dSMax Laier #ifdef HAVE_CONFIG_H 25b5bfcb5dSMax Laier #include "config.h" 26b5bfcb5dSMax Laier #endif 27b5bfcb5dSMax Laier 283340d773SGleb Smirnoff #include <netdissect-stdinc.h> 29b5bfcb5dSMax Laier 303340d773SGleb Smirnoff #include "netdissect.h" 31b5bfcb5dSMax Laier #include "addrtoname.h" 32b5bfcb5dSMax Laier #include "extract.h" 33b5bfcb5dSMax Laier 34b5bfcb5dSMax Laier /* 35b5bfcb5dSMax Laier * RFC 3626 common header 36b5bfcb5dSMax Laier * 37b5bfcb5dSMax Laier * 0 1 2 3 38b5bfcb5dSMax Laier * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 39b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 40b5bfcb5dSMax Laier * | Packet Length | Packet Sequence Number | 41b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 42b5bfcb5dSMax Laier * | Message Type | Vtime | Message Size | 43b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 44b5bfcb5dSMax Laier * | Originator Address | 45b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46b5bfcb5dSMax Laier * | Time To Live | Hop Count | Message Sequence Number | 47b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48b5bfcb5dSMax Laier * | | 49b5bfcb5dSMax Laier * : MESSAGE : 50b5bfcb5dSMax Laier * | | 51b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 52b5bfcb5dSMax Laier * | Message Type | Vtime | Message Size | 53b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 54b5bfcb5dSMax Laier * | Originator Address | 55b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 56b5bfcb5dSMax Laier * | Time To Live | Hop Count | Message Sequence Number | 57b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 58b5bfcb5dSMax Laier * | | 59b5bfcb5dSMax Laier * : MESSAGE : 60b5bfcb5dSMax Laier * | | 61b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 62b5bfcb5dSMax Laier * : : 63b5bfcb5dSMax Laier */ 64b5bfcb5dSMax Laier 65b5bfcb5dSMax Laier struct olsr_common { 663c602fabSXin LI uint8_t packet_len[2]; 673c602fabSXin LI uint8_t packet_seq[2]; 68b5bfcb5dSMax Laier }; 69b5bfcb5dSMax Laier 70b5bfcb5dSMax Laier #define OLSR_HELLO_MSG 1 /* rfc3626 */ 71b5bfcb5dSMax Laier #define OLSR_TC_MSG 2 /* rfc3626 */ 72b5bfcb5dSMax Laier #define OLSR_MID_MSG 3 /* rfc3626 */ 73b5bfcb5dSMax Laier #define OLSR_HNA_MSG 4 /* rfc3626 */ 74b5bfcb5dSMax Laier #define OLSR_POWERINFO_MSG 128 75b5bfcb5dSMax Laier #define OLSR_NAMESERVICE_MSG 130 76b5bfcb5dSMax Laier #define OLSR_HELLO_LQ_MSG 201 /* LQ extensions olsr.org */ 77b5bfcb5dSMax Laier #define OLSR_TC_LQ_MSG 202 /* LQ extensions olsr.org */ 78b5bfcb5dSMax Laier 793c602fabSXin LI static const struct tok olsr_msg_values[] = { 80b5bfcb5dSMax Laier { OLSR_HELLO_MSG, "Hello" }, 81b5bfcb5dSMax Laier { OLSR_TC_MSG, "TC" }, 82b5bfcb5dSMax Laier { OLSR_MID_MSG, "MID" }, 83b5bfcb5dSMax Laier { OLSR_HNA_MSG, "HNA" }, 84b5bfcb5dSMax Laier { OLSR_POWERINFO_MSG, "Powerinfo" }, 85b5bfcb5dSMax Laier { OLSR_NAMESERVICE_MSG, "Nameservice" }, 86b5bfcb5dSMax Laier { OLSR_HELLO_LQ_MSG, "Hello-LQ" }, 87b5bfcb5dSMax Laier { OLSR_TC_LQ_MSG, "TC-LQ" }, 88b5bfcb5dSMax Laier { 0, NULL} 89b5bfcb5dSMax Laier }; 90b5bfcb5dSMax Laier 9127df3f5dSRui Paulo struct olsr_msg4 { 923c602fabSXin LI uint8_t msg_type; 933c602fabSXin LI uint8_t vtime; 943c602fabSXin LI uint8_t msg_len[2]; 953c602fabSXin LI uint8_t originator[4]; 963c602fabSXin LI uint8_t ttl; 973c602fabSXin LI uint8_t hopcount; 983c602fabSXin LI uint8_t msg_seq[2]; 99b5bfcb5dSMax Laier }; 100b5bfcb5dSMax Laier 10127df3f5dSRui Paulo struct olsr_msg6 { 1023c602fabSXin LI uint8_t msg_type; 1033c602fabSXin LI uint8_t vtime; 1043c602fabSXin LI uint8_t msg_len[2]; 1053c602fabSXin LI uint8_t originator[16]; 1063c602fabSXin LI uint8_t ttl; 1073c602fabSXin LI uint8_t hopcount; 1083c602fabSXin LI uint8_t msg_seq[2]; 10927df3f5dSRui Paulo }; 11027df3f5dSRui Paulo 111b5bfcb5dSMax Laier struct olsr_hello { 1123c602fabSXin LI uint8_t res[2]; 1133c602fabSXin LI uint8_t htime; 1143c602fabSXin LI uint8_t will; 115b5bfcb5dSMax Laier }; 116b5bfcb5dSMax Laier 117b5bfcb5dSMax Laier struct olsr_hello_link { 1183c602fabSXin LI uint8_t link_code; 1193c602fabSXin LI uint8_t res; 1203c602fabSXin LI uint8_t len[2]; 121b5bfcb5dSMax Laier }; 122b5bfcb5dSMax Laier 123b5bfcb5dSMax Laier struct olsr_tc { 1243c602fabSXin LI uint8_t ans_seq[2]; 1253c602fabSXin LI uint8_t res[2]; 126b5bfcb5dSMax Laier }; 127b5bfcb5dSMax Laier 12827df3f5dSRui Paulo struct olsr_hna4 { 1293c602fabSXin LI uint8_t network[4]; 1303c602fabSXin LI uint8_t mask[4]; 131b5bfcb5dSMax Laier }; 132b5bfcb5dSMax Laier 13327df3f5dSRui Paulo struct olsr_hna6 { 1343c602fabSXin LI uint8_t network[16]; 1353c602fabSXin LI uint8_t mask[16]; 13627df3f5dSRui Paulo }; 13727df3f5dSRui Paulo 138b5bfcb5dSMax Laier 1393340d773SGleb Smirnoff /** gateway HNA flags */ 1403340d773SGleb Smirnoff enum gateway_hna_flags { 1413340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED = 1 << 0, 1423340d773SGleb Smirnoff GW_HNA_FLAG_IPV4 = 1 << 1, 1433340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT = 1 << 2, 1443340d773SGleb Smirnoff GW_HNA_FLAG_IPV6 = 1 << 3, 1453340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX = 1 << 4 1463340d773SGleb Smirnoff }; 1473340d773SGleb Smirnoff 1483340d773SGleb Smirnoff /** gateway HNA field byte offsets in the netmask field of the HNA */ 1493340d773SGleb Smirnoff enum gateway_hna_fields { 1503340d773SGleb Smirnoff GW_HNA_PAD = 0, 1513340d773SGleb Smirnoff GW_HNA_FLAGS = 1, 1523340d773SGleb Smirnoff GW_HNA_UPLINK = 2, 1533340d773SGleb Smirnoff GW_HNA_DOWNLINK = 3, 1543340d773SGleb Smirnoff GW_HNA_V6PREFIXLEN = 4, 1553340d773SGleb Smirnoff GW_HNA_V6PREFIX = 5 1563340d773SGleb Smirnoff }; 1573340d773SGleb Smirnoff 1583340d773SGleb Smirnoff 159b5bfcb5dSMax Laier #define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3) 160b5bfcb5dSMax Laier #define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2) 161b5bfcb5dSMax Laier 1623c602fabSXin LI static const struct tok olsr_link_type_values[] = { 163b5bfcb5dSMax Laier { 0, "Unspecified" }, 164b5bfcb5dSMax Laier { 1, "Asymmetric" }, 165b5bfcb5dSMax Laier { 2, "Symmetric" }, 166b5bfcb5dSMax Laier { 3, "Lost" }, 167b5bfcb5dSMax Laier { 0, NULL} 168b5bfcb5dSMax Laier }; 169b5bfcb5dSMax Laier 1703c602fabSXin LI static const struct tok olsr_neighbor_type_values[] = { 171b5bfcb5dSMax Laier { 0, "Not-Neighbor" }, 172b5bfcb5dSMax Laier { 1, "Symmetric" }, 173b5bfcb5dSMax Laier { 2, "Symmetric-MPR" }, 174b5bfcb5dSMax Laier { 0, NULL} 175b5bfcb5dSMax Laier }; 176b5bfcb5dSMax Laier 17727df3f5dSRui Paulo struct olsr_lq_neighbor4 { 1783c602fabSXin LI uint8_t neighbor[4]; 1793c602fabSXin LI uint8_t link_quality; 1803c602fabSXin LI uint8_t neighbor_link_quality; 1813c602fabSXin LI uint8_t res[2]; 182b5bfcb5dSMax Laier }; 183b5bfcb5dSMax Laier 18427df3f5dSRui Paulo struct olsr_lq_neighbor6 { 1853c602fabSXin LI uint8_t neighbor[16]; 1863c602fabSXin LI uint8_t link_quality; 1873c602fabSXin LI uint8_t neighbor_link_quality; 1883c602fabSXin LI uint8_t res[2]; 18927df3f5dSRui Paulo }; 19027df3f5dSRui Paulo 1913340d773SGleb Smirnoff #define MAX_SMARTGW_SPEED 320000000 1923340d773SGleb Smirnoff 1933340d773SGleb Smirnoff /** 1943340d773SGleb Smirnoff * Convert an encoded 1 byte transport value (5 bits mantissa, 3 bits exponent) 1953340d773SGleb Smirnoff * to an uplink/downlink speed value 1963340d773SGleb Smirnoff * 1973340d773SGleb Smirnoff * @param value the encoded 1 byte transport value 1983340d773SGleb Smirnoff * @return the uplink/downlink speed value (in kbit/s) 1993340d773SGleb Smirnoff */ 2003340d773SGleb Smirnoff static uint32_t deserialize_gw_speed(uint8_t value) { 2013340d773SGleb Smirnoff uint32_t speed; 2023340d773SGleb Smirnoff uint32_t exp; 2033340d773SGleb Smirnoff 2043340d773SGleb Smirnoff if (!value) { 2053340d773SGleb Smirnoff return 0; 2063340d773SGleb Smirnoff } 2073340d773SGleb Smirnoff 2083340d773SGleb Smirnoff if (value == UINT8_MAX) { 2093340d773SGleb Smirnoff /* maximum value: also return maximum value */ 2103340d773SGleb Smirnoff return MAX_SMARTGW_SPEED; 2113340d773SGleb Smirnoff } 2123340d773SGleb Smirnoff 2133340d773SGleb Smirnoff speed = (value >> 3) + 1; 2143340d773SGleb Smirnoff exp = value & 7; 2153340d773SGleb Smirnoff 2163340d773SGleb Smirnoff while (exp-- > 0) { 2173340d773SGleb Smirnoff speed *= 10; 2183340d773SGleb Smirnoff } 2193340d773SGleb Smirnoff return speed; 2203340d773SGleb Smirnoff } 2213340d773SGleb Smirnoff 222b5bfcb5dSMax Laier /* 223b5bfcb5dSMax Laier * macro to convert the 8-bit mantissa/exponent to a double float 224b5bfcb5dSMax Laier * taken from olsr.org. 225b5bfcb5dSMax Laier */ 226b5bfcb5dSMax Laier #define VTIME_SCALE_FACTOR 0.0625 227b5bfcb5dSMax Laier #define ME_TO_DOUBLE(me) \ 228b5bfcb5dSMax Laier (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F))) 229b5bfcb5dSMax Laier 230b5bfcb5dSMax Laier /* 231b5bfcb5dSMax Laier * print a neighbor list with LQ extensions. 232b5bfcb5dSMax Laier */ 2338bdc5a62SPatrick Kelsey static int 2343c602fabSXin LI olsr_print_lq_neighbor4(netdissect_options *ndo, 2353c602fabSXin LI const u_char *msg_data, u_int hello_len) 236b5bfcb5dSMax Laier { 2373340d773SGleb Smirnoff const struct olsr_lq_neighbor4 *lq_neighbor; 238b5bfcb5dSMax Laier 23927df3f5dSRui Paulo while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { 240b5bfcb5dSMax Laier 2413340d773SGleb Smirnoff lq_neighbor = (const struct olsr_lq_neighbor4 *)msg_data; 2428bdc5a62SPatrick Kelsey if (!ND_TTEST(*lq_neighbor)) 2438bdc5a62SPatrick Kelsey return (-1); 244b5bfcb5dSMax Laier 2453340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" 2463340d773SGleb Smirnoff ", neighbor-link-quality %.2f%%", 2473c602fabSXin LI ipaddr_string(ndo, lq_neighbor->neighbor), 248b5bfcb5dSMax Laier ((double)lq_neighbor->link_quality/2.55), 2493c602fabSXin LI ((double)lq_neighbor->neighbor_link_quality/2.55))); 250b5bfcb5dSMax Laier 25127df3f5dSRui Paulo msg_data += sizeof(struct olsr_lq_neighbor4); 25227df3f5dSRui Paulo hello_len -= sizeof(struct olsr_lq_neighbor4); 253b5bfcb5dSMax Laier } 2548bdc5a62SPatrick Kelsey return (0); 255b5bfcb5dSMax Laier } 256b5bfcb5dSMax Laier 2578bdc5a62SPatrick Kelsey static int 2583c602fabSXin LI olsr_print_lq_neighbor6(netdissect_options *ndo, 2593c602fabSXin LI const u_char *msg_data, u_int hello_len) 26027df3f5dSRui Paulo { 2613340d773SGleb Smirnoff const struct olsr_lq_neighbor6 *lq_neighbor; 26227df3f5dSRui Paulo 26327df3f5dSRui Paulo while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { 26427df3f5dSRui Paulo 2653340d773SGleb Smirnoff lq_neighbor = (const struct olsr_lq_neighbor6 *)msg_data; 2668bdc5a62SPatrick Kelsey if (!ND_TTEST(*lq_neighbor)) 2678bdc5a62SPatrick Kelsey return (-1); 26827df3f5dSRui Paulo 2693340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" 2703340d773SGleb Smirnoff ", neighbor-link-quality %.2f%%", 2713c602fabSXin LI ip6addr_string(ndo, lq_neighbor->neighbor), 27227df3f5dSRui Paulo ((double)lq_neighbor->link_quality/2.55), 2733c602fabSXin LI ((double)lq_neighbor->neighbor_link_quality/2.55))); 27427df3f5dSRui Paulo 27527df3f5dSRui Paulo msg_data += sizeof(struct olsr_lq_neighbor6); 27627df3f5dSRui Paulo hello_len -= sizeof(struct olsr_lq_neighbor6); 27727df3f5dSRui Paulo } 2788bdc5a62SPatrick Kelsey return (0); 27927df3f5dSRui Paulo } 28027df3f5dSRui Paulo 281b5bfcb5dSMax Laier /* 282b5bfcb5dSMax Laier * print a neighbor list. 283b5bfcb5dSMax Laier */ 2848bdc5a62SPatrick Kelsey static int 2853c602fabSXin LI olsr_print_neighbor(netdissect_options *ndo, 2863c602fabSXin LI const u_char *msg_data, u_int hello_len) 287b5bfcb5dSMax Laier { 288b5bfcb5dSMax Laier int neighbor; 289b5bfcb5dSMax Laier 2903c602fabSXin LI ND_PRINT((ndo, "\n\t neighbor\n\t\t")); 291b5bfcb5dSMax Laier neighbor = 1; 292b5bfcb5dSMax Laier 293b5bfcb5dSMax Laier while (hello_len >= sizeof(struct in_addr)) { 294b5bfcb5dSMax Laier 2958bdc5a62SPatrick Kelsey if (!ND_TTEST2(*msg_data, sizeof(struct in_addr))) 2968bdc5a62SPatrick Kelsey return (-1); 297b5bfcb5dSMax Laier /* print 4 neighbors per line */ 298b5bfcb5dSMax Laier 2993c602fabSXin LI ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data), 3003c602fabSXin LI neighbor % 4 == 0 ? "\n\t\t" : " ")); 301b5bfcb5dSMax Laier 302b5bfcb5dSMax Laier msg_data += sizeof(struct in_addr); 303b5bfcb5dSMax Laier hello_len -= sizeof(struct in_addr); 304b5bfcb5dSMax Laier } 3058bdc5a62SPatrick Kelsey return (0); 306b5bfcb5dSMax Laier } 307b5bfcb5dSMax Laier 308b5bfcb5dSMax Laier 309b5bfcb5dSMax Laier void 3103c602fabSXin LI olsr_print(netdissect_options *ndo, 3113c602fabSXin LI const u_char *pptr, u_int length, int is_ipv6) 312b5bfcb5dSMax Laier { 313b5bfcb5dSMax Laier union { 314b5bfcb5dSMax Laier const struct olsr_common *common; 31527df3f5dSRui Paulo const struct olsr_msg4 *msg4; 31627df3f5dSRui Paulo const struct olsr_msg6 *msg6; 317b5bfcb5dSMax Laier const struct olsr_hello *hello; 318b5bfcb5dSMax Laier const struct olsr_hello_link *hello_link; 319b5bfcb5dSMax Laier const struct olsr_tc *tc; 32027df3f5dSRui Paulo const struct olsr_hna4 *hna; 321b5bfcb5dSMax Laier } ptr; 322b5bfcb5dSMax Laier 32327df3f5dSRui Paulo u_int msg_type, msg_len, msg_tlen, hello_len; 3243c602fabSXin LI uint16_t name_entry_type, name_entry_len; 32527df3f5dSRui Paulo u_int name_entry_padding; 3263c602fabSXin LI uint8_t link_type, neighbor_type; 327b5bfcb5dSMax Laier const u_char *tptr, *msg_data; 328b5bfcb5dSMax Laier 329b5bfcb5dSMax Laier tptr = pptr; 330b5bfcb5dSMax Laier 331b5bfcb5dSMax Laier if (length < sizeof(struct olsr_common)) { 332b5bfcb5dSMax Laier goto trunc; 333b5bfcb5dSMax Laier } 334b5bfcb5dSMax Laier 3353c602fabSXin LI ND_TCHECK2(*tptr, sizeof(struct olsr_common)); 336b5bfcb5dSMax Laier 3373340d773SGleb Smirnoff ptr.common = (const struct olsr_common *)tptr; 3383c602fabSXin LI length = min(length, EXTRACT_16BITS(ptr.common->packet_len)); 339b5bfcb5dSMax Laier 3403c602fabSXin LI ND_PRINT((ndo, "OLSRv%i, seq 0x%04x, length %u", 34127df3f5dSRui Paulo (is_ipv6 == 0) ? 4 : 6, 342b5bfcb5dSMax Laier EXTRACT_16BITS(ptr.common->packet_seq), 3433c602fabSXin LI length)); 344b5bfcb5dSMax Laier 345b5bfcb5dSMax Laier tptr += sizeof(struct olsr_common); 346b5bfcb5dSMax Laier 347b5bfcb5dSMax Laier /* 348b5bfcb5dSMax Laier * In non-verbose mode, just print version. 349b5bfcb5dSMax Laier */ 3503c602fabSXin LI if (ndo->ndo_vflag < 1) { 351b5bfcb5dSMax Laier return; 352b5bfcb5dSMax Laier } 353b5bfcb5dSMax Laier 354b5bfcb5dSMax Laier while (tptr < (pptr+length)) { 35527df3f5dSRui Paulo union 35627df3f5dSRui Paulo { 3573340d773SGleb Smirnoff const struct olsr_msg4 *v4; 3583340d773SGleb Smirnoff const struct olsr_msg6 *v6; 35927df3f5dSRui Paulo } msgptr; 36027df3f5dSRui Paulo int msg_len_valid = 0; 361b5bfcb5dSMax Laier 36227df3f5dSRui Paulo if (is_ipv6) 36327df3f5dSRui Paulo { 364*0bff6a5aSEd Maste ND_TCHECK2(*tptr, sizeof(struct olsr_msg6)); 3653340d773SGleb Smirnoff msgptr.v6 = (const struct olsr_msg6 *) tptr; 36627df3f5dSRui Paulo msg_type = msgptr.v6->msg_type; 36727df3f5dSRui Paulo msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); 36827df3f5dSRui Paulo if ((msg_len >= sizeof (struct olsr_msg6)) 36927df3f5dSRui Paulo && (msg_len <= length)) 37027df3f5dSRui Paulo msg_len_valid = 1; 371b5bfcb5dSMax Laier 372b5bfcb5dSMax Laier /* infinite loop check */ 373b5bfcb5dSMax Laier if (msg_type == 0 || msg_len == 0) { 374b5bfcb5dSMax Laier return; 375b5bfcb5dSMax Laier } 376b5bfcb5dSMax Laier 3773c602fabSXin LI ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" 3783340d773SGleb Smirnoff "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s", 379b5bfcb5dSMax Laier tok2str(olsr_msg_values, "Unknown", msg_type), 3803c602fabSXin LI msg_type, ip6addr_string(ndo, msgptr.v6->originator), 38127df3f5dSRui Paulo msgptr.v6->ttl, 38227df3f5dSRui Paulo msgptr.v6->hopcount, 38327df3f5dSRui Paulo ME_TO_DOUBLE(msgptr.v6->vtime), 38427df3f5dSRui Paulo EXTRACT_16BITS(msgptr.v6->msg_seq), 3853c602fabSXin LI msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); 3868bdc5a62SPatrick Kelsey if (!msg_len_valid) { 3878bdc5a62SPatrick Kelsey return; 3888bdc5a62SPatrick Kelsey } 389b5bfcb5dSMax Laier 39027df3f5dSRui Paulo msg_tlen = msg_len - sizeof(struct olsr_msg6); 39127df3f5dSRui Paulo msg_data = tptr + sizeof(struct olsr_msg6); 39227df3f5dSRui Paulo } 39327df3f5dSRui Paulo else /* (!is_ipv6) */ 39427df3f5dSRui Paulo { 395*0bff6a5aSEd Maste ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); 3963340d773SGleb Smirnoff msgptr.v4 = (const struct olsr_msg4 *) tptr; 39727df3f5dSRui Paulo msg_type = msgptr.v4->msg_type; 39827df3f5dSRui Paulo msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); 39927df3f5dSRui Paulo if ((msg_len >= sizeof (struct olsr_msg4)) 40027df3f5dSRui Paulo && (msg_len <= length)) 40127df3f5dSRui Paulo msg_len_valid = 1; 40227df3f5dSRui Paulo 40327df3f5dSRui Paulo /* infinite loop check */ 40427df3f5dSRui Paulo if (msg_type == 0 || msg_len == 0) { 40527df3f5dSRui Paulo return; 40627df3f5dSRui Paulo } 40727df3f5dSRui Paulo 4083c602fabSXin LI ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" 4093340d773SGleb Smirnoff "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s", 41027df3f5dSRui Paulo tok2str(olsr_msg_values, "Unknown", msg_type), 4113c602fabSXin LI msg_type, ipaddr_string(ndo, msgptr.v4->originator), 41227df3f5dSRui Paulo msgptr.v4->ttl, 41327df3f5dSRui Paulo msgptr.v4->hopcount, 41427df3f5dSRui Paulo ME_TO_DOUBLE(msgptr.v4->vtime), 41527df3f5dSRui Paulo EXTRACT_16BITS(msgptr.v4->msg_seq), 4163c602fabSXin LI msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); 4178bdc5a62SPatrick Kelsey if (!msg_len_valid) { 4188bdc5a62SPatrick Kelsey return; 4198bdc5a62SPatrick Kelsey } 42027df3f5dSRui Paulo 42127df3f5dSRui Paulo msg_tlen = msg_len - sizeof(struct olsr_msg4); 42227df3f5dSRui Paulo msg_data = tptr + sizeof(struct olsr_msg4); 42327df3f5dSRui Paulo } 424b5bfcb5dSMax Laier 425b5bfcb5dSMax Laier switch (msg_type) { 426b5bfcb5dSMax Laier case OLSR_HELLO_MSG: 427b5bfcb5dSMax Laier case OLSR_HELLO_LQ_MSG: 4288bdc5a62SPatrick Kelsey if (msg_tlen < sizeof(struct olsr_hello)) 4298bdc5a62SPatrick Kelsey goto trunc; 4303c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hello)); 431b5bfcb5dSMax Laier 4323340d773SGleb Smirnoff ptr.hello = (const struct olsr_hello *)msg_data; 4333340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t hello-time %.3fs, MPR willingness %u", 4343c602fabSXin LI ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will)); 435b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_hello); 436b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_hello); 437b5bfcb5dSMax Laier 438b5bfcb5dSMax Laier while (msg_tlen >= sizeof(struct olsr_hello_link)) { 43927df3f5dSRui Paulo int hello_len_valid = 0; 440b5bfcb5dSMax Laier 441b5bfcb5dSMax Laier /* 442b5bfcb5dSMax Laier * link-type. 443b5bfcb5dSMax Laier */ 4443c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hello_link)); 445b5bfcb5dSMax Laier 4463340d773SGleb Smirnoff ptr.hello_link = (const struct olsr_hello_link *)msg_data; 447b5bfcb5dSMax Laier 448b5bfcb5dSMax Laier hello_len = EXTRACT_16BITS(ptr.hello_link->len); 449b5bfcb5dSMax Laier link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code); 450b5bfcb5dSMax Laier neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code); 451b5bfcb5dSMax Laier 45227df3f5dSRui Paulo if ((hello_len <= msg_tlen) 45327df3f5dSRui Paulo && (hello_len >= sizeof(struct olsr_hello_link))) 45427df3f5dSRui Paulo hello_len_valid = 1; 45527df3f5dSRui Paulo 4563c602fabSXin LI ND_PRINT((ndo, "\n\t link-type %s, neighbor-type %s, len %u%s", 457b5bfcb5dSMax Laier tok2str(olsr_link_type_values, "Unknown", link_type), 458b5bfcb5dSMax Laier tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type), 45927df3f5dSRui Paulo hello_len, 4603c602fabSXin LI (hello_len_valid == 0) ? " (invalid)" : "")); 46127df3f5dSRui Paulo 46227df3f5dSRui Paulo if (hello_len_valid == 0) 46327df3f5dSRui Paulo break; 464b5bfcb5dSMax Laier 465b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_hello_link); 466b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_hello_link); 467b5bfcb5dSMax Laier hello_len -= sizeof(struct olsr_hello_link); 468b5bfcb5dSMax Laier 4698bdc5a62SPatrick Kelsey ND_TCHECK2(*msg_data, hello_len); 470b5bfcb5dSMax Laier if (msg_type == OLSR_HELLO_MSG) { 4718bdc5a62SPatrick Kelsey if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1) 4728bdc5a62SPatrick Kelsey goto trunc; 473b5bfcb5dSMax Laier } else { 4748bdc5a62SPatrick Kelsey if (is_ipv6) { 4758bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1) 4768bdc5a62SPatrick Kelsey goto trunc; 4773340d773SGleb Smirnoff } else { 4788bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1) 4798bdc5a62SPatrick Kelsey goto trunc; 4808bdc5a62SPatrick Kelsey } 481b5bfcb5dSMax Laier } 482b5bfcb5dSMax Laier 483b5bfcb5dSMax Laier msg_data += hello_len; 484b5bfcb5dSMax Laier msg_tlen -= hello_len; 485b5bfcb5dSMax Laier } 486b5bfcb5dSMax Laier break; 487b5bfcb5dSMax Laier 488b5bfcb5dSMax Laier case OLSR_TC_MSG: 489b5bfcb5dSMax Laier case OLSR_TC_LQ_MSG: 4908bdc5a62SPatrick Kelsey if (msg_tlen < sizeof(struct olsr_tc)) 4918bdc5a62SPatrick Kelsey goto trunc; 4923c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_tc)); 493b5bfcb5dSMax Laier 4943340d773SGleb Smirnoff ptr.tc = (const struct olsr_tc *)msg_data; 4953c602fabSXin LI ND_PRINT((ndo, "\n\t advertised neighbor seq 0x%04x", 4963c602fabSXin LI EXTRACT_16BITS(ptr.tc->ans_seq))); 497b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_tc); 498b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_tc); 499b5bfcb5dSMax Laier 500b5bfcb5dSMax Laier if (msg_type == OLSR_TC_MSG) { 5018bdc5a62SPatrick Kelsey if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1) 5028bdc5a62SPatrick Kelsey goto trunc; 503b5bfcb5dSMax Laier } else { 5048bdc5a62SPatrick Kelsey if (is_ipv6) { 5058bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1) 5068bdc5a62SPatrick Kelsey goto trunc; 5073340d773SGleb Smirnoff } else { 5088bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1) 5098bdc5a62SPatrick Kelsey goto trunc; 5108bdc5a62SPatrick Kelsey } 511b5bfcb5dSMax Laier } 512b5bfcb5dSMax Laier break; 513b5bfcb5dSMax Laier 514b5bfcb5dSMax Laier case OLSR_MID_MSG: 51527df3f5dSRui Paulo { 51627df3f5dSRui Paulo size_t addr_size = sizeof(struct in_addr); 51727df3f5dSRui Paulo 51827df3f5dSRui Paulo if (is_ipv6) 51927df3f5dSRui Paulo addr_size = sizeof(struct in6_addr); 52027df3f5dSRui Paulo 52127df3f5dSRui Paulo while (msg_tlen >= addr_size) { 5223c602fabSXin LI ND_TCHECK2(*msg_data, addr_size); 5233c602fabSXin LI ND_PRINT((ndo, "\n\t interface address %s", 5243c602fabSXin LI is_ipv6 ? ip6addr_string(ndo, msg_data) : 5253c602fabSXin LI ipaddr_string(ndo, msg_data))); 5263c602fabSXin LI 52727df3f5dSRui Paulo msg_data += addr_size; 52827df3f5dSRui Paulo msg_tlen -= addr_size; 529b5bfcb5dSMax Laier } 530b5bfcb5dSMax Laier break; 53127df3f5dSRui Paulo } 532b5bfcb5dSMax Laier 533b5bfcb5dSMax Laier case OLSR_HNA_MSG: 53427df3f5dSRui Paulo if (is_ipv6) 53527df3f5dSRui Paulo { 53627df3f5dSRui Paulo int i = 0; 5373340d773SGleb Smirnoff 5383340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t Advertised networks (total %u)", 5393340d773SGleb Smirnoff (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)))); 5403340d773SGleb Smirnoff 54127df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna6)) { 5423340d773SGleb Smirnoff const struct olsr_hna6 *hna6; 54327df3f5dSRui Paulo 5443c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hna6)); 545b5bfcb5dSMax Laier 5463340d773SGleb Smirnoff hna6 = (const struct olsr_hna6 *)msg_data; 54727df3f5dSRui Paulo 5483c602fabSXin LI ND_PRINT((ndo, "\n\t #%i: %s/%u", 5493c602fabSXin LI i, ip6addr_string(ndo, hna6->network), 5503c602fabSXin LI mask62plen (hna6->mask))); 55127df3f5dSRui Paulo 55227df3f5dSRui Paulo msg_data += sizeof(struct olsr_hna6); 55327df3f5dSRui Paulo msg_tlen -= sizeof(struct olsr_hna6); 55427df3f5dSRui Paulo } 55527df3f5dSRui Paulo } 55627df3f5dSRui Paulo else 55727df3f5dSRui Paulo { 55827df3f5dSRui Paulo int col = 0; 5593340d773SGleb Smirnoff 5603340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t Advertised networks (total %u)", 5613340d773SGleb Smirnoff (unsigned int) (msg_tlen / sizeof(struct olsr_hna4)))); 5623340d773SGleb Smirnoff 56327df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna4)) { 5643c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hna4)); 56527df3f5dSRui Paulo 5663340d773SGleb Smirnoff ptr.hna = (const struct olsr_hna4 *)msg_data; 567b5bfcb5dSMax Laier 568b5bfcb5dSMax Laier /* print 4 prefixes per line */ 5693340d773SGleb Smirnoff if (!ptr.hna->network[0] && !ptr.hna->network[1] && 5703340d773SGleb Smirnoff !ptr.hna->network[2] && !ptr.hna->network[3] && 5713340d773SGleb Smirnoff !ptr.hna->mask[GW_HNA_PAD] && 5723340d773SGleb Smirnoff ptr.hna->mask[GW_HNA_FLAGS]) { 5733340d773SGleb Smirnoff /* smart gateway */ 5743340d773SGleb Smirnoff ND_PRINT((ndo, "%sSmart-Gateway:%s%s%s%s%s %u/%u", 5753340d773SGleb Smirnoff col == 0 ? "\n\t " : ", ", /* indent */ 5763340d773SGleb Smirnoff /* sgw */ 5773340d773SGleb Smirnoff /* LINKSPEED */ 5783340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5793340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? " LINKSPEED" : "", 5803340d773SGleb Smirnoff /* IPV4 */ 5813340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5823340d773SGleb Smirnoff GW_HNA_FLAG_IPV4) ? " IPV4" : "", 5833340d773SGleb Smirnoff /* IPV4-NAT */ 5843340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5853340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT) ? " IPV4-NAT" : "", 5863340d773SGleb Smirnoff /* IPV6 */ 5873340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5883340d773SGleb Smirnoff GW_HNA_FLAG_IPV6) ? " IPV6" : "", 5893340d773SGleb Smirnoff /* IPv6PREFIX */ 5903340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5913340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX) ? " IPv6-PREFIX" : "", 5923340d773SGleb Smirnoff /* uplink */ 5933340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5943340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? 5953340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_UPLINK]) : 0, 5963340d773SGleb Smirnoff /* downlink */ 5973340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 5983340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? 5993340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_DOWNLINK]) : 0 6003340d773SGleb Smirnoff )); 6013340d773SGleb Smirnoff } else { 6023340d773SGleb Smirnoff /* normal route */ 6033c602fabSXin LI ND_PRINT((ndo, "%s%s/%u", 6043c602fabSXin LI col == 0 ? "\n\t " : ", ", 6053c602fabSXin LI ipaddr_string(ndo, ptr.hna->network), 6063c602fabSXin LI mask2plen(EXTRACT_32BITS(ptr.hna->mask)))); 6073340d773SGleb Smirnoff } 608b5bfcb5dSMax Laier 60927df3f5dSRui Paulo msg_data += sizeof(struct olsr_hna4); 61027df3f5dSRui Paulo msg_tlen -= sizeof(struct olsr_hna4); 61127df3f5dSRui Paulo 61227df3f5dSRui Paulo col = (col + 1) % 4; 61327df3f5dSRui Paulo } 614b5bfcb5dSMax Laier } 615b5bfcb5dSMax Laier break; 616b5bfcb5dSMax Laier 61727df3f5dSRui Paulo case OLSR_NAMESERVICE_MSG: 61827df3f5dSRui Paulo { 619*0bff6a5aSEd Maste u_int name_entries; 620*0bff6a5aSEd Maste u_int addr_size; 621*0bff6a5aSEd Maste int name_entries_valid; 62227df3f5dSRui Paulo u_int i; 62327df3f5dSRui Paulo 62427df3f5dSRui Paulo if (msg_tlen < 4) 62527df3f5dSRui Paulo goto trunc; 6263c602fabSXin LI ND_TCHECK2(*msg_data, 4); 62727df3f5dSRui Paulo 628*0bff6a5aSEd Maste name_entries = EXTRACT_16BITS(msg_data+2); 629*0bff6a5aSEd Maste addr_size = 4; 630*0bff6a5aSEd Maste if (is_ipv6) 631*0bff6a5aSEd Maste addr_size = 16; 632*0bff6a5aSEd Maste 633*0bff6a5aSEd Maste name_entries_valid = 0; 634*0bff6a5aSEd Maste if ((name_entries > 0) 635*0bff6a5aSEd Maste && ((name_entries * (4 + addr_size)) <= msg_tlen)) 636*0bff6a5aSEd Maste name_entries_valid = 1; 637*0bff6a5aSEd Maste 6383c602fabSXin LI ND_PRINT((ndo, "\n\t Version %u, Entries %u%s", 63927df3f5dSRui Paulo EXTRACT_16BITS(msg_data), 6403c602fabSXin LI name_entries, (name_entries_valid == 0) ? " (invalid)" : "")); 64127df3f5dSRui Paulo 64227df3f5dSRui Paulo if (name_entries_valid == 0) 64327df3f5dSRui Paulo break; 64427df3f5dSRui Paulo 64527df3f5dSRui Paulo msg_data += 4; 64627df3f5dSRui Paulo msg_tlen -= 4; 64727df3f5dSRui Paulo 64827df3f5dSRui Paulo for (i = 0; i < name_entries; i++) { 64927df3f5dSRui Paulo int name_entry_len_valid = 0; 65027df3f5dSRui Paulo 65127df3f5dSRui Paulo if (msg_tlen < 4) 65227df3f5dSRui Paulo break; 6533c602fabSXin LI ND_TCHECK2(*msg_data, 4); 65427df3f5dSRui Paulo 65527df3f5dSRui Paulo name_entry_type = EXTRACT_16BITS(msg_data); 65627df3f5dSRui Paulo name_entry_len = EXTRACT_16BITS(msg_data+2); 65727df3f5dSRui Paulo 65827df3f5dSRui Paulo msg_data += 4; 65927df3f5dSRui Paulo msg_tlen -= 4; 66027df3f5dSRui Paulo 66127df3f5dSRui Paulo if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) 66227df3f5dSRui Paulo name_entry_len_valid = 1; 66327df3f5dSRui Paulo 6643c602fabSXin LI ND_PRINT((ndo, "\n\t #%u: type %#06x, length %u%s", 66527df3f5dSRui Paulo (unsigned int) i, name_entry_type, 6663c602fabSXin LI name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "")); 66727df3f5dSRui Paulo 66827df3f5dSRui Paulo if (name_entry_len_valid == 0) 66927df3f5dSRui Paulo break; 67027df3f5dSRui Paulo 67127df3f5dSRui Paulo /* 32-bit alignment */ 67227df3f5dSRui Paulo name_entry_padding = 0; 67327df3f5dSRui Paulo if (name_entry_len%4 != 0) 67427df3f5dSRui Paulo name_entry_padding = 4-(name_entry_len%4); 67527df3f5dSRui Paulo 67627df3f5dSRui Paulo if (msg_tlen < addr_size + name_entry_len + name_entry_padding) 67727df3f5dSRui Paulo goto trunc; 67827df3f5dSRui Paulo 6793c602fabSXin LI ND_TCHECK2(*msg_data, addr_size + name_entry_len + name_entry_padding); 68027df3f5dSRui Paulo 68127df3f5dSRui Paulo if (is_ipv6) 6823c602fabSXin LI ND_PRINT((ndo, ", address %s, name \"", 6833c602fabSXin LI ip6addr_string(ndo, msg_data))); 68427df3f5dSRui Paulo else 6853c602fabSXin LI ND_PRINT((ndo, ", address %s, name \"", 6863c602fabSXin LI ipaddr_string(ndo, msg_data))); 6878bdc5a62SPatrick Kelsey (void)fn_printn(ndo, msg_data + addr_size, name_entry_len, NULL); 6883c602fabSXin LI ND_PRINT((ndo, "\"")); 68927df3f5dSRui Paulo 69027df3f5dSRui Paulo msg_data += addr_size + name_entry_len + name_entry_padding; 69127df3f5dSRui Paulo msg_tlen -= addr_size + name_entry_len + name_entry_padding; 69227df3f5dSRui Paulo } /* for (i = 0; i < name_entries; i++) */ 69327df3f5dSRui Paulo break; 69427df3f5dSRui Paulo } /* case OLSR_NAMESERVICE_MSG */ 69527df3f5dSRui Paulo 696b5bfcb5dSMax Laier /* 697b5bfcb5dSMax Laier * FIXME those are the defined messages that lack a decoder 698b5bfcb5dSMax Laier * you are welcome to contribute code ;-) 699b5bfcb5dSMax Laier */ 700b5bfcb5dSMax Laier case OLSR_POWERINFO_MSG: 701b5bfcb5dSMax Laier default: 7023c602fabSXin LI print_unknown_data(ndo, msg_data, "\n\t ", msg_tlen); 703b5bfcb5dSMax Laier break; 70427df3f5dSRui Paulo } /* switch (msg_type) */ 705b5bfcb5dSMax Laier tptr += msg_len; 70627df3f5dSRui Paulo } /* while (tptr < (pptr+length)) */ 707b5bfcb5dSMax Laier 708b5bfcb5dSMax Laier return; 709b5bfcb5dSMax Laier 710b5bfcb5dSMax Laier trunc: 7113c602fabSXin LI ND_PRINT((ndo, "[|olsr]")); 712b5bfcb5dSMax Laier } 713b5bfcb5dSMax Laier 714b5bfcb5dSMax Laier /* 715b5bfcb5dSMax Laier * Local Variables: 716b5bfcb5dSMax Laier * c-style: whitesmith 717b5bfcb5dSMax Laier * c-basic-offset: 4 718b5bfcb5dSMax Laier * End: 719b5bfcb5dSMax Laier */ 720