Add interface data to systeminfo
[oonf.git] / src-plugins / generic / systeminfo / systeminfo.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 <stdio.h>
47
48 #include "common/autobuf.h"
49 #include "common/common_types.h"
50 #include "common/netaddr.h"
51 #include "common/netaddr_acl.h"
52 #include "common/string.h"
53 #include "common/template.h"
54
55 #include "core/oonf_logging.h"
56 #include "core/oonf_subsystem.h"
57 #include "subsystems/oonf_clock.h"
58 #include "subsystems/oonf_telnet.h"
59 #include "subsystems/oonf_viewer.h"
60 #include "subsystems/os_interface.h"
61
62 #include "systeminfo/systeminfo.h"
63
64 /* definitions */
65 #define LOG_SYSTEMINFO _oonf_systeminfo_subsystem.logging
66
67 /* prototypes */
68 static int _init(void);
69 static void _cleanup(void);
70
71 static enum oonf_telnet_result _cb_systeminfo(struct oonf_telnet_data *con);
72 static enum oonf_telnet_result _cb_systeminfo_help(struct oonf_telnet_data *con);
73
74 static void _initialize_time_values(struct oonf_viewer_template *template);
75 static void _initialize_version_values(struct oonf_viewer_template *template);
76 static void _initialize_memory_values(struct oonf_viewer_template *template, struct oonf_class *c);
77 static void _initialize_timer_values(struct oonf_viewer_template *template, struct oonf_timer_class *tc);
78 static void _initialize_socket_values(struct oonf_viewer_template *template, struct oonf_socket_entry *sock);
79 static void _initialize_logging_values(struct oonf_viewer_template *template, enum oonf_log_source source);
80 static void _initialize_interface_key_values(struct oonf_viewer_template *template, struct os_interface *);
81 static void _initialize_interface_data_values(struct oonf_viewer_template *template, struct os_interface *);
82 static void _initialize_ifaddr_data_values(struct oonf_viewer_template *template, struct os_interface_ip *);
83
84 static int _cb_create_text_time(struct oonf_viewer_template *);
85 static int _cb_create_text_version(struct oonf_viewer_template *);
86 static int _cb_create_text_memory(struct oonf_viewer_template *);
87 static int _cb_create_text_timer(struct oonf_viewer_template *);
88 static int _cb_create_text_socket(struct oonf_viewer_template *);
89 static int _cb_create_text_logging(struct oonf_viewer_template *);
90 static int _cb_create_text_interface(struct oonf_viewer_template *);
91 static int _cb_create_text_ifaddr(struct oonf_viewer_template *);
92 static int _cb_create_text_ifpeer(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 system wall-time */
101 #define KEY_TIME_SYSTEM "time_system"
102
103 /*! template key for internal OONF relative timestamp */
104 #define KEY_TIME_INTERNAL "time_internal"
105
106 /*! template key for version text */
107 #define KEY_VERSION_TEXT "version_text"
108
109 /*! template key for version git commit */
110 #define KEY_VERSION_COMMIT "version_commit"
111
112 /*! template key for statistic object name */
113 #define KEY_STATISTICS_NAME "statistics_name"
114
115 /*! template key for current memory usage */
116 #define KEY_MEMORY_USAGE "memory_usage"
117
118 /*! template key for memory freelist size */
119 #define KEY_MEMORY_FREELIST "memory_freelist"
120
121 /*! template key for total memory allocations */
122 #define KEY_MEMORY_ALLOC "memory_alloc"
123
124 /*! template key for recycled memory blocks */
125 #define KEY_MEMORY_RECYCLED "memory_recycled"
126
127 /*! template key for timer usage */
128 #define KEY_TIMER_USAGE "timer_usage"
129
130 /*! template key for timer changes */
131 #define KEY_TIMER_CHANGE "timer_change"
132
133 /*! template key for timer fired */
134 #define KEY_TIMER_FIRE "timer_fire"
135
136 /*! template key for timer long usage events*/
137 #define KEY_TIMER_LONG "timer_long"
138
139 /*! template key for socket receive events */
140 #define KEY_SOCKET_RECV "socket_recv"
141
142 /*! template key for socket send events */
143 #define KEY_SOCKET_SEND "socket_send"
144
145 /*! template key for socket long usage events */
146 #define KEY_SOCKET_LONG "socket_long"
147
148 /*! template key for name of logging source */
149 #define KEY_LOG_SOURCE "log_source"
150
151 /*! template key for number of warnings per logging source */
152 #define KEY_LOG_WARNINGS "log_warnings"
153
154 #define KEY_IF_NAME "if_name"
155 #define KEY_IF_INDEX "if_index"
156 #define KEY_IF_BASEIDX "if_baseidx"
157 #define KEY_IF_FLAG_UP "if_flag_up"
158 #define KEY_IF_FLAG_PROMISC "if_flag_promisc"
159 #define KEY_IF_FLAG_LOOPBACK "if_flag_loopback"
160 #define KEY_IF_FLAG_ANY "if_flag_any"
161 #define KEY_IF_FLAG_UNICAST "if_flag_unicast"
162 #define KEY_IF_FLAG_MESH "if_flag_mesh"
163 #define KEY_IF_MAC "if_mac"
164 #define KEY_IF_IPV4 "if_ipv4"
165 #define KEY_IF_IPV6 "if_ipv6"
166 #define KEY_IF_LLV4 "if_llv4"
167 #define KEY_IF_LLV6 "if_llv6"
168 #define KEY_IF_ADDR_COUNT "if_addr_count"
169 #define KEY_IF_PEER_COUNT "if_peer_count"
170
171 #define KEY_IFADDR_PREFIXED "ifaddr_prefixed_addr"
172 #define KEY_IFADDR_ADDR "ifaddr_address"
173 #define KEY_IFADDR_PREFIX "ifaddr_prefix"
174
175 /*
176  * buffer space for values that will be assembled
177  * into the output of the plugin
178  */
179 static struct oonf_walltime_str _value_system_time;
180 static struct isonumber_str _value_internal_time;
181
182 static char _value_version_text[256];
183 static char _value_version_commit[21];
184
185 static char _value_stat_name[256];
186
187 static struct isonumber_str _value_memory_usage;
188 static struct isonumber_str _value_memory_freelist;
189 static struct isonumber_str _value_memory_alloc;
190 static struct isonumber_str _value_memory_recycled;
191
192 static struct isonumber_str _value_timer_usage;
193 static struct isonumber_str _value_timer_change;
194 static struct isonumber_str _value_timer_fire;
195 static struct isonumber_str _value_timer_long;
196
197 static struct isonumber_str _value_socket_recv;
198 static struct isonumber_str _value_socket_send;
199 static struct isonumber_str _value_socket_long;
200
201 static char _value_log_source[64];
202 static struct isonumber_str _value_log_warnings;
203
204 static char _value_if_name[IF_NAMESIZE];
205 static char _value_if_index[21];
206 static char _value_if_baseidx[21];
207 static char _value_if_flag_up[TEMPLATE_JSON_BOOL_LENGTH];
208 static char _value_if_flag_promisc[TEMPLATE_JSON_BOOL_LENGTH];
209 static char _value_if_flag_loopback[TEMPLATE_JSON_BOOL_LENGTH];
210 static char _value_if_flag_any[TEMPLATE_JSON_BOOL_LENGTH];
211 static char _value_if_flag_unicast[TEMPLATE_JSON_BOOL_LENGTH];
212 static char _value_if_flag_mesh[TEMPLATE_JSON_BOOL_LENGTH];
213 static struct netaddr_str _value_if_mac;
214 static struct netaddr_str _value_if_ipv4;
215 static struct netaddr_str _value_if_ipv6;
216 static struct netaddr_str _value_if_llv4;
217 static struct netaddr_str _value_if_llv6;
218 static char _value_if_addr_count[21];
219 static char _value_if_peer_count[21];
220 static struct netaddr_str _value_ifaddr_prefixed;
221 static struct netaddr_str _value_ifaddr_addr;
222 static struct netaddr_str _value_ifaddr_prefix;
223
224 /* definition of the template data entries for JSON and table output */
225 static struct abuf_template_data_entry _tde_time_key[] = {
226   { KEY_TIME_SYSTEM, _value_system_time.buf, true },
227   { KEY_TIME_INTERNAL, _value_internal_time.buf, true },
228 };
229 static struct abuf_template_data_entry _tde_version_key[] = {
230   { KEY_VERSION_TEXT, _value_version_text, true },
231   { KEY_VERSION_COMMIT, _value_version_commit, true },
232 };
233 static struct abuf_template_data_entry _tde_memory_key[] = {
234   { KEY_STATISTICS_NAME, _value_stat_name, true },
235   { KEY_MEMORY_USAGE, _value_memory_usage.buf, false },
236   { KEY_MEMORY_FREELIST, _value_memory_freelist.buf, false },
237   { KEY_MEMORY_ALLOC, _value_memory_alloc.buf, false },
238   { KEY_MEMORY_RECYCLED, _value_memory_recycled.buf, false },
239 };
240 static struct abuf_template_data_entry _tde_timer_key[] = {
241   { KEY_STATISTICS_NAME, _value_stat_name, true },
242   { KEY_TIMER_USAGE, _value_timer_usage.buf, false },
243   { KEY_TIMER_CHANGE, _value_timer_change.buf, false },
244   { KEY_TIMER_FIRE, _value_timer_fire.buf, false },
245   { KEY_TIMER_LONG, _value_timer_long.buf, false },
246 };
247 static struct abuf_template_data_entry _tde_socket_key[] = {
248   { KEY_STATISTICS_NAME, _value_stat_name, true },
249   { KEY_SOCKET_RECV, _value_socket_recv.buf, false },
250   { KEY_SOCKET_SEND, _value_socket_send.buf, false },
251   { KEY_SOCKET_LONG, _value_socket_long.buf, false },
252 };
253 static struct abuf_template_data_entry _tde_logging_key[] = {
254   { KEY_LOG_SOURCE, _value_log_source, true },
255   { KEY_LOG_WARNINGS, _value_log_warnings.buf, false },
256 };
257 static struct abuf_template_data_entry _tde_if_key[] = {
258   { KEY_IF_NAME, _value_if_name, true },
259   { KEY_IF_INDEX, _value_if_index, false },
260   { KEY_IF_BASEIDX, _value_if_baseidx, false },
261 };
262 static struct abuf_template_data_entry _tde_if_data[] = {
263   { KEY_IF_FLAG_UP, _value_if_flag_up, true },
264   { KEY_IF_FLAG_PROMISC, _value_if_flag_promisc, true },
265   { KEY_IF_FLAG_LOOPBACK, _value_if_flag_loopback, true },
266   { KEY_IF_FLAG_ANY, _value_if_flag_any, true },
267   { KEY_IF_FLAG_UNICAST, _value_if_flag_unicast, true },
268   { KEY_IF_FLAG_MESH, _value_if_flag_mesh, true },
269   { KEY_IF_MAC, _value_if_mac.buf, true },
270   { KEY_IF_IPV4, _value_if_ipv4.buf , true },
271   { KEY_IF_IPV6, _value_if_ipv6.buf , true },
272   { KEY_IF_LLV4, _value_if_llv4.buf , true },
273   { KEY_IF_LLV6, _value_if_llv6.buf , true },
274   { KEY_IF_ADDR_COUNT, _value_if_addr_count, false },
275   { KEY_IF_PEER_COUNT, _value_if_peer_count, false },
276 };
277 static struct abuf_template_data_entry _tde_ifaddr_data[] = {
278   { KEY_IFADDR_PREFIXED, _value_ifaddr_prefixed.buf, true },
279   { KEY_IFADDR_ADDR, _value_ifaddr_addr.buf, true },
280   { KEY_IFADDR_PREFIX, _value_ifaddr_prefix.buf, true },
281 };
282
283 static struct abuf_template_storage _template_storage;
284
285 /* Template Data objects (contain one or more Template Data Entries) */
286 static struct abuf_template_data _td_time[] = {
287   { _tde_time_key, ARRAYSIZE(_tde_time_key) },
288 };
289 static struct abuf_template_data _td_version[] = {
290   { _tde_version_key, ARRAYSIZE(_tde_version_key) },
291 };
292 static struct abuf_template_data _td_memory[] = {
293   { _tde_memory_key, ARRAYSIZE(_tde_memory_key) },
294 };
295 static struct abuf_template_data _td_timer[] = {
296   { _tde_timer_key, ARRAYSIZE(_tde_timer_key) },
297 };
298 static struct abuf_template_data _td_socket[] = {
299   { _tde_socket_key, ARRAYSIZE(_tde_socket_key) },
300 };
301 static struct abuf_template_data _td_logging[] = {
302   { _tde_logging_key, ARRAYSIZE(_tde_logging_key) },
303 };
304 static struct abuf_template_data _td_if[] = {
305   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
306   { _tde_if_data, ARRAYSIZE(_tde_if_data) },
307 };
308 static struct abuf_template_data _td_ifaddr[] = {
309   { _tde_if_key, ARRAYSIZE(_tde_if_key) },
310   { _tde_ifaddr_data, ARRAYSIZE(_tde_ifaddr_data) },
311 };
312
313 /* OONF viewer templates (based on Template Data arrays) */
314 static struct oonf_viewer_template _templates[] = {
315   {
316     .data = _td_time,
317     .data_size = ARRAYSIZE(_td_time),
318     .json_name = "time",
319     .cb_function = _cb_create_text_time,
320   },
321   {
322     .data = _td_version,
323     .data_size = ARRAYSIZE(_td_version),
324     .json_name = "version",
325     .cb_function = _cb_create_text_version,
326   },
327   {
328     .data = _td_memory,
329     .data_size = ARRAYSIZE(_td_memory),
330     .json_name = "memory",
331     .cb_function = _cb_create_text_memory,
332   },
333   {
334     .data = _td_timer,
335     .data_size = ARRAYSIZE(_td_timer),
336     .json_name = "timer",
337     .cb_function = _cb_create_text_timer,
338   },
339   {
340     .data = _td_socket,
341     .data_size = ARRAYSIZE(_td_socket),
342     .json_name = "socket",
343     .cb_function = _cb_create_text_socket,
344   },
345   {
346     .data = _td_logging,
347     .data_size = ARRAYSIZE(_td_logging),
348     .json_name = "logging",
349     .cb_function = _cb_create_text_logging,
350   },
351   {
352     .data = _td_if,
353     .data_size = ARRAYSIZE(_td_if),
354     .json_name = "interface",
355     .cb_function = _cb_create_text_interface,
356   },
357   {
358     .data = _td_ifaddr,
359     .data_size = ARRAYSIZE(_td_ifaddr),
360     .json_name = "if_addr",
361     .cb_function = _cb_create_text_ifaddr,
362   },
363   {
364     .data = _td_ifaddr,
365     .data_size = ARRAYSIZE(_td_ifaddr),
366     .json_name = "if_peer",
367     .cb_function = _cb_create_text_ifpeer,
368   },
369 };
370
371 /* telnet command of this plugin */
372 static struct oonf_telnet_command _telnet_commands[] = {
373   TELNET_CMD(OONF_SYSTEMINFO_SUBSYSTEM, _cb_systeminfo, "", .help_handler = _cb_systeminfo_help),
374 };
375
376 /* plugin declaration */
377 static const char *_dependencies[] = {
378   OONF_CLOCK_SUBSYSTEM,
379   OONF_TELNET_SUBSYSTEM,
380   OONF_VIEWER_SUBSYSTEM,
381 };
382
383 static struct oonf_subsystem _olsrv2_systeminfo_subsystem = {
384   .name = OONF_SYSTEMINFO_SUBSYSTEM,
385   .dependencies = _dependencies,
386   .dependencies_count = ARRAYSIZE(_dependencies),
387   .descr = "OLSRv2 system info plugin",
388   .author = "Henning Rogge",
389   .init = _init,
390   .cleanup = _cleanup,
391 };
392 DECLARE_OONF_PLUGIN(_olsrv2_systeminfo_subsystem);
393
394 /**
395  * Initialize plugin
396  * @return -1 if an error happened, 0 otherwise
397  */
398 static int
399 _init(void) {
400   oonf_telnet_add(&_telnet_commands[0]);
401   return 0;
402 }
403
404 /**
405  * Cleanup plugin
406  */
407 static void
408 _cleanup(void) {
409   oonf_telnet_remove(&_telnet_commands[0]);
410 }
411
412 /**
413  * Callback for the telnet command of this plugin
414  * @param con pointer to telnet session data
415  * @return telnet result value
416  */
417 static enum oonf_telnet_result
418 _cb_systeminfo(struct oonf_telnet_data *con) {
419   return oonf_viewer_telnet_handler(
420     con->out, &_template_storage, OONF_SYSTEMINFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
421 }
422
423 /**
424  * Callback for the help output of this plugin
425  * @param con pointer to telnet session data
426  * @return telnet result value
427  */
428 static enum oonf_telnet_result
429 _cb_systeminfo_help(struct oonf_telnet_data *con) {
430   return oonf_viewer_telnet_help(
431     con->out, OONF_SYSTEMINFO_SUBSYSTEM, con->parameter, _templates, ARRAYSIZE(_templates));
432 }
433
434 /**
435  * Initialize the value buffers for the time of the system
436  */
437 static void
438 _initialize_time_values(struct oonf_viewer_template *template) {
439   oonf_log_get_walltime(&_value_system_time);
440   isonumber_from_u64(&_value_internal_time, oonf_clock_getNow(), "", 3, template->create_raw);
441 }
442
443 /**
444  * Initialize the value buffers for the version of OONF
445  */
446 static void
447 _initialize_version_values(struct oonf_viewer_template *template __attribute__((unused))) {
448   strscpy(_value_version_text, oonf_log_get_libdata()->version, sizeof(_value_version_text));
449   strscpy(_value_version_commit, oonf_log_get_libdata()->git_commit, sizeof(_value_version_commit));
450 }
451
452 /**
453  * Initialize the value buffers for a memory class
454  */
455 static void
456 _initialize_memory_values(struct oonf_viewer_template *template, struct oonf_class *cl) {
457   strscpy(_value_stat_name, cl->name, sizeof(_value_stat_name));
458
459   isonumber_from_u64(&_value_memory_usage, oonf_class_get_usage(cl), "", 0, template->create_raw);
460   isonumber_from_u64(&_value_memory_freelist, oonf_class_get_free(cl), "", 0, template->create_raw);
461   isonumber_from_u64(&_value_memory_alloc, oonf_class_get_allocations(cl), "", 0, template->create_raw);
462   isonumber_from_u64(&_value_memory_recycled, oonf_class_get_recycled(cl), "", 0, template->create_raw);
463 }
464
465 /**
466  * Initialize the value buffers for a timer class
467  */
468 static void
469 _initialize_timer_values(struct oonf_viewer_template *template, struct oonf_timer_class *tc) {
470   strscpy(_value_stat_name, tc->name, sizeof(_value_stat_name));
471
472   isonumber_from_u64(&_value_timer_usage, oonf_timer_get_usage(tc), "", 0, template->create_raw);
473   isonumber_from_u64(&_value_timer_change, oonf_timer_get_changes(tc), "", 0, template->create_raw);
474   isonumber_from_u64(&_value_timer_fire, oonf_timer_get_fired(tc), "", 0, template->create_raw);
475   isonumber_from_u64(&_value_timer_long, oonf_timer_get_long(tc), "", 0, template->create_raw);
476 }
477
478 /**
479  * Initialize the value buffers for a timer class
480  */
481 static void
482 _initialize_socket_values(struct oonf_viewer_template *template, struct oonf_socket_entry *sock) {
483   strscpy(_value_stat_name, sock->name, sizeof(_value_stat_name));
484
485   isonumber_from_u64(&_value_socket_recv, oonf_socket_get_recv(sock), "", 0, template->create_raw);
486   isonumber_from_u64(&_value_socket_send, oonf_socket_get_send(sock), "", 0, template->create_raw);
487   isonumber_from_u64(&_value_socket_long, oonf_socket_get_long(sock), "", 0, template->create_raw);
488 }
489
490 /**
491  * Initialize the value buffers for a logging source
492  * @param template viewer template
493  * @param source logging source
494  */
495 static void
496 _initialize_logging_values(struct oonf_viewer_template *template, enum oonf_log_source source) {
497   strscpy(_value_log_source, LOG_SOURCE_NAMES[source], sizeof(_value_log_source));
498   isonumber_from_u64(&_value_log_warnings, oonf_log_get_warning_count(source), "", 0, template->create_raw);
499 }
500
501 /**
502  * Initialize the value buffers for an interface key
503  * @param template viewer template
504  * @param interf OONF interface instance
505  */
506 static void
507 _initialize_interface_key_values(struct oonf_viewer_template *template __attribute__((unused)),
508                                  struct os_interface *interf) {
509   strscpy(_value_if_name, interf->name, IF_NAMESIZE);
510   snprintf(_value_if_index, sizeof(_value_if_index), "%u", interf->index);
511   snprintf(_value_if_baseidx, sizeof(_value_if_baseidx), "%u", interf->base_index);
512 }
513
514 /**
515  * Initialize the value buffers for interface data
516  * @param template viewer template
517  * @param interf OONF interface instance
518  */
519 static void
520 _initialize_interface_data_values(struct oonf_viewer_template *template __attribute__((unused)),
521                                   struct os_interface *interf) {
522   strscpy(_value_if_flag_up, json_getbool(interf->flags.up), sizeof(_value_if_flag_up));
523   strscpy(_value_if_flag_promisc, json_getbool(interf->flags.promisc), sizeof(_value_if_flag_promisc));
524   strscpy(_value_if_flag_loopback, json_getbool(interf->flags.loopback), sizeof(_value_if_flag_loopback));
525   strscpy(_value_if_flag_any, json_getbool(interf->flags.any), sizeof(_value_if_flag_any));
526   strscpy(_value_if_flag_unicast, json_getbool(interf->flags.unicast_only), sizeof(_value_if_flag_unicast));
527   strscpy(_value_if_flag_mesh, json_getbool(interf->flags.mesh), sizeof(_value_if_flag_mesh));
528   netaddr_to_string(&_value_if_mac, &interf->mac);
529   netaddr_to_string(&_value_if_ipv4, interf->if_v4);
530   netaddr_to_string(&_value_if_ipv6, interf->if_v6);
531   netaddr_to_string(&_value_if_llv4, interf->if_linklocal_v4);
532   netaddr_to_string(&_value_if_llv6, interf->if_linklocal_v6);
533   snprintf(_value_if_addr_count, sizeof(_value_if_addr_count), "%u", interf->addresses.count);
534   snprintf(_value_if_peer_count, sizeof(_value_if_peer_count), "%u", interf->peers.count);
535 }
536
537 /**
538  * Initialize the value buffers for interface addresses or peers
539  * @param template viewer template
540  * @param ip OONF interface ip instance
541  */
542 static void
543 _initialize_ifaddr_data_values(struct oonf_viewer_template *template __attribute__((unused)),
544                                   struct os_interface_ip *ip) {
545   netaddr_to_string(&_value_ifaddr_prefixed, &ip->prefixed_addr);
546   netaddr_to_string(&_value_ifaddr_addr, &ip->address);
547   netaddr_to_string(&_value_ifaddr_prefix, &ip->prefix);
548 }
549
550 /**
551  * Callback to generate text/json description of current time
552  * @param template viewer template
553  * @return -1 if an error happened, 0 otherwise
554  */
555 static int
556 _cb_create_text_time(struct oonf_viewer_template *template) {
557   /* initialize values */
558   _initialize_time_values(template);
559
560   /* generate template output */
561   oonf_viewer_output_print_line(template);
562   return 0;
563 }
564
565 /**
566  * Callback to generate text/json description of version of OONF
567  * @param template viewer template
568  * @return -1 if an error happened, 0 otherwise
569  */
570 static int
571 _cb_create_text_version(struct oonf_viewer_template *template) {
572   /* initialize values */
573   _initialize_version_values(template);
574
575   /* generate template output */
576   oonf_viewer_output_print_line(template);
577   return 0;
578 }
579
580 /**
581  * Callback to generate text/json description of registered memory blocks
582  * @param template viewer template
583  * @return -1 if an error happened, 0 otherwise
584  */
585 static int
586 _cb_create_text_memory(struct oonf_viewer_template *template) {
587   struct oonf_class *c;
588
589   avl_for_each_element(oonf_class_get_tree(), c, _node) {
590     _initialize_memory_values(template, c);
591
592     /* generate template output */
593     oonf_viewer_output_print_line(template);
594   }
595
596   return 0;
597 }
598
599 /**
600  * Callback to generate text/json description of registered timers
601  * @param template viewer template
602  * @return -1 if an error happened, 0 otherwise
603  */
604 static int
605 _cb_create_text_timer(struct oonf_viewer_template *template) {
606   struct oonf_timer_class *tc;
607
608   list_for_each_element(oonf_timer_get_list(), tc, _node) {
609     _initialize_timer_values(template, tc);
610
611     /* generate template output */
612     oonf_viewer_output_print_line(template);
613   }
614
615   return 0;
616 }
617
618 /**
619  * Callback to generate text/json description of registered sockets
620  * @param template viewer template
621  * @return -1 if an error happened, 0 otherwise
622  */
623 static int
624 _cb_create_text_socket(struct oonf_viewer_template *template) {
625   struct oonf_socket_entry *sock;
626
627   list_for_each_element(oonf_socket_get_list(), sock, _node) {
628     _initialize_socket_values(template, sock);
629
630     /* generate template output */
631     oonf_viewer_output_print_line(template);
632   }
633
634   return 0;
635 }
636
637 /**
638  * Callback to generate text/json description for logging sources
639  * @param template viewer template
640  * @return -1 if an error happened, 0 otherwise
641  */
642 static int
643 _cb_create_text_logging(struct oonf_viewer_template *template) {
644   enum oonf_log_source source;
645
646   for (source = 0; source < oonf_log_get_sourcecount(); source++) {
647     _initialize_logging_values(template, source);
648
649     /* generate template output */
650     oonf_viewer_output_print_line(template);
651   }
652
653   return 0;
654 }
655
656 /**
657  * Callback to generate text/json description for interfaces
658  * @param template viewer template
659  * @return -1 if an error happened, 0 otherwise
660  */
661 static int
662 _cb_create_text_interface(struct oonf_viewer_template *template) {
663   struct os_interface *interf;
664
665   avl_for_each_element(os_interface_get_tree(), interf, _node) {
666     _initialize_interface_key_values(template, interf);
667     _initialize_interface_data_values(template, interf);
668
669     /* generate template output */
670     oonf_viewer_output_print_line(template);
671   }
672
673   return 0;
674 }
675
676 /**
677  * Callback to generate text/json description for interface addresses
678  * @param template viewer template
679  * @return -1 if an error happened, 0 otherwise
680  */
681 static int
682 _cb_create_text_ifaddr(struct oonf_viewer_template *template) {
683   struct os_interface *interf;
684   struct os_interface_ip *ip;
685
686   avl_for_each_element(os_interface_get_tree(), interf, _node) {
687     _initialize_interface_key_values(template, interf);
688
689     avl_for_each_element(&interf->addresses, ip, _node) {
690       _initialize_ifaddr_data_values(template, ip);
691
692       /* generate template output */
693       oonf_viewer_output_print_line(template);
694     }
695   }
696
697   return 0;
698 }
699
700 /**
701  * Callback to generate text/json description for interface peers
702  * @param template viewer template
703  * @return -1 if an error happened, 0 otherwise
704  */
705 static int
706 _cb_create_text_ifpeer(struct oonf_viewer_template *template) {
707   struct os_interface *interf;
708   struct os_interface_ip *ip;
709
710   avl_for_each_element(os_interface_get_tree(), interf, _node) {
711     _initialize_interface_key_values(template, interf);
712
713     avl_for_each_element(&interf->peers, ip, _node) {
714       _initialize_ifaddr_data_values(template, ip);
715
716       /* generate template output */
717       oonf_viewer_output_print_line(template);
718     }
719   }
720
721   return 0;
722 }