Relicense to ISC License.
[routeros-api.git] / src / interface.c
1 /**
2  * librouteros - src/interface.c
3  * Copyright (C) 2009  Florian octo Forster
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  *
17  * Authors:
18  *   Florian octo Forster <octo at verplant.org>
19  **/
20
21 #ifndef _ISOC99_SOURCE
22 # define _ISOC99_SOURCE
23 #endif
24
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
27 #endif
28
29 #include "config.h"
30
31 #include <stdlib.h>
32 #include <stdbool.h>
33 #include <math.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <stdint.h>
38 #include <inttypes.h>
39 #include <assert.h>
40
41 #include "routeros_api.h"
42 #include "ros_parse.h"
43
44 /*
45  * Private data types
46  */
47 struct rt_internal_data_s
48 {
49         ros_interface_handler_t handler;
50         void *user_data;
51 };
52 typedef struct rt_internal_data_s rt_internal_data_t;
53
54 /*
55  * Private functions
56  */
57 static ros_interface_t *rt_reply_to_interface (const ros_reply_t *r) /* {{{ */
58 {
59         ros_interface_t *ret;
60
61         if (r == NULL)
62                 return (NULL);
63
64         if (strcmp ("re", ros_reply_status (r)) != 0)
65                 return (rt_reply_to_interface (ros_reply_next (r)));
66
67         ret = malloc (sizeof (*ret));
68         if (ret == NULL)
69                 return (NULL);
70         memset (ret, 0, sizeof (*ret));
71
72         ret->name = ros_reply_param_val_by_key (r, "name");
73         ret->type = ros_reply_param_val_by_key (r, "type");
74         ret->comment = ros_reply_param_val_by_key (r, "comment");
75
76         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "packets"),
77                         &ret->rx_packets, &ret->tx_packets);
78         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "bytes"),
79                         &ret->rx_bytes, &ret->tx_bytes);
80         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "errors"),
81                         &ret->rx_errors, &ret->tx_errors);
82         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "drops"),
83                         &ret->rx_drops, &ret->tx_drops);
84
85         ret->mtu = sstrtoui (ros_reply_param_val_by_key (r, "mtu"));
86         ret->l2mtu = sstrtoui (ros_reply_param_val_by_key (r, "l2mtu"));
87
88         ret->dynamic = sstrtob (ros_reply_param_val_by_key (r, "dynamic"));
89         ret->running = sstrtob (ros_reply_param_val_by_key (r, "running"));
90         ret->enabled = !sstrtob (ros_reply_param_val_by_key (r, "disabled"));
91
92         ret->next = rt_reply_to_interface (ros_reply_next (r));
93
94         return (ret);
95 } /* }}} ros_interface_t *rt_reply_to_interface */
96
97 static void if_interface_free (const ros_interface_t *r) /* {{{ */
98 {
99         const ros_interface_t *next;
100
101         while (r != NULL)
102         {
103                 next = r->next;
104                 free ((void *) r);
105                 r = next;
106         }
107 } /* }}} void if_interface_free */
108
109 static int if_internal_handler (ros_connection_t *c, /* {{{ */
110                 const ros_reply_t *r, void *user_data)
111 {
112         ros_interface_t *if_data;
113         rt_internal_data_t *internal_data;
114         int status;
115
116         if_data = rt_reply_to_interface (r);
117         if (if_data == NULL)
118                 return (errno);
119
120         internal_data = user_data;
121
122         status = internal_data->handler (c, if_data, internal_data->user_data);
123
124         if_interface_free (if_data);
125
126         return (status);
127 } /* }}} int if_internal_handler */
128
129 /*
130  * Public functions
131  */
132 int ros_interface (ros_connection_t *c, /* {{{ */
133                 ros_interface_handler_t handler, void *user_data)
134 {
135         rt_internal_data_t data;
136
137         if ((c == NULL) || (handler == NULL))
138                 return (EINVAL);
139
140         data.handler = handler;
141         data.user_data = user_data;
142
143         return (ros_query (c, "/interface/print",
144                                 /* args_num = */ 0, /* args = */ NULL,
145                                 if_internal_handler, &data));
146 } /* }}} int ros_interface */
147
148 /* vim: set ts=2 sw=2 noet fdm=marker : */