12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064 |
- #include "includes.h"
- #include "common.h"
- static int hex2num(char c)
- {
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
- }
- int hex2byte(const char *hex)
- {
- int a, b;
- a = hex2num(*hex++);
- if (a < 0)
- return -1;
- b = hex2num(*hex++);
- if (b < 0)
- return -1;
- return (a << 4) | b;
- }
- static const char * hwaddr_parse(const char *txt, u8 *addr)
- {
- size_t i;
- for (i = 0; i < ETH_ALEN; i++) {
- int a;
- a = hex2byte(txt);
- if (a < 0)
- return NULL;
- txt += 2;
- addr[i] = a;
- if (i < ETH_ALEN - 1 && *txt++ != ':')
- return NULL;
- }
- return txt;
- }
- int hwaddr_aton(const char *txt, u8 *addr)
- {
- return hwaddr_parse(txt, addr) ? 0 : -1;
- }
- int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable)
- {
- const char *r;
-
- r = hwaddr_parse(txt, addr);
- if (!r)
- return -1;
-
- if (*r == '\0' || isspace(*r)) {
-
- os_memset(mask, 0xff, ETH_ALEN);
- } else if (maskable && *r == '/') {
-
- r = hwaddr_parse(r + 1, mask);
-
- if (!r)
- return -1;
- } else {
-
- return -1;
- }
- return 0;
- }
- 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;
- }
- int hwaddr_aton2(const char *txt, u8 *addr)
- {
- int i;
- const char *pos = txt;
- for (i = 0; i < 6; i++) {
- int a, b;
- while (*pos == ':' || *pos == '.' || *pos == '-')
- pos++;
- a = hex2num(*pos++);
- if (a < 0)
- return -1;
- b = hex2num(*pos++);
- if (b < 0)
- return -1;
- *addr++ = (a << 4) | b;
- }
- return pos - txt;
- }
- int hexstr2bin(const char *hex, u8 *buf, size_t len)
- {
- size_t i;
- int a;
- const char *ipos = hex;
- u8 *opos = buf;
- for (i = 0; i < len; i++) {
- a = hex2byte(ipos);
- if (a < 0)
- return -1;
- *opos++ = a;
- ipos += 2;
- }
- return 0;
- }
- int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask)
- {
- size_t i;
- int print_mask = 0;
- int res;
- for (i = 0; i < ETH_ALEN; i++) {
- if (mask[i] != 0xff) {
- print_mask = 1;
- break;
- }
- }
- if (print_mask)
- res = os_snprintf(buf, len, MACSTR "/" MACSTR,
- MAC2STR(addr), MAC2STR(mask));
- else
- res = os_snprintf(buf, len, MACSTR, MAC2STR(addr));
- if (os_snprintf_error(len, res))
- return -1;
- return res;
- }
- void inc_byte_array(u8 *counter, size_t len)
- {
- int pos = len - 1;
- while (pos >= 0) {
- counter[pos]++;
- if (counter[pos] != 0)
- break;
- pos--;
- }
- }
- void wpa_get_ntp_timestamp(u8 *buf)
- {
- struct os_time now;
- u32 sec, usec;
- be32 tmp;
-
- os_get_time(&now);
- sec = now.sec + 2208988800U;
-
- usec = now.usec;
- usec = 4295 * usec - (usec >> 5) - (usec >> 9);
- tmp = host_to_be32(sec);
- os_memcpy(buf, (u8 *) &tmp, 4);
- tmp = host_to_be32(usec);
- os_memcpy(buf + 4, (u8 *) &tmp, 4);
- }
- int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...)
- {
- va_list ap;
- int ret;
- if (!size)
- return 0;
- va_start(ap, fmt);
- ret = vsnprintf(buf, size, fmt, ap);
- va_end(ap);
- if (ret < 0)
- return 0;
- if ((size_t) ret >= size)
- return size - 1;
- return ret;
- }
- static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
- size_t len, int uppercase)
- {
- size_t i;
- char *pos = buf, *end = buf + buf_size;
- int ret;
- if (buf_size == 0)
- return 0;
- for (i = 0; i < len; i++) {
- ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
- data[i]);
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return pos - buf;
- }
- pos += ret;
- }
- end[-1] = '\0';
- return pos - buf;
- }
- int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
- {
- return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
- }
- int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
- size_t len)
- {
- return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
- }
- #ifdef CONFIG_ANSI_C_EXTRA
- #ifdef _WIN32_WCE
- void perror(const char *s)
- {
- wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
- s, (int) GetLastError());
- }
- #endif
- int optind = 1;
- int optopt;
- char *optarg;
- int getopt(int argc, char *const argv[], const char *optstring)
- {
- static int optchr = 1;
- char *cp;
- if (optchr == 1) {
- if (optind >= argc) {
-
- return EOF;
- }
- if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
-
- return EOF;
- }
- }
- if (os_strcmp(argv[optind], "--") == 0) {
-
- optind++;
- return EOF;
- }
- optopt = argv[optind][optchr];
- cp = os_strchr(optstring, optopt);
- if (cp == NULL || optopt == ':') {
- if (argv[optind][++optchr] == '\0') {
- optchr = 1;
- optind++;
- }
- return '?';
- }
- if (cp[1] == ':') {
-
- optchr = 1;
- if (argv[optind][optchr + 1]) {
-
- optarg = &argv[optind++][optchr + 1];
- } else if (++optind >= argc) {
-
- return '?';
- } else {
-
- optarg = argv[optind++];
- }
- } else {
-
- if (argv[optind][++optchr] == '\0') {
- optchr = 1;
- optind++;
- }
- optarg = NULL;
- }
- return *cp;
- }
- #endif
- #ifdef CONFIG_NATIVE_WINDOWS
- void wpa_unicode2ascii_inplace(TCHAR *str)
- {
- #ifdef UNICODE
- char *dst = (char *) str;
- while (*str)
- *dst++ = (char) *str++;
- *dst = '\0';
- #endif
- }
- TCHAR * wpa_strdup_tchar(const char *str)
- {
- #ifdef UNICODE
- TCHAR *buf;
- buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
- if (buf == NULL)
- return NULL;
- wsprintf(buf, L"%S", str);
- return buf;
- #else
- return os_strdup(str);
- #endif
- }
- #endif
- 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 '\033':
- *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 + 1 >= 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++] = '\033';
- 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;
- }
- }
- if (maxlen > len)
- buf[len] = '\0';
- return len;
- }
- const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
- {
- 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;
- }
- 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 = dup_binstr(value, *len);
- if (str == NULL)
- return NULL;
- 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 = dup_binstr(value, tlen);
- if (tstr == NULL)
- return NULL;
- 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;
- }
- char * dup_binstr(const void *src, size_t len)
- {
- char *res;
- if (src == NULL)
- return NULL;
- res = os_malloc(len + 1);
- if (res == NULL)
- return NULL;
- os_memcpy(res, src, len);
- res[len] = '\0';
- return res;
- }
- int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
- {
- struct wpa_freq_range *freq = NULL, *n;
- unsigned int count = 0;
- const char *pos, *pos2, *pos3;
-
- pos = value;
- while (pos && pos[0]) {
- n = os_realloc_array(freq, count + 1,
- sizeof(struct wpa_freq_range));
- if (n == NULL) {
- os_free(freq);
- return -1;
- }
- freq = n;
- freq[count].min = atoi(pos);
- pos2 = os_strchr(pos, '-');
- pos3 = os_strchr(pos, ',');
- if (pos2 && (!pos3 || pos2 < pos3)) {
- pos2++;
- freq[count].max = atoi(pos2);
- } else
- freq[count].max = freq[count].min;
- pos = pos3;
- if (pos)
- pos++;
- count++;
- }
- os_free(res->range);
- res->range = freq;
- res->num = count;
- return 0;
- }
- int freq_range_list_includes(const struct wpa_freq_range_list *list,
- unsigned int freq)
- {
- unsigned int i;
- if (list == NULL)
- return 0;
- for (i = 0; i < list->num; i++) {
- if (freq >= list->range[i].min && freq <= list->range[i].max)
- return 1;
- }
- return 0;
- }
- char * freq_range_list_str(const struct wpa_freq_range_list *list)
- {
- char *buf, *pos, *end;
- size_t maxlen;
- unsigned int i;
- int res;
- if (list->num == 0)
- return NULL;
- maxlen = list->num * 30;
- buf = os_malloc(maxlen);
- if (buf == NULL)
- return NULL;
- pos = buf;
- end = buf + maxlen;
- for (i = 0; i < list->num; i++) {
- struct wpa_freq_range *range = &list->range[i];
- if (range->min == range->max)
- res = os_snprintf(pos, end - pos, "%s%u",
- i == 0 ? "" : ",", range->min);
- else
- res = os_snprintf(pos, end - pos, "%s%u-%u",
- i == 0 ? "" : ",",
- range->min, range->max);
- if (os_snprintf_error(end - pos, res)) {
- os_free(buf);
- return NULL;
- }
- pos += res;
- }
- return buf;
- }
- int int_array_len(const int *a)
- {
- int i;
- for (i = 0; a && a[i]; i++)
- ;
- return i;
- }
- void int_array_concat(int **res, const int *a)
- {
- int reslen, alen, i;
- int *n;
- reslen = int_array_len(*res);
- alen = int_array_len(a);
- n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
- if (n == NULL) {
- os_free(*res);
- *res = NULL;
- return;
- }
- for (i = 0; i <= alen; i++)
- n[reslen + i] = a[i];
- *res = n;
- }
- static int freq_cmp(const void *a, const void *b)
- {
- int _a = *(int *) a;
- int _b = *(int *) b;
- if (_a == 0)
- return 1;
- if (_b == 0)
- return -1;
- return _a - _b;
- }
- void int_array_sort_unique(int *a)
- {
- int alen;
- int i, j;
- if (a == NULL)
- return;
- alen = int_array_len(a);
- qsort(a, alen, sizeof(int), freq_cmp);
- i = 0;
- j = 1;
- while (a[i] && a[j]) {
- if (a[i] == a[j]) {
- j++;
- continue;
- }
- a[++i] = a[j++];
- }
- if (a[i])
- i++;
- a[i] = 0;
- }
- void int_array_add_unique(int **res, int a)
- {
- int reslen;
- int *n;
- for (reslen = 0; *res && (*res)[reslen]; reslen++) {
- if ((*res)[reslen] == a)
- return;
- }
- n = os_realloc_array(*res, reslen + 2, sizeof(int));
- if (n == NULL) {
- os_free(*res);
- *res = NULL;
- return;
- }
- n[reslen] = a;
- n[reslen + 1] = 0;
- *res = n;
- }
- void str_clear_free(char *str)
- {
- if (str) {
- size_t len = os_strlen(str);
- os_memset(str, 0, len);
- os_free(str);
- }
- }
- void bin_clear_free(void *bin, size_t len)
- {
- if (bin) {
- os_memset(bin, 0, len);
- os_free(bin);
- }
- }
- int random_mac_addr(u8 *addr)
- {
- if (os_get_random(addr, ETH_ALEN) < 0)
- return -1;
- addr[0] &= 0xfe;
- addr[0] |= 0x02;
- return 0;
- }
- int random_mac_addr_keep_oui(u8 *addr)
- {
- if (os_get_random(addr + 3, 3) < 0)
- return -1;
- addr[0] &= 0xfe;
- addr[0] |= 0x02;
- return 0;
- }
- char * str_token(char *str, const char *delim, char **context)
- {
- char *end, *pos = str;
- if (*context)
- pos = *context;
- while (*pos && os_strchr(delim, *pos))
- pos++;
- if (!*pos)
- return NULL;
- end = pos + 1;
- while (*end && !os_strchr(delim, *end))
- end++;
- if (*end)
- *end++ = '\0';
- *context = end;
- return pos;
- }
- size_t utf8_unescape(const char *inp, size_t in_size,
- char *outp, size_t out_size)
- {
- size_t res_size = 0;
- if (!inp || !outp)
- return 0;
- if (!in_size)
- in_size = os_strlen(inp);
-
- if (*inp == '\'' && in_size) {
- inp++;
- in_size--;
- }
- while (in_size--) {
- if (res_size >= out_size)
- return 0;
- switch (*inp) {
- case '\'':
-
- *outp = '\0';
- return res_size;
- case '\\':
- if (!in_size--)
- return 0;
- inp++;
-
- default:
- *outp++ = *inp++;
- res_size++;
- }
- }
-
- if (res_size < out_size)
- *outp = '\0';
- return res_size;
- }
- size_t utf8_escape(const char *inp, size_t in_size,
- char *outp, size_t out_size)
- {
- size_t res_size = 0;
- if (!inp || !outp)
- return 0;
-
- if (!in_size)
- in_size = os_strlen(inp);
- while (in_size--) {
- if (res_size++ >= out_size)
- return 0;
- switch (*inp) {
- case '\\':
- case '\'':
- if (res_size++ >= out_size)
- return 0;
- *outp++ = '\\';
-
- default:
- *outp++ = *inp++;
- break;
- }
- }
-
- if (res_size < out_size)
- *outp = '\0';
- return res_size;
- }
|