Keep statistics of logged warnings
[oonf.git] / src-plugins / nhdp / nhdpinfo / nhdpinfo.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #include "common/common_types.h"
47 #include "common/autobuf.h"
48 #include "common/template.h"
49
50 #include "core/oonf_logging.h"
51 #include "core/oonf_subsystem.h"
52 #include "subsystems/oonf_clock.h"
53 #include "subsystems/oonf_telnet.h"
54 #include "subsystems/oonf_viewer.h"
55
56 #include "nhdp/nhdp_domain.h"
57 #include "nhdp/nhdp_interfaces.h"
58 #include "nhdp/nhdp_db.h"
59
60 #include "nhdpinfo/nhdpinfo.h"
61
62 /* Definitions */
63 #define LOG_NHDPINFO _olsrv2_nhdpinfo_subsystem.logging
64
65 /* prototypes */
66 static int _init(void);
67 static void _cleanup(void);
68
69 static enum oonf_telnet_result _cb_nhdpinfo(struct oonf_telnet_data *con);
70 static enum oonf_telnet_result _cb_nhdpinfo_help(struct oonf_telnet_data *con);
71
72 static void _initialize_interface_values(struct nhdp_interface *nhdp_if);
73 static void _initialize_interface_address_values(struct nhdp_interface_addr *if_addr);
74 static void _initialize_nhdp_link_values(struct nhdp_link *lnk);
75 static void _initialize_nhdp_domain_metric_values(struct nhdp_domain *domain,
76     struct nhdp_metric *metric);
77 static void _initialize_nhdp_neighbor_mpr_values(struct nhdp_domain *domain,
78     struct nhdp_neighbor_domaindata *domaindata);
79 static void _initialize_nhdp_domain_metric_int_values(struct nhdp_domain *domain,
80     struct nhdp_link *lnk);
81 static void _initialize_nhdp_link_address_values(struct nhdp_laddr *laddr);
82 static void _initialize_nhdp_link_twohop_values(struct nhdp_l2hop *twohop);
83 static void _initialize_nhdp_neighbor_values(struct nhdp_neighbor *neigh);
84 static void _initialize_nhdp_neighbor_address_values(struct nhdp_naddr *naddr);
85
86 static int _cb_create_text_interface(struct oonf_viewer_template *);
87 static int _cb_create_text_if_address(struct oonf_viewer_template *);
88 static int _cb_create_text_link(struct oonf_viewer_template *);
89 static int _cb_create_text_link_address(struct oonf_viewer_template *);
90 static int _cb_create_text_link_twohop(struct oonf_viewer_template *);
91 static int _cb_create_text_neighbor(struct oonf_viewer_template *);
92 static int _cb_create_text_neighbor_address(struct oonf_viewer_template *);
93
94 /*
95  * list of template keys and corresponding buffers for values.
96  *
97  * The keys are API, so they should not be changed after published
98  */
99
100 /*! template key for interface name */
101 #define KEY_IF                      "if"
102
103 /*! template key for interface IPv4 socket address */
104 #define KEY_IF_BINDTO_V4            "if_bindto_v4"
105
106 /*! template key for interface IPv6 socket address */
107 #define KEY_IF_BINDTO_V6            "if_bindto_v6"
108
109 /*! template key for interface MAP address */
110 #define KEY_IF_MAC                  "if_mac"
111
112 /*! template key for IPv4 flooding flag */
113 #define KEY_IF_FLOODING_V4          "if_flooding_v4"
114
115 /*! template key for IPv6 flooding flag */
116 #define KEY_IF_FLOODING_V6          "if_flooding_v6"
117
118 /*! template key for dualstack mode */
119 #define KEY_IF_DUALSTACK_MODE       "if_dualstack_mode"
120
121 /*! template key for an interface address */
122 #define KEY_IF_ADDRESS              "if_address"
123
124 /*! template key for a lost interface address */
125 #define KEY_IF_ADDRESS_LOST         "if_address_lost"
126
127 /*! template key for validity time of a lost interface address */
128 #define KEY_IF_ADDRESS_LOST_VTIME   "if_address_lost_vtime"
129
130 /*! template key for the links remote socket IP address */
131 #define KEY_LINK_BINDTO             "link_bindto"
132
133 /*! template key for the validity time of the link */
134 #define KEY_LINK_VTIME_VALUE        "link_vtime_value"
135
136 /*! template key for the interval time of the link */
137 #define KEY_LINK_ITIME_VALUE        "link_itime_value"
138
139 /*! template key for the time the link will still be symmetric */
140 #define KEY_LINK_SYMTIME            "link_symtime"
141
142 /*! template key for the time the link will still be heard */
143 #define KEY_LINK_HEARDTIME          "link_heardtime"
144
145 /*! template key for validity time of the link */
146 #define KEY_LINK_VTIME              "link_vtime"
147
148 /*! template key for link status */
149 #define KEY_LINK_STATUS             "link_status"
150
151 /*! template key for links local dualstack IP address */
152 #define KEY_LINK_DUALSTACK          "link_dualstack"
153
154 /*! template key for links remote mac address */
155 #define KEY_LINK_MAC                "link_mac"
156
157 /*! template key for a link IP address */
158 #define KEY_LINK_ADDRESS            "link_address"
159
160 /*! template key for an IP address of a two-hop link */
161 #define KEY_TWOHOP_ADDRESS          "twohop_address"
162
163 /*! template key for the flag to signal a two-hop link on the same interface */
164 #define KEY_TWOHOP_SAMEIF           "twohop_same_interface"
165
166 /*! template key for the validity time of a two-hop link */
167 #define KEY_TWOHOP_VTIME            "twohop_vtime"
168
169 /*! template key for neighbors originator IP */
170 #define KEY_NEIGHBOR_ORIGINATOR     "neighbor_originator"
171
172 /*! template key for neighbors dualstack originator IP */
173 #define KEY_NEIGHBOR_DUALSTACK      "neighbor_dualstack"
174
175 /*! template key signaling neighbor has selected node as flooding MPR */
176 #define KEY_NEIGHBOR_FLOOD_LOCAL    "neighbor_flood_local"
177
178 /*! template key signaling route has selected neighbor as flooding MPR */
179 #define KEY_NEIGHBOR_FLOOD_REMOTE   "neighbor_flood_remote"
180
181 /*! template key for number of symmetric links of neighbor */
182 #define KEY_NEIGHBOR_SYMMETRIC      "neighbor_symmetric"
183
184 /*! template key for number of links of neighbor */
185 #define KEY_NEIGHBOR_LINKCOUNT      "neighbor_linkcount"
186
187 /*! template key for neighbor flooding willingness */
188 #define KEY_NEIGHBOR_FLOOD_WILL     "neighbor_flood_willingness"
189
190 /*! template key for neighbor address */
191 #define KEY_NEIGHBOR_ADDRESS        "neighbor_address"
192
193 /*! template key for lost neighbor address */
194 #define KEY_NEIGHBOR_ADDRESS_LOST   "neighbor_address_lost"
195
196 /*! template key for validity time of lost neighbor address */
197 #define KEY_NEIGHBOR_ADDRESS_VTIME  "neighbor_address_lost_vtime"
198
199 /*! template key for NHDP domain */
200 #define KEY_DOMAIN                  "domain"
201
202 /*! template key for NHDP domain metric name */
203 #define KEY_DOMAIN_METRIC           "domain_metric"
204
205 /*! template key for incoming human readable metric */
206 #define KEY_DOMAIN_METRIC_IN        "domain_metric_in"
207
208 /*! template key for outgoing human readable metric */
209 #define KEY_DOMAIN_METRIC_OUT       "domain_metric_out"
210
211 /*! template key for incoming numeric metric */
212 #define KEY_DOMAIN_METRIC_IN_RAW    "domain_metric_in_raw"
213
214 /*! template key for outgoing numeric metric */
215 #define KEY_DOMAIN_METRIC_OUT_RAW   "domain_metric_out_raw"
216
217 /*! template key for internal metric representation */
218 #define KEY_DOMAIN_METRIC_INTERNAL  "domain_metric_internal"
219
220 /*! template key for NHDP domain MPR name */
221 #define KEY_DOMAIN_MPR              "domain_mpr"
222
223 /*! template key signaling local node is selected as routing MPR */
224 #define KEY_DOMAIN_MPR_LOCAL        "domain_mpr_local"
225
226 /*! template key signaling remote node has been selected as routing MPR */
227 #define KEY_DOMAIN_MPR_REMOTE       "domain_mpr_remote"
228
229 /*! template key for routing willingness */
230 #define KEY_DOMAIN_MPR_WILL         "domain_mpr_willingness"
231
232 /*
233  * buffer space for values that will be assembled
234  * into the output of the plugin
235  */
236 static char                       _value_if[IF_NAMESIZE];
237 static struct netaddr_str         _value_if_bindto_v4;
238 static struct netaddr_str         _value_if_bindto_v6;
239 static struct netaddr_str         _value_if_mac;
240 static char                       _value_if_flooding_v4[TEMPLATE_JSON_BOOL_LENGTH];
241 static char                       _value_if_flooding_v6[TEMPLATE_JSON_BOOL_LENGTH];
242 static char                       _value_if_dualstack_mode[5];
243 static struct netaddr_str         _value_if_address;
244 static char                       _value_if_address_lost[TEMPLATE_JSON_BOOL_LENGTH];
245 static struct isonumber_str       _value_if_address_vtime;
246
247 static struct netaddr_str         _value_link_bindto;
248 static struct isonumber_str       _value_link_vtime_value;
249 static struct isonumber_str       _value_link_itime_value;
250 static struct isonumber_str       _value_link_symtime;
251 static struct isonumber_str       _value_link_heardtime;
252 static struct isonumber_str       _value_link_vtime;
253 static char                       _value_link_status[NHDP_LINK_STATUS_TXTLENGTH];
254 static struct netaddr_str         _value_link_dualstack;
255 static struct netaddr_str         _value_link_mac;
256
257 static struct netaddr_str         _value_link_address;
258
259 static struct netaddr_str         _value_twohop_address;
260 static char                       _value_twohop_sameif[TEMPLATE_JSON_BOOL_LENGTH];
261 static struct isonumber_str       _value_twohop_vtime;
262
263 static struct netaddr_str         _value_neighbor_originator;
264 static struct netaddr_str         _value_neighbor_dualstack;
265 static char                       _value_neighbor_flood_local[TEMPLATE_JSON_BOOL_LENGTH];
266 static char                       _value_neighbor_flood_remote[TEMPLATE_JSON_BOOL_LENGTH];
267 static char                       _value_neighbor_symmetric[TEMPLATE_JSON_BOOL_LENGTH];
268 static char                       _value_neighbor_linkcount[10];
269 static char                       _value_neighbor_willingness[3];
270 static struct netaddr_str         _value_neighbor_address;
271 static char                       _value_neighbor_address_lost[TEMPLATE_JSON_BOOL_LENGTH];
272 static struct isonumber_str       _value_neighbor_address_lost_vtime;
273
274 static char                       _value_domain[4];
275 static char                       _value_domain_metric[NHDP_DOMAIN_METRIC_MAXLEN];
276 static struct nhdp_metric_str     _value_domain_metric_in;
277 static struct nhdp_metric_str     _value_domain_metric_out;
278 static char                       _value_domain_metric_in_raw[12];
279 static char                       _value_domain_metric_out_raw[12];
280 static struct nhdp_metric_str     _value_domain_metric_internal;
281 static char                       _value_domain_mpr[NHDP_DOMAIN_MPR_MAXLEN];
282 static char                       _value_domain_mpr_local[TEMPLATE_JSON_BOOL_LENGTH];
283 static char                       _value_domain_mpr_remote[TEMPLATE_JSON_BOOL_LENGTH];
284 static char                       _value_domain_mpr_will[3];
285
286
287 /* definition of the template data entries for JSON and table output */
288 static struct abuf_template_data_entry _tde_if_key[] = {
289     { KEY_IF, _value_if, true },
290 };
291
292 static struct abuf_template_data_entry _tde_if[] = {
293     { KEY_IF, _value_if, true },
294     { KEY_IF_BINDTO_V4, _value_if_bindto_v4.buf, true },
295     { KEY_IF_BINDTO_V6, _value_if_bindto_v6.buf, true },
296     { KEY_IF_MAC, _value_if_mac.buf, true },
297     { KEY_IF_FLOODING_V4, _value_if_flooding_v4, true },
298     { KEY_IF_FLOODING_V6, _value_if_flooding_v6, true },
299     { KEY_IF_DUALSTACK_MODE, _value_if_dualstack_mode, true },
300 };
301
302 static struct abuf_template_data_entry _tde_if_addr[] = {
303     { KEY_IF_ADDRESS, _value_if_address.buf, true },
304     { KEY_IF_ADDRESS_LOST, _value_if_address_lost, true },
305     { KEY_IF_ADDRESS_LOST_VTIME, _value_if_address_vtime.buf, false },
306 };
307
308 static struct abuf_template_data_entry _tde_link_key[] = {
309     { KEY_LINK_BINDTO, _value_link_bindto.buf, true },
310     { KEY_NEIGHBOR_ORIGINATOR, _value_neighbor_originator.buf, true },
311 };
312
313 static struct abuf_template_data_entry _tde_link[] = {
314     { KEY_LINK_BINDTO, _value_link_bindto.buf, true },
315     { KEY_LINK_VTIME_VALUE, _value_link_vtime_value.buf, false },
316     { KEY_LINK_ITIME_VALUE, _value_link_itime_value.buf, false },
317     { KEY_LINK_SYMTIME, _value_link_symtime.buf, false },
318     { KEY_LINK_HEARDTIME, _value_link_heardtime.buf, false },
319     { KEY_LINK_VTIME, _value_link_vtime.buf, false },
320     { KEY_LINK_STATUS, _value_link_status, true },
321     { KEY_LINK_DUALSTACK, _value_link_dualstack.buf, true },
322     { KEY_LINK_MAC, _value_link_mac.buf, true },
323     { KEY_NEIGHBOR_ORIGINATOR, _value_neighbor_originator.buf, true },
324     { KEY_NEIGHBOR_DUALSTACK, _value_neighbor_dualstack.buf, true },
325 };
326
327 static struct abuf_template_data_entry _tde_domain[] = {
328     { KEY_DOMAIN, _value_domain, false },
329 };
330
331 static struct abuf_template_data_entry _tde_domain_metric[] = {
332     { KEY_DOMAIN_METRIC, _value_domain_metric, true },
333     { KEY_DOMAIN_METRIC_IN, _value_domain_metric_in.buf, true },
334     { KEY_DOMAIN_METRIC_IN_RAW, _value_domain_metric_in_raw, false },
335     { KEY_DOMAIN_METRIC_OUT, _value_domain_metric_out.buf, true },
336     { KEY_DOMAIN_METRIC_OUT_RAW, _value_domain_metric_out_raw, false },
337 };
338 static struct abuf_template_data_entry _tde_domain_metric_int[] = {
339     { KEY_DOMAIN_METRIC_INTERNAL, _value_domain_metric_internal.buf, true },
340 };
341
342 static struct abuf_template_data_entry _tde_domain_mpr[] = {
343     { KEY_DOMAIN_MPR, _value_domain_mpr, true },
344     { KEY_DOMAIN_MPR_LOCAL, _value_domain_mpr_local, true },
345     { KEY_DOMAIN_MPR_REMOTE, _value_domain_mpr_remote, true},
346     { KEY_DOMAIN_MPR_WILL, _value_domain_mpr_will, false },
347 };
348
349 static struct abuf_template_data_entry _tde_link_addr[] = {
350     { KEY_LINK_ADDRESS, _value_link_address.buf, true },
351 };
352
353 static struct abuf_template_data_entry _tde_twohop_addr[] = {
354     { KEY_TWOHOP_ADDRESS, _value_twohop_address.buf, true },
355     { KEY_TWOHOP_SAMEIF, _value_twohop_sameif, true },
356     { KEY_TWOHOP_VTIME, _value_twohop_vtime.buf, false },
357 };
358
359 static struct abuf_template_data_entry _tde_neigh_key[] = {
360     { KEY_NEIGHBOR_ORIGINATOR, _value_neighbor_originator.buf, true },
361 };
362
363 static struct abuf_template_data_entry _tde_neigh[] = {
364     { KEY_NEIGHBOR_DUALSTACK, _value_neighbor_dualstack.buf, true },
365     { KEY_NEIGHBOR_FLOOD_LOCAL, _value_neighbor_flood_local, true },
366     { KEY_NEIGHBOR_FLOOD_REMOTE, _value_neighbor_flood_remote, true },
367     { KEY_NEIGHBOR_FLOOD_WILL, _value_neighbor_willingness, false },
368     { KEY_NEIGHBOR_SYMMETRIC, _value_neighbor_symmetric, true },
369     { KEY_NEIGHBOR_LINKCOUNT, _value_neighbor_linkcount, false },
370 };
371
372 static struct abuf_template_data_entry _tde_neigh_addr[] = {
373     { KEY_NEIGHBOR_ADDRESS, _value_neighbor_address.buf, true },
374     { KEY_NEIGHBOR_ADDRESS_LOST, _value_neighbor_address_lost, true },
375     { KEY_NEIGHBOR_ADDRESS_VTIME, _value_neighbor_address_lost_vtime.buf, false },
376 };
377
378 static struct abuf_template_storage _template_storage;
379
380 /* Template Data objects (contain one or more Template Data Entries) */
381 static struct abuf_template_data _td_if[] = {
382     { _tde_if, ARRAYSIZE(_tde_if) },
383 };
384 static struct abuf_template_data _td_if_addr[] = {
385     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
386     { _tde_if_addr, ARRAYSIZE(_tde_if_addr) },
387 };
388 static struct abuf_template_data _td_link[] = {
389     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
390     { _tde_link, ARRAYSIZE(_tde_link) },
391     { _tde_domain, ARRAYSIZE(_tde_domain) },
392     { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
393     { _tde_domain_metric_int, ARRAYSIZE(_tde_domain_metric_int) },
394 };
395 static struct abuf_template_data _td_link_addr[] = {
396     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
397     { _tde_link_key, ARRAYSIZE(_tde_link_key) },
398     { _tde_link_addr, ARRAYSIZE(_tde_link_addr) },
399 };
400 static struct abuf_template_data _td_twohop_addr[] = {
401     { _tde_if_key, ARRAYSIZE(_tde_if_key) },
402     { _tde_link_key, ARRAYSIZE(_tde_link_key) },
403     { _tde_twohop_addr, ARRAYSIZE(_tde_twohop_addr) },
404     { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
405 };
406 static struct abuf_template_data _td_neigh[] = {
407     { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
408     { _tde_neigh, ARRAYSIZE(_tde_neigh) },
409     { _tde_domain, ARRAYSIZE(_tde_domain) },
410     { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
411     { _tde_domain_mpr, ARRAYSIZE(_tde_domain_mpr) },
412 };
413 static struct abuf_template_data _td_neigh_addr[] = {
414     { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
415     { _tde_neigh_addr, ARRAYSIZE(_tde_neigh_addr) },
416 };
417
418 /* OONF viewer templates (based on Template Data arrays) */
419 static struct oonf_viewer_template _templates[] = {
420     {
421         .data = _td_if,
422         .data_size = ARRAYSIZE(_td_if),
423         .json_name = "interface",
424         .cb_function = _cb_create_text_interface,
425     },
426     {
427         .data = _td_if_addr,
428         .data_size = ARRAYSIZE(_td_if_addr),
429         .json_name = "if_addr",
430         .cb_function = _cb_create_text_if_address,
431     },
432     {
433         .data = _td_link,
434         .data_size = ARRAYSIZE(_td_link),
435         .json_name = "link",
436         .cb_function = _cb_create_text_link,
437     },
438     {
439         .data = _td_link_addr,
440         .data_size = ARRAYSIZE(_td_link_addr),
441         .json_name = "link_addr",
442         .cb_function = _cb_create_text_link_address,
443     },
444     {
445         .data = _td_twohop_addr,
446         .data_size = ARRAYSIZE(_td_twohop_addr),
447         .json_name = "link_twohop",
448         .cb_function = _cb_create_text_link_twohop,
449     },
450     {
451         .data = _td_neigh,
452         .data_size = ARRAYSIZE(_td_neigh),
453         .json_name = "neighbor",
454         .cb_function = _cb_create_text_neighbor,
455     },
456     {
457         .data = _td_neigh_addr,
458         .data_size = ARRAYSIZE(_td_neigh_addr),
459         .json_name = "neighbor_addr",
460         .cb_function = _cb_create_text_neighbor_address,
461     }
462 };
463
464 /* telnet command of this plugin */
465 static struct oonf_telnet_command _telnet_commands[] = {
466     TELNET_CMD(OONF_NHDPINFO_SUBSYSTEM, _cb_nhdpinfo,
467         "", .help_handler = _cb_nhdpinfo_help),
468 };
469
470 /* plugin declaration */
471 static const char *_dependencies[] = {
472   OONF_CLOCK_SUBSYSTEM,
473   OONF_TELNET_SUBSYSTEM,
474   OONF_VIEWER_SUBSYSTEM,
475   OONF_NHDP_SUBSYSTEM,
476 };
477 static struct oonf_subsystem _olsrv2_nhdpinfo_subsystem = {
478   .name = OONF_NHDPINFO_SUBSYSTEM,
479   .dependencies = _dependencies,
480   .dependencies_count = ARRAYSIZE(_dependencies),
481   .descr = "NHDPinfo plugin",
482   .author = "Henning Rogge",
483   .init = _init,
484   .cleanup = _cleanup,
485 };
486 DECLARE_OONF_PLUGIN(_olsrv2_nhdpinfo_subsystem);
487
488 /**
489  * Initialize plugin
490  * @return always returns 0
491  */
492 static int
493 _init(void) {
494   oonf_telnet_add(&_telnet_commands[0]);
495   return 0;
496 }
497
498 /**
499  * Cleanup plugin
500  */
501 static void
502 _cleanup(void) {
503   oonf_telnet_remove(&_telnet_commands[0]);
504 }
505
506 /**
507  * Callback for the telnet command of this plugin
508  * @param con pointer to telnet session data
509  * @return telnet result value
510  */
511 static enum oonf_telnet_result
512 _cb_nhdpinfo(struct oonf_telnet_data *con) {
513   return oonf_viewer_telnet_handler(con->out, &_template_storage,
514       OONF_NHDPINFO_SUBSYSTEM, con->parameter,
515       _templates, ARRAYSIZE(_templates));
516 }
517
518 /**
519  * Callback for the help output of this plugin
520  * @param con pointer to telnet session data
521  * @return telnet result value
522  */
523 static enum oonf_telnet_result
524 _cb_nhdpinfo_help(struct oonf_telnet_data *con) {
525   return oonf_viewer_telnet_help(con->out, OONF_NHDPINFO_SUBSYSTEM,
526       con->parameter, _templates, ARRAYSIZE(_templates));
527 }
528
529 /**
530  * Initialize the value buffers for a NHDP interface
531  * @param nhdp_if nhdp interface
532  */
533 static void
534 _initialize_interface_values(struct nhdp_interface *nhdp_if) {
535   struct os_interface_listener *if_listener;
536   struct netaddr temp_addr;
537
538   if_listener = nhdp_interface_get_if_listener(nhdp_if);
539
540   /* fill output buffers for template engine */
541   strscpy(_value_if, nhdp_interface_get_name(nhdp_if), sizeof(_value_if));
542
543   netaddr_from_socket(&temp_addr,
544       &nhdp_if->rfc5444_if.interface->_socket.socket_v4.local_socket);
545   netaddr_to_string(&_value_if_bindto_v4, &temp_addr);
546
547   netaddr_from_socket(&temp_addr,
548       &nhdp_if->rfc5444_if.interface->_socket.socket_v6.local_socket);
549   netaddr_to_string(&_value_if_bindto_v6, &temp_addr);
550
551   netaddr_to_string(&_value_if_mac, &if_listener->data->mac);
552
553   strscpy(_value_if_flooding_v4,
554       json_getbool(nhdp_if->use_ipv4_for_flooding), TEMPLATE_JSON_BOOL_LENGTH);
555
556   strscpy(_value_if_flooding_v6,
557       json_getbool(nhdp_if->use_ipv6_for_flooding), TEMPLATE_JSON_BOOL_LENGTH);
558
559   if (nhdp_if->dualstack_af_type == AF_INET) {
560     strscpy(_value_if_dualstack_mode, "IPv4", sizeof(_value_if_dualstack_mode));
561   }
562   else if (nhdp_if->dualstack_af_type == AF_INET6) {
563     strscpy(_value_if_dualstack_mode, "IPv6", sizeof(_value_if_dualstack_mode));
564   }
565   else {
566     strscpy(_value_if_dualstack_mode, "-", sizeof(_value_if_dualstack_mode));
567   }
568 }
569
570 /**
571  * Initialize the value buffers for a NHDP interface address
572  * @param if_addr interface NHDP address
573  */
574 static void
575 _initialize_interface_address_values(struct nhdp_interface_addr *if_addr) {
576   netaddr_to_string(&_value_if_address, &if_addr->if_addr);
577
578   strscpy(_value_if_address_lost, json_getbool(if_addr->removed),
579       sizeof(_value_if_address_lost));
580
581   if (oonf_timer_is_active(&if_addr->_vtime)) {
582     uint64_t due = oonf_timer_get_due(&if_addr->_vtime);
583     oonf_clock_toIntervalString(&_value_if_address_vtime, due);
584   }
585   else {
586     strscpy(_value_if_address_vtime.buf, "-1", sizeof(_value_if_address_vtime));
587   }
588 }
589
590 /**
591  * Initialize the value buffers for a NHDP link
592  * @param lnk NHDP link
593  */
594 static void
595 _initialize_nhdp_link_values(struct nhdp_link *lnk) {
596   netaddr_to_string(&_value_link_bindto, &lnk->if_addr);
597
598   oonf_clock_toIntervalString(&_value_link_vtime_value, lnk->vtime_value);
599   oonf_clock_toIntervalString(&_value_link_itime_value, lnk->itime_value);
600
601   oonf_clock_toIntervalString(&_value_link_symtime,
602       oonf_timer_get_due(&lnk->sym_time));
603   oonf_clock_toIntervalString(&_value_link_heardtime,
604       oonf_timer_get_due(&lnk->heard_time));
605   oonf_clock_toIntervalString(&_value_link_vtime,
606       oonf_timer_get_due(&lnk->vtime));
607
608   strscpy(_value_link_status, nhdp_db_link_status_to_string(lnk),
609       sizeof(_value_link_status));
610
611   if (lnk->dualstack_partner) {
612     netaddr_to_string(
613         &_value_link_dualstack, &lnk->dualstack_partner->if_addr);
614   }
615   else {
616     strscpy(_value_link_dualstack.buf, "-", sizeof(_value_link_dualstack));
617   }
618
619   netaddr_to_string(&_value_link_mac, &lnk->remote_mac);
620 }
621
622 /**
623  * Initialize the value buffers for NHDP domain metric values
624  * @param domain NHDP domain
625  * @param metric NHDP metric
626  */
627 static void
628 _initialize_nhdp_domain_metric_values(struct nhdp_domain *domain,
629     struct nhdp_metric *metric) {
630   snprintf(_value_domain, sizeof(_value_domain), "%u", domain->ext);
631   strscpy(_value_domain_metric, domain->metric->name, sizeof(_value_domain_metric));
632
633   nhdp_domain_get_link_metric_value(&_value_domain_metric_in, domain, metric->in);
634   nhdp_domain_get_link_metric_value(&_value_domain_metric_out, domain, metric->out);
635
636   snprintf(_value_domain_metric_in_raw,
637       sizeof(_value_domain_metric_in_raw), "%u", metric->in);
638   snprintf(_value_domain_metric_out_raw,
639       sizeof(_value_domain_metric_out_raw), "%u", metric->out);
640 }
641
642 /**
643  * Initialize the value buffers for a NHDP domain MPR values
644  * @param domain NHDP domain
645  * @param domaindata NHDP neighbor domain data
646  */
647 static void
648 _initialize_nhdp_neighbor_mpr_values(struct nhdp_domain *domain,
649     struct nhdp_neighbor_domaindata *domaindata) {
650   snprintf(_value_domain, sizeof(_value_domain), "%u", domain->ext);
651   strscpy(_value_domain_mpr, domain->mpr->name, sizeof(_value_domain_mpr));
652
653   strscpy(_value_domain_mpr_local,
654       json_getbool(domaindata->local_is_mpr),
655       sizeof(_value_domain_mpr_local));
656
657   strscpy(_value_domain_mpr_remote,
658       json_getbool(domaindata->neigh_is_mpr),
659       sizeof(_value_domain_mpr_remote));
660
661   snprintf(_value_domain_mpr_will, sizeof(_value_domain_mpr_will),
662       "%d", domaindata->willingness);
663 }
664
665 static void
666 _initialize_nhdp_domain_metric_int_values(struct nhdp_domain *domain,
667     struct nhdp_link *lnk) {
668   nhdp_domain_get_internal_link_metric_value(
669       &_value_domain_metric_internal, domain->metric, lnk);
670 }
671
672 /**
673  * Initialize the value buffers for a NHDP link address
674  * @param laddr NHDP link address
675  */
676 static void
677 _initialize_nhdp_link_address_values(struct nhdp_laddr *laddr) {
678   netaddr_to_string(&_value_link_address, &laddr->link_addr);
679 }
680
681 /**
682  * Initialize the value buffers for a NHDP link twohop address
683  * @param twohop NHDP twohop address
684  */
685 static void
686 _initialize_nhdp_link_twohop_values(struct nhdp_l2hop *twohop) {
687   netaddr_to_string(&_value_twohop_address, &twohop->twohop_addr);
688
689   strscpy(_value_twohop_sameif,
690       json_getbool(twohop->same_interface),
691       sizeof(_value_twohop_sameif));
692
693   oonf_clock_toIntervalString(&_value_twohop_vtime,
694       oonf_timer_get_due(&twohop->_vtime));
695 }
696
697 /**
698  * Initialize the value buffers for a NHDP neighbor
699  * @param neigh NHDP neighbor
700  */
701 static void
702 _initialize_nhdp_neighbor_values(struct nhdp_neighbor *neigh) {
703   netaddr_to_string(&_value_neighbor_originator, &neigh->originator);
704   if (neigh->dualstack_partner) {
705     netaddr_to_string(
706         &_value_neighbor_dualstack, &neigh->dualstack_partner->originator);
707   }
708   else {
709     strscpy(_value_neighbor_dualstack.buf, "-", sizeof(_value_neighbor_dualstack));
710   }
711
712   strscpy(_value_neighbor_flood_local,
713       json_getbool(neigh->local_is_flooding_mpr),
714       sizeof(_value_neighbor_flood_local));
715   strscpy(_value_neighbor_flood_remote,
716       json_getbool(neigh->neigh_is_flooding_mpr),
717       sizeof(_value_neighbor_flood_remote));
718   snprintf(_value_neighbor_willingness, sizeof(_value_neighbor_willingness),
719       "%d", neigh->flooding_willingness);
720
721   strscpy(_value_neighbor_symmetric,
722       json_getbool(neigh->symmetric > 0),
723       sizeof(_value_neighbor_symmetric));
724   snprintf(_value_neighbor_linkcount, sizeof(_value_neighbor_linkcount),
725       "%d", neigh->symmetric);
726 }
727
728 /**
729  * Initialize the value buffers for a NHDP neighbor address
730  * @param naddr NHDP neighbor address
731  */
732 static void
733 _initialize_nhdp_neighbor_address_values(struct nhdp_naddr *naddr) {
734   netaddr_to_string(&_value_neighbor_address, &naddr->neigh_addr);
735
736   strscpy(_value_neighbor_address_lost,
737       json_getbool(oonf_timer_is_active(&naddr->_lost_vtime)),
738       sizeof(_value_neighbor_address_lost));
739
740   oonf_clock_toIntervalString(&_value_neighbor_address_lost_vtime,
741       oonf_timer_get_due(&naddr->_lost_vtime));
742 }
743
744 /**
745  * Displays the known data about each NHDP interface.
746  * @param template oonf viewer template
747  * @return -1 if an error happened, 0 otherwise
748  */
749 static int
750 _cb_create_text_interface(struct oonf_viewer_template *template) {
751   struct nhdp_interface *nhdpif;
752
753   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
754     _initialize_interface_values(nhdpif);
755
756     /* generate template output */
757     oonf_viewer_output_print_line(template);
758   }
759   return 0;
760 }
761
762 /**
763  * Displays the addresses of a NHDP interface.
764  * @param template oonf viewer template
765  * @return -1 if an error happened, 0 otherwise
766  */
767 static int
768 _cb_create_text_if_address(struct oonf_viewer_template *template) {
769   struct nhdp_interface *nhdp_if;
770   struct nhdp_interface_addr *nhdp_addr;
771
772   avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
773     /* fill output buffers for template engine */
774     _initialize_interface_values(nhdp_if);
775
776     avl_for_each_element(&nhdp_if->_if_addresses, nhdp_addr, _if_node) {
777       /* fill address specific output buffers for template engine */
778       _initialize_interface_address_values(nhdp_addr);
779
780       /* generate template output */
781       oonf_viewer_output_print_line(template);
782     }
783   }
784   return 0;
785 }
786
787 /**
788  * Displays the data of a NHDP link.
789  * @param template oonf viewer template
790  * @return -1 if an error happened, 0 otherwise
791  */
792 static int
793 _cb_create_text_link(struct oonf_viewer_template *template) {
794   struct nhdp_interface *nhdp_if;
795   struct nhdp_link *nlink;
796   struct nhdp_domain *domain;
797
798   avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
799     /* fill output buffers for template engine */
800     _initialize_interface_values(nhdp_if);
801
802     list_for_each_element(&nhdp_if->_links, nlink, _if_node) {
803       _initialize_nhdp_link_values(nlink);
804       _initialize_nhdp_neighbor_values(nlink->neigh);
805
806       list_for_each_element(nhdp_domain_get_list(), domain, _node) {
807         _initialize_nhdp_domain_metric_values(domain,
808             &(nhdp_domain_get_linkdata(domain, nlink)->metric));
809         _initialize_nhdp_domain_metric_int_values(domain, nlink);
810
811         /* generate template output */
812         oonf_viewer_output_print_line(template);
813       }
814     }
815   }
816   return 0;
817 }
818
819 /**
820  * Displays the addresses of a NHDP link.
821  * @param template oonf viewer template
822  * @return -1 if an error happened, 0 otherwise
823  */
824 static int
825 _cb_create_text_link_address(struct oonf_viewer_template *template) {
826   struct nhdp_interface *nhdpif;
827   struct nhdp_link *nhdplink;
828   struct nhdp_laddr *laddr;
829
830   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
831     /* fill output buffers for template engine */
832     _initialize_interface_values(nhdpif);
833
834     list_for_each_element(&nhdpif->_links, nhdplink, _if_node) {
835       _initialize_nhdp_link_values(nhdplink);
836       _initialize_nhdp_neighbor_values(nhdplink->neigh);
837
838       avl_for_each_element(&nhdplink->_addresses, laddr, _link_node) {
839         _initialize_nhdp_link_address_values(laddr);
840
841         /* generate template output */
842         oonf_viewer_output_print_line(template);
843       }
844     }
845   }
846   return 0;
847 }
848
849 /**
850  * Displays the twohop neighbors of a NHDP link.
851  * @param template oonf viewer template
852  * @return -1 if an error happened, 0 otherwise
853  */
854 static int
855 _cb_create_text_link_twohop(struct oonf_viewer_template *template) {
856   struct nhdp_interface *nhdpif;
857   struct nhdp_link *nhdplink;
858   struct nhdp_l2hop *twohop;
859   struct nhdp_domain *domain;
860
861   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
862     /* fill output buffers for template engine */
863     _initialize_interface_values(nhdpif);
864
865     list_for_each_element(&nhdpif->_links, nhdplink, _if_node) {
866       _initialize_nhdp_link_values(nhdplink);
867       _initialize_nhdp_neighbor_values(nhdplink->neigh);
868
869       avl_for_each_element(&nhdplink->_2hop, twohop, _link_node) {
870         _initialize_nhdp_link_twohop_values(twohop);
871
872         list_for_each_element(nhdp_domain_get_list(), domain, _node) {
873           _initialize_nhdp_domain_metric_values(domain,
874               &nhdp_domain_get_l2hopdata(domain, twohop)->metric);
875
876           /* generate template output */
877           oonf_viewer_output_print_line(template);
878         }
879       }
880     }
881   }
882   return 0;
883 }
884
885 /**
886  * Displays the data of a NHDP neighbor.
887  * @param template oonf viewer template
888  * @return -1 if an error happened, 0 otherwise
889  */
890 static int
891 _cb_create_text_neighbor(struct oonf_viewer_template *template) {
892   struct nhdp_neighbor *neigh;
893   struct nhdp_domain *domain;
894
895   list_for_each_element(nhdp_db_get_neigh_list(), neigh, _global_node) {
896     _initialize_nhdp_neighbor_values(neigh);
897
898     list_for_each_element(nhdp_domain_get_list(), domain, _node) {
899       struct nhdp_neighbor_domaindata *data;
900
901       data = nhdp_domain_get_neighbordata(domain, neigh);
902
903       _initialize_nhdp_domain_metric_values(domain, &data->metric);
904       _initialize_nhdp_neighbor_mpr_values(domain, data);
905
906       /* generate template output */
907       oonf_viewer_output_print_line(template);
908     }
909   }
910   return 0;
911 }
912
913 /**
914  * Displays the addresses of a NHDP neighbor.
915  * @param template oonf viewer template
916  * @return -1 if an error happened, 0 otherwise
917  */
918 static int
919 _cb_create_text_neighbor_address(struct oonf_viewer_template *template) {
920   struct nhdp_neighbor *neigh;
921   struct nhdp_naddr *naddr;
922
923   list_for_each_element(nhdp_db_get_neigh_list(), neigh, _global_node) {
924     _initialize_nhdp_neighbor_values(neigh);
925
926     avl_for_each_element(&neigh->_neigh_addresses, naddr, _neigh_node) {
927       _initialize_nhdp_neighbor_address_values(naddr);
928
929       /* generate template output */
930       oonf_viewer_output_print_line(template);
931     }
932   }
933   return 0;
934 }