Relicense to ISC License.
[routeros-api.git] / src / ros.c
index cf65a61..770b84e 100644 (file)
--- a/src/ros.c
+++ b/src/ros.c
@@ -2,18 +2,17 @@
  * libmikrotik - src/ros.c
  * Copyright (C) 2009  Florian octo Forster
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; only version 2 of the License is applicable.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
  *
  * Authors:
  *   Florian octo Forster <octo at verplant.org>
 
 #include "routeros_api.h"
 
+#if !__GNUC__
+# define __attribute__(x) /**/
+#endif
+
 static const char *opt_username = "admin";
 
 static int result_handler (ros_connection_t *c, const ros_reply_t *r, /* {{{ */
@@ -78,7 +81,9 @@ static void regtable_dump (const ros_registration_table_t *r) /* {{{ */
        if (r == NULL)
                return;
 
-       printf ("=== %s ===\n", r->interface);
+       printf ("=== %s / %s ===\n", r->interface, r->radio_name);
+       printf ("Mode:           %12s\n",
+                       r->ap ? (r->wds ? "AP with WDS" : "Access point") : "Station");
        printf ("Rate:           %7g Mbps / %7g Mbps\n", r->rx_rate, r->tx_rate);
        printf ("Packets:        %12"PRIu64" / %12"PRIu64"\n",
                        r->rx_packets, r->tx_packets);
@@ -102,13 +107,104 @@ static void regtable_dump (const ros_registration_table_t *r) /* {{{ */
        regtable_dump (r->next);
 } /* }}} void regtable_dump */
 
-static int regtable_handler (ros_connection_t *c, /* {{{ */
-               const ros_registration_table_t *r, void *user_data)
+static int regtable_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
+               const ros_registration_table_t *r,
+               __attribute__((unused)) void *user_data)
 {
        regtable_dump (r);
        return (0);
 } /* }}} int regtable_handler */
 
+static void interface_dump (const ros_interface_t *i) /* {{{ */
+{
+       if (i == NULL)
+               return;
+
+       printf ("=== %s ===\n"
+                       "Type:    %12s\n"
+                       "Comment: %12s\n"
+                       "Bytes:   %12"PRIu64" / %12"PRIu64"\n"
+                       "Packets: %12"PRIu64" / %12"PRIu64"\n"
+                       "Errors:  %12"PRIu64" / %12"PRIu64"\n"
+                       "Drops:   %12"PRIu64" / %12"PRIu64"\n"
+                       "MTU:     %12u\n"
+                       "L2 MTU:  %12u\n"
+                       "Running: %12s\n"
+                       "Dynamic: %12s\n"
+                       "Enabled: %12s\n"
+                       "==========\n",
+                       i->name, i->type, i->comment,
+                       i->rx_bytes, i->tx_bytes,
+                       i->rx_packets, i->tx_packets,
+                       i->rx_errors, i->tx_errors,
+                       i->rx_drops, i->tx_drops,
+                       i->mtu, i->l2mtu,
+                       i->running ? "true" : "false",
+                       i->dynamic ? "true" : "false",
+                       i->enabled ? "true" : "false");
+
+       interface_dump (i->next);
+} /* }}} void interface_dump */
+
+static int interface_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
+               const ros_interface_t *i,
+               __attribute__((unused)) void *user_data)
+{
+       interface_dump (i);
+       return (0);
+} /* }}} int interface_handler */
+
+static int system_resource_handler (__attribute__((unused)) ros_connection_t *c, /* {{{ */
+               const ros_system_resource_t *r, __attribute__((unused)) void *user_data)
+{
+       uint64_t used_memory;
+       uint64_t used_hdd_space;
+
+       if (r == NULL)
+               return (EINVAL);
+
+       used_memory = r->total_memory - r->free_memory;
+       used_hdd_space = r->total_hdd_space - r->free_hdd_space;
+
+       printf ("====== System resources ======\n"
+                       "Uptime:        %10.2f days\n"
+                       "RouterOS version:  %11s\n"
+                       "Architecture name: %11s\n"
+                       "Board name:    %15s\n"
+                       "CPU model:     %15s\n"
+                       "CPU count:     %15u\n"
+                       "CPU load:      %15u\n"
+                       "CPU frequency: %11g MHz\n"
+                       "Memory free:   %10"PRIu64" Byte (%4.1f %%)\n"
+                       "Memory used:   %10"PRIu64" Byte (%4.1f %%)\n"
+                       "Memory total:  %10"PRIu64" Byte\n"
+                       "Space free:    %10"PRIu64" Byte (%4.1f %%)\n"
+                       "Space used:    %10"PRIu64" Byte (%4.1f %%)\n"
+                       "Space total:   %10"PRIu64" Byte\n"
+                       "Sectors written: %13"PRIu64" (%"PRIu64")\n"
+                       "Bad blocks:    %15"PRIu64"\n"
+                       "==============================\n",
+                       ((double) r->uptime) / 86400.0, r->version,
+                       r->architecture_name, r->board_name,
+                       r->cpu_model, r->cpu_count, r->cpu_load,
+                       ((double) r->cpu_frequency) / 1000000.0,
+                       r->free_memory,
+                       100.0 * (((double) r->free_memory) / ((double) r->total_memory)),
+                       used_memory,
+                       100.0 * (((double) used_memory) / ((double) r->total_memory)),
+                       r->total_memory,
+                       r->free_hdd_space,
+                       100.0 * (((double) r->free_hdd_space) / ((double) r->total_hdd_space)),
+                       used_hdd_space,
+                       100.0 * (((double) used_hdd_space) / ((double) r->total_hdd_space)),
+                       r->total_hdd_space,
+                       r->write_sect_since_reboot,
+                       r->write_sect_total,
+                       r->bad_blocks);
+
+       return (0);
+} /* }}} int system_resource_handler */
+
 static char *read_password (void) /* {{{ */
 {
        FILE *tty;
@@ -146,7 +242,12 @@ static char *read_password (void) /* {{{ */
                return (NULL);
        }
 
