summaryrefslogtreecommitdiff
path: root/accel-pppd/cli/std_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/cli/std_cmd.c')
-rw-r--r--accel-pppd/cli/std_cmd.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c
new file mode 100644
index 0000000..a49bbce
--- /dev/null
+++ b/accel-pppd/cli/std_cmd.c
@@ -0,0 +1,324 @@
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <arpa/inet.h>
+
+#include "triton.h"
+#include "events.h"
+#include "ppp.h"
+#include "cli.h"
+#include "utils.h"
+#include "log.h"
+#include "memdebug.h"
+
+static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
+{
+ time_t dt;
+ int day,hour;
+ char statm_fname[128];
+ FILE *f;
+ unsigned long vmsize = 0, vmrss = 0;
+ unsigned long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
+
+ sprintf(statm_fname, "/proc/%i/statm", getpid());
+ f = fopen(statm_fname, "r");
+ if (f) {
+ fscanf(f, "%lu %lu", &vmsize, &vmrss);
+ fclose(f);
+ }
+
+ time(&dt);
+ dt -= triton_stat.start_time;
+ day = dt / (60 * 60 * 24);
+ dt %= 60 * 60 * 24;
+ hour = dt / (60 * 60);
+ dt %= 60 * 60;
+
+ cli_sendv(client, "uptime: %i.%02i:%02i:%02i\r\n", day, hour, dt / 60, dt % 60);
+ cli_sendv(client, "cpu: %i%%\r\n", triton_stat.cpu);
+ cli_sendv(client, "mem(rss/virt): %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb);
+ cli_send(client, "core:\r\n");
+ cli_sendv(client, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated);
+ cli_sendv(client, " mempool_available: %u\r\n", triton_stat.mempool_available);
+ cli_sendv(client, " thread_count: %u\r\n", triton_stat.thread_count);
+ cli_sendv(client, " thread_active: %u\r\n", triton_stat.thread_active);
+ cli_sendv(client, " context_count: %u\r\n", triton_stat.context_count);
+ cli_sendv(client, " context_sleeping: %u\r\n", triton_stat.context_sleeping);
+ cli_sendv(client, " context_pending: %u\r\n", triton_stat.context_pending);
+ cli_sendv(client, " md_handler_count: %u\r\n", triton_stat.md_handler_count);
+ cli_sendv(client, " md_handler_pending: %u\r\n", triton_stat.md_handler_pending);
+ cli_sendv(client, " timer_count: %u\r\n", triton_stat.timer_count);
+ cli_sendv(client, " timer_pending: %u\r\n", triton_stat.timer_pending);
+
+//===========
+ cli_send(client, "ppp:\r\n");
+ cli_sendv(client, " staring: %u\r\n", ppp_stat.starting);
+ cli_sendv(client, " active: %u\r\n", ppp_stat.active);
+ cli_sendv(client, " finishing: %u\r\n", ppp_stat.finishing);
+
+ return CLI_CMD_OK;
+}
+
+static void show_stat_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "show stat - shows various statistics information\r\n");
+}
+//=============================
+
+static int exit_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
+{
+ return CLI_CMD_EXIT;
+}
+
+static void exit_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "exit - exit cli\r\n");
+}
+
+//=============================
+
+static void ppp_terminate_soft(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_NAS_REQUEST, 0);
+}
+
+static void ppp_terminate_hard(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_NAS_REQUEST, 1);
+}
+
+static int terminate_exec1(char * const *f, int f_cnt, void *cli)
+{
+ struct ppp_t *ppp;
+ int hard = 0;
+ pcre *re;
+ const char *pcre_err;
+ int pcre_offset;
+
+ if (f_cnt == 5) {
+ if (!strcmp(f[4], "hard"))
+ hard = 1;
+ else if (strcmp(f[4], "soft"))
+ return CLI_CMD_SYNTAX;
+ } else if (f_cnt != 4)
+ return CLI_CMD_SYNTAX;
+
+ re = pcre_compile2(f[3], 0, NULL, &pcre_err, &pcre_offset, NULL);
+ if (!re) {
+ cli_sendv(cli, "match: %s at %i\r\n", pcre_err, pcre_offset);
+ return CLI_CMD_OK;
+ }
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (pcre_exec(re, NULL, ppp->username, strlen(ppp->username), 0, 0, NULL, 0) < 0)
+ continue;
+ if (hard)
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
+ else
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ pcre_free(re);
+
+ return CLI_CMD_OK;
+}
+
+static int terminate_exec2(int key, char * const *f, int f_cnt, void *cli)
+{
+ struct ppp_t *ppp;
+ int hard = 0;
+ in_addr_t ipaddr = 0;
+
+ if (f_cnt == 4) {
+ if (!strcmp(f[3], "hard"))
+ hard = 1;
+ else if (strcmp(f[3], "soft"))
+ return CLI_CMD_SYNTAX;
+ } else if (f_cnt != 3)
+ return CLI_CMD_SYNTAX;
+
+ if (key == 1)
+ ipaddr = inet_addr(f[2]);
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ switch (key) {
+ case 0:
+ if (strcmp(ppp->username, f[2]))
+ continue;
+ break;
+ case 1:
+ if (ppp->peer_ipaddr != ipaddr)
+ continue;
+ break;
+ case 2:
+ if (strcmp(ppp->ctrl->calling_station_id, f[2]))
+ continue;
+ break;
+ case 3:
+ if (strcmp(ppp->sessionid, f[2]))
+ continue;
+ break;
+ case 4:
+ if (strcmp(ppp->ifname, f[2]))
+ continue;
+ break;
+ }
+ if (hard)
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
+ else
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
+ break;
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ return CLI_CMD_OK;
+}
+
+static int terminate_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
+{
+ struct ppp_t *ppp;
+ int hard = 0;
+
+ if (fields_cnt == 1)
+ return CLI_CMD_SYNTAX;
+
+ if (!strcmp(fields[1], "match") && fields_cnt > 3 && !strcmp(fields[2], "username"))
+ return terminate_exec1(fields, fields_cnt, client);
+ else if (!strcmp(fields[1], "username"))
+ return terminate_exec2(0, fields, fields_cnt, client);
+ else if (!strcmp(fields[1], "ip"))
+ return terminate_exec2(1, fields, fields_cnt, client);
+ else if (!strcmp(fields[1], "csid"))
+ return terminate_exec2(2, fields, fields_cnt, client);
+ else if (!strcmp(fields[1], "sid"))
+ return terminate_exec2(3, fields, fields_cnt, client);
+ else if (!strcmp(fields[1], "if"))
+ return terminate_exec2(4, fields, fields_cnt, client);
+ else if (strcmp(fields[1], "all"))
+ return CLI_CMD_SYNTAX;
+
+ if (fields_cnt == 3) {
+ if (!strcmp(fields[2], "hard"))
+ hard = 1;
+ else if (strcmp(fields[2], "soft"))
+ return CLI_CMD_SYNTAX;
+ } else if (fields_cnt != 2)
+ return CLI_CMD_SYNTAX;
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (hard)
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
+ else
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ return CLI_CMD_OK;
+}
+
+static void terminate_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "terminate if <interface> [soft|hard]- terminate session by interface name\r\n");
+ cli_send(client, "\t[match] username <username> [soft|hard]- terminate session by username\r\n");
+ cli_send(client, "\tip <addresss> [soft|hard]- terminate session by ip address\r\n");
+ cli_send(client, "\tcsid <id> [soft|hard]- terminate session by calling station id\r\n");
+ cli_send(client, "\tsid <id> [soft|hard]- terminate session by session id\r\n");
+ cli_send(client, "\tall [soft|hard]- terminate all sessions\r\n");
+}
+
+//=============================
+
+static void shutdown_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "shutdown [soft|hard|cancel]- shutdown daemon\r\n");
+ cli_send(client, "\t\tdefault action - send termination signals to all clients and wait everybody disconnects\r\n");
+ cli_send(client, "\t\tsoft - wait until all clients disconnects, don't accept new connections\r\n");
+ cli_send(client, "\t\thard - shutdown now, don't wait anything\r\n");
+ cli_send(client, "\t\tcancel - cancel 'shutdown soft' and return to normal operation\r\n");
+}
+
+static void ppp_terminate_soft2(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_NAS_REBOOT, 0);
+}
+
+static void ppp_terminate_hard2(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp, TERM_NAS_REBOOT, 1);
+}
+
+static int shutdown_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
+{
+ int hard = 0;
+ struct ppp_t *ppp;
+
+ if (f_cnt == 2) {
+ if (!strcmp(f[1], "soft")) {
+ ppp_shutdown_soft();
+ return CLI_CMD_OK;
+ } else if (!strcmp(f[1], "hard"))
+ hard = 1;
+ else if (!strcmp(f[1], "cancel")) {
+ ppp_shutdown = 0;
+ return CLI_CMD_OK;
+ } else
+ return CLI_CMD_SYNTAX;
+ }
+
+ ppp_shutdown_soft();
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(ppp, &ppp_list, entry) {
+ if (hard)
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard2, ppp);
+ else
+ triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft2, ppp);
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ return CLI_CMD_OK;
+}
+
+//==========================
+static int conf_reload_res;
+static struct triton_context_t *conf_reload_ctx;
+static void conf_reload_notify(int r)
+{
+ if (!r)
+ triton_event_fire(EV_CONFIG_RELOAD, NULL);
+ conf_reload_res = r;
+ triton_context_wakeup(conf_reload_ctx);
+}
+static int reload_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
+{
+ if (f_cnt == 1) {
+ conf_reload_ctx = triton_context_self();
+ triton_conf_reload(conf_reload_notify);
+ triton_context_schedule();
+ if (conf_reload_res)
+ cli_send(cli, "failed\r\n");
+ return CLI_CMD_OK;
+ } else
+ return CLI_CMD_SYNTAX;
+}
+
+static void reload_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "reload - reload config file\r\n");
+}
+
+static void __init init(void)
+{
+ cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat");
+ cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate");
+ cli_register_simple_cmd2(reload_exec, reload_help, 1, "reload");
+ cli_register_simple_cmd2(shutdown_exec, shutdown_help, 1, "shutdown");
+ cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit");
+}
+