Use session[s].opened consistently when checking for in-use sessions (rather than...
[l2tpns.git] / cli.c
diff --git a/cli.c b/cli.c
index 190372e..9f50323 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -2,10 +2,11 @@
 // vim: sw=8 ts=8
 
 char const *cvs_name = "$Name:  $";
-char const *cvs_id_cli = "$Id: cli.c,v 1.34 2004/11/29 02:17:17 bodea Exp $";
+char const *cvs_id_cli = "$Id: cli.c,v 1.43.2.5 2005/01/13 08:26:51 bodea Exp $";
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <unistd.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <syslog.h>
@@ -19,9 +20,10 @@ char const *cvs_id_cli = "$Id: cli.c,v 1.34 2004/11/29 02:17:17 bodea Exp $";
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <signal.h>
-#include <unistd.h>
 #include <dlfcn.h>
+#include <netdb.h>
 #include <libcli.h>
+
 #include "l2tpns.h"
 #include "util.h"
 #include "cluster.h"
@@ -29,7 +31,6 @@ char const *cvs_id_cli = "$Id: cli.c,v 1.34 2004/11/29 02:17:17 bodea Exp $";
 #include "ll.h"
 #ifdef BGP
 #include "bgp.h"
-#include <netdb.h>
 #endif
 
 extern tunnelt *tunnel;
@@ -288,8 +289,9 @@ void cli_do(int sockfd)
        if (fork_and_close()) return;
        if (getpeername(sockfd, (struct sockaddr *)&addr, &l) == 0)
        {
-               LOG(3, 0, 0, "Accepted connection to CLI from %s\n", fmtaddr(addr.sin_addr.s_addr, 0));
                require_auth = addr.sin_addr.s_addr != inet_addr("127.0.0.1");
+               LOG(require_auth ? 3 : 4, 0, 0, "Accepted connection to CLI from %s\n",
+                       fmtaddr(addr.sin_addr.s_addr, 0));
        }
        else
                LOG(0, 0, 0, "getpeername() failed on cli socket.  Requiring authentication: %s\n", strerror(errno));
@@ -320,7 +322,9 @@ void cli_do(int sockfd)
        cli_loop(cli, sockfd);
 
        close(sockfd);
-       LOG(3, 0, 0, "Closed CLI connection from %s\n", fmtaddr(addr.sin_addr.s_addr, 0));
+       LOG(require_auth ? 3 : 4, 0, 0, "Closed CLI connection from %s\n",
+               fmtaddr(addr.sin_addr.s_addr, 0));
+
        exit(0);
 }
 
@@ -405,12 +409,12 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
                        cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
                        cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
                        cli_print(cli, "\tNext Send:\t%u", session[s].ns);
-                       cli_print(cli, "\tBytes In/Out:\t%lu/%lu", (unsigned long)session[s].total_cout, (unsigned long)session[s].total_cin);
-                       cli_print(cli, "\tPkts In/Out:\t%lu/%lu", (unsigned long)session[s].pout, (unsigned long)session[s].pin);
+                       cli_print(cli, "\tBytes In/Out:\t%u/%u", session[s].total_cout, session[s].total_cin);
+                       cli_print(cli, "\tPkts In/Out:\t%u/%u", session[s].pout, session[s].pin);
                        cli_print(cli, "\tMRU:\t\t%d", session[s].mru);
                        cli_print(cli, "\tRadius Session:\t%u", session[s].radius);
-                       cli_print(cli, "\tRx Speed:\t%lu", session[s].rx_connect_speed);
-                       cli_print(cli, "\tTx Speed:\t%lu", session[s].tx_connect_speed);
+                       cli_print(cli, "\tRx Speed:\t%u", session[s].rx_connect_speed);
+                       cli_print(cli, "\tTx Speed:\t%u", session[s].tx_connect_speed);
                        if (session[s].filter_in && session[s].filter_in <= MAXFILTER)
                                cli_print(cli, "\tFilter in:\t%u (%s)", session[s].filter_in, ip_filters[session[s].filter_in - 1].name);
                        if (session[s].filter_out && session[s].filter_out <= MAXFILTER)
