summaryrefslogtreecommitdiff
path: root/src/utils/common.c
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2013-06-25 02:47:41 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2013-06-25 02:47:41 +0000
commit5e2639d568f6bb660501a77cc83413c3412562e3 (patch)
treedb97ebf07cc76b41926fb6696433b541307fbc19 /src/utils/common.c
parent19f9885f6aafcd7c3eee4df8a014287d12279851 (diff)
Diffstat (limited to 'src/utils/common.c')
-rw-r--r--src/utils/common.c287
1 files changed, 268 insertions, 19 deletions
diff --git a/src/utils/common.c b/src/utils/common.c
index 1b8ea80e7d05c..e63698491444b 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -2,14 +2,8 @@
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
- * 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
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
@@ -29,7 +23,7 @@ static int hex2num(char c)
}
-static int hex2byte(const char *hex)
+int hex2byte(const char *hex)
{
int a, b;
a = hex2num(*hex++);
@@ -69,6 +63,30 @@ int hwaddr_aton(const char *txt, u8 *addr)
return 0;
}
+/**
+ * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
+ * @txt: MAC address as a string (e.g., "001122334455")
+ * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
+ * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
+ */
+int hwaddr_compact_aton(const char *txt, u8 *addr)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ int a, b;
+
+ a = hex2num(*txt++);
+ if (a < 0)
+ return -1;
+ b = hex2num(*txt++);
+ if (b < 0)
+ return -1;
+ *addr++ = (a << 4) | b;
+ }
+
+ return 0;
+}
/**
* hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
@@ -326,6 +344,135 @@ TCHAR * wpa_strdup_tchar(const char *str)
#endif /* CONFIG_NATIVE_WINDOWS */
+void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
+{
+ char *end = txt + maxlen;
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ if (txt + 4 > end)
+ break;
+
+ switch (data[i]) {
+ case '\"':
+ *txt++ = '\\';
+ *txt++ = '\"';
+ break;
+ case '\\':
+ *txt++ = '\\';
+ *txt++ = '\\';
+ break;
+ case '\e':
+ *txt++ = '\\';
+ *txt++ = 'e';
+ break;
+ case '\n':
+ *txt++ = '\\';
+ *txt++ = 'n';
+ break;
+ case '\r':
+ *txt++ = '\\';
+ *txt++ = 'r';
+ break;
+ case '\t':
+ *txt++ = '\\';
+ *txt++ = 't';
+ break;
+ default:
+ if (data[i] >= 32 && data[i] <= 127) {
+ *txt++ = data[i];
+ } else {
+ txt += os_snprintf(txt, end - txt, "\\x%02x",
+ data[i]);
+ }
+ break;
+ }
+ }
+
+ *txt = '\0';
+}
+
+
+size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
+{
+ const char *pos = str;
+ size_t len = 0;
+ int val;
+
+ while (*pos) {
+ if (len == maxlen)
+ break;
+ switch (*pos) {
+ case '\\':
+ pos++;
+ switch (*pos) {
+ case '\\':
+ buf[len++] = '\\';
+ pos++;
+ break;
+ case '"':
+ buf[len++] = '"';
+ pos++;
+ break;
+ case 'n':
+ buf[len++] = '\n';
+ pos++;
+ break;
+ case 'r':
+ buf[len++] = '\r';
+ pos++;
+ break;
+ case 't':
+ buf[len++] = '\t';
+ pos++;
+ break;
+ case 'e':
+ buf[len++] = '\e';
+ pos++;
+ break;
+ case 'x':
+ pos++;
+ val = hex2byte(pos);
+ if (val < 0) {
+ val = hex2num(*pos);
+ if (val < 0)
+ break;
+ buf[len++] = val;
+ pos++;
+ } else {
+ buf[len++] = val;
+ pos += 2;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ val = *pos++ - '0';
+ if (*pos >= '0' && *pos <= '7')
+ val = val * 8 + (*pos++ - '0');
+ if (*pos >= '0' && *pos <= '7')
+ val = val * 8 + (*pos++ - '0');
+ buf[len++] = val;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ buf[len++] = *pos++;
+ break;
+ }
+ }
+
+ return len;
+}
+
+
/**
* wpa_ssid_txt - Convert SSID to a printable string
* @ssid: SSID (32-octet string)
@@ -342,17 +489,14 @@ TCHAR * wpa_strdup_tchar(const char *str)
*/
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
{
- static char ssid_txt[33];
- char *pos;
-
- if (ssid_len > 32)
- ssid_len = 32;
- os_memcpy(ssid_txt, ssid, ssid_len);
- ssid_txt[ssid_len] = '\0';
- for (pos = ssid_txt; *pos != '\0'; pos++) {
- if ((u8) *pos < 32 || (u8) *pos >= 127)
- *pos = '_';
+ static char ssid_txt[32 * 4 + 1];
+
+ if (ssid == NULL) {
+ ssid_txt[0] = '\0';
+ return ssid_txt;
}
+
+ printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
return ssid_txt;
}
@@ -361,3 +505,108 @@ void * __hide_aliasing_typecast(void *foo)
{
return foo;
}
+
+
+char * wpa_config_parse_string(const char *value, size_t *len)
+{
+ if (*value == '"') {
+ const char *pos;
+ char *str;
+ value++;
+ pos = os_strrchr(value, '"');
+ if (pos == NULL || pos[1] != '\0')
+ return NULL;
+ *len = pos - value;
+ str = os_malloc(*len + 1);
+ if (str == NULL)
+ return NULL;
+ os_memcpy(str, value, *len);
+ str[*len] = '\0';
+ return str;
+ } else if (*value == 'P' && value[1] == '"') {
+ const char *pos;
+ char *tstr, *str;
+ size_t tlen;
+ value += 2;
+ pos = os_strrchr(value, '"');
+ if (pos == NULL || pos[1] != '\0')
+ return NULL;
+ tlen = pos - value;
+ tstr = os_malloc(tlen + 1);
+ if (tstr == NULL)
+ return NULL;
+ os_memcpy(tstr, value, tlen);
+ tstr[tlen] = '\0';
+
+ str = os_malloc(tlen + 1);
+ if (str == NULL) {
+ os_free(tstr);
+ return NULL;
+ }
+
+ *len = printf_decode((u8 *) str, tlen + 1, tstr);
+ os_free(tstr);
+
+ return str;
+ } else {
+ u8 *str;
+ size_t tlen, hlen = os_strlen(value);
+ if (hlen & 1)
+ return NULL;
+ tlen = hlen / 2;
+ str = os_malloc(tlen + 1);
+ if (str == NULL)
+ return NULL;
+ if (hexstr2bin(value, str, tlen)) {
+ os_free(str);
+ return NULL;
+ }
+ str[tlen] = '\0';
+ *len = tlen;
+ return (char *) str;
+ }
+}
+
+
+int is_hex(const u8 *data, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ if (data[i] < 32 || data[i] >= 127)
+ return 1;
+ }
+ return 0;
+}
+
+
+size_t merge_byte_arrays(u8 *res, size_t res_len,
+ const u8 *src1, size_t src1_len,
+ const u8 *src2, size_t src2_len)
+{
+ size_t len = 0;
+
+ os_memset(res, 0, res_len);
+
+ if (src1) {
+ if (src1_len >= res_len) {
+ os_memcpy(res, src1, res_len);
+ return res_len;
+ }
+
+ os_memcpy(res, src1, src1_len);
+ len += src1_len;
+ }
+
+ if (src2) {
+ if (len + src2_len >= res_len) {
+ os_memcpy(res + len, src2, res_len - len);
+ return res_len;
+ }
+
+ os_memcpy(res + len, src2, src2_len);
+ len += src2_len;
+ }
+
+ return len;
+}