0dc08a9cca49c143d0f19a4a0017618934a9cd50
[oonf.git] / src / olsrv2 / olsrv2info / olsrv2info.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.h>
57 #include <oonf/nhdp/nhdp/nhdp_domain.h>
58 #include <oonf/olsrv2/olsrv2/olsrv2.h>
59 #include <oonf/olsrv2/olsrv2/olsrv2_lan.h>
60 #include <oonf/olsrv2/olsrv2/olsrv2_originator.h>
61 #include <oonf/olsrv2/olsrv2/olsrv2_routing.h>
62 #include <oonf/olsrv2/olsrv2/olsrv2_tc.h>
63
64 #include <oonf/olsrv2/olsrv2info/olsrv2info.h>
65
66 /* definitions */
67 #define LOG_OLSRV2INFO olsrv2_olsrv2info_subsystem.logging
68
69 /* prototypes */
70 static int _init(void);
71 static void _cleanup(void);
72
73 static enum oonf_telnet_result _cb_olsrv2info(struct oonf_telnet_data *con);
74 static enum oonf_telnet_result _cb_olsrv2info_help(struct oonf_telnet_data *con);
75
76 static void _initialize_originator_values(int af_type);
77 static void _initialize_old_originator_values(struct olsrv2_originator_set_entry *);
78 static void _initialize_domain_values(struct nhdp_domain *domain);
79 static void _initialize_domain_link_metric_values(struct nhdp_domain *domain, uint32_t);
80 static void _initialize_domain_distance(uint8_t);
81 static void _initialize_lan_values(struct olsrv2_lan_entry *);
82 static void _initialize_node_values(struct olsrv2_tc_node *);
83 static void _initialize_attached_network_values(struct olsrv2_tc_attachment *edge);
84 static void _initialize_edge_values(struct olsrv2_tc_edge *edge);
85 static void _initialize_route_values(struct olsrv2_routing_entry *route);
86
87 static int _cb_create_text_originator(struct oonf_viewer_template *);
88 static int _cb_create_text_old_originator(struct oonf_viewer_template *);
89 static int _cb_create_text_lan(struct oonf_viewer_template *);
90 static int _cb_create_text_node(struct oonf_viewer_template *);
91 static int _cb_create_text_attached_network(struct oonf_viewer_template *);
92 static int _cb_create_text_edge(struct oonf_viewer_template *);
93 static int _cb_create_text_route(struct oonf_viewer_template *);
94
95 /*
96  * list of template keys and corresponding buffers for values.
97  *
98  * The keys are API, so they should not be changed after published
99  */
100
101 /*! template key for originator IP */
102 #define KEY_ORIGINATOR "originator"
103
104 /*! template key for former originator IP */
105 #define KEY_OLD_ORIGINATOR "old_originator"
106
107 /*! template key for former originator validity time */
108 #define KEY_OLD_ORIGINATOR_VTIME "old_originator_vtime"
109
110 /*! template key for nhdp domain */
111 #define KEY_DOMAIN "domain"
112
113 /*! template key for metric name */
114 #define KEY_DOMAIN_METRIC "domain_metric"
115
116 /*! template key for incoming human readable metric */
117 #define KEY_DOMAIN_METRIC_IN "domain_metric_in"
118
119 /*! template key for outgoing human readable metric */
120 #define KEY_DOMAIN_METRIC_OUT "domain_metric_out"
121
122 /*! template key for incoming numeric metric */
123 #define KEY_DOMAIN_METRIC_IN_RAW "domain_metric_in_raw"
124
125 /*! template key for outgoing numeric metric */
126 #define KEY_DOMAIN_METRIC_OUT_RAW "domain_metric_out_raw"
127
128 /*! template key for route distance */
129 #define KEY_DOMAIN_DISTANCE "domain_distance"
130
131 /*! template key for hopcount of a routing path */
132 #define KEY_DOMAIN_PATH_HOPS "domain_path_hops"
133
134 /*! template key for local attached network destination prefix */
135 #define KEY_LAN_DST "lan"
136
137 /*! template key for local attached network source prefix */
138 #define KEY_LAN_SRC "lan_src"
139
140 /*! template key for node IP */
141 #define KEY_NODE "node"
142
143 /*! template key for node validity time */
144 #define KEY_NODE_VTIME "node_vtime"
145
146 /*! template key for current node answer set number */
147 #define KEY_NODE_ANSN "node_ansn"
148
149 /*! template key for nodes that exist because of HELLOs or foreign TCs */
150 #define KEY_NODE_VIRTUAL "node_virtual"
151
152 /*! template key for nodes that are direct neighbors */
153 #define KEY_NODE_NEIGHBOR "node_neighbor"
154
155 /*! template key for attached network destination prefix*/
156 #define KEY_ATTACHED_NET "attached_net"
157
158 /*! template key for attached network source prefix */
159 #define KEY_ATTACHED_NET_SRC "attached_net_src"
160
161 /*! template key for attached network answer set number */
162 #define KEY_ATTACHED_NET_ANSN "attached_net_ansn"
163
164 /*! template key for edge destination */
165 #define KEY_EDGE "edge"
166
167 /*! template key for edge answer set number */
168 #define KEY_EDGE_ANSN "edge_ansn"
169
170 /*! template key for route source ip */
171 #define KEY_ROUTE_SRC_IP "route_src_ip"
172
173 /*! template key for route gateway IP */
174 #define KEY_ROUTE_GW "route_gw"
175
176 /*! template key for route destination prefix */
177 #define KEY_ROUTE_DST "route_dst"
178
179 /*! template key for route source prefix */
180 #define KEY_ROUTE_SRC_PREFIX "route_src_prefix"
181
182 /*! template key for route metric */
183 #define KEY_ROUTE_METRIC "route_metric"
184
185 /*! template key for routing table */
186 #define KEY_ROUTE_TABLE "route_table"
187
188 /*! template key for routing protocol */
189 #define KEY_ROUTE_PROTO "route_proto"
190
191 /*! template key for route interface name */
192 #define KEY_ROUTE_IF "route_if"
193
194 /*! template key for route interface index */
195 #define KEY_ROUTE_IFINDEX "route_ifindex"
196
197 /*! template key for the last hop before the route destination */
198 #define KEY_ROUTE_LASTHOP "route_lasthop"
199
200 /*
201  * buffer space for values that will be assembled
202  * into the output of the plugin
203  */
204 static struct netaddr_str _value_originator;
205
206 static struct netaddr_str _value_old_originator;
207 static struct isonumber_str _value_old_originator_vtime;
208
209 static char _value_domain[4];
210 static char _value_domain_metric[NHDP_DOMAIN_METRIC_MAXLEN];
211 static struct nhdp_metric_str _value_domain_metric_out;
212 static char _value_domain_metric_out_raw[12];
213 static char _value_domain_distance[4];
214 static char _value_domain_path_hops[4];
215
216 static struct netaddr_str _value_lan_dst;
217 static struct netaddr_str _value_lan_src;
218
219 static struct netaddr_str _value_node;
220 static struct isonumber_str _value_node_vtime;
221 static char _value_node_ansn[6];
222 static char _value_node_virtual[TEMPLATE_JSON_BOOL_LENGTH];
223 static char _value_node_neighbor[TEMPLATE_JSON_BOOL_LENGTH];
224
225 static struct netaddr_str _value_attached_net_dst;
226 static struct netaddr_str _value_attached_net_src;
227 static char _value_attached_net_ansn[6];
228
229 static struct netaddr_str _value_edge;
230 static char _value_edge_ansn[6];
231
232 static struct netaddr_str _value_route_dst;
233 static struct netaddr_str _value_route_gw;
234 static struct netaddr_str _value_route_src_ip;
235 static struct netaddr_str _value_route_src_prefix;
236 static char _value_route_metric[12];
237 static char _value_route_table[4];
238 static char _value_route_proto[4];
239 static char _value_route_if[IF_NAMESIZE];
240 static char _value_route_ifindex[12];
241 static struct netaddr_str _value_route_lasthop;
242
243 /* definition of the template data entries for JSON and table output */
244 static struct abuf_template_data_entry _tde_originator[] = {
245   { KEY_ORIGINATOR, _value_originator.buf, true },
246 };
247
248 static struct abuf_template_data_entry _tde_old_originator[] = {
249   { KEY_OLD_ORIGINATOR, _value_old_originator.buf, true },
250   { KEY_OLD_ORIGINATOR_VTIME, _value_old_originator_vtime.buf, false },
251 };
252
253 static struct abuf_template_data_entry _tde_domain[] = {
254   { KEY_DOMAIN, _value_domain, true },
255 };
256
257 static struct abuf_template_data_entry _tde_domain_metric_out[] = {
258   { KEY_DOMAIN_METRIC, _value_domain_metric, true },
259   { KEY_DOMAIN_METRIC_OUT, _value_domain_metric_out.buf, true },
260   { KEY_DOMAIN_METRIC_OUT_RAW, _value_domain_metric_out_raw, false },
261 };
262
263 static struct abuf_template_data_entry _tde_domain_lan_distance[] = {
264   { KEY_DOMAIN_DISTANCE, _value_domain_distance, false },
265 };
266
267 static struct abuf_template_data_entry _tde_domain_path_hops[] = {
268   { KEY_DOMAIN_PATH_HOPS, _value_domain_path_hops, false },
269 };
270
271 static struct abuf_template_data_entry _tde_lan[] = {
272   { KEY_LAN_DST, _value_lan_dst.buf, true },
273   { KEY_LAN_SRC, _value_lan_src.buf, true },
274 };
275
276 static struct abuf_template_data_entry _tde_node_key[] = {
277   { KEY_NODE, _value_node.buf, true },
278 };
279
280 static struct abuf_template_data_entry _tde_node[] = {
281   { KEY_NODE, _value_node.buf, true },
282   { KEY_NODE_ANSN, _value_node_ansn, false },
283   { KEY_NODE_VTIME, _value_node_vtime.buf, false },
284   { KEY_NODE_VIRTUAL, _value_node_virtual, true },
285   { KEY_NODE_NEIGHBOR, _value_node_neighbor, true },
286 };
287
288 static struct abuf_template_data_entry _tde_attached_net[] = {
289   { KEY_ATTACHED_NET, _value_attached_net_dst.buf, true },
290   { KEY_ATTACHED_NET_SRC, _value_attached_net_src.buf, true },
291   { KEY_ATTACHED_NET_ANSN, _value_attached_net_ansn, false },
292 };
293
294 static struct abuf_template_data_entry _tde_edge[] = {
295   { KEY_EDGE, _value_edge.buf, true },
296   { KEY_EDGE_ANSN, _value_edge_ansn, false },
297 };
298
299 static struct abuf_template_data_entry _tde_route[] = {
300   { KEY_ROUTE_DST, _value_route_dst.buf, true },
301   { KEY_ROUTE_GW, _value_route_gw.buf, true },
302   { KEY_ROUTE_SRC_IP, _value_route_src_ip.buf, true },
303   { KEY_ROUTE_SRC_PREFIX, _value_route_src_prefix.buf, true },
304   { KEY_ROUTE_METRIC, _value_route_metric, false },
305   { KEY_ROUTE_TABLE, _value_route_table, false },
306   { KEY_ROUTE_PROTO, _value_route_proto, false },
307   { KEY_ROUTE_IF, _value_route_if, true },
308   { KEY_ROUTE_IFINDEX, _value_route_ifindex, false },
309   { KEY_ROUTE_LASTHOP, _value_route_lasthop.buf, true },
310 };
311
312 static struct abuf_template_storage _template_storage;
313
314 /* Template Data objects (contain one or more Template Data Entries) */
315 static struct abuf_template_data _td_orig[] = {
316   { _tde_originator, ARRAYSIZE(_tde_originator) },
317 };
318 static struct abuf_template_data _td_old_orig[] = {
319   { _tde_old_originator, ARRAYSIZE(_tde_old_originator) },
320 };
321 static struct abuf_template_data _td_lan[] = {
322   { _tde_lan, ARRAYSIZE(_tde_lan) },
323   { _tde_domain, ARRAYSIZE(_tde_domain) },
324   { _tde_domain_metric_out, ARRAYSIZE(_tde_domain_metric_out) },
325   { _tde_domain_lan_distance, ARRAYSIZE(_tde_domain_lan_distance) },
326 };
327 static struct abuf_template_data _td_node[] = {
328   { _tde_node, ARRAYSIZE(_tde_node) },
329 };
330 static struct abuf_template_data _td_attached_net[] = {
331   { _tde_node_key, ARRAYSIZE(_tde_node_key) },
332   { _tde_attached_net, ARRAYSIZE(_tde_attached_net) },
333   { _tde_domain, ARRAYSIZE(_tde_domain) },
334   { _tde_domain_metric_out, ARRAYSIZE(_tde_domain_metric_out) },
335   { _tde_domain_lan_distance, ARRAYSIZE(_tde_domain_lan_distance) },
336 };
337 static struct abuf_template_data _td_edge[] = {
338   { _tde_node_key, ARRAYSIZE(_tde_node_key) },
339   { _tde_edge, ARRAYSIZE(_tde_edge) },
340   { _tde_domain, ARRAYSIZE(_tde_domain) },
341   { _tde_domain_metric_out, ARRAYSIZE(_tde_domain_metric_out) },
342 };
343 static struct abuf_template_data _td_route[] = {
344   { _tde_route, ARRAYSIZE(_tde_route) },
345   { _tde_domain, ARRAYSIZE(_tde_domain) },
346   { _tde_domain_metric_out, ARRAYSIZE(_tde_domain_metric_out) },
347   { _tde_domain_path_hops, ARRAYSIZE(_tde_domain_path_hops) },
348 };
349
350 /* OONF viewer templates (based on Template Data arrays) */
351 static struct oonf_viewer_template _templates[] = { {
352                                                       .data = _td_orig,
353                                                       .data_size = ARRAYSIZE(_td_orig),
354                                                       .json_name = "originator",
355                                                       .cb_function = _cb_create_text_originator,
356                                                     },
357   {
358     .data = _td_old_orig,
359     .data_size = ARRAYSIZE(_td_old_orig),
360     .json_name = "old_originator",
361     .cb_function = _cb_create_text_old_originator,
362   },
363   {
364     .data = _td_lan,
365     .data_size = ARRAYSIZE(_td_lan),
366     .json_name = "lan",
367     .cb_function = _cb_create_text_lan,
368   },
369   {
370     .data = _td_node,
371     .data_size = ARRAYSIZE(_td_node),
372     .json_name = "node",
373     .cb_function = _cb_create_text_node,
374   },
375   {
376     .data = _td_attached_net,
377     .data_size = ARRAYSIZE(_td_attached_net),
378     .json_name = "attached_network",
379     .cb_function = _cb_create_text_attached_network,
380   },
381   {
382     .data = _td_edge,
383     .data_size = ARRAYSIZE(_td_edge),
384     .json_name = "edge",
385     .cb_function = _cb_create_text_edge,
386   },
387   {
388     .data = _td_route,
389     .data_size = ARRAYSIZE(_td_route),
390     .json_name = "route",
391     .cb_function = _cb_create_text_route,
392   } };
393
394 /* telnet command of this plugin */
395 static struct oonf_telnet_command _telnet_commands[] = {
396   TELNET_CMD(OONF_OLSRV2INFO_SUBSYSTEM, _cb_olsrv2info, "", .help_handler = _cb_olsrv2info_help),
397 };
398
399 /* plugin declaration */
400 static const char *_dependencies[] = {
401   OONF_NHDP_SUBSYSTEM,
402   OONF_OLSRV2_SUBSYSTEM,
403 };
404 static struct oonf_subsystem olsrv2_olsrv2info_subsystem = {
405   .name = OONF_OLSRV2INFO_SUBSYSTEM,
406   .dependencies = _dependencies,
407   .dependencies_count = ARRAYSIZE(_dependencies),
408   .descr = "OLSRv2 olsrv2 info plugin",
409   .author = "Henning Rogge",
410   .init = _init,
411   .cleanup = _cleanup,
412 };
413 DECLARE_OONF_PLUGIN(olsrv2_olsrv2info_subsystem);
414
415 /**
416  * Initialize plugin
417  * @return always returns 0
418  */
419 static int
420 _init(void) {
421   oonf_telnet_add(&_telnet_commands[0]);
422   return 0;
423 }
424
425 /**
426  * Cleanup plugin
427  */
428 static void
429 _cleanup(void) {
430   oonf_telnet_remove(&_telnet_commands[0]);
431 }
432
433 /**
434  * Callback for the telnet command of this plugin
435  * @param con pointer to telnet session data
436  * @return telnet result value
437  */
438 static enum oonf_telnet_result
439 _cb_olsrv2info(struct oonf_telnet_data *con) {
440   return oonf_viewer_telnet_handler(
441     con->out, &_template_storage, OONF_OLSRV2INFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
442 }
443
444 /**
445  * Callback for the help output of this plugin
446  * @param con pointer to telnet session data
447  * @return telnet result value
448  */
449 static enum oonf_telnet_result
450 _cb_olsrv2info_help(struct oonf_telnet_data *con) {
451   return oonf_viewer_telnet_help(
452     con->out, OONF_OLSRV2INFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
453 }
454
455 /**
456  * Initialize the value buffers for an originator entry
457  * @param af_type address family of originator
458  */
459 static void
460 _initialize_originator_values(int af_type) {
461   netaddr_to_string(&_value_originator, olsrv2_originator_get(af_type));
462 }
463
464 /**
465  * Initialize the value buffer for old originator entries
466  * @param entry originator set entry
467  */
468 static void
469 _initialize_old_originator_values(struct olsrv2_originator_set_entry *entry) {
470   netaddr_to_string(&_value_old_originator, &entry->originator);
471
472   oonf_clock_toIntervalString(&_value_old_originator_vtime, oonf_timer_get_due(&entry->_vtime));
473 }
474
475 /**
476  * Initialize the value buffers for a NHDP domain
477  * @param domain NHDP domain
478  */
479 static void
480 _initialize_domain_values(struct nhdp_domain *domain) {
481   snprintf(_value_domain, sizeof(_value_domain), "%u", domain->ext);
482   strscpy(_value_domain_metric, domain->metric->name, sizeof(_value_domain_metric));
483 }
484
485 /**
486  * Initialize the value buffers for a metric value
487  * @param domain NHDP domain
488  * @param metric raw metric value
489  */
490 static void
491 _initialize_domain_link_metric_values(struct nhdp_domain *domain, uint32_t metric) {
492   nhdp_domain_get_link_metric_value(&_value_domain_metric_out, domain, metric);
493
494   snprintf(_value_domain_metric_out_raw, sizeof(_value_domain_metric_out_raw), "%u", metric);
495 }
496
497 /**
498  * Initialize the value buffers for a metric value
499  * @param domain NHDP domain
500  * @param metric raw metric value
501  */
502 static void
503 _initialize_domain_path_metric_values(struct nhdp_domain *domain, uint32_t metric, uint8_t hopcount) {
504   nhdp_domain_get_path_metric_value(&_value_domain_metric_out, domain, metric, hopcount);
505
506   snprintf(_value_domain_metric_out_raw, sizeof(_value_domain_metric_out_raw), "%u", metric);
507 }
508
509 /**
510  * Initialize the value buffer for the hopcount value for routes
511  * @param distance hopcount value
512  */
513 static void
514 _initialize_domain_distance(uint8_t distance) {
515   snprintf(_value_domain_distance, sizeof(_value_domain_distance), "%u", distance);
516 }
517
518 /**
519  * Initialize the value buffer for the path hopcount
520  * @param path_hops path distance
521  */
522 static void
523 _initialize_domain_path_hops(uint8_t path_hops) {
524   snprintf(_value_domain_path_hops, sizeof(_value_domain_path_hops), "%u", path_hops);
525 }
526
527 /**
528  * Initialize the value buffer for a LAN entry
529  * @param lan OLSRv2 LAN entry
530  */
531 static void
532 _initialize_lan_values(struct olsrv2_lan_entry *lan) {
533   netaddr_to_string(&_value_lan_dst, &lan->prefix.dst);
534   netaddr_to_string(&_value_lan_src, &lan->prefix.src);
535 }
536
537 /**
538  * Initialize the value buffers for an OLSRv2 node
539  * @param node OLSRv2 node
540  */
541 static void
542 _initialize_node_values(struct olsrv2_tc_node *node) {
543   netaddr_to_string(&_value_node, &node->target.prefix.dst);
544
545   oonf_clock_toIntervalString(&_value_node_vtime, oonf_timer_get_due(&node->_validity_time));
546
547   snprintf(_value_node_ansn, sizeof(_value_node_ansn), "%u", node->ansn);
548
549   strscpy(_value_node_virtual, json_getbool(!oonf_timer_is_active(&node->_validity_time)), sizeof(_value_node_virtual));
550   strscpy(_value_node_neighbor, json_getbool(node->direct_neighbor), sizeof(_value_node_neighbor));
551 }
552
553 /**
554  * Initialize the value buffers for an OLSRv2 attached network
555  * @param edge attached network edge
556  */
557 static void
558 _initialize_attached_network_values(struct olsrv2_tc_attachment *edge) {
559   netaddr_to_string(&_value_attached_net_dst, &edge->dst->target.prefix.dst);
560   netaddr_to_string(&_value_attached_net_src, &edge->dst->target.prefix.src);
561
562   snprintf(_value_attached_net_ansn, sizeof(_value_attached_net_ansn), "%u", edge->ansn);
563 }
564
565 /**
566  * Initialize the value buffers for an OLSRv2 edge
567  * @param edge OLSRv2 edge
568  */
569 static void
570 _initialize_edge_values(struct olsrv2_tc_edge *edge) {
571   netaddr_to_string(&_value_edge, &edge->dst->target.prefix.dst);
572
573   snprintf(_value_edge_ansn, sizeof(_value_edge_ansn), "%u", edge->ansn);
574 }
575
576 /**
577  * Initialize the value buffers for a OLSRv2 route
578  * @param route OLSRv2 routing entry
579  */
580 static void
581 _initialize_route_values(struct olsrv2_routing_entry *route) {
582   netaddr_to_string(&_value_route_dst, &route->route.p.key.dst);
583   netaddr_to_string(&_value_route_gw, &route->route.p.gw);
584   netaddr_to_string(&_value_route_src_ip, &route->route.p.src_ip);
585   netaddr_to_string(&_value_route_src_prefix, &route->route.p.key.src);
586
587   snprintf(_value_route_metric, sizeof(_value_route_metric), "%u", route->route.p.metric);
588   snprintf(_value_route_table, sizeof(_value_route_table), "%u", route->route.p.table);
589   snprintf(_value_route_proto, sizeof(_value_route_proto), "%u", route->route.p.protocol);
590
591   if_indextoname(route->route.p.if_index, _value_route_if);
592   snprintf(_value_route_ifindex, sizeof(_value_route_ifindex), "%u", route->route.p.if_index);
593
594   netaddr_to_string(&_value_route_lasthop, &route->last_originator);
595 }
596
597 /**
598  * Displays the known data about each NHDP interface.
599  * @param template oonf viewer template
600  * @return -1 if an error happened, 0 otherwise
601  */
602 static int
603 _cb_create_text_old_originator(struct oonf_viewer_template *template) {
604   struct olsrv2_originator_set_entry *entry;
605
606   avl_for_each_element(olsrv2_originator_get_tree(), entry, _node) {
607     _initialize_old_originator_values(entry);
608
609     /* generate template output */
610     oonf_viewer_output_print_line(template);
611   }
612   return 0;
613 }
614
615 /**
616  * Display the originator addresses of the local node
617  * @param template oonf viewer template
618  * @return -1 if an error happened, 0 otherwise
619  */
620 static int
621 _cb_create_text_originator(struct oonf_viewer_template *template) {
622   /* generate template output */
623   _initialize_originator_values(AF_INET);
624   oonf_viewer_output_print_line(template);
625
626   /* generate template output */
627   _initialize_originator_values(AF_INET6);
628   oonf_viewer_output_print_line(template);
629
630   return 0;
631 }
632
633 /**
634  * Display all locally attached networks
635  * @param template oonf viewer template
636  * @return -1 if an error happened, 0 otherwise
637  */
638 static int
639 _cb_create_text_lan(struct oonf_viewer_template *template) {
640   struct olsrv2_lan_entry *lan;
641   struct nhdp_domain *domain;
642
643   avl_for_each_element(olsrv2_lan_get_tree(), lan, _node) {
644     _initialize_lan_values(lan);
645
646     list_for_each_element(nhdp_domain_get_list(), domain, _node) {
647       if (olsrv2_lan_get_domaindata(domain, lan)->active) {
648         _initialize_domain_values(domain);
649         _initialize_domain_link_metric_values(domain, olsrv2_lan_get_domaindata(domain, lan)->outgoing_metric);
650         _initialize_domain_distance(olsrv2_lan_get_domaindata(domain, lan)->distance);
651
652         oonf_viewer_output_print_line(template);
653       }
654     }
655   }
656   return 0;
657 }
658
659 /**
660  * Display all known OLSRv2 nodes
661  * @param template oonf viewer template
662  * @return -1 if an error happened, 0 otherwise
663  */
664 static int
665 _cb_create_text_node(struct oonf_viewer_template *template) {
666   struct olsrv2_tc_node *node;
667
668   avl_for_each_element(olsrv2_tc_get_tree(), node, _originator_node) {
669     _initialize_node_values(node);
670
671     oonf_viewer_output_print_line(template);
672   }
673   return 0;
674 }
675
676 /**
677  * Display all known OLSRv2 attached networks
678  * @param template oonf viewer template
679  * @return -1 if an error happened, 0 otherwise
680  */
681 static int
682 _cb_create_text_attached_network(struct oonf_viewer_template *template) {
683   struct olsrv2_tc_node *node;
684   struct olsrv2_tc_attachment *attached;
685   struct nhdp_domain *domain;
686
687   avl_for_each_element(olsrv2_tc_get_tree(), node, _originator_node) {
688     _initialize_node_values(node);
689
690     if (olsrv2_tc_is_node_virtual(node)) {
691       continue;
692     }
693
694     avl_for_each_element(&node->_attached_networks, attached, _src_node) {
695       _initialize_attached_network_values(attached);
696
697       list_for_each_element(nhdp_domain_get_list(), domain, _node) {
698         _initialize_domain_values(domain);
699         _initialize_domain_link_metric_values(domain, olsrv2_tc_attachment_get_metric(domain, attached));
700         _initialize_domain_distance(olsrv2_tc_attachment_get_distance(domain, attached));
701
702         oonf_viewer_output_print_line(template);
703       }
704     }
705   }
706   return 0;
707 }
708
709 /**
710  * Display all known OLSRv2 edges
711  * @param template oonf viewer template
712  * @return -1 if an error happened, 0 otherwise
713  */
714 static int
715 _cb_create_text_edge(struct oonf_viewer_template *template) {
716   struct olsrv2_tc_node *node;
717   struct olsrv2_tc_edge *edge;
718   struct nhdp_domain *domain;
719   uint32_t metric;
720
721   avl_for_each_element(olsrv2_tc_get_tree(), node, _originator_node) {
722     _initialize_node_values(node);
723
724     if (olsrv2_tc_is_node_virtual(node)) {
725       continue;
726     }
727     avl_for_each_element(&node->_edges, edge, _node) {
728       if (edge->virtual) {
729         continue;
730       }
731
732       _initialize_edge_values(edge);
733
734       list_for_each_element(nhdp_domain_get_list(), domain, _node) {
735         metric = olsrv2_tc_edge_get_metric(domain, edge);
736         if (metric <= RFC7181_METRIC_MAX) {
737           _initialize_domain_values(domain);
738           _initialize_domain_link_metric_values(domain, metric);
739
740           oonf_viewer_output_print_line(template);
741         }
742       }
743     }
744   }
745   return 0;
746 }
747
748 /**
749  * Display all current entries of the OLSRv2 routing table
750  * @param template oonf viewer template
751  * @return -1 if an error happened, 0 otherwise
752  */
753 static int
754 _cb_create_text_route(struct oonf_viewer_template *template) {
755   struct olsrv2_routing_entry *route;
756   struct nhdp_domain *domain;
757
758   list_for_each_element(nhdp_domain_get_list(), domain, _node) {
759     _initialize_domain_values(domain);
760
761     avl_for_each_element(olsrv2_routing_get_tree(domain), route, _node) {
762       _initialize_domain_path_metric_values(domain, route->path_cost, route->path_hops);
763       _initialize_domain_path_hops(route->path_hops);
764       _initialize_route_values(route);
765
766       oonf_viewer_output_print_line(template);
767     }
768   }
769   return 0;
770 }