@@ -644,24 +648,24 @@ static int cmd_show_counters(struct cli_def *cli, char *command, char **argv, in
        if (CLI_HELP_REQUESTED)
                return CLI_HELP_NO_ARGS;
 
-       cli_print(cli, "%-10s %-8s %-10s %-8s", "Ethernet", "Bytes", "Packets", "Errors");
-       cli_print(cli, "%-10s %8lu %8lu %8lu", "RX",
+       cli_print(cli, "%-10s %10s %10s %10s %10s", "Ethernet", "Bytes", "Packets", "Errors", "Dropped");
+       cli_print(cli, "%-10s %10u %10u %10u %10u", "RX",
                        GET_STAT(tun_rx_bytes),
                        GET_STAT(tun_rx_packets),
-                       GET_STAT(tun_rx_errors));
-       cli_print(cli, "%-10s %8lu %8lu %8lu", "TX",
+                       GET_STAT(tun_rx_errors),
+                       GET_STAT(tun_rx_dropped));
+       cli_print(cli, "%-10s %10u %10u %10u", "TX",
                        GET_STAT(tun_tx_bytes),
                        GET_STAT(tun_tx_packets),
                        GET_STAT(tun_tx_errors));
        cli_print(cli, "");
 
-       cli_print(cli, "%-10s %-8s %-10s %-8s %-8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
-       cli_print(cli, "%-10s %8lu %8lu %8lu %8lu", "RX",
+       cli_print(cli, "%-10s %10s %10s %10s %10s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
+       cli_print(cli, "%-10s %10u %10u %10u", "RX",
                        GET_STAT(tunnel_rx_bytes),
                        GET_STAT(tunnel_rx_packets),
-                       GET_STAT(tunnel_rx_errors),
-                       0L);
-       cli_print(cli, "%-10s %8lu %8lu %8lu %8lu", "TX",
+                       GET_STAT(tunnel_rx_errors));
+       cli_print(cli, "%-10s %10u %10u %10u %10u", "TX",
                        GET_STAT(tunnel_tx_bytes),
                        GET_STAT(tunnel_tx_packets),
                        GET_STAT(tunnel_tx_errors),
@@ -670,53 +674,67 @@ static int cmd_show_counters(struct cli_def *cli, char *command, char **argv, in
 
        cli_print(cli, "%-30s%-10s", "Counter", "Value");
        cli_print(cli, "-----------------------------------------");
-       cli_print(cli, "%-30s%lu", "radius_retries",            GET_STAT(radius_retries));
-       cli_print(cli, "%-30s%lu", "arp_sent",                  GET_STAT(arp_sent));
-       cli_print(cli, "%-30s%lu", "packets_snooped",           GET_STAT(packets_snooped));
-       cli_print(cli, "%-30s%lu", "tunnel_created",            GET_STAT(tunnel_created));
-       cli_print(cli, "%-30s%lu", "session_created",           GET_STAT(session_created));
-       cli_print(cli, "%-30s%lu", "tunnel_timeout",            GET_STAT(tunnel_timeout));
-       cli_print(cli, "%-30s%lu", "session_timeout",           GET_STAT(session_timeout));
-       cli_print(cli, "%-30s%lu", "radius_timeout",            GET_STAT(radius_timeout));
-       cli_print(cli, "%-30s%lu", "radius_overflow",           GET_STAT(radius_overflow));
-       cli_print(cli, "%-30s%lu", "tunnel_overflow",           GET_STAT(tunnel_overflow));
-       cli_print(cli, "%-30s%lu", "session_overflow",          GET_STAT(session_overflow));
-       cli_print(cli, "%-30s%lu", "ip_allocated",              GET_STAT(ip_allocated));
-       cli_print(cli, "%-30s%lu", "ip_freed",                  GET_STAT(ip_freed));
-       cli_print(cli, "%-30s%lu", "cluster_forwarded",         GET_STAT(c_forwarded));
-       cli_print(cli, "%-30s%lu", "recv_forward",              GET_STAT(recv_forward));
+       cli_print(cli, "%-30s%u", "radius_retries",             GET_STAT(radius_retries));
+       cli_print(cli, "%-30s%u", "arp_sent",                   GET_STAT(arp_sent));
+       cli_print(cli, "%-30s%u", "packets_snooped",            GET_STAT(packets_snooped));
+       cli_print(cli, "%-30s%u", "tunnel_created",             GET_STAT(tunnel_created));
+       cli_print(cli, "%-30s%u", "session_created",            GET_STAT(session_created));
+       cli_print(cli, "%-30s%u", "tunnel_timeout",             GET_STAT(tunnel_timeout));
+       cli_print(cli, "%-30s%u", "session_timeout",            GET_STAT(session_timeout));
+       cli_print(cli, "%-30s%u", "radius_timeout",             GET_STAT(radius_timeout));
+       cli_print(cli, "%-30s%u", "radius_overflow",            GET_STAT(radius_overflow));
+       cli_print(cli, "%-30s%u", "tunnel_overflow",            GET_STAT(tunnel_overflow));
+       cli_print(cli, "%-30s%u", "session_overflow",           GET_STAT(session_overflow));
+       cli_print(cli, "%-30s%u", "ip_allocated",               GET_STAT(ip_allocated));
+       cli_print(cli, "%-30s%u", "ip_freed",                   GET_STAT(ip_freed));
+       cli_print(cli, "%-30s%u", "cluster_forwarded",          GET_STAT(c_forwarded));
+       cli_print(cli, "%-30s%u", "recv_forward",               GET_STAT(recv_forward));
+       cli_print(cli, "%-30s%u", "select_called",              GET_STAT(select_called));
+       cli_print(cli, "%-30s%u", "multi_read_used",            GET_STAT(multi_read_used));
+       cli_print(cli, "%-30s%u", "multi_read_exceeded",        GET_STAT(multi_read_exceeded));
 
 
 #ifdef STATISTICS
        cli_print(cli, "\n%-30s%-10s", "Counter", "Value");
        cli_print(cli, "-----------------------------------------");
-       cli_print(cli, "%-30s%lu", "call_processtun",           GET_STAT(call_processtun));
-       cli_print(cli, "%-30s%lu", "call_processipout",         GET_STAT(call_processipout));
-       cli_print(cli, "%-30s%lu", "call_processudp",           GET_STAT(call_processudp));
-       cli_print(cli, "%-30s%lu", "call_processpap",           GET_STAT(call_processpap));
-       cli_print(cli, "%-30s%lu", "call_processchap",          GET_STAT(call_processchap));
-       cli_print(cli, "%-30s%lu", "call_processlcp",           GET_STAT(call_processlcp));
-       cli_print(cli, "%-30s%lu", "call_processipcp",          GET_STAT(call_processipcp));
-       cli_print(cli, "%-30s%lu", "call_processipin",          GET_STAT(call_processipin));
-       cli_print(cli, "%-30s%lu", "call_processccp",           GET_STAT(call_processccp));
-       cli_print(cli, "%-30s%lu", "call_processrad",           GET_STAT(call_processrad));
-       cli_print(cli, "%-30s%lu", "call_sendarp",              GET_STAT(call_sendarp));
-       cli_print(cli, "%-30s%lu", "call_sendipcp",             GET_STAT(call_sendipcp));
-       cli_print(cli, "%-30s%lu", "call_sendchap",             GET_STAT(call_sendchap));
-       cli_print(cli, "%-30s%lu", "call_sessionbyip",          GET_STAT(call_sessionbyip));
-       cli_print(cli, "%-30s%lu", "call_sessionbyuser",        GET_STAT(call_sessionbyuser));
-       cli_print(cli, "%-30s%lu", "call_tunnelsend",           GET_STAT(call_tunnelsend));
-       cli_print(cli, "%-30s%lu", "call_tunnelkill",           GET_STAT(call_tunnelkill));
-       cli_print(cli, "%-30s%lu", "call_tunnelshutdown",       GET_STAT(call_tunnelshutdown));
-       cli_print(cli, "%-30s%lu", "call_sessionkill",          GET_STAT(call_sessionkill));
-       cli_print(cli, "%-30s%lu", "call_sessionshutdown",      GET_STAT(call_sessionshutdown));
-       cli_print(cli, "%-30s%lu", "call_sessionsetup",         GET_STAT(call_sessionsetup));
-       cli_print(cli, "%-30s%lu", "call_assign_ip_address",    GET_STAT(call_assign_ip_address));
-       cli_print(cli, "%-30s%lu", "call_free_ip_address",      GET_STAT(call_free_ip_address));
-       cli_print(cli, "%-30s%lu", "call_dump_acct_info",       GET_STAT(call_dump_acct_info));
-       cli_print(cli, "%-30s%lu", "call_radiussend",           GET_STAT(call_radiussend));
-       cli_print(cli, "%-30s%lu", "call_radiusretry",          GET_STAT(call_radiusretry));
+       cli_print(cli, "%-30s%u", "call_processtun",            GET_STAT(call_processtun));
+       cli_print(cli, "%-30s%u", "call_processipout",          GET_STAT(call_processipout));
+       cli_print(cli, "%-30s%u", "call_processudp",            GET_STAT(call_processudp));
+       cli_print(cli, "%-30s%u", "call_processpap",            GET_STAT(call_processpap));
+       cli_print(cli, "%-30s%u", "call_processchap",           GET_STAT(call_processchap));
+       cli_print(cli, "%-30s%u", "call_processlcp",            GET_STAT(call_processlcp));
+       cli_print(cli, "%-30s%u", "call_processipcp",           GET_STAT(call_processipcp));
+       cli_print(cli, "%-30s%u", "call_processipin",           GET_STAT(call_processipin));
+       cli_print(cli, "%-30s%u", "call_processccp",            GET_STAT(call_processccp));
+       cli_print(cli, "%-30s%u", "call_processrad",            GET_STAT(call_processrad));
+       cli_print(cli, "%-30s%u", "call_sendarp",               GET_STAT(call_sendarp));
+       cli_print(cli, "%-30s%u", "call_sendipcp",              GET_STAT(call_sendipcp));
+       cli_print(cli, "%-30s%u", "call_sendchap",              GET_STAT(call_sendchap));
+       cli_print(cli, "%-30s%u", "call_sessionbyip",           GET_STAT(call_sessionbyip));
+       cli_print(cli, "%-30s%u", "call_sessionbyuser",         GET_STAT(call_sessionbyuser));
+       cli_print(cli, "%-30s%u", "call_tunnelsend",            GET_STAT(call_tunnelsend));
+       cli_print(cli, "%-30s%u", "call_tunnelkill",            GET_STAT(call_tunnelkill));
+       cli_print(cli, "%-30s%u", "call_tunnelshutdown",        GET_STAT(call_tunnelshutdown));
+       cli_print(cli, "%-30s%u", "call_sessionkill",           GET_STAT(call_sessionkill));
+       cli_print(cli, "%-30s%u", "call_sessionshutdown",       GET_STAT(call_sessionshutdown));
+       cli_print(cli, "%-30s%u", "call_sessionsetup",          GET_STAT(call_sessionsetup));
+       cli_print(cli, "%-30s%u", "call_assign_ip_address",     GET_STAT(call_assign_ip_address));
+       cli_print(cli, "%-30s%u", "call_free_ip_address",       GET_STAT(call_free_ip_address));
+       cli_print(cli, "%-30s%u", "call_dump_acct_info",        GET_STAT(call_dump_acct_info));
+       cli_print(cli, "%-30s%u", "call_radiussend",            GET_STAT(call_radiussend));
+       cli_print(cli, "%-30s%u", "call_radiusretry",           GET_STAT(call_radiusretry));
 #endif
+
+       {
+               time_t l = GET_STAT(last_reset);
+               char *t = ctime(&l);
+               char *p = strchr(t, '\n');
+               if (p) *p = 0;
+
+               cli_print(cli, "");
+               cli_print(cli, "Last counter reset %s", t);
+       }
+
        return CLI_OK;
 }
 
@@ -754,7 +772,7 @@ static int cmd_show_version(struct cli_def *cli, char *command, char **argv, int
                        p = "HEAD";
 
                e = strpbrk(p, " \t$");
-               cli_print(cli, "Tag: %.*s", e ? e - p + 1 : strlen(p), p);
+               cli_print(cli, "Tag: %.*s", (int) (e ? e - p + 1 : strlen(p)), p);
        }
        
        if (file)
@@ -837,7 +855,7 @@ static int cmd_show_pool(struct cli_def *cli, char *command, char **argv, int ar
                        if (ip_address_pool[i].last)
                                cli_print(cli, "%-15s\tN %8s [%s] %ds",
                                        fmtaddr(htonl(ip_address_pool[i].address), 0), "",
-                                       ip_address_pool[i].user, time_now - ip_address_pool[i].last);
+                                       ip_address_pool[i].user, (int) time_now - ip_address_pool[i].last);
 
                        else if (show_all)
                                cli_print(cli, "%-15s\tN", fmtaddr(htonl(ip_address_pool[i].address), 0));
@@ -1003,7 +1021,7 @@ static int cmd_show_radius(struct cli_def *cli, char *command, char **argv, int
                        NULL);
        }
 
-       cli_print(cli, "%6s%6s%5s%6s%9s%9s%4s", "ID", "Radius", "Sock", "State", "Session", "Retry", "Try");
+       cli_print(cli, "%6s%7s%5s%6s%9s%9s%4s", "ID", "Radius", "Sock", "State", "Session", "Retry", "Try");
 
        time(&time_now);
 
@@ -1019,7 +1037,7 @@ static int cmd_show_radius(struct cli_def *cli, char *command, char **argv, int
 
                if (!show_all && radius[i].state == RADIUSNULL) continue;
 
-               cli_print(cli, "%6d%6d%5d%6s%9d%9u%4d",
+               cli_print(cli, "%6d%7d%5d%6s%9d%9u%4d",
                                i,
                                i >> RADIUS_SHIFT,
                                i & RADIUS_MASK,
@@ -1109,8 +1127,10 @@ static int cmd_clear_counters(struct cli_def *cli, char *command, char **argv, i
        if (CLI_HELP_REQUESTED)
                return CLI_HELP_NO_ARGS;
 
-       cli_print(cli, "Counters cleared");
+       memset(_statistics, 0, sizeof(struct Tstats));
        SET_STAT(last_reset, time(NULL));
+
+       cli_print(cli, "Counters cleared");
        return CLI_OK;
 }
 
@@ -1252,8 +1272,8 @@ static int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int
 
 static int cmd_snoop(struct cli_def *cli, char *command, char **argv, int argc)
 {
-       ipt ip;
-       u16 port;
+       in_addr_t ip;
+       uint16_t port;
        sessionidt s;
 
        if (CLI_HELP_REQUESTED)
@@ -1861,42 +1881,44 @@ static int cmd_set(struct cli_def *cli, char *command, char **argv, int argc)
 
 int regular_stuff(struct cli_def *cli)
 {
-       int i = debug_rb_tail;
-       int reprompt = 0;
+       int out = 0;
+       int i;
 
 #ifdef RINGBUFFER
-       while (i != ringbuffer->tail)
+       for (i = debug_rb_tail; i != ringbuffer->tail; i = (i + 1) % RINGBUFFER_SIZE)
        {
-               int show_message = 0;
+               char *m = ringbuffer->buffer[i].message;
+               char *p;
+               int show = 0;
+
+               if (!*m) continue;
 
-               if (*ringbuffer->buffer[i].message)
+               switch (ringbuffer->buffer[i].level)
                {
-                       // Always show messages if we are doing general debug
-                       if (ringbuffer->buffer[i].level == 0 && debug_flags.critical) show_message = 1;
-                       if (ringbuffer->buffer[i].level == 1 && debug_flags.error)    show_message = 1;
-                       if (ringbuffer->buffer[i].level == 2 && debug_flags.warning)  show_message = 1;
-                       if (ringbuffer->buffer[i].level == 3 && debug_flags.info)     show_message = 1;
-                       if (ringbuffer->buffer[i].level == 4 && debug_flags.calls)    show_message = 1;
-                       if (ringbuffer->buffer[i].level == 5 && debug_flags.data)     show_message = 1;
+               case 0: show = debug_flags.critical;    break;
+               case 1: show = debug_flags.error;       break;
+               case 2: show = debug_flags.warning;     break;
+               case 3: show = debug_flags.info;        break;
+               case 4: show = debug_flags.calls;       break;
+               case 5: show = debug_flags.data;        break;
                }
 
-               if (show_message)
-               {
-                       cli_print(cli, "\r%s-%u-%u %s",
-                                       debug_levels[(int)ringbuffer->buffer[i].level],
-                                       ringbuffer->buffer[i].tunnel,
-                                       ringbuffer->buffer[i].session,
-                                       ringbuffer->buffer[i].message);
+               if (!show) continue;
 
-                       reprompt = 1;
-               }
+               if (!(p = strchr(m, '\n')))
+                       p = m + strlen(p);
+
+               cli_print(cli, "\r%s-%u-%u %.*s",
+                       debug_levels[(int)ringbuffer->buffer[i].level],
+                       ringbuffer->buffer[i].tunnel,
+                       ringbuffer->buffer[i].session,
+                       (int) (p - m), m);
 
-               if (++i == ringbuffer->tail) break;
-               if (i == RINGBUFFER_SIZE) i = 0;
+               out++;
        }
 
        debug_rb_tail = ringbuffer->tail;
-       if (reprompt)
+       if (out)
                cli_reprompt(cli);
 #endif
        return CLI_OK;
@@ -2159,7 +2181,7 @@ static int cmd_show_bgp(struct cli_def *cli, char *command, char **argv, int arg
                            "----------- ------- -------- ----- ---- ---------");
                }
 
-               cli_print(cli, "%-18.18s %5d %15s %-11s %7d %7ds %5s %4s %4d %4d",
+               cli_print(cli, "%-18.18s %5d %15s %-11s %7d %7lds %5s %4s %4d %4d",
                        bgp_peers[i].name,
                        bgp_peers[i].as,
                        addr,
@@ -2391,7 +2413,7 @@ static int cmd_no_ip_access_list(struct cli_def *cli, char *command, char **argv
        return access_list(cli, argv, argc, 0);
 }
 
-static int show_ip_wild(char *buf, ipt ip, ipt wild)
+static int show_ip_wild(char *buf, in_addr_t ip, in_addr_t wild)
 {
        if (ip == INADDR_ANY && wild == INADDR_BROADCAST)
                return sprintf(buf, " any");
@@ -2522,8 +2544,8 @@ ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char *
 
        for (a = 1, i = 0; i < 2; i++)
        {
-               ipt *ip;
-               ipt *wild;
+               in_addr_t *ip;
+               in_addr_t *wild;
                ip_filter_portt *port;
 
                if (i == 0)
@@ -2665,7 +2687,7 @@ ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char *
 
                        while (a < argc && (argv[a][0] == '+' || argv[a][0] == '-'))
                        {
-                               u8 *f;
+                               uint8_t *f;
 
                                f = (argv[a][0] == '+') ? &rule.tcp_sflags : &rule.tcp_cflags;
 
@@ -2688,6 +2710,12 @@ ip_filter_rulet *access_list_rule_ext(struct cli_def *cli, char *command, char *
 
        if (a < argc && MATCH("fragments", argv[a]))
        {
+               if (rule.src_ports.op || rule.dst_ports.op || rule.tcp_flag_op)
+               {
+                       cli_print(cli, "Can't specify \"fragments\" on rules with layer 4 matches");
+                       return NULL;
+               }
+
                rule.frag = 1;
                a++;
        }
@@ -3008,6 +3036,9 @@ static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv,
                        return CLI_OK;
                }
 
+               if (i)
+                       cli_print(cli, "");
+
                cli_print(cli, "%s IP access list %s",
                        ip_filters[f].extended ? "Extended" : "Standard",
                        ip_filters[f].name);