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 * 16b5bfcb5dSMax Laier * Original code by Hannes Gredler <hannes@juniper.net> 1727df3f5dSRui Paulo * IPv6 additions by Florian Forster <octo at verplant.org> 18b5bfcb5dSMax Laier */ 19b5bfcb5dSMax Laier 20*3340d773SGleb Smirnoff /* \summary: Optimized Link State Routing Protocol (OLSR) printer */ 21*3340d773SGleb Smirnoff 22*3340d773SGleb Smirnoff /* specification: RFC 3626 */ 23*3340d773SGleb Smirnoff 24b5bfcb5dSMax Laier #ifdef HAVE_CONFIG_H 25b5bfcb5dSMax Laier #include "config.h" 26b5bfcb5dSMax Laier #endif 27b5bfcb5dSMax Laier 28*3340d773SGleb Smirnoff #include <netdissect-stdinc.h> 29b5bfcb5dSMax Laier 30*3340d773SGleb 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 139*3340d773SGleb Smirnoff /** gateway HNA flags */ 140*3340d773SGleb Smirnoff enum gateway_hna_flags { 141*3340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED = 1 << 0, 142*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV4 = 1 << 1, 143*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT = 1 << 2, 144*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV6 = 1 << 3, 145*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX = 1 << 4 146*3340d773SGleb Smirnoff }; 147*3340d773SGleb Smirnoff 148*3340d773SGleb Smirnoff /** gateway HNA field byte offsets in the netmask field of the HNA */ 149*3340d773SGleb Smirnoff enum gateway_hna_fields { 150*3340d773SGleb Smirnoff GW_HNA_PAD = 0, 151*3340d773SGleb Smirnoff GW_HNA_FLAGS = 1, 152*3340d773SGleb Smirnoff GW_HNA_UPLINK = 2, 153*3340d773SGleb Smirnoff GW_HNA_DOWNLINK = 3, 154*3340d773SGleb Smirnoff GW_HNA_V6PREFIXLEN = 4, 155*3340d773SGleb Smirnoff GW_HNA_V6PREFIX = 5 156*3340d773SGleb Smirnoff }; 157*3340d773SGleb Smirnoff 158*3340d773SGleb 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 191*3340d773SGleb Smirnoff #define MAX_SMARTGW_SPEED 320000000 192*3340d773SGleb Smirnoff 193*3340d773SGleb Smirnoff /** 194*3340d773SGleb Smirnoff * Convert an encoded 1 byte transport value (5 bits mantissa, 3 bits exponent) 195*3340d773SGleb Smirnoff * to an uplink/downlink speed value 196*3340d773SGleb Smirnoff * 197*3340d773SGleb Smirnoff * @param value the encoded 1 byte transport value 198*3340d773SGleb Smirnoff * @return the uplink/downlink speed value (in kbit/s) 199*3340d773SGleb Smirnoff */ 200*3340d773SGleb Smirnoff static uint32_t deserialize_gw_speed(uint8_t value) { 201*3340d773SGleb Smirnoff uint32_t speed; 202*3340d773SGleb Smirnoff uint32_t exp; 203*3340d773SGleb Smirnoff 204*3340d773SGleb Smirnoff if (!value) { 205*3340d773SGleb Smirnoff return 0; 206*3340d773SGleb Smirnoff } 207*3340d773SGleb Smirnoff 208*3340d773SGleb Smirnoff if (value == UINT8_MAX) { 209*3340d773SGleb Smirnoff /* maximum value: also return maximum value */ 210*3340d773SGleb Smirnoff return MAX_SMARTGW_SPEED; 211*3340d773SGleb Smirnoff } 212*3340d773SGleb Smirnoff 213*3340d773SGleb Smirnoff speed = (value >> 3) + 1; 214*3340d773SGleb Smirnoff exp = value & 7; 215*3340d773SGleb Smirnoff 216*3340d773SGleb Smirnoff while (exp-- > 0) { 217*3340d773SGleb Smirnoff speed *= 10; 218*3340d773SGleb Smirnoff } 219*3340d773SGleb Smirnoff return speed; 220*3340d773SGleb Smirnoff } 221*3340d773SGleb 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 { 237*3340d773SGleb Smirnoff const struct olsr_lq_neighbor4 *lq_neighbor; 238b5bfcb5dSMax Laier 23927df3f5dSRui Paulo while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { 240b5bfcb5dSMax Laier 241*3340d773SGleb Smirnoff lq_neighbor = (const struct olsr_lq_neighbor4 *)msg_data; 2428bdc5a62SPatrick Kelsey if (!ND_TTEST(*lq_neighbor)) 2438bdc5a62SPatrick Kelsey return (-1); 244b5bfcb5dSMax Laier 245*3340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" 246*3340d773SGleb 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 { 261*3340d773SGleb Smirnoff const struct olsr_lq_neighbor6 *lq_neighbor; 26227df3f5dSRui Paulo 26327df3f5dSRui Paulo while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { 26427df3f5dSRui Paulo 265*3340d773SGleb Smirnoff lq_neighbor = (const struct olsr_lq_neighbor6 *)msg_data; 2668bdc5a62SPatrick Kelsey if (!ND_TTEST(*lq_neighbor)) 2678bdc5a62SPatrick Kelsey return (-1); 26827df3f5dSRui Paulo 269*3340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2f%%" 270*3340d773SGleb 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 337*3340d773SGleb 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 { 357*3340d773SGleb Smirnoff const struct olsr_msg4 *v4; 358*3340d773SGleb Smirnoff const struct olsr_msg6 *v6; 35927df3f5dSRui Paulo } msgptr; 36027df3f5dSRui Paulo int msg_len_valid = 0; 361b5bfcb5dSMax Laier 3623c602fabSXin LI ND_TCHECK2(*tptr, sizeof(struct olsr_msg4)); 363b5bfcb5dSMax Laier 36427df3f5dSRui Paulo if (is_ipv6) 36527df3f5dSRui Paulo { 366*3340d773SGleb Smirnoff msgptr.v6 = (const struct olsr_msg6 *) tptr; 36727df3f5dSRui Paulo msg_type = msgptr.v6->msg_type; 36827df3f5dSRui Paulo msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); 36927df3f5dSRui Paulo if ((msg_len >= sizeof (struct olsr_msg6)) 37027df3f5dSRui Paulo && (msg_len <= length)) 37127df3f5dSRui Paulo msg_len_valid = 1; 372b5bfcb5dSMax Laier 373b5bfcb5dSMax Laier /* infinite loop check */ 374b5bfcb5dSMax Laier if (msg_type == 0 || msg_len == 0) { 375b5bfcb5dSMax Laier return; 376b5bfcb5dSMax Laier } 377b5bfcb5dSMax Laier 3783c602fabSXin LI ND_PRINT((ndo, "\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" 379*3340d773SGleb Smirnoff "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s", 380b5bfcb5dSMax Laier tok2str(olsr_msg_values, "Unknown", msg_type), 3813c602fabSXin LI msg_type, ip6addr_string(ndo, msgptr.v6->originator), 38227df3f5dSRui Paulo msgptr.v6->ttl, 38327df3f5dSRui Paulo msgptr.v6->hopcount, 38427df3f5dSRui Paulo ME_TO_DOUBLE(msgptr.v6->vtime), 38527df3f5dSRui Paulo EXTRACT_16BITS(msgptr.v6->msg_seq), 3863c602fabSXin LI msg_len, (msg_len_valid == 0) ? " (invalid)" : "")); 3878bdc5a62SPatrick Kelsey if (!msg_len_valid) { 3888bdc5a62SPatrick Kelsey return; 3898bdc5a62SPatrick Kelsey } 390b5bfcb5dSMax Laier 39127df3f5dSRui Paulo msg_tlen = msg_len - sizeof(struct olsr_msg6); 39227df3f5dSRui Paulo msg_data = tptr + sizeof(struct olsr_msg6); 39327df3f5dSRui Paulo } 39427df3f5dSRui Paulo else /* (!is_ipv6) */ 39527df3f5dSRui Paulo { 396*3340d773SGleb 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" 409*3340d773SGleb 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 432*3340d773SGleb Smirnoff ptr.hello = (const struct olsr_hello *)msg_data; 433*3340d773SGleb 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 446*3340d773SGleb 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; 477*3340d773SGleb 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 494*3340d773SGleb 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; 507*3340d773SGleb 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; 537*3340d773SGleb Smirnoff 538*3340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t Advertised networks (total %u)", 539*3340d773SGleb Smirnoff (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)))); 540*3340d773SGleb Smirnoff 54127df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna6)) { 542*3340d773SGleb Smirnoff const struct olsr_hna6 *hna6; 54327df3f5dSRui Paulo 5443c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hna6)); 545b5bfcb5dSMax Laier 546*3340d773SGleb 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; 559*3340d773SGleb Smirnoff 560*3340d773SGleb Smirnoff ND_PRINT((ndo, "\n\t Advertised networks (total %u)", 561*3340d773SGleb Smirnoff (unsigned int) (msg_tlen / sizeof(struct olsr_hna4)))); 562*3340d773SGleb Smirnoff 56327df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna4)) { 5643c602fabSXin LI ND_TCHECK2(*msg_data, sizeof(struct olsr_hna4)); 56527df3f5dSRui Paulo 566*3340d773SGleb Smirnoff ptr.hna = (const struct olsr_hna4 *)msg_data; 567b5bfcb5dSMax Laier 568b5bfcb5dSMax Laier /* print 4 prefixes per line */ 569*3340d773SGleb Smirnoff if (!ptr.hna->network[0] && !ptr.hna->network[1] && 570*3340d773SGleb Smirnoff !ptr.hna->network[2] && !ptr.hna->network[3] && 571*3340d773SGleb Smirnoff !ptr.hna->mask[GW_HNA_PAD] && 572*3340d773SGleb Smirnoff ptr.hna->mask[GW_HNA_FLAGS]) { 573*3340d773SGleb Smirnoff /* smart gateway */ 574*3340d773SGleb Smirnoff ND_PRINT((ndo, "%sSmart-Gateway:%s%s%s%s%s %u/%u", 575*3340d773SGleb Smirnoff col == 0 ? "\n\t " : ", ", /* indent */ 576*3340d773SGleb Smirnoff /* sgw */ 577*3340d773SGleb Smirnoff /* LINKSPEED */ 578*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 579*3340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? " LINKSPEED" : "", 580*3340d773SGleb Smirnoff /* IPV4 */ 581*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 582*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV4) ? " IPV4" : "", 583*3340d773SGleb Smirnoff /* IPV4-NAT */ 584*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 585*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT) ? " IPV4-NAT" : "", 586*3340d773SGleb Smirnoff /* IPV6 */ 587*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 588*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV6) ? " IPV6" : "", 589*3340d773SGleb Smirnoff /* IPv6PREFIX */ 590*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 591*3340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX) ? " IPv6-PREFIX" : "", 592*3340d773SGleb Smirnoff /* uplink */ 593*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 594*3340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? 595*3340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_UPLINK]) : 0, 596*3340d773SGleb Smirnoff /* downlink */ 597*3340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] & 598*3340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? 599*3340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_DOWNLINK]) : 0 600*3340d773SGleb Smirnoff )); 601*3340d773SGleb Smirnoff } else { 602*3340d773SGleb 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)))); 607*3340d773SGleb 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 { 61927df3f5dSRui Paulo u_int name_entries = EXTRACT_16BITS(msg_data+2); 62027df3f5dSRui Paulo u_int addr_size = 4; 62127df3f5dSRui Paulo int name_entries_valid = 0; 62227df3f5dSRui Paulo u_int i; 62327df3f5dSRui Paulo 62427df3f5dSRui Paulo if (is_ipv6) 62527df3f5dSRui Paulo addr_size = 16; 62627df3f5dSRui Paulo 62727df3f5dSRui Paulo if ((name_entries > 0) 62827df3f5dSRui Paulo && ((name_entries * (4 + addr_size)) <= msg_tlen)) 62927df3f5dSRui Paulo name_entries_valid = 1; 63027df3f5dSRui Paulo 63127df3f5dSRui Paulo if (msg_tlen < 4) 63227df3f5dSRui Paulo goto trunc; 6333c602fabSXin LI ND_TCHECK2(*msg_data, 4); 63427df3f5dSRui Paulo 6353c602fabSXin LI ND_PRINT((ndo, "\n\t Version %u, Entries %u%s", 63627df3f5dSRui Paulo EXTRACT_16BITS(msg_data), 6373c602fabSXin LI name_entries, (name_entries_valid == 0) ? " (invalid)" : "")); 63827df3f5dSRui Paulo 63927df3f5dSRui Paulo if (name_entries_valid == 0) 64027df3f5dSRui Paulo break; 64127df3f5dSRui Paulo 64227df3f5dSRui Paulo msg_data += 4; 64327df3f5dSRui Paulo msg_tlen -= 4; 64427df3f5dSRui Paulo 64527df3f5dSRui Paulo for (i = 0; i < name_entries; i++) { 64627df3f5dSRui Paulo int name_entry_len_valid = 0; 64727df3f5dSRui Paulo 64827df3f5dSRui Paulo if (msg_tlen < 4) 64927df3f5dSRui Paulo break; 6503c602fabSXin LI ND_TCHECK2(*msg_data, 4); 65127df3f5dSRui Paulo 65227df3f5dSRui Paulo name_entry_type = EXTRACT_16BITS(msg_data); 65327df3f5dSRui Paulo name_entry_len = EXTRACT_16BITS(msg_data+2); 65427df3f5dSRui Paulo 65527df3f5dSRui Paulo msg_data += 4; 65627df3f5dSRui Paulo msg_tlen -= 4; 65727df3f5dSRui Paulo 65827df3f5dSRui Paulo if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) 65927df3f5dSRui Paulo name_entry_len_valid = 1; 66027df3f5dSRui Paulo 6613c602fabSXin LI ND_PRINT((ndo, "\n\t #%u: type %#06x, length %u%s", 66227df3f5dSRui Paulo (unsigned int) i, name_entry_type, 6633c602fabSXin LI name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "")); 66427df3f5dSRui Paulo 66527df3f5dSRui Paulo if (name_entry_len_valid == 0) 66627df3f5dSRui Paulo break; 66727df3f5dSRui Paulo 66827df3f5dSRui Paulo /* 32-bit alignment */ 66927df3f5dSRui Paulo name_entry_padding = 0; 67027df3f5dSRui Paulo if (name_entry_len%4 != 0) 67127df3f5dSRui Paulo name_entry_padding = 4-(name_entry_len%4); 67227df3f5dSRui Paulo 67327df3f5dSRui Paulo if (msg_tlen < addr_size + name_entry_len + name_entry_padding) 67427df3f5dSRui Paulo goto trunc; 67527df3f5dSRui Paulo 6763c602fabSXin LI ND_TCHECK2(*msg_data, addr_size + name_entry_len + name_entry_padding); 67727df3f5dSRui Paulo 67827df3f5dSRui Paulo if (is_ipv6) 6793c602fabSXin LI ND_PRINT((ndo, ", address %s, name \"", 6803c602fabSXin LI ip6addr_string(ndo, msg_data))); 68127df3f5dSRui Paulo else 6823c602fabSXin LI ND_PRINT((ndo, ", address %s, name \"", 6833c602fabSXin LI ipaddr_string(ndo, msg_data))); 6848bdc5a62SPatrick Kelsey (void)fn_printn(ndo, msg_data + addr_size, name_entry_len, NULL); 6853c602fabSXin LI ND_PRINT((ndo, "\"")); 68627df3f5dSRui Paulo 68727df3f5dSRui Paulo msg_data += addr_size + name_entry_len + name_entry_padding; 68827df3f5dSRui Paulo msg_tlen -= addr_size + name_entry_len + name_entry_padding; 68927df3f5dSRui Paulo } /* for (i = 0; i < name_entries; i++) */ 69027df3f5dSRui Paulo break; 69127df3f5dSRui Paulo } /* case OLSR_NAMESERVICE_MSG */ 69227df3f5dSRui Paulo 693b5bfcb5dSMax Laier /* 694b5bfcb5dSMax Laier * FIXME those are the defined messages that lack a decoder 695b5bfcb5dSMax Laier * you are welcome to contribute code ;-) 696b5bfcb5dSMax Laier */ 697b5bfcb5dSMax Laier case OLSR_POWERINFO_MSG: 698b5bfcb5dSMax Laier default: 6993c602fabSXin LI print_unknown_data(ndo, msg_data, "\n\t ", msg_tlen); 700b5bfcb5dSMax Laier break; 70127df3f5dSRui Paulo } /* switch (msg_type) */ 702b5bfcb5dSMax Laier tptr += msg_len; 70327df3f5dSRui Paulo } /* while (tptr < (pptr+length)) */ 704b5bfcb5dSMax Laier 705b5bfcb5dSMax Laier return; 706b5bfcb5dSMax Laier 707b5bfcb5dSMax Laier trunc: 7083c602fabSXin LI ND_PRINT((ndo, "[|olsr]")); 709b5bfcb5dSMax Laier } 710b5bfcb5dSMax Laier 711b5bfcb5dSMax Laier /* 712b5bfcb5dSMax Laier * Local Variables: 713b5bfcb5dSMax Laier * c-style: whitesmith 714b5bfcb5dSMax Laier * c-basic-offset: 4 715b5bfcb5dSMax Laier * End: 716b5bfcb5dSMax Laier */ 717