xref: /freebsd/contrib/tcpdump/print-olsr.c (revision 0bff6a5af8cb6d8e5123f8b667df78cac885dbb7)
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