3ee105ff787bd789b022a88b576166a5cfa43b0b
[routeros-api.git] / src / interface.c
1 /**
2  * librouteros - src/interface.c
3  * Copyright (C) 2009  Florian octo Forster
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; only version 2 of the License is applicable.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  * Authors:
19  *   Florian octo Forster <octo at verplant.org>
20  **/
21
22 #ifndef _ISOC99_SOURCE
23 # define _ISOC99_SOURCE
24 #endif
25
26 #ifndef _POSIX_C_SOURCE
27 # define _POSIX_C_SOURCE 200112L
28 #endif
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <stdbool.h>
34 #include <math.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <stdint.h>
39 #include <inttypes.h>
40 #include <assert.h>
41
42 #include "routeros_api.h"
43 #include "ros_parse.h"
44
45 /*
46  * Private data types
47  */
48 struct rt_internal_data_s
49 {
50         ros_interface_handler_t handler;
51         void *user_data;
52 };
53 typedef struct rt_internal_data_s rt_internal_data_t;
54
55 /*
56  * Private functions
57  */
58 static ros_interface_t *rt_reply_to_interface (const ros_reply_t *r) /* {{{ */
59 {
60         ros_interface_t *ret;
61
62         if (r == NULL)
63                 return (NULL);
64
65         if (strcmp ("re", ros_reply_status (r)) != 0)
66                 return (rt_reply_to_interface (ros_reply_next (r)));
67
68         ret = malloc (sizeof (*ret));
69         if (ret == NULL)
70                 return (NULL);
71         memset (ret, 0, sizeof (*ret));
72
73         ret->name = ros_reply_param_val_by_key (r, "name");
74         ret->type = ros_reply_param_val_by_key (r, "type");
75         ret->comment = ros_reply_param_val_by_key (r, "comment");
76
77         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "packets"),
78                         &ret->rx_packets, &ret->tx_packets);
79         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "bytes"),
80                         &ret->rx_bytes, &ret->tx_bytes);
81         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "errors"),
82                         &ret->rx_errors, &ret->tx_errors);
83         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "drops"),
84                         &ret->rx_drops, &ret->tx_drops);
85
86         ret->mtu = sstrtoui (ros_reply_param_val_by_key (r, "mtu"));
87         ret->l2mtu = sstrtoui (ros_reply_param_val_by_key (r, "l2mtu"));
88
89         ret->dynamic = sstrtob (ros_reply_param_val_by_key (r, "dynamic"));
90         ret->running = sstrtob (ros_reply_param_val_by_key (r, "running"));
91         ret->enabled = !sstrtob (ros_reply_param_val_by_key (r, "disabled"));
92
93         ret->next = rt_reply_to_interface (ros_reply_next (r));
94
95         return (ret);
96 } /* }}} ros_interface_t *rt_reply_to_interface */
97
98 static void if_interface_free (const ros_interface_t *r) /* {{{ */
99 {
100         const ros_interface_t *next;
101
102         while (r != NULL)
103         {
104                 next = r->next;
105                 free ((void *) r);
106                 r = next;
107         }
108 } /* }}} void if_interface_free */
109
110 static int if_internal_handler (ros_connection_t *c, /* {{{ */
111                 const ros_reply_t *r, void *user_data)
112 {
113         ros_interface_t *if_data;
114         rt_internal_data_t *internal_data;
115         int status;
116
117         if_data = rt_reply_to_interface (r);
118         if (if_data == NULL)
119                 return (errno);
120
121         internal_data = user_data;
122
123         status = internal_data->handler (c, if_data, internal_data->user_data);
124
125         if_interface_free (if_data);
126
127         return (status);
128 } /* }}} int if_internal_handler */
129
130 /*
131  * Public functions
132  */
133 int ros_interface (ros_connection_t *c, /* {{{ */
134                 ros_interface_handler_t handler, void *user_data)
135 {
136         rt_internal_data_t data;
137
138         if ((c == NULL) || (handler == NULL))
139                 return (EINVAL);
140
141         data.handler = handler;
142         data.user_data = user_data;
143
144         return (ros_query (c, "/interface/print",
145                                 /* args_num = */ 0, /* args = */ NULL,
146                                 if_internal_handler, &data));
147 } /* }}} int ros_interface */
148
149 /* vim: set ts=2 sw=2 noet fdm=marker : */