2 * libmikrotik - src/ros.c
3 * Copyright (C) 2009 Florian octo Forster
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.
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.
18 * Florian octo Forster <octo at verplant.org>
21 #ifndef _ISOC99_SOURCE
22 # define _ISOC99_SOURCE
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
36 #include "routeros_api.h"
39 # define __attribute__(x) /**/
42 static const char *opt_username = "admin";
44 static int result_handler (ros_connection_t *c, const ros_reply_t *r, /* {{{ */
52 printf ("Status: %s\n", ros_reply_status (r));
54 for (i = 0; /* true */; i++)
59 key = ros_reply_param_key_by_index (r, i);
60 val = ros_reply_param_val_by_index (r, i);
62 if ((key == NULL) || (val == NULL))
65 fprintf (stderr, "val is NULL but key is %s!\n", key);
67 fprintf (stderr, "key is NULL but val is %s!\n", val);
71 printf (" Param %u: %s = %s\n", i, key, val);
76 return (result_handler (c, ros_reply_next (r), user_data));
77 } /* }}} int result_handler */
79 static void regtable_dump (const ros_registration_table_t *r) /* {{{ */
84 printf ("=== %s / %s ===\n", r->interface, r->radio_name);
85 printf ("Mode: %12s\n",
86 r->ap ? (r->wds ? "AP with WDS" : "Access point") : "Station");
87 printf ("Rate: %7g Mbps / %7g Mbps\n", r->rx_rate, r->tx_rate);
88 printf ("Packets: %12"PRIu64" / %12"PRIu64"\n",
89 r->rx_packets, r->tx_packets);
90 printf ("Bytes: %12"PRIu64" / %12"PRIu64"\n",
91 r->rx_bytes, r->tx_bytes);
92 printf ("Frames %12"PRIu64" / %12"PRIu64"\n",
93 r->rx_frames, r->tx_frames);
94 printf ("Frame Bytes: %12"PRIu64" / %12"PRIu64"\n",
95 r->rx_frame_bytes, r->tx_frame_bytes);
96 printf ("HW Frames: %12"PRIu64" / %12"PRIu64"\n",
97 r->rx_hw_frames, r->tx_hw_frames);
98 printf ("HW Frame Bytes: %12"PRIu64" / %12"PRIu64"\n",
99 r->rx_hw_frame_bytes, r->tx_hw_frame_bytes);
100 printf ("Quality: %10g %% / %10g %%\n",
101 r->rx_ccq, r->tx_ccq);
102 printf ("Signal str.: %8g dBm / %8g dBm\n",
103 r->rx_signal_strength, r->tx_signal_strength);
104 printf ("Signal / noise: %8g dBm\n", r->signal_to_noise);
105 printf ("==========\n");
107 regtable_dump (r->next);
108 } /* }}} void regtable_dump */
110 static int regtable_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
111 const ros_registration_table_t *r,
112 __attribute__((unused)) void *user_data)
116 } /* }}} int regtable_handler */
118 static void interface_dump (const ros_interface_t *i) /* {{{ */
123 printf ("=== %s ===\n"
126 "Bytes: %12"PRIu64" / %12"PRIu64"\n"
127 "Packets: %12"PRIu64" / %12"PRIu64"\n"
128 "Errors: %12"PRIu64" / %12"PRIu64"\n"
129 "Drops: %12"PRIu64" / %12"PRIu64"\n"
136 i->name, i->type, i->comment,
137 i->rx_bytes, i->tx_bytes,
138 i->rx_packets, i->tx_packets,
139 i->rx_errors, i->tx_errors,
140 i->rx_drops, i->tx_drops,
142 i->running ? "true" : "false",
143 i->dynamic ? "true" : "false",
144 i->enabled ? "true" : "false");
146 interface_dump (i->next);
147 } /* }}} void interface_dump */
149 static int interface_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
150 const ros_interface_t *i,
151 __attribute__((unused)) void *user_data)
155 } /* }}} int interface_handler */
157 static int system_resource_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
158 const ros_system_resource_t *r, __attribute__((unused)) void *user_data)
160 uint64_t used_memory;
161 uint64_t used_hdd_space;
166 used_memory = r->total_memory - r->free_memory;
167 used_hdd_space = r->total_hdd_space - r->free_hdd_space;
169 printf ("====== System resources ======\n"
170 "Uptime: %10.2f days\n"
171 "RouterOS version: %11s\n"
172 "Architecture name: %11s\n"
177 "CPU frequency: %11g MHz\n"
178 "Memory free: %10"PRIu64" Byte (%4.1f %%)\n"
179 "Memory used: %10"PRIu64" Byte (%4.1f %%)\n"
180 "Memory total: %10"PRIu64" Byte\n"
181 "Space free: %10"PRIu64" Byte (%4.1f %%)\n"
182 "Space used: %10"PRIu64" Byte (%4.1f %%)\n"
183 "Space total: %10"PRIu64" Byte\n"
184 "Sectors written: %13"PRIu64" (%"PRIu64")\n"
185 "Bad blocks: %15"PRIu64"\n"
186 "==============================\n",
187 ((double) r->uptime) / 86400.0, r->version,
188 r->architecture_name, r->board_name,
189 r->cpu_model, r->cpu_count, r->cpu_load,
190 ((double) r->cpu_frequency) / 1000000.0,
192 100.0 * (((double) r->free_memory) / ((double) r->total_memory)),
194 100.0 * (((double) used_memory) / ((double) r->total_memory)),
197 100.0 * (((double) r->free_hdd_space) / ((double) r->total_hdd_space)),
199 100.0 * (((double) used_hdd_space) / ((double) r->total_hdd_space)),
201 r->write_sect_since_reboot,
206 } /* }}} int system_resource_handler */
208 static char *read_password (void) /* {{{ */
211 struct termios old_flags;
212 struct termios new_flags;
218 tty = fopen ("/dev/tty", "w+");
221 fprintf (stderr, "Unable to open /dev/tty: %s\n",
226 fprintf (tty, "Password for user %s: ", opt_username);
229 memset (&old_flags, 0, sizeof (old_flags));
230 tcgetattr (fileno (tty), &old_flags);
231 new_flags = old_flags;
233 new_flags.c_lflag &= ~ECHO;
235 new_flags.c_lflag |= ECHONL;
237 status = tcsetattr (fileno (tty), TCSANOW, &new_flags);
240 fprintf (stderr, "tcsetattr failed: %s\n", strerror (errno));
245 if (fgets (buffer, sizeof (buffer), tty) == NULL)
247 fprintf (stderr, "fgets failed: %s\n", strerror (errno));
251 buffer[sizeof (buffer) - 1] = 0;
252 buffer_len = strlen (buffer);
254 status = tcsetattr (fileno (tty), TCSANOW, &old_flags);
256 fprintf (stderr, "tcsetattr failed: %s\n", strerror (errno));
261 while ((buffer_len > 0) && ((buffer[buffer_len-1] == '\n') || (buffer[buffer_len-1] == '\r')))
264 buffer[buffer_len] = 0;
269 passwd = malloc (strlen (buffer) + 1);
272 memcpy (passwd, buffer, strlen (buffer) + 1);
273 memset (buffer, 0, sizeof (buffer));
276 } /* }}} char *read_password */
278 static void exit_usage (void) /* {{{ */
280 printf ("Usage: ros [options] <host> <command> [args]\n"
283 " -u <user> Use <user> to authenticate.\n"
284 " -h Display this help message.\n"
286 if (ros_version () == ROS_VERSION)
287 printf ("Using librouteros %s\n", ROS_VERSION_STRING);
289 printf ("Using librouteros %s (%s)\n",
290 ros_version_string (), ROS_VERSION_STRING);
291 printf ("Copyright (c) 2009 by Florian Forster\n");
294 } /* }}} void exit_usage */
296 int main (int argc, char **argv) /* {{{ */
305 while ((option = getopt (argc, argv, "u:h?")) != -1)
310 opt_username = optarg;
321 if ((argc - optind) < 2)
325 command = argv[optind+1];
327 passwd = read_password ();
331 c = ros_connect (host, ROUTEROS_API_PORT,
332 opt_username, passwd);
333 memset (passwd, 0, strlen (passwd));
336 fprintf (stderr, "ros_connect failed: %s\n", strerror (errno));
340 if (command[0] == '/')
342 ros_query (c, command,
343 (size_t) (argc - (optind + 2)), (const char * const *) (argv + optind + 2),
344 result_handler, /* user data = */ NULL);
346 else if (strcmp ("interface", command) == 0)
348 ros_interface (c, interface_handler, /* user data = */ NULL);
350 else if (strcmp ("registration-table", command) == 0)
352 ros_registration_table (c, regtable_handler, /* user data = */ NULL);
354 else if (strcmp ("system-resource", command) == 0)
356 ros_system_resource (c, system_resource_handler, /* user data = */ NULL);
360 fprintf (stderr, "Unknown built-in command %s. "
361 "Are you missing a leading slash?\n", command);
369 /* vim: set ts=2 sw=2 noet fdm=marker : */