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 *
160bff6a5aSEd 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
24ee67461eSJoseph Mingrone #include <config.h>
25b5bfcb5dSMax Laier
26ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
27b5bfcb5dSMax Laier
283340d773SGleb Smirnoff #include "netdissect.h"
29b5bfcb5dSMax Laier #include "addrtoname.h"
30b5bfcb5dSMax Laier #include "extract.h"
31b5bfcb5dSMax Laier
32b5bfcb5dSMax Laier /*
33b5bfcb5dSMax Laier * RFC 3626 common header
34b5bfcb5dSMax Laier *
35b5bfcb5dSMax Laier * 0 1 2 3
36b5bfcb5dSMax 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
37b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38b5bfcb5dSMax Laier * | Packet Length | Packet Sequence Number |
39b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40b5bfcb5dSMax Laier * | Message Type | Vtime | Message Size |
41b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42b5bfcb5dSMax Laier * | Originator Address |
43b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44b5bfcb5dSMax Laier * | Time To Live | Hop Count | Message Sequence Number |
45b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46b5bfcb5dSMax Laier * | |
47b5bfcb5dSMax Laier * : MESSAGE :
48b5bfcb5dSMax Laier * | |
49b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50b5bfcb5dSMax Laier * | Message Type | Vtime | Message Size |
51b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52b5bfcb5dSMax Laier * | Originator Address |
53b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54b5bfcb5dSMax Laier * | Time To Live | Hop Count | Message Sequence Number |
55b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56b5bfcb5dSMax Laier * | |
57b5bfcb5dSMax Laier * : MESSAGE :
58b5bfcb5dSMax Laier * | |
59b5bfcb5dSMax Laier * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60b5bfcb5dSMax Laier * : :
61b5bfcb5dSMax Laier */
62b5bfcb5dSMax Laier
63b5bfcb5dSMax Laier struct olsr_common {
64ee67461eSJoseph Mingrone nd_uint16_t packet_len;
65ee67461eSJoseph Mingrone nd_uint16_t packet_seq;
66b5bfcb5dSMax Laier };
67b5bfcb5dSMax Laier
68b5bfcb5dSMax Laier #define OLSR_HELLO_MSG 1 /* rfc3626 */
69b5bfcb5dSMax Laier #define OLSR_TC_MSG 2 /* rfc3626 */
70b5bfcb5dSMax Laier #define OLSR_MID_MSG 3 /* rfc3626 */
71b5bfcb5dSMax Laier #define OLSR_HNA_MSG 4 /* rfc3626 */
72b5bfcb5dSMax Laier #define OLSR_POWERINFO_MSG 128
73b5bfcb5dSMax Laier #define OLSR_NAMESERVICE_MSG 130
74b5bfcb5dSMax Laier #define OLSR_HELLO_LQ_MSG 201 /* LQ extensions olsr.org */
75b5bfcb5dSMax Laier #define OLSR_TC_LQ_MSG 202 /* LQ extensions olsr.org */
76b5bfcb5dSMax Laier
773c602fabSXin LI static const struct tok olsr_msg_values[] = {
78b5bfcb5dSMax Laier { OLSR_HELLO_MSG, "Hello" },
79b5bfcb5dSMax Laier { OLSR_TC_MSG, "TC" },
80b5bfcb5dSMax Laier { OLSR_MID_MSG, "MID" },
81b5bfcb5dSMax Laier { OLSR_HNA_MSG, "HNA" },
82b5bfcb5dSMax Laier { OLSR_POWERINFO_MSG, "Powerinfo" },
83b5bfcb5dSMax Laier { OLSR_NAMESERVICE_MSG, "Nameservice" },
84b5bfcb5dSMax Laier { OLSR_HELLO_LQ_MSG, "Hello-LQ" },
85b5bfcb5dSMax Laier { OLSR_TC_LQ_MSG, "TC-LQ" },
86b5bfcb5dSMax Laier { 0, NULL}
87b5bfcb5dSMax Laier };
88b5bfcb5dSMax Laier
8927df3f5dSRui Paulo struct olsr_msg4 {
90ee67461eSJoseph Mingrone nd_uint8_t msg_type;
91ee67461eSJoseph Mingrone nd_uint8_t vtime;
92ee67461eSJoseph Mingrone nd_uint16_t msg_len;
93ee67461eSJoseph Mingrone nd_ipv4 originator;
94ee67461eSJoseph Mingrone nd_uint8_t ttl;
95ee67461eSJoseph Mingrone nd_uint8_t hopcount;
96ee67461eSJoseph Mingrone nd_uint16_t msg_seq;
97b5bfcb5dSMax Laier };
98b5bfcb5dSMax Laier
9927df3f5dSRui Paulo struct olsr_msg6 {
100ee67461eSJoseph Mingrone nd_uint8_t msg_type;
101ee67461eSJoseph Mingrone nd_uint8_t vtime;
102ee67461eSJoseph Mingrone nd_uint16_t msg_len;
103ee67461eSJoseph Mingrone nd_ipv6 originator;
104ee67461eSJoseph Mingrone nd_uint8_t ttl;
105ee67461eSJoseph Mingrone nd_uint8_t hopcount;
106ee67461eSJoseph Mingrone nd_uint16_t msg_seq;
10727df3f5dSRui Paulo };
10827df3f5dSRui Paulo
109b5bfcb5dSMax Laier struct olsr_hello {
110ee67461eSJoseph Mingrone nd_byte res[2];
111ee67461eSJoseph Mingrone nd_uint8_t htime;
112ee67461eSJoseph Mingrone nd_uint8_t will;
113b5bfcb5dSMax Laier };
114b5bfcb5dSMax Laier
115b5bfcb5dSMax Laier struct olsr_hello_link {
116ee67461eSJoseph Mingrone nd_uint8_t link_code;
117ee67461eSJoseph Mingrone nd_byte res;
118ee67461eSJoseph Mingrone nd_uint16_t len;
119b5bfcb5dSMax Laier };
120b5bfcb5dSMax Laier
121b5bfcb5dSMax Laier struct olsr_tc {
122ee67461eSJoseph Mingrone nd_uint16_t ans_seq;
123ee67461eSJoseph Mingrone nd_byte res[2];
124b5bfcb5dSMax Laier };
125b5bfcb5dSMax Laier
12627df3f5dSRui Paulo struct olsr_hna4 {
127ee67461eSJoseph Mingrone nd_ipv4 network;
128ee67461eSJoseph Mingrone nd_ipv4 mask;
129b5bfcb5dSMax Laier };
130b5bfcb5dSMax Laier
13127df3f5dSRui Paulo struct olsr_hna6 {
132ee67461eSJoseph Mingrone nd_ipv6 network;
133ee67461eSJoseph Mingrone nd_ipv6 mask;
13427df3f5dSRui Paulo };
13527df3f5dSRui Paulo
136b5bfcb5dSMax Laier
1373340d773SGleb Smirnoff /** gateway HNA flags */
1383340d773SGleb Smirnoff enum gateway_hna_flags {
1393340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED = 1 << 0,
1403340d773SGleb Smirnoff GW_HNA_FLAG_IPV4 = 1 << 1,
1413340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT = 1 << 2,
1423340d773SGleb Smirnoff GW_HNA_FLAG_IPV6 = 1 << 3,
1433340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX = 1 << 4
1443340d773SGleb Smirnoff };
1453340d773SGleb Smirnoff
1463340d773SGleb Smirnoff /** gateway HNA field byte offsets in the netmask field of the HNA */
1473340d773SGleb Smirnoff enum gateway_hna_fields {
1483340d773SGleb Smirnoff GW_HNA_PAD = 0,
1493340d773SGleb Smirnoff GW_HNA_FLAGS = 1,
1503340d773SGleb Smirnoff GW_HNA_UPLINK = 2,
1513340d773SGleb Smirnoff GW_HNA_DOWNLINK = 3,
1523340d773SGleb Smirnoff GW_HNA_V6PREFIXLEN = 4,
1533340d773SGleb Smirnoff GW_HNA_V6PREFIX = 5
1543340d773SGleb Smirnoff };
1553340d773SGleb Smirnoff
1563340d773SGleb Smirnoff
157b5bfcb5dSMax Laier #define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3)
158b5bfcb5dSMax Laier #define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2)
159b5bfcb5dSMax Laier
1603c602fabSXin LI static const struct tok olsr_link_type_values[] = {
161b5bfcb5dSMax Laier { 0, "Unspecified" },
162b5bfcb5dSMax Laier { 1, "Asymmetric" },
163b5bfcb5dSMax Laier { 2, "Symmetric" },
164b5bfcb5dSMax Laier { 3, "Lost" },
165b5bfcb5dSMax Laier { 0, NULL}
166b5bfcb5dSMax Laier };
167b5bfcb5dSMax Laier
1683c602fabSXin LI static const struct tok olsr_neighbor_type_values[] = {
169b5bfcb5dSMax Laier { 0, "Not-Neighbor" },
170b5bfcb5dSMax Laier { 1, "Symmetric" },
171b5bfcb5dSMax Laier { 2, "Symmetric-MPR" },
172b5bfcb5dSMax Laier { 0, NULL}
173b5bfcb5dSMax Laier };
174b5bfcb5dSMax Laier
17527df3f5dSRui Paulo struct olsr_lq_neighbor4 {
176ee67461eSJoseph Mingrone nd_ipv4 neighbor;
177ee67461eSJoseph Mingrone nd_uint8_t link_quality;
178ee67461eSJoseph Mingrone nd_uint8_t neighbor_link_quality;
179ee67461eSJoseph Mingrone nd_byte res[2];
180b5bfcb5dSMax Laier };
181b5bfcb5dSMax Laier
18227df3f5dSRui Paulo struct olsr_lq_neighbor6 {
183ee67461eSJoseph Mingrone nd_ipv6 neighbor;
184ee67461eSJoseph Mingrone nd_uint8_t link_quality;
185ee67461eSJoseph Mingrone nd_uint8_t neighbor_link_quality;
186ee67461eSJoseph Mingrone nd_byte res[2];
18727df3f5dSRui Paulo };
18827df3f5dSRui Paulo
1893340d773SGleb Smirnoff #define MAX_SMARTGW_SPEED 320000000
1903340d773SGleb Smirnoff
1913340d773SGleb Smirnoff /**
1923340d773SGleb Smirnoff * Convert an encoded 1 byte transport value (5 bits mantissa, 3 bits exponent)
1933340d773SGleb Smirnoff * to an uplink/downlink speed value
1943340d773SGleb Smirnoff *
1953340d773SGleb Smirnoff * @param value the encoded 1 byte transport value
1963340d773SGleb Smirnoff * @return the uplink/downlink speed value (in kbit/s)
1973340d773SGleb Smirnoff */
deserialize_gw_speed(uint8_t value)1983340d773SGleb Smirnoff static uint32_t deserialize_gw_speed(uint8_t value) {
1993340d773SGleb Smirnoff uint32_t speed;
2003340d773SGleb Smirnoff uint32_t exp;
2013340d773SGleb Smirnoff
2023340d773SGleb Smirnoff if (!value) {
2033340d773SGleb Smirnoff return 0;
2043340d773SGleb Smirnoff }
2053340d773SGleb Smirnoff
2063340d773SGleb Smirnoff if (value == UINT8_MAX) {
2073340d773SGleb Smirnoff /* maximum value: also return maximum value */
2083340d773SGleb Smirnoff return MAX_SMARTGW_SPEED;
2093340d773SGleb Smirnoff }
2103340d773SGleb Smirnoff
2113340d773SGleb Smirnoff speed = (value >> 3) + 1;
2123340d773SGleb Smirnoff exp = value & 7;
2133340d773SGleb Smirnoff
214ee67461eSJoseph Mingrone while (exp != 0) {
2153340d773SGleb Smirnoff speed *= 10;
216ee67461eSJoseph Mingrone exp--;
2173340d773SGleb Smirnoff }
2183340d773SGleb Smirnoff return speed;
2193340d773SGleb Smirnoff }
2203340d773SGleb Smirnoff
221b5bfcb5dSMax Laier /*
222b5bfcb5dSMax Laier * macro to convert the 8-bit mantissa/exponent to a double float
223b5bfcb5dSMax Laier * taken from olsr.org.
224b5bfcb5dSMax Laier */
225b5bfcb5dSMax Laier #define VTIME_SCALE_FACTOR 0.0625
226b5bfcb5dSMax Laier #define ME_TO_DOUBLE(me) \
227b5bfcb5dSMax Laier (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F)))
228b5bfcb5dSMax Laier
229b5bfcb5dSMax Laier /*
230b5bfcb5dSMax Laier * print a neighbor list with LQ extensions.
231b5bfcb5dSMax Laier */
2328bdc5a62SPatrick Kelsey static int
olsr_print_lq_neighbor4(netdissect_options * ndo,const u_char * msg_data,u_int hello_len)2333c602fabSXin LI olsr_print_lq_neighbor4(netdissect_options *ndo,
2343c602fabSXin LI const u_char *msg_data, u_int hello_len)
235b5bfcb5dSMax Laier {
2363340d773SGleb Smirnoff const struct olsr_lq_neighbor4 *lq_neighbor;
237b5bfcb5dSMax Laier
23827df3f5dSRui Paulo while (hello_len >= sizeof(struct olsr_lq_neighbor4)) {
239b5bfcb5dSMax Laier
2403340d773SGleb Smirnoff lq_neighbor = (const struct olsr_lq_neighbor4 *)msg_data;
241ee67461eSJoseph Mingrone ND_TCHECK_SIZE(lq_neighbor);
242b5bfcb5dSMax Laier
243ee67461eSJoseph Mingrone ND_PRINT("\n\t neighbor %s, link-quality %.2f%%"
2443340d773SGleb Smirnoff ", neighbor-link-quality %.2f%%",
245ee67461eSJoseph Mingrone GET_IPADDR_STRING(lq_neighbor->neighbor),
246ee67461eSJoseph Mingrone ((double) GET_U_1(lq_neighbor->link_quality)/2.55),
247ee67461eSJoseph Mingrone ((double) GET_U_1(lq_neighbor->neighbor_link_quality)/2.55));
248b5bfcb5dSMax Laier
24927df3f5dSRui Paulo msg_data += sizeof(struct olsr_lq_neighbor4);
25027df3f5dSRui Paulo hello_len -= sizeof(struct olsr_lq_neighbor4);
251b5bfcb5dSMax Laier }
2528bdc5a62SPatrick Kelsey return (0);
253ee67461eSJoseph Mingrone trunc:
254ee67461eSJoseph Mingrone return -1;
255b5bfcb5dSMax Laier }
256b5bfcb5dSMax Laier
2578bdc5a62SPatrick Kelsey static int
olsr_print_lq_neighbor6(netdissect_options * ndo,const u_char * msg_data,u_int hello_len)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;
266ee67461eSJoseph Mingrone ND_TCHECK_SIZE(lq_neighbor);
26727df3f5dSRui Paulo
268ee67461eSJoseph Mingrone ND_PRINT("\n\t neighbor %s, link-quality %.2f%%"
2693340d773SGleb Smirnoff ", neighbor-link-quality %.2f%%",
270ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(lq_neighbor->neighbor),
271ee67461eSJoseph Mingrone ((double) GET_U_1(lq_neighbor->link_quality)/2.55),
272ee67461eSJoseph Mingrone ((double) GET_U_1(lq_neighbor->neighbor_link_quality)/2.55));
27327df3f5dSRui Paulo
27427df3f5dSRui Paulo msg_data += sizeof(struct olsr_lq_neighbor6);
27527df3f5dSRui Paulo hello_len -= sizeof(struct olsr_lq_neighbor6);
27627df3f5dSRui Paulo }
2778bdc5a62SPatrick Kelsey return (0);
278ee67461eSJoseph Mingrone trunc:
279ee67461eSJoseph Mingrone return -1;
28027df3f5dSRui Paulo }
28127df3f5dSRui Paulo
282b5bfcb5dSMax Laier /*
283b5bfcb5dSMax Laier * print a neighbor list.
284b5bfcb5dSMax Laier */
2858bdc5a62SPatrick Kelsey static int
olsr_print_neighbor(netdissect_options * ndo,const u_char * msg_data,u_int hello_len)2863c602fabSXin LI olsr_print_neighbor(netdissect_options *ndo,
2873c602fabSXin LI const u_char *msg_data, u_int hello_len)
288b5bfcb5dSMax Laier {
289b5bfcb5dSMax Laier int neighbor;
290b5bfcb5dSMax Laier
291ee67461eSJoseph Mingrone ND_PRINT("\n\t neighbor\n\t\t");
292b5bfcb5dSMax Laier neighbor = 1;
293b5bfcb5dSMax Laier
294ee67461eSJoseph Mingrone while (hello_len >= sizeof(nd_ipv4)) {
295b5bfcb5dSMax Laier /* print 4 neighbors per line */
296ee67461eSJoseph Mingrone ND_PRINT("%s%s", GET_IPADDR_STRING(msg_data),
297ee67461eSJoseph Mingrone neighbor % 4 == 0 ? "\n\t\t" : " ");
298b5bfcb5dSMax Laier
299ee67461eSJoseph Mingrone msg_data += sizeof(nd_ipv4);
300ee67461eSJoseph Mingrone hello_len -= sizeof(nd_ipv4);
301b5bfcb5dSMax Laier }
3028bdc5a62SPatrick Kelsey return (0);
303b5bfcb5dSMax Laier }
304b5bfcb5dSMax Laier
305b5bfcb5dSMax Laier
306b5bfcb5dSMax Laier void
olsr_print(netdissect_options * ndo,const u_char * pptr,u_int length,int is_ipv6)3073c602fabSXin LI olsr_print(netdissect_options *ndo,
3083c602fabSXin LI const u_char *pptr, u_int length, int is_ipv6)
309b5bfcb5dSMax Laier {
310b5bfcb5dSMax Laier union {
311b5bfcb5dSMax Laier const struct olsr_common *common;
31227df3f5dSRui Paulo const struct olsr_msg4 *msg4;
31327df3f5dSRui Paulo const struct olsr_msg6 *msg6;
314b5bfcb5dSMax Laier const struct olsr_hello *hello;
315b5bfcb5dSMax Laier const struct olsr_hello_link *hello_link;
316b5bfcb5dSMax Laier const struct olsr_tc *tc;
31727df3f5dSRui Paulo const struct olsr_hna4 *hna;
318b5bfcb5dSMax Laier } ptr;
319b5bfcb5dSMax Laier
32027df3f5dSRui Paulo u_int msg_type, msg_len, msg_tlen, hello_len;
3213c602fabSXin LI uint16_t name_entry_type, name_entry_len;
32227df3f5dSRui Paulo u_int name_entry_padding;
3233c602fabSXin LI uint8_t link_type, neighbor_type;
324b5bfcb5dSMax Laier const u_char *tptr, *msg_data;
325b5bfcb5dSMax Laier
326ee67461eSJoseph Mingrone ndo->ndo_protocol = "olsr";
327b5bfcb5dSMax Laier tptr = pptr;
328b5bfcb5dSMax Laier
329ee67461eSJoseph Mingrone nd_print_protocol_caps(ndo);
330ee67461eSJoseph Mingrone ND_PRINT("v%u", (is_ipv6) ? 6 : 4);
331ee67461eSJoseph Mingrone
332b5bfcb5dSMax Laier if (length < sizeof(struct olsr_common)) {
333b5bfcb5dSMax Laier goto trunc;
334b5bfcb5dSMax Laier }
335b5bfcb5dSMax Laier
336ee67461eSJoseph Mingrone ND_TCHECK_LEN(tptr, sizeof(struct olsr_common));
337b5bfcb5dSMax Laier
3383340d773SGleb Smirnoff ptr.common = (const struct olsr_common *)tptr;
339ee67461eSJoseph Mingrone length = ND_MIN(length, GET_BE_U_2(ptr.common->packet_len));
340b5bfcb5dSMax Laier
341ee67461eSJoseph Mingrone ND_PRINT(", seq 0x%04x, length %u",
342ee67461eSJoseph Mingrone GET_BE_U_2(ptr.common->packet_seq),
343ee67461eSJoseph Mingrone 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
362*0a7e5f1fSJoseph Mingrone if (is_ipv6) {
363ee67461eSJoseph Mingrone ND_TCHECK_LEN(tptr, sizeof(struct olsr_msg6));
3643340d773SGleb Smirnoff msgptr.v6 = (const struct olsr_msg6 *) tptr;
365ee67461eSJoseph Mingrone msg_type = GET_U_1(msgptr.v6->msg_type);
366ee67461eSJoseph Mingrone msg_len = GET_BE_U_2(msgptr.v6->msg_len);
36727df3f5dSRui Paulo if ((msg_len >= sizeof (struct olsr_msg6))
36827df3f5dSRui Paulo && (msg_len <= length))
36927df3f5dSRui Paulo msg_len_valid = 1;
370b5bfcb5dSMax Laier
371b5bfcb5dSMax Laier /* infinite loop check */
372b5bfcb5dSMax Laier if (msg_type == 0 || msg_len == 0) {
373b5bfcb5dSMax Laier return;
374b5bfcb5dSMax Laier }
375b5bfcb5dSMax Laier
376ee67461eSJoseph Mingrone ND_PRINT("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
3773340d773SGleb Smirnoff "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s",
378b5bfcb5dSMax Laier tok2str(olsr_msg_values, "Unknown", msg_type),
379ee67461eSJoseph Mingrone msg_type, GET_IP6ADDR_STRING(msgptr.v6->originator),
380ee67461eSJoseph Mingrone GET_U_1(msgptr.v6->ttl),
381ee67461eSJoseph Mingrone GET_U_1(msgptr.v6->hopcount),
382ee67461eSJoseph Mingrone ME_TO_DOUBLE(GET_U_1(msgptr.v6->vtime)),
383ee67461eSJoseph Mingrone GET_BE_U_2(msgptr.v6->msg_seq),
384ee67461eSJoseph Mingrone msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
3858bdc5a62SPatrick Kelsey if (!msg_len_valid) {
3868bdc5a62SPatrick Kelsey return;
3878bdc5a62SPatrick Kelsey }
388b5bfcb5dSMax Laier
38927df3f5dSRui Paulo msg_tlen = msg_len - sizeof(struct olsr_msg6);
39027df3f5dSRui Paulo msg_data = tptr + sizeof(struct olsr_msg6);
391*0a7e5f1fSJoseph Mingrone } else { /* (!is_ipv6) */
392ee67461eSJoseph Mingrone ND_TCHECK_LEN(tptr, sizeof(struct olsr_msg4));
3933340d773SGleb Smirnoff msgptr.v4 = (const struct olsr_msg4 *) tptr;
394ee67461eSJoseph Mingrone msg_type = GET_U_1(msgptr.v4->msg_type);
395ee67461eSJoseph Mingrone msg_len = GET_BE_U_2(msgptr.v4->msg_len);
39627df3f5dSRui Paulo if ((msg_len >= sizeof (struct olsr_msg4))
39727df3f5dSRui Paulo && (msg_len <= length))
39827df3f5dSRui Paulo msg_len_valid = 1;
39927df3f5dSRui Paulo
40027df3f5dSRui Paulo /* infinite loop check */
40127df3f5dSRui Paulo if (msg_type == 0 || msg_len == 0) {
40227df3f5dSRui Paulo return;
40327df3f5dSRui Paulo }
40427df3f5dSRui Paulo
405ee67461eSJoseph Mingrone ND_PRINT("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
4063340d773SGleb Smirnoff "\n\t vtime %.3fs, msg-seq 0x%04x, length %u%s",
40727df3f5dSRui Paulo tok2str(olsr_msg_values, "Unknown", msg_type),
408ee67461eSJoseph Mingrone msg_type, GET_IPADDR_STRING(msgptr.v4->originator),
409ee67461eSJoseph Mingrone GET_U_1(msgptr.v4->ttl),
410ee67461eSJoseph Mingrone GET_U_1(msgptr.v4->hopcount),
411ee67461eSJoseph Mingrone ME_TO_DOUBLE(GET_U_1(msgptr.v4->vtime)),
412ee67461eSJoseph Mingrone GET_BE_U_2(msgptr.v4->msg_seq),
413ee67461eSJoseph Mingrone msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
4148bdc5a62SPatrick Kelsey if (!msg_len_valid) {
4158bdc5a62SPatrick Kelsey return;
4168bdc5a62SPatrick Kelsey }
41727df3f5dSRui Paulo
41827df3f5dSRui Paulo msg_tlen = msg_len - sizeof(struct olsr_msg4);
41927df3f5dSRui Paulo msg_data = tptr + sizeof(struct olsr_msg4);
42027df3f5dSRui Paulo }
421b5bfcb5dSMax Laier
422b5bfcb5dSMax Laier switch (msg_type) {
423b5bfcb5dSMax Laier case OLSR_HELLO_MSG:
424b5bfcb5dSMax Laier case OLSR_HELLO_LQ_MSG:
4258bdc5a62SPatrick Kelsey if (msg_tlen < sizeof(struct olsr_hello))
4268bdc5a62SPatrick Kelsey goto trunc;
427ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hello));
428b5bfcb5dSMax Laier
4293340d773SGleb Smirnoff ptr.hello = (const struct olsr_hello *)msg_data;
430ee67461eSJoseph Mingrone ND_PRINT("\n\t hello-time %.3fs, MPR willingness %u",
431ee67461eSJoseph Mingrone ME_TO_DOUBLE(GET_U_1(ptr.hello->htime)),
432ee67461eSJoseph Mingrone GET_U_1(ptr.hello->will));
433b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_hello);
434b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_hello);
435b5bfcb5dSMax Laier
436b5bfcb5dSMax Laier while (msg_tlen >= sizeof(struct olsr_hello_link)) {
43727df3f5dSRui Paulo int hello_len_valid = 0;
438b5bfcb5dSMax Laier
439b5bfcb5dSMax Laier /*
440b5bfcb5dSMax Laier * link-type.
441b5bfcb5dSMax Laier */
442ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hello_link));
443b5bfcb5dSMax Laier
4443340d773SGleb Smirnoff ptr.hello_link = (const struct olsr_hello_link *)msg_data;
445b5bfcb5dSMax Laier
446ee67461eSJoseph Mingrone hello_len = GET_BE_U_2(ptr.hello_link->len);
447ee67461eSJoseph Mingrone link_type = OLSR_EXTRACT_LINK_TYPE(GET_U_1(ptr.hello_link->link_code));
448ee67461eSJoseph Mingrone neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(GET_U_1(ptr.hello_link->link_code));
449b5bfcb5dSMax Laier
45027df3f5dSRui Paulo if ((hello_len <= msg_tlen)
45127df3f5dSRui Paulo && (hello_len >= sizeof(struct olsr_hello_link)))
45227df3f5dSRui Paulo hello_len_valid = 1;
45327df3f5dSRui Paulo
454ee67461eSJoseph Mingrone ND_PRINT("\n\t link-type %s, neighbor-type %s, len %u%s",
455b5bfcb5dSMax Laier tok2str(olsr_link_type_values, "Unknown", link_type),
456b5bfcb5dSMax Laier tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type),
45727df3f5dSRui Paulo hello_len,
458ee67461eSJoseph Mingrone (hello_len_valid == 0) ? " (invalid)" : "");
45927df3f5dSRui Paulo
46027df3f5dSRui Paulo if (hello_len_valid == 0)
46127df3f5dSRui Paulo break;
462b5bfcb5dSMax Laier
463b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_hello_link);
464b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_hello_link);
465b5bfcb5dSMax Laier hello_len -= sizeof(struct olsr_hello_link);
466b5bfcb5dSMax Laier
467ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, hello_len);
468b5bfcb5dSMax Laier if (msg_type == OLSR_HELLO_MSG) {
4698bdc5a62SPatrick Kelsey if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1)
4708bdc5a62SPatrick Kelsey goto trunc;
471b5bfcb5dSMax Laier } else {
4728bdc5a62SPatrick Kelsey if (is_ipv6) {
4738bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1)
4748bdc5a62SPatrick Kelsey goto trunc;
4753340d773SGleb Smirnoff } else {
4768bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1)
4778bdc5a62SPatrick Kelsey goto trunc;
4788bdc5a62SPatrick Kelsey }
479b5bfcb5dSMax Laier }
480b5bfcb5dSMax Laier
481b5bfcb5dSMax Laier msg_data += hello_len;
482b5bfcb5dSMax Laier msg_tlen -= hello_len;
483b5bfcb5dSMax Laier }
484b5bfcb5dSMax Laier break;
485b5bfcb5dSMax Laier
486b5bfcb5dSMax Laier case OLSR_TC_MSG:
487b5bfcb5dSMax Laier case OLSR_TC_LQ_MSG:
4888bdc5a62SPatrick Kelsey if (msg_tlen < sizeof(struct olsr_tc))
4898bdc5a62SPatrick Kelsey goto trunc;
490ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, sizeof(struct olsr_tc));
491b5bfcb5dSMax Laier
4923340d773SGleb Smirnoff ptr.tc = (const struct olsr_tc *)msg_data;
493ee67461eSJoseph Mingrone ND_PRINT("\n\t advertised neighbor seq 0x%04x",
494ee67461eSJoseph Mingrone GET_BE_U_2(ptr.tc->ans_seq));
495b5bfcb5dSMax Laier msg_data += sizeof(struct olsr_tc);
496b5bfcb5dSMax Laier msg_tlen -= sizeof(struct olsr_tc);
497b5bfcb5dSMax Laier
498b5bfcb5dSMax Laier if (msg_type == OLSR_TC_MSG) {
4998bdc5a62SPatrick Kelsey if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1)
5008bdc5a62SPatrick Kelsey goto trunc;
501b5bfcb5dSMax Laier } else {
5028bdc5a62SPatrick Kelsey if (is_ipv6) {
5038bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1)
5048bdc5a62SPatrick Kelsey goto trunc;
5053340d773SGleb Smirnoff } else {
5068bdc5a62SPatrick Kelsey if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1)
5078bdc5a62SPatrick Kelsey goto trunc;
5088bdc5a62SPatrick Kelsey }
509b5bfcb5dSMax Laier }
510b5bfcb5dSMax Laier break;
511b5bfcb5dSMax Laier
512b5bfcb5dSMax Laier case OLSR_MID_MSG:
51327df3f5dSRui Paulo {
514ee67461eSJoseph Mingrone u_int addr_size = (u_int)sizeof(nd_ipv4);
51527df3f5dSRui Paulo
51627df3f5dSRui Paulo if (is_ipv6)
517ee67461eSJoseph Mingrone addr_size = (u_int)sizeof(nd_ipv6);
51827df3f5dSRui Paulo
51927df3f5dSRui Paulo while (msg_tlen >= addr_size) {
520ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, addr_size);
521ee67461eSJoseph Mingrone ND_PRINT("\n\t interface address %s",
522ee67461eSJoseph Mingrone is_ipv6 ? GET_IP6ADDR_STRING(msg_data) :
523ee67461eSJoseph Mingrone GET_IPADDR_STRING(msg_data));
5243c602fabSXin LI
52527df3f5dSRui Paulo msg_data += addr_size;
52627df3f5dSRui Paulo msg_tlen -= addr_size;
527b5bfcb5dSMax Laier }
528b5bfcb5dSMax Laier break;
52927df3f5dSRui Paulo }
530b5bfcb5dSMax Laier
531b5bfcb5dSMax Laier case OLSR_HNA_MSG:
532*0a7e5f1fSJoseph Mingrone if (is_ipv6) {
53327df3f5dSRui Paulo int i = 0;
5343340d773SGleb Smirnoff
535ee67461eSJoseph Mingrone ND_PRINT("\n\t Advertised networks (total %u)",
536ee67461eSJoseph Mingrone (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)));
5373340d773SGleb Smirnoff
53827df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna6)) {
5393340d773SGleb Smirnoff const struct olsr_hna6 *hna6;
54027df3f5dSRui Paulo
541ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hna6));
542b5bfcb5dSMax Laier
5433340d773SGleb Smirnoff hna6 = (const struct olsr_hna6 *)msg_data;
54427df3f5dSRui Paulo
545ee67461eSJoseph Mingrone ND_PRINT("\n\t #%i: %s/%u",
546ee67461eSJoseph Mingrone i, GET_IP6ADDR_STRING(hna6->network),
547ee67461eSJoseph Mingrone mask62plen (hna6->mask));
54827df3f5dSRui Paulo
54927df3f5dSRui Paulo msg_data += sizeof(struct olsr_hna6);
55027df3f5dSRui Paulo msg_tlen -= sizeof(struct olsr_hna6);
55127df3f5dSRui Paulo }
552*0a7e5f1fSJoseph Mingrone } else {
55327df3f5dSRui Paulo int col = 0;
5543340d773SGleb Smirnoff
555ee67461eSJoseph Mingrone ND_PRINT("\n\t Advertised networks (total %u)",
556ee67461eSJoseph Mingrone (unsigned int) (msg_tlen / sizeof(struct olsr_hna4)));
5573340d773SGleb Smirnoff
55827df3f5dSRui Paulo while (msg_tlen >= sizeof(struct olsr_hna4)) {
559ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data, sizeof(struct olsr_hna4));
56027df3f5dSRui Paulo
5613340d773SGleb Smirnoff ptr.hna = (const struct olsr_hna4 *)msg_data;
562b5bfcb5dSMax Laier
563b5bfcb5dSMax Laier /* print 4 prefixes per line */
5643340d773SGleb Smirnoff if (!ptr.hna->network[0] && !ptr.hna->network[1] &&
5653340d773SGleb Smirnoff !ptr.hna->network[2] && !ptr.hna->network[3] &&
5663340d773SGleb Smirnoff !ptr.hna->mask[GW_HNA_PAD] &&
5673340d773SGleb Smirnoff ptr.hna->mask[GW_HNA_FLAGS]) {
5683340d773SGleb Smirnoff /* smart gateway */
569ee67461eSJoseph Mingrone ND_PRINT("%sSmart-Gateway:%s%s%s%s%s %u/%u",
5703340d773SGleb Smirnoff col == 0 ? "\n\t " : ", ", /* indent */
5713340d773SGleb Smirnoff /* sgw */
5723340d773SGleb Smirnoff /* LINKSPEED */
5733340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5743340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ? " LINKSPEED" : "",
5753340d773SGleb Smirnoff /* IPV4 */
5763340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5773340d773SGleb Smirnoff GW_HNA_FLAG_IPV4) ? " IPV4" : "",
5783340d773SGleb Smirnoff /* IPV4-NAT */
5793340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5803340d773SGleb Smirnoff GW_HNA_FLAG_IPV4_NAT) ? " IPV4-NAT" : "",
5813340d773SGleb Smirnoff /* IPV6 */
5823340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5833340d773SGleb Smirnoff GW_HNA_FLAG_IPV6) ? " IPV6" : "",
5843340d773SGleb Smirnoff /* IPv6PREFIX */
5853340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5863340d773SGleb Smirnoff GW_HNA_FLAG_IPV6PREFIX) ? " IPv6-PREFIX" : "",
5873340d773SGleb Smirnoff /* uplink */
5883340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5893340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ?
5903340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_UPLINK]) : 0,
5913340d773SGleb Smirnoff /* downlink */
5923340d773SGleb Smirnoff (ptr.hna->mask[GW_HNA_FLAGS] &
5933340d773SGleb Smirnoff GW_HNA_FLAG_LINKSPEED) ?
5943340d773SGleb Smirnoff deserialize_gw_speed(ptr.hna->mask[GW_HNA_DOWNLINK]) : 0
595ee67461eSJoseph Mingrone );
5963340d773SGleb Smirnoff } else {
5973340d773SGleb Smirnoff /* normal route */
598ee67461eSJoseph Mingrone ND_PRINT("%s%s/%u",
5993c602fabSXin LI col == 0 ? "\n\t " : ", ",
600ee67461eSJoseph Mingrone GET_IPADDR_STRING(ptr.hna->network),
601ee67461eSJoseph Mingrone mask2plen(GET_BE_U_4(ptr.hna->mask)));
6023340d773SGleb Smirnoff }
603b5bfcb5dSMax Laier
60427df3f5dSRui Paulo msg_data += sizeof(struct olsr_hna4);
60527df3f5dSRui Paulo msg_tlen -= sizeof(struct olsr_hna4);
60627df3f5dSRui Paulo
60727df3f5dSRui Paulo col = (col + 1) % 4;
60827df3f5dSRui Paulo }
609b5bfcb5dSMax Laier }
610b5bfcb5dSMax Laier break;
611b5bfcb5dSMax Laier
61227df3f5dSRui Paulo case OLSR_NAMESERVICE_MSG:
61327df3f5dSRui Paulo {
6140bff6a5aSEd Maste u_int name_entries;
6150bff6a5aSEd Maste u_int addr_size;
6160bff6a5aSEd Maste int name_entries_valid;
61727df3f5dSRui Paulo u_int i;
61827df3f5dSRui Paulo
61927df3f5dSRui Paulo if (msg_tlen < 4)
62027df3f5dSRui Paulo goto trunc;
62127df3f5dSRui Paulo
622ee67461eSJoseph Mingrone name_entries = GET_BE_U_2(msg_data + 2);
6230bff6a5aSEd Maste addr_size = 4;
6240bff6a5aSEd Maste if (is_ipv6)
6250bff6a5aSEd Maste addr_size = 16;
6260bff6a5aSEd Maste
6270bff6a5aSEd Maste name_entries_valid = 0;
6280bff6a5aSEd Maste if ((name_entries > 0)
6290bff6a5aSEd Maste && ((name_entries * (4 + addr_size)) <= msg_tlen))
6300bff6a5aSEd Maste name_entries_valid = 1;
6310bff6a5aSEd Maste
632ee67461eSJoseph Mingrone ND_PRINT("\n\t Version %u, Entries %u%s",
633ee67461eSJoseph Mingrone GET_BE_U_2(msg_data),
634ee67461eSJoseph Mingrone name_entries, (name_entries_valid == 0) ? " (invalid)" : "");
63527df3f5dSRui Paulo
63627df3f5dSRui Paulo if (name_entries_valid == 0)
63727df3f5dSRui Paulo break;
63827df3f5dSRui Paulo
63927df3f5dSRui Paulo msg_data += 4;
64027df3f5dSRui Paulo msg_tlen -= 4;
64127df3f5dSRui Paulo
64227df3f5dSRui Paulo for (i = 0; i < name_entries; i++) {
64327df3f5dSRui Paulo int name_entry_len_valid = 0;
64427df3f5dSRui Paulo
64527df3f5dSRui Paulo if (msg_tlen < 4)
64627df3f5dSRui Paulo break;
64727df3f5dSRui Paulo
648ee67461eSJoseph Mingrone name_entry_type = GET_BE_U_2(msg_data);
649ee67461eSJoseph Mingrone name_entry_len = GET_BE_U_2(msg_data + 2);
65027df3f5dSRui Paulo
65127df3f5dSRui Paulo msg_data += 4;
65227df3f5dSRui Paulo msg_tlen -= 4;
65327df3f5dSRui Paulo
65427df3f5dSRui Paulo if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen))
65527df3f5dSRui Paulo name_entry_len_valid = 1;
65627df3f5dSRui Paulo
657ee67461eSJoseph Mingrone ND_PRINT("\n\t #%u: type %#06x, length %u%s",
65827df3f5dSRui Paulo (unsigned int) i, name_entry_type,
659ee67461eSJoseph Mingrone name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "");
66027df3f5dSRui Paulo
66127df3f5dSRui Paulo if (name_entry_len_valid == 0)
66227df3f5dSRui Paulo break;
66327df3f5dSRui Paulo
66427df3f5dSRui Paulo /* 32-bit alignment */
66527df3f5dSRui Paulo name_entry_padding = 0;
66627df3f5dSRui Paulo if (name_entry_len%4 != 0)
66727df3f5dSRui Paulo name_entry_padding = 4-(name_entry_len%4);
66827df3f5dSRui Paulo
66927df3f5dSRui Paulo if (msg_tlen < addr_size + name_entry_len + name_entry_padding)
67027df3f5dSRui Paulo goto trunc;
67127df3f5dSRui Paulo
672ee67461eSJoseph Mingrone ND_TCHECK_LEN(msg_data,
673ee67461eSJoseph Mingrone addr_size + name_entry_len + name_entry_padding);
67427df3f5dSRui Paulo
67527df3f5dSRui Paulo if (is_ipv6)
676ee67461eSJoseph Mingrone ND_PRINT(", address %s, name \"",
677ee67461eSJoseph Mingrone GET_IP6ADDR_STRING(msg_data));
67827df3f5dSRui Paulo else
679ee67461eSJoseph Mingrone ND_PRINT(", address %s, name \"",
680ee67461eSJoseph Mingrone GET_IPADDR_STRING(msg_data));
681ee67461eSJoseph Mingrone (void)nd_printn(ndo, msg_data + addr_size, name_entry_len, NULL);
682ee67461eSJoseph Mingrone ND_PRINT("\"");
68327df3f5dSRui Paulo
68427df3f5dSRui Paulo msg_data += addr_size + name_entry_len + name_entry_padding;
68527df3f5dSRui Paulo msg_tlen -= addr_size + name_entry_len + name_entry_padding;
68627df3f5dSRui Paulo } /* for (i = 0; i < name_entries; i++) */
68727df3f5dSRui Paulo break;
68827df3f5dSRui Paulo } /* case OLSR_NAMESERVICE_MSG */
68927df3f5dSRui Paulo
690b5bfcb5dSMax Laier /*
691b5bfcb5dSMax Laier * FIXME those are the defined messages that lack a decoder
692b5bfcb5dSMax Laier * you are welcome to contribute code ;-)
693b5bfcb5dSMax Laier */
694b5bfcb5dSMax Laier case OLSR_POWERINFO_MSG:
695b5bfcb5dSMax Laier default:
6963c602fabSXin LI print_unknown_data(ndo, msg_data, "\n\t ", msg_tlen);
697b5bfcb5dSMax Laier break;
69827df3f5dSRui Paulo } /* switch (msg_type) */
699b5bfcb5dSMax Laier tptr += msg_len;
70027df3f5dSRui Paulo } /* while (tptr < (pptr+length)) */
701b5bfcb5dSMax Laier
702b5bfcb5dSMax Laier return;
703b5bfcb5dSMax Laier
704b5bfcb5dSMax Laier trunc:
705ee67461eSJoseph Mingrone nd_print_trunc(ndo);
706b5bfcb5dSMax Laier }
707