From acec8d320384c636e6d3b89de8e628fded1bf6c9 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 31 Oct 2010 17:07:31 +0200 Subject: [PATCH] Add ctrl_iface command 'GET version' This can be used to fetch the wpa_supplicant/hostapd version string. --- hostapd/ctrl_iface.c | 24 +++++++++++++++++++++++- hostapd/hostapd_cli.c | 26 ++++++++++++++++++++++++++ wpa_supplicant/ctrl_iface.c | 22 ++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 23 +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index d0ed897c8..84a1b7e76 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1,6 +1,6 @@ /* * hostapd / UNIX domain socket -based control interface - * Copyright (c) 2004-2009, Jouni Malinen + * Copyright (c) 2004-2010, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,6 +22,7 @@ #include "utils/common.h" #include "utils/eloop.h" +#include "common/version.h" #include "common/ieee802_11_defs.h" #include "drivers/driver.h" #include "radius/radius_client.h" @@ -729,6 +730,24 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) } +static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd, + char *buf, size_t buflen) +{ + int res; + + wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); + + if (os_strcmp(cmd, "version") == 0) { + res = os_snprintf(buf, buflen, "%s", VERSION_STR); + if (res < 0 || (unsigned int) res >= buflen) + return -1; + return res; + } + + return -1; +} + + static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, void *sock_ctx) { @@ -858,6 +877,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, } else if (os_strncmp(buf, "SET ", 4) == 0) { if (hostapd_ctrl_iface_set(hapd, buf + 4)) reply_len = -1; + } else if (os_strncmp(buf, "GET ", 4) == 0) { + reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply, + reply_size); } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index 3fdaa1596..7cc84bb98 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -670,6 +670,26 @@ static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 1) { + printf("Invalid GET command: needs one argument (variable " + "name)\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long GET command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + struct hostapd_cli_cmd { const char *cmd; int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); @@ -703,6 +723,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { { "license", hostapd_cli_cmd_license }, { "quit", hostapd_cli_cmd_quit }, { "set", hostapd_cli_cmd_set }, + { "get", hostapd_cli_cmd_get }, { NULL, NULL } }; @@ -717,6 +738,11 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) while (cmd->cmd) { if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) { match = cmd; + if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { + /* we have an exact match */ + count = 1; + break; + } count++; } cmd++; diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index bcf544b39..197d9a1a4 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -16,6 +16,7 @@ #include "utils/common.h" #include "utils/eloop.h" +#include "common/version.h" #include "common/ieee802_11_defs.h" #include "common/wpa_ctrl.h" #include "eap_peer/eap.h" @@ -118,6 +119,24 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, } +static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s, + char *cmd, char *buf, size_t buflen) +{ + int res; + + wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); + + if (os_strcmp(cmd, "version") == 0) { + res = os_snprintf(buf, buflen, "%s", VERSION_STR); + if (res < 0 || (unsigned int) res >= buflen) + return -1; + return res; + } + + return -1; +} + + #ifdef IEEE8021X_EAPOL static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, char *addr) @@ -2731,6 +2750,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "SET ", 4) == 0) { if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) reply_len = -1; + } else if (os_strncmp(buf, "GET ", 4) == 0) { + reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, + reply, reply_size); } else if (os_strcmp(buf, "LOGON") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, FALSE); } else if (os_strcmp(buf, "LOGOFF") == 0) { diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 17afc5faa..30d1f7b7e 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -462,6 +462,26 @@ static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 1) { + printf("Invalid GET command: need one argument (variable " + "name)\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long GET command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) { return wpa_ctrl_command(ctrl, "LOGOFF"); @@ -2209,6 +2229,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { cli_cmd_flag_none, "= set variables (shows list of variables when run without " "arguments)" }, + { "get", wpa_cli_cmd_get, + cli_cmd_flag_none, + " = get information" }, { "logon", wpa_cli_cmd_logon, cli_cmd_flag_none, "= IEEE 802.1X EAPOL state machine logon" },