15892cc534a054781070de5245442b1b30856353
[oonf.git] / src / 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 <oonf/libcommon/autobuf.h>
47 #include <oonf/oonf.h>
48 #include <oonf/libcommon/template.h>
49
50 #include <oonf/libcore/oonf_logging.h>
51 #include <oonf/libcore/oonf_subsystem.h>
52 #include <oonf/subsystems/oonf_clock.h>
53 #include <oonf/subsystems/oonf_telnet.h>
54 #include <oonf/subsystems/oonf_viewer.h>
55
56 #include <oonf/nhdp/nhdp/nhdp_db.h>
57 #include <oonf/nhdp/nhdp/nhdp_domain.h>
58 #include <oonf/nhdp/nhdp/nhdp_interfaces.h>
59
60 #include <oonf/nhdp/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, struct nhdp_metric *metric);
76 static void _initialize_nhdp_neighbor_mpr_values(
77   struct nhdp_domain *domain, struct nhdp_neighbor_domaindata *domaindata);
78 static void _initialize_nhdp_domain_metric_int_values(struct nhdp_domain *domain, struct nhdp_link *lnk);
79 static void _initialize_nhdp_link_address_values(struct nhdp_laddr *laddr);
80 static void _initialize_nhdp_link_twohop_values(struct nhdp_l2hop *twohop);
81 static void _initialize_nhdp_neighbor_values(struct nhdp_neighbor *neigh);
82 static void _initialize_nhdp_neighbor_address_values(struct nhdp_naddr *naddr);
83
84 static int _cb_create_text_interface(struct oonf_viewer_template *);
85 static int _cb_create_text_if_address(struct oonf_viewer_template *);
86 static int _cb_create_text_link(struct oonf_viewer_template *);
87 static int _cb_create_text_link_address(struct oonf_viewer_template *);
88 static int _cb_create_text_link_twohop(struct oonf_viewer_template *);
89 static int _cb_create_text_neighbor(struct oonf_viewer_template *);
90 static int _cb_create_text_neighbor_address(struct oonf_viewer_template *);
91
92 /*
93  * list of template keys and corresponding buffers for values.
94  *
95  * The keys are API, so they should not be changed after published
96  */
97
98 /*! template key for interface name */
99 #define KEY_IF "if"
100
101 /*! template key for interface IPv4 socket address */
102 #define KEY_IF_BINDTO_V4 "if_bindto_v4"
103
104 /*! template key for interface IPv6 socket address */
105 #define KEY_IF_BINDTO_V6 "if_bindto_v6"
106
107 /*! template key for interface MAP address */
108 #define KEY_IF_MAC "if_mac"
109
110 /*! template key for IPv4 flooding flag */
111 #define KEY_IF_FLOODING_V4 "if_flooding_v4"
112
113 /*! template key for IPv6 flooding flag */
114 #define KEY_IF_FLOODING_V6 "if_flooding_v6"
115
116 /*! template key for dualstack mode */
117 #define KEY_IF_DUALSTACK_MODE "if_dualstack_mode"
118
119 /*! template key for an interface address */
120 #define KEY_IF_ADDRESS "if_address"
121
122 /*! template key for a lost interface address */
123 #define KEY_IF_ADDRESS_LOST "if_address_lost"
124
125 /*! template key for validity time of a lost interface address */
126 #define KEY_IF_ADDRESS_LOST_VTIME "if_address_lost_vtime"
127
128 /*! template key for the links remote socket IP address */
129 #define KEY_LINK_BINDTO "link_bindto"
130
131 /*! template key for the validity time of the link */
132 #define KEY_LINK_VTIME_VALUE "link_vtime_value"
133
134 /*! template key for the interval time of the link */
135 #define KEY_LINK_ITIME_VALUE "link_itime_value"
136
137 /*! template key for the time the link will still be symmetric */
138 #define KEY_LINK_SYMTIME "link_symtime"
139
140 /*! template key for the time the link will still be heard */
141 #define KEY_LINK_HEARDTIME "link_heardtime"
142
143 /*! template key for validity time of the link */
144 #define KEY_LINK_VTIME "link_vtime"
145
146 /*! template key for link status */
147 #define KEY_LINK_STATUS "link_status"
148
149 /*! template key for links local dualstack IP address */
150 #define KEY_LINK_DUALSTACK "link_dualstack"
151
152 /*! template key for links remote mac address */
153 #define KEY_LINK_MAC "link_mac"
154
155 /*! template key signaling link has selected node as flooding MPR */
156 #define KEY_LINK_FLOOD_LOCAL "link_flood_local"
157
158 /*! template key signaling route has selected link as flooding MPR */
159 #define KEY_LINK_FLOOD_REMOTE "link_flood_remote"
160
161 /*! template key for link flooding willingness */
162 #define KEY_LINK_FLOOD_WILL "link_flood_willingness"
163
164 /*! template key for a link IP address */
165 #define KEY_LINK_ADDRESS "link_address"
166
167 /*! template key for an IP address of a two-hop link */
168 #define KEY_TWOHOP_ADDRESS "twohop_address"
169
170 /*! template key for the flag to signal a two-hop link on the same interface */
171 #define KEY_TWOHOP_SAMEIF "twohop_same_interface"
172
173 /*! template key for the validity time of a two-hop link */
174 #define KEY_TWOHOP_VTIME "twohop_vtime"
175
176 /*! template key for neighbors originator IP */
177 #define KEY_NEIGHBOR_ORIGINATOR "neighbor_originator"
178
179 /*! template key for neighbors dualstack originator IP */
180 #define KEY_NEIGHBOR_DUALSTACK "neighbor_dualstack"
181
182 /*! template key for number of symmetric links of neighbor */
183 #define KEY_NEIGHBOR_SYMMETRIC "neighbor_symmetric"
184
185 /*! template key for number of links of neighbor */
186 #define KEY_NEIGHBOR_LINKCOUNT "neighbor_linkcount"
187
188 /*! template key for neighbor address */
189 #define KEY_NEIGHBOR_ADDRESS "neighbor_address"
190
191 /*! template key for lost neighbor address */
192 #define KEY_NEIGHBOR_ADDRESS_LOST "neighbor_address_lost"
193
194 /*! template key for validity time of lost neighbor address */
195 #define KEY_NEIGHBOR_ADDRESS_VTIME "neighbor_address_lost_vtime"
196
197 /*! template key for NHDP domain */
198 #define KEY_DOMAIN "domain"
199
200 /*! template key for NHDP domain metric name */
201 #define KEY_DOMAIN_METRIC "domain_metric"
202
203 /*! template key for incoming human readable metric */
204 #define KEY_DOMAIN_METRIC_IN "domain_metric_in"
205
206 /*! template key for outgoing human readable metric */
207 #define KEY_DOMAIN_METRIC_OUT "domain_metric_out"
208
209 /*! template key for incoming numeric metric */
210 #define KEY_DOMAIN_METRIC_IN_RAW "domain_metric_in_raw"
211
212 /*! template key for outgoing numeric metric */
213 #define KEY_DOMAIN_METRIC_OUT_RAW "domain_metric_out_raw"
214
215 /*! template key for internal metric representation */
216 #define KEY_DOMAIN_METRIC_INTERNAL "domain_metric_internal"
217
218 /*! template key for NHDP domain MPR name */
219 #define KEY_DOMAIN_MPR "domain_mpr"
220
221 /*! template key signaling local node is selected as routing MPR */
222 #define KEY_DOMAIN_MPR_LOCAL "domain_mpr_local"
223
224 /*! template key signaling remote node has been selected as routing MPR */
225 #define KEY_DOMAIN_MPR_REMOTE "domain_mpr_remote"
226
227 /*! template key for routing willingness */
228 #define KEY_DOMAIN_MPR_WILL "domain_mpr_willingness"
229
230 /*
231  * buffer space for values that will be assembled
232  * into the output of the plugin
233  */
234 static char _value_if[IF_NAMESIZE];
235 static struct netaddr_str _value_if_bindto_v4;
236 static struct netaddr_str _value_if_bindto_v6;
237 static struct netaddr_str _value_if_mac;
238 static char _value_if_flooding_v4[TEMPLATE_JSON_BOOL_LENGTH];
239 static char _value_if_flooding_v6[TEMPLATE_JSON_BOOL_LENGTH];
240 static char _value_if_dualstack_mode[5];
241 static struct netaddr_str _value_if_address;
242 static char _value_if_address_lost[TEMPLATE_JSON_BOOL_LENGTH];
243 static struct isonumber_str _value_if_address_vtime;
244
245 static struct netaddr_str _value_link_bindto;
246 static struct isonumber_str _value_link_vtime_value;
247 static struct isonumber_str _value_link_itime_value;
248 static struct isonumber_str _value_link_symtime;
249 static struct isonumber_str _value_link_heardtime;
250 static struct isonumber_str _value_link_vtime;
251 static char _value_link_status[NHDP_LINK_STATUS_TXTLENGTH];
252 static struct netaddr_str _value_link_dualstack;
253 static struct netaddr_str _value_link_mac;
254 static char _value_link_flood_local[TEMPLATE_JSON_BOOL_LENGTH];
255 static char _value_link_flood_remote[TEMPLATE_JSON_BOOL_LENGTH];
256 static char _value_link_willingness[3];
257
258 static struct netaddr_str _value_link_address;
259
260 static struct netaddr_str _value_twohop_address;
261 static char _value_twohop_sameif[TEMPLATE_JSON_BOOL_LENGTH];
262 static struct isonumber_str _value_twohop_vtime;
263
264 static struct netaddr_str _value_neighbor_originator;
265 static struct netaddr_str _value_neighbor_dualstack;
266 static char _value_neighbor_symmetric[TEMPLATE_JSON_BOOL_LENGTH];
267 static char _value_neighbor_linkcount[10];
268 static struct netaddr_str _value_neighbor_address;
269 static char _value_neighbor_address_lost[TEMPLATE_JSON_BOOL_LENGTH];
270 static struct isonumber_str _value_neighbor_address_lost_vtime;
271
272 static char _value_domain[4];
273 static char _value_domain_metric[NHDP_DOMAIN_METRIC_MAXLEN];
274 static struct nhdp_metric_str _value_domain_metric_in;
275 static struct nhdp_metric_str _value_domain_metric_out;
276 static char _value_domain_metric_in_raw[12];
277 static char _value_domain_metric_out_raw[12];
278 static struct nhdp_metric_str _value_domain_metric_internal;
279 static char _value_domain_mpr[NHDP_DOMAIN_MPR_MAXLEN];
280 static char _value_domain_mpr_local[TEMPLATE_JSON_BOOL_LENGTH];
281 static char _value_domain_mpr_remote[TEMPLATE_JSON_BOOL_LENGTH];
282 static char _value_domain_mpr_will[3];
283
284 /* definition of the template data entries for JSON and table output */
285 static struct abuf_template_data_entry _tde_if_key[] = {
286   { KEY_IF, _value_if, true },
287 };
288
289 static struct abuf_template_data_entry _tde_if[] = {
290   { KEY_IF, _value_if, true },
291   { KEY_IF_BINDTO_V4, _value_if_bindto_v4.buf, true },
292   { KEY_IF_BINDTO_V6, _value_if_bindto_v6.buf, true },
293   { KEY_IF_MAC, _value_if_mac.buf, true },
294   { KEY_IF_FLOODING_V4, _value_if_flooding_v4, true },
295   { KEY_IF_FLOODING_V6, _value_if_flooding_v6, true },
296   { KEY_IF_DUALSTACK_MODE, _value_if_dualstack_mode, true },
297 };
298
299 static struct abuf_template_data_entry _tde_if_addr[] = {
300   { KEY_IF_ADDRESS, _value_if_address.buf, true },
301   { KEY_IF_ADDRESS_LOST, _value_if_address_lost, true },
302   { KEY_IF_ADDRESS_LOST_VTIME, _value_if_address_vtime.buf, false },
303 };
304
305 static struct abuf_template_data_entry _tde_link_key[] = {
306   { KEY_LINK_BINDTO, _value_link_bindto.buf, true },
307   { KEY_NEIGHBOR_ORIGINATOR, _value_neighbor_originator.buf, true },
308 };
309
310 static struct abuf_template_data_entry _tde_link[] = {
311   { KEY_LINK_BINDTO, _value_link_bindto.buf, true },
312   { KEY_LINK_VTIME_VALUE, _value_link_vtime_value.buf, false },
313   { KEY_LINK_ITIME_VALUE, _value_link_itime_value.buf, false },
314   { KEY_LINK_SYMTIME, _value_link_symtime.buf, false },
315   { KEY_LINK_HEARDTIME, _value_link_heardtime.buf, false },
316   { KEY_LINK_VTIME, _value_link_vtime.buf, false },
317   { KEY_LINK_STATUS, _value_link_status, true },
318   { KEY_LINK_DUALSTACK, _value_link_dualstack.buf, true },
319   { KEY_LINK_MAC, _value_link_mac.buf, true },
320   { KEY_LINK_FLOOD_LOCAL, _value_link_flood_local, true },
321   { KEY_LINK_FLOOD_REMOTE, _value_link_flood_remote, true },
322   { KEY_LINK_FLOOD_WILL, _value_link_willingness, false },
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_SYMMETRIC, _value_neighbor_symmetric, true },
366   { KEY_NEIGHBOR_LINKCOUNT, _value_neighbor_linkcount, false },
367 };
368
369 static struct abuf_template_data_entry _tde_neigh_addr[] = {
370   { KEY_NEIGHBOR_ADDRESS, _value_neighbor_address.buf, true },
371   { KEY_NEIGHBOR_ADDRESS_LOST, _value_neighbor_address_lost, true },
372   { KEY_NEIGHBOR_ADDRESS_VTIME, _value_neighbor_address_lost_vtime.buf, false },
373 };
374
375 static struct abuf_template_storage _template_storage;
376
377 /* Template Data objects (contain one or more Template Data Entries) */
378 static struct abuf_template_data _td_if[] = {
379   { _tde_if, ARRAYSIZE(_tde_if) },
380 };
381 static struct abuf_template_data _td_if_addr[] = {
382   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
383   { _tde_if_addr, ARRAYSIZE(_tde_if_addr) },
384 };
385 static struct abuf_template_data _td_link[] = {
386   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
387   { _tde_link, ARRAYSIZE(_tde_link) },
388   { _tde_domain, ARRAYSIZE(_tde_domain) },
389   { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
390   { _tde_domain_metric_int, ARRAYSIZE(_tde_domain_metric_int) },
391 };
392 static struct abuf_template_data _td_link_addr[] = {
393   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
394   { _tde_link_key, ARRAYSIZE(_tde_link_key) },
395   { _tde_link_addr, ARRAYSIZE(_tde_link_addr) },
396 };
397 static struct abuf_template_data _td_twohop_addr[] = {
398   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
399   { _tde_link_key, ARRAYSIZE(_tde_link_key) },
400   { _tde_twohop_addr, ARRAYSIZE(_tde_twohop_addr) },
401   { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
402 };
403 static struct abuf_template_data _td_neigh[] = {
404   { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
405   { _tde_neigh, ARRAYSIZE(_tde_neigh) },
406   { _tde_domain, ARRAYSIZE(_tde_domain) },
407   { _tde_domain_metric, ARRAYSIZE(_tde_domain_metric) },
408   { _tde_domain_mpr, ARRAYSIZE(_tde_domain_mpr) },
409 };
410 static struct abuf_template_data _td_neigh_addr[] = {
411   { _tde_neigh_key, ARRAYSIZE(_tde_neigh_key) },
412   { _tde_neigh_addr, ARRAYSIZE(_tde_neigh_addr) },
413 };
414
415 /* OONF viewer templates (based on Template Data arrays) */
416 static struct oonf_viewer_template _templates[] = { {
417                                                       .data = _td_if,
418                                                       .data_size = ARRAYSIZE(_td_if),
419                                                       .json_name = "interface",
420                                                       .cb_function = _cb_create_text_interface,
421                                                     },
422   {
423     .data = _td_if_addr,
424     .data_size = ARRAYSIZE(_td_if_addr),
425     .json_name = "if_addr",
426     .cb_function = _cb_create_text_if_address,
427   },
428   {
429     .data = _td_link,
430     .data_size = ARRAYSIZE(_td_link),
431     .json_name = "link",
432     .cb_function = _cb_create_text_link,
433   },
434   {
435     .data = _td_link_addr,
436     .data_size = ARRAYSIZE(_td_link_addr),
437     .json_name = "link_addr",
438     .cb_function = _cb_create_text_link_address,
439   },
440   {
441     .data = _td_twohop_addr,
442     .data_size = ARRAYSIZE(_td_twohop_addr),
443     .json_name = "link_twohop",
444     .cb_function = _cb_create_text_link_twohop,
445   },
446   {
447     .data = _td_neigh,
448     .data_size = ARRAYSIZE(_td_neigh),
449     .json_name = "neighbor",
450     .cb_function = _cb_create_text_neighbor,
451   },
452   {
453     .data = _td_neigh_addr,
454     .data_size = ARRAYSIZE(_td_neigh_addr),
455     .json_name = "neighbor_addr",
456     .cb_function = _cb_create_text_neighbor_address,
457   } };
458
459 /* telnet command of this plugin */
460 static struct oonf_telnet_command _telnet_commands[] = {
461   TELNET_CMD(OONF_NHDPINFO_SUBSYSTEM, _cb_nhdpinfo, "", .help_handler = _cb_nhdpinfo_help),
462 };
463
464 /* plugin declaration */
465 static const char *_dependencies[] = {
466   OONF_CLOCK_SUBSYSTEM,
467   OONF_TELNET_SUBSYSTEM,
468   OONF_VIEWER_SUBSYSTEM,
469   OONF_NHDP_SUBSYSTEM,
470 };
471 static struct oonf_subsystem _olsrv2_nhdpinfo_subsystem = {
472   .name = OONF_NHDPINFO_SUBSYSTEM,
473   .dependencies = _dependencies,
474   .dependencies_count = ARRAYSIZE(_dependencies),
475   .descr = "NHDPinfo plugin",
476   .author = "Henning Rogge",
477   .init = _init,
478   .cleanup = _cleanup,
479 };
480 DECLARE_OONF_PLUGIN(_olsrv2_nhdpinfo_subsystem);
481
482 /**
483  * Initialize plugin
484  * @return always returns 0
485  */
486 static int
487 _init(void) {
488   oonf_telnet_add(&_telnet_commands[0]);
489   return 0;
490 }
491
492 /**
493  * Cleanup plugin
494  */
495 static void
496 _cleanup(void) {
497   oonf_telnet_remove(&_telnet_commands[0]);
498 }
499
500 /**
501  * Callback for the telnet command of this plugin
502  * @param con pointer to telnet session data
503  * @return telnet result value
504  */
505 static enum oonf_telnet_result
506 _cb_nhdpinfo(struct oonf_telnet_data *con) {
507   return oonf_viewer_telnet_handler(
508     con->out, &_template_storage, OONF_NHDPINFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
509 }
510
511 /**
512  * Callback for the help output of this plugin
513  * @param con pointer to telnet session data
514  * @return telnet result value
515  */
516 static enum oonf_telnet_result
517 _cb_nhdpinfo_help(struct oonf_telnet_data *con) {
518   return oonf_viewer_telnet_help(con->out, OONF_NHDPINFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
519 }
520
521 /**
522  * Initialize the value buffers for a NHDP interface
523  * @param nhdp_if nhdp interface
524  */
525 static void
526 _initialize_interface_values(struct nhdp_interface *nhdp_if) {
527   struct os_interface_listener *if_listener;
528   struct netaddr temp_addr;
529
530   if_listener = nhdp_interface_get_if_listener(nhdp_if);
531
532   /* fill output buffers for template engine */
533   strscpy(_value_if, nhdp_interface_get_name(nhdp_if), sizeof(_value_if));
534
535   netaddr_from_socket(&temp_addr, &nhdp_if->rfc5444_if.interface->_socket.socket_v4.local_socket);
536   netaddr_to_string(&_value_if_bindto_v4, &temp_addr);
537
538   netaddr_from_socket(&temp_addr, &nhdp_if->rfc5444_if.interface->_socket.socket_v6.local_socket);
539   netaddr_to_string(&_value_if_bindto_v6, &temp_addr);
540
541   netaddr_to_string(&_value_if_mac, &if_listener->data->mac);
542
543   strscpy(_value_if_flooding_v4, json_getbool(nhdp_if->use_ipv4_for_flooding), TEMPLATE_JSON_BOOL_LENGTH);
544
545   strscpy(_value_if_flooding_v6, json_getbool(nhdp_if->use_ipv6_for_flooding), TEMPLATE_JSON_BOOL_LENGTH);
546
547   if (nhdp_if->dualstack_af_type == AF_INET) {
548     strscpy(_value_if_dualstack_mode, "IPv4", sizeof(_value_if_dualstack_mode));
549   }
550   else if (nhdp_if->dualstack_af_type == AF_INET6) {
551     strscpy(_value_if_dualstack_mode, "IPv6", sizeof(_value_if_dualstack_mode));
552   }
553   else {
554     strscpy(_value_if_dualstack_mode, "-", sizeof(_value_if_dualstack_mode));
555   }
556 }
557
558 /**
559  * Initialize the value buffers for a NHDP interface address
560  * @param if_addr interface NHDP address
561  */
562 static void
563 _initialize_interface_address_values(struct nhdp_interface_addr *if_addr) {
564   netaddr_to_string(&_value_if_address, &if_addr->if_addr);
565
566   strscpy(_value_if_address_lost, json_getbool(if_addr->removed), sizeof(_value_if_address_lost));
567
568   if (oonf_timer_is_active(&if_addr->_vtime)) {
569     uint64_t due = oonf_timer_get_due(&if_addr->_vtime);
570     oonf_clock_toIntervalString(&_value_if_address_vtime, due);
571   }
572   else {
573     strscpy(_value_if_address_vtime.buf, "-1", sizeof(_value_if_address_vtime));
574   }
575 }
576
577 /**
578  * Initialize the value buffers for a NHDP link
579  * @param lnk NHDP link
580  */
581 static void
582 _initialize_nhdp_link_values(struct nhdp_link *lnk) {
583   netaddr_to_string(&_value_link_bindto, &lnk->if_addr);
584
585   oonf_clock_toIntervalString(&_value_link_vtime_value, lnk->vtime_value);
586   oonf_clock_toIntervalString(&_value_link_itime_value, lnk->itime_value);
587
588   oonf_clock_toIntervalString(&_value_link_symtime, oonf_timer_get_due(&lnk->sym_time));
589   oonf_clock_toIntervalString(&_value_link_heardtime, oonf_timer_get_due(&lnk->heard_time));
590   oonf_clock_toIntervalString(&_value_link_vtime, oonf_timer_get_due(&lnk->vtime));
591
592   strscpy(_value_link_status, nhdp_db_link_status_to_string(lnk), sizeof(_value_link_status));
593
594   if (lnk->dualstack_partner) {
595     netaddr_to_string(&_value_link_dualstack, &lnk->dualstack_partner->if_addr);
596   }
597   else {
598     strscpy(_value_link_dualstack.buf, "-", sizeof(_value_link_dualstack));
599   }
600
601   netaddr_to_string(&_value_link_mac, &lnk->remote_mac);
602
603   strscpy(_value_link_flood_local, json_getbool(lnk->local_is_flooding_mpr), sizeof(_value_link_flood_local));
604   strscpy(_value_link_flood_remote, json_getbool(lnk->neigh_is_flooding_mpr), sizeof(_value_link_flood_remote));
605   snprintf(_value_link_willingness, sizeof(_value_link_willingness), "%u", lnk->flooding_willingness & 15);
606 }
607
608 /**
609  * Initialize the value buffers for NHDP domain metric values
610  * @param domain NHDP domain
611  * @param metric NHDP metric
612  */
613 static void
614 _initialize_nhdp_domain_metric_values(struct nhdp_domain *domain, struct nhdp_metric *metric) {
615   snprintf(_value_domain, sizeof(_value_domain), "%u", domain->ext);
616   strscpy(_value_domain_metric, domain->metric->name, sizeof(_value_domain_metric));
617
618   nhdp_domain_get_link_metric_value(&_value_domain_metric_in, domain, metric->in);
619   nhdp_domain_get_link_metric_value(&_value_domain_metric_out, domain, metric->out);
620
621   snprintf(_value_domain_metric_in_raw, sizeof(_value_domain_metric_in_raw), "%u", metric->in);
622   snprintf(_value_domain_metric_out_raw, sizeof(_value_domain_metric_out_raw), "%u", metric->out);
623 }
624
625 /**
626  * Initialize the value buffers for a NHDP domain MPR values
627  * @param domain NHDP domain
628  * @param domaindata NHDP neighbor domain data
629  */
630 static void
631 _initialize_nhdp_neighbor_mpr_values(struct nhdp_domain *domain, struct nhdp_neighbor_domaindata *domaindata) {
632   snprintf(_value_domain, sizeof(_value_domain), "%u", domain->ext);
633   strscpy(_value_domain_mpr, domain->mpr->name, sizeof(_value_domain_mpr));
634
635   strscpy(_value_domain_mpr_local, json_getbool(domaindata->local_is_mpr), sizeof(_value_domain_mpr_local));
636
637   strscpy(_value_domain_mpr_remote, json_getbool(domaindata->neigh_is_mpr), sizeof(_value_domain_mpr_remote));
638
639   snprintf(_value_domain_mpr_will, sizeof(_value_domain_mpr_will), "%1u", domaindata->willingness & 15);
640 }
641
642 static void
643 _initialize_nhdp_domain_metric_int_values(struct nhdp_domain *domain, struct nhdp_link *lnk) {
644   nhdp_domain_get_internal_link_metric_value(&_value_domain_metric_internal, domain->metric, lnk);
645 }
646
647 /**
648  * Initialize the value buffers for a NHDP link address
649  * @param laddr NHDP link address
650  */
651 static void
652 _initialize_nhdp_link_address_values(struct nhdp_laddr *laddr) {
653   netaddr_to_string(&_value_link_address, &laddr->link_addr);
654 }
655
656 /**
657  * Initialize the value buffers for a NHDP link twohop address
658  * @param twohop NHDP twohop address
659  */
660 static void
661 _initialize_nhdp_link_twohop_values(struct nhdp_l2hop *twohop) {
662   netaddr_to_string(&_value_twohop_address, &twohop->twohop_addr);
663
664   strscpy(_value_twohop_sameif, json_getbool(twohop->same_interface), sizeof(_value_twohop_sameif));
665
666   oonf_clock_toIntervalString(&_value_twohop_vtime, oonf_timer_get_due(&twohop->_vtime));
667 }
668
669 /**
670  * Initialize the value buffers for a NHDP neighbor
671  * @param neigh NHDP neighbor
672  */
673 static void
674 _initialize_nhdp_neighbor_values(struct nhdp_neighbor *neigh) {
675   netaddr_to_string(&_value_neighbor_originator, &neigh->originator);
676   if (neigh->dualstack_partner) {
677     netaddr_to_string(&_value_neighbor_dualstack, &neigh->dualstack_partner->originator);
678   }
679   else {
680     strscpy(_value_neighbor_dualstack.buf, "-", sizeof(_value_neighbor_dualstack));
681   }
682
683   strscpy(_value_neighbor_symmetric, json_getbool(neigh->symmetric > 0), sizeof(_value_neighbor_symmetric));
684   snprintf(_value_neighbor_linkcount, sizeof(_value_neighbor_linkcount), "%d", neigh->symmetric);
685 }
686
687 /**
688  * Initialize the value buffers for a NHDP neighbor address
689  * @param naddr NHDP neighbor address
690  */
691 static void
692 _initialize_nhdp_neighbor_address_values(struct nhdp_naddr *naddr) {
693   netaddr_to_string(&_value_neighbor_address, &naddr->neigh_addr);
694
695   strscpy(_value_neighbor_address_lost, json_getbool(oonf_timer_is_active(&naddr->_lost_vtime)),
696     sizeof(_value_neighbor_address_lost));
697
698   oonf_clock_toIntervalString(&_value_neighbor_address_lost_vtime, oonf_timer_get_due(&naddr->_lost_vtime));
699 }
700
701 /**
702  * Displays the known data about each NHDP interface.
703  * @param template oonf viewer template
704  * @return -1 if an error happened, 0 otherwise
705  */
706 static int
707 _cb_create_text_interface(struct oonf_viewer_template *template) {
708   struct nhdp_interface *nhdpif;
709
710   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
711     _initialize_interface_values(nhdpif);
712
713     /* generate template output */
714     oonf_viewer_output_print_line(template);
715   }
716   return 0;
717 }
718
719 /**
720  * Displays the addresses of a NHDP interface.
721  * @param template oonf viewer template
722  * @return -1 if an error happened, 0 otherwise
723  */
724 static int
725 _cb_create_text_if_address(struct oonf_viewer_template *template) {
726   struct nhdp_interface *nhdp_if;
727   struct nhdp_interface_addr *nhdp_addr;
728
729   avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
730     /* fill output buffers for template engine */
731     _initialize_interface_values(nhdp_if);
732
733     avl_for_each_element(&nhdp_if->_if_addresses, nhdp_addr, _if_node) {
734       /* fill address specific output buffers for template engine */
735       _initialize_interface_address_values(nhdp_addr);
736
737       /* generate template output */
738       oonf_viewer_output_print_line(template);
739     }
740   }
741   return 0;
742 }
743
744 /**
745  * Displays the data of a NHDP link.
746  * @param template oonf viewer template
747  * @return -1 if an error happened, 0 otherwise
748  */
749 static int
750 _cb_create_text_link(struct oonf_viewer_template *template) {
751   struct nhdp_interface *nhdp_if;
752   struct nhdp_link *nlink;
753   struct nhdp_domain *domain;
754
755   avl_for_each_element(nhdp_interface_get_tree(), nhdp_if, _node) {
756     /* fill output buffers for template engine */
757     _initialize_interface_values(nhdp_if);
758
759     list_for_each_element(&nhdp_if->_links, nlink, _if_node) {
760       _initialize_nhdp_link_values(nlink);
761       _initialize_nhdp_neighbor_values(nlink->neigh);
762
763       list_for_each_element(nhdp_domain_get_list(), domain, _node) {
764         _initialize_nhdp_domain_metric_values(domain, &(nhdp_domain_get_linkdata(domain, nlink)->metric));
765         _initialize_nhdp_domain_metric_int_values(domain, nlink);
766
767         /* generate template output */
768         oonf_viewer_output_print_line(template);
769       }
770     }
771   }
772   return 0;
773 }
774
775 /**
776  * Displays the addresses of a NHDP link.
777  * @param template oonf viewer template
778  * @return -1 if an error happened, 0 otherwise
779  */
780 static int
781 _cb_create_text_link_address(struct oonf_viewer_template *template) {
782   struct nhdp_interface *nhdpif;
783   struct nhdp_link *nhdplink;
784   struct nhdp_laddr *laddr;
785
786   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
787     /* fill output buffers for template engine */
788     _initialize_interface_values(nhdpif);
789
790     list_for_each_element(&nhdpif->_links, nhdplink, _if_node) {
791       _initialize_nhdp_link_values(nhdplink);
792       _initialize_nhdp_neighbor_values(nhdplink->neigh);
793
794       avl_for_each_element(&nhdplink->_addresses, laddr, _link_node) {
795         _initialize_nhdp_link_address_values(laddr);
796
797         /* generate template output */
798         oonf_viewer_output_print_line(template);
799       }
800     }
801   }
802   return 0;
803 }
804
805 /**
806  * Displays the twohop neighbors of a NHDP link.
807  * @param template oonf viewer template
808  * @return -1 if an error happened, 0 otherwise
809  */
810 static int
811 _cb_create_text_link_twohop(struct oonf_viewer_template *template) {
812   struct nhdp_interface *nhdpif;
813   struct nhdp_link *nhdplink;
814   struct nhdp_l2hop *twohop;
815   struct nhdp_domain *domain;
816
817   avl_for_each_element(nhdp_interface_get_tree(), nhdpif, _node) {
818     /* fill output buffers for template engine */
819     _initialize_interface_values(nhdpif);
820
821     list_for_each_element(&nhdpif->_links, nhdplink, _if_node) {
822       _initialize_nhdp_link_values(nhdplink);
823       _initialize_nhdp_neighbor_values(nhdplink->neigh);
824
825       avl_for_each_element(&nhdplink->_2hop, twohop, _link_node) {
826         _initialize_nhdp_link_twohop_values(twohop);
827
828         list_for_each_element(nhdp_domain_get_list(), domain, _node) {
829           _initialize_nhdp_domain_metric_values(domain, &nhdp_domain_get_l2hopdata(domain, twohop)->metric);
830
831           /* generate template output */
832           oonf_viewer_output_print_line(template);
833         }
834       }
835     }
836   }
837   return 0;
838 }
839
840 /**
841  * Displays the data of a NHDP neighbor.
842  * @param template oonf viewer template
843  * @return -1 if an error happened, 0 otherwise
844  */
845 static int
846 _cb_create_text_neighbor(struct oonf_viewer_template *template) {
847   struct nhdp_neighbor *neigh;
848   struct nhdp_domain *domain;
849
850   list_for_each_element(nhdp_db_get_neigh_list(), neigh, _global_node) {
851     _initialize_nhdp_neighbor_values(neigh);
852
853     list_for_each_element(nhdp_domain_get_list(), domain, _node) {
854       struct nhdp_neighbor_domaindata *data;
855
856       data = nhdp_domain_get_neighbordata(domain, neigh);
857
858       _initialize_nhdp_domain_metric_values(domain, &data->metric);
859       _initialize_nhdp_neighbor_mpr_values(domain, data);
860
861       /* generate template output */
862       oonf_viewer_output_print_line(template);
863     }
864   }
865   return 0;
866 }
867
868 /**
869  * Displays the addresses of a NHDP neighbor.
870  * @param template oonf viewer template
871  * @return -1 if an error happened, 0 otherwise
872  */
873 static int
874 _cb_create_text_neighbor_address(struct oonf_viewer_template *template) {
875   struct nhdp_neighbor *neigh;
876   struct nhdp_naddr *naddr;
877
878   list_for_each_element(nhdp_db_get_neigh_list(), neigh, _global_node) {
879     _initialize_nhdp_neighbor_values(neigh);
880
881     avl_for_each_element(&neigh->_neigh_addresses, naddr, _neigh_node) {
882       _initialize_nhdp_neighbor_address_values(naddr);
883
884       /* generate template output */
885       oonf_viewer_output_print_line(template);
886     }
887   }
888   return 0;
889 }