-       fgets (buffer, sizeof (buffer), tty);
+       if (fgets (buffer, sizeof (buffer), tty) == NULL)
+       {
+               fprintf (stderr, "fgets failed: %s\n", strerror (errno));
+               fclose (tty);
+               return (NULL);
+       }
        buffer[sizeof (buffer) - 1] = 0;
        buffer_len = strlen (buffer);
 
@@ -176,7 +277,19 @@ static char *read_password (void) /* {{{ */
 
 static void exit_usage (void) /* {{{ */
 {
-       printf ("Usage: ros [options] <host> <command> [args]\n");
+       printf ("Usage: ros [options] <host> <command> [args]\n"
+                       "\n"
+                       "OPTIONS:\n"
+                       "  -u <user>       Use <user> to authenticate.\n"
+                       "  -h              Display this help message.\n"
+                       "\n");
+       if (ros_version () == ROS_VERSION)
+               printf ("Using librouteros %s\n", ROS_VERSION_STRING);
+       else
+               printf ("Using librouteros %s (%s)\n",
+                               ros_version_string (), ROS_VERSION_STRING);
+       printf ("Copyright (c) 2009 by Florian Forster\n");
+
        exit (EXIT_SUCCESS);
 } /* }}} void exit_usage */
 
@@ -215,7 +328,7 @@ int main (int argc, char **argv) /* {{{ */
        if (passwd == NULL)
                exit (EXIT_FAILURE);
 
-       c = ros_connect (argv[optind], ROUTEROS_API_PORT,
+       c = ros_connect (host, ROUTEROS_API_PORT,
                        opt_username, passwd);
        memset (passwd, 0, strlen (passwd));
        if (c == NULL)
@@ -230,10 +343,18 @@ int main (int argc, char **argv) /* {{{ */
                                (size_t) (argc - (optind + 2)), (const char * const *) (argv + optind + 2),
                                result_handler, /* user data = */ NULL);
        }
+       else if (strcmp ("interface", command) == 0)
+       {
+               ros_interface (c, interface_handler, /* user data = */ NULL);
+       }
        else if (strcmp ("registration-table", command) == 0)
        {
                ros_registration_table (c, regtable_handler, /* user data = */ NULL);
        }
+       else if (strcmp ("system-resource", command) == 0)
+       {
+               ros_system_resource (c, system_resource_handler, /* user data = */ NULL);
+       }
        else
        {
                fprintf (stderr, "Unknown built-in command %s. "