LCOV - code coverage report
Current view: top level - src/utils - common.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 509 526 96.8 %
Date: 2016-10-02 Functions: 45 45 100.0 %

          Line data    Source code
       1             : /*
       2             :  * wpa_supplicant/hostapd / common helper functions, etc.
       3             :  * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common/ieee802_11_defs.h"
      12             : #include "common.h"
      13             : 
      14             : 
      15      801048 : static int hex2num(char c)
      16             : {
      17      801048 :         if (c >= '0' && c <= '9')
      18      633849 :                 return c - '0';
      19      167199 :         if (c >= 'a' && c <= 'f')
      20      158452 :                 return c - 'a' + 10;
      21        8747 :         if (c >= 'A' && c <= 'F')
      22        8319 :                 return c - 'A' + 10;
      23         428 :         return -1;
      24             : }
      25             : 
      26             : 
      27      338582 : int hex2byte(const char *hex)
      28             : {
      29             :         int a, b;
      30      338582 :         a = hex2num(*hex++);
      31      338582 :         if (a < 0)
      32          78 :                 return -1;
      33      338504 :         b = hex2num(*hex++);
      34      338504 :         if (b < 0)
      35         328 :                 return -1;
      36      338176 :         return (a << 4) | b;
      37             : }
      38             : 
      39             : 
      40        7390 : static const char * hwaddr_parse(const char *txt, u8 *addr)
      41             : {
      42             :         size_t i;
      43             : 
      44       49838 :         for (i = 0; i < ETH_ALEN; i++) {
      45             :                 int a;
      46             : 
      47       42786 :                 a = hex2byte(txt);
      48       42786 :                 if (a < 0)
      49         308 :                         return NULL;
      50       42478 :                 txt += 2;
      51       42478 :                 addr[i] = a;
      52       42478 :                 if (i < ETH_ALEN - 1 && *txt++ != ':')
      53          30 :                         return NULL;
      54             :         }
      55        7052 :         return txt;
      56             : }
      57             : 
      58             : 
      59             : /**
      60             :  * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
      61             :  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
      62             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
      63             :  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
      64             :  */
      65        7326 : int hwaddr_aton(const char *txt, u8 *addr)
      66             : {
      67        7326 :         return hwaddr_parse(txt, addr) ? 0 : -1;
      68             : }
      69             : 
      70             : 
      71             : /**
      72             :  * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format)
      73             :  * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00")
      74             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
      75             :  * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes)
      76             :  * @maskable: Flag to indicate whether a mask is allowed
      77             :  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
      78             :  */
      79          47 : int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable)
      80             : {
      81             :         const char *r;
      82             : 
      83             :         /* parse address part */
      84          47 :         r = hwaddr_parse(txt, addr);
      85          47 :         if (!r)
      86           4 :                 return -1;
      87             : 
      88             :         /* check for optional mask */
      89          43 :         if (*r == '\0' || isspace((unsigned char) *r)) {
      90             :                 /* no mask specified, assume default */
      91          25 :                 os_memset(mask, 0xff, ETH_ALEN);
      92          18 :         } else if (maskable && *r == '/') {
      93             :                 /* mask specified and allowed */
      94          17 :                 r = hwaddr_parse(r + 1, mask);
      95             :                 /* parser error? */
      96          32 :                 if (!r)
      97           2 :                         return -1;
      98             :         } else {
      99             :                 /* mask specified but not allowed or trailing garbage */
     100           1 :                 return -1;
     101             :         }
     102             : 
     103          40 :         return 0;
     104             : }
     105             : 
     106             : 
     107             : /**
     108             :  * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
     109             :  * @txt: MAC address as a string (e.g., "001122334455")
     110             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
     111             :  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
     112             :  */
     113          30 : int hwaddr_compact_aton(const char *txt, u8 *addr)
     114             : {
     115             :         int i;
     116             : 
     117         192 :         for (i = 0; i < 6; i++) {
     118             :                 int a, b;
     119             : 
     120         165 :                 a = hex2num(*txt++);
     121         165 :                 if (a < 0)
     122           1 :                         return -1;
     123         164 :                 b = hex2num(*txt++);
     124         164 :                 if (b < 0)
     125           2 :                         return -1;
     126         162 :                 *addr++ = (a << 4) | b;
     127             :         }
     128             : 
     129          27 :         return 0;
     130             : }
     131             : 
     132             : /**
     133             :  * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
     134             :  * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
     135             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
     136             :  * Returns: Characters used (> 0) on success, -1 on failure
     137             :  */
     138       10317 : int hwaddr_aton2(const char *txt, u8 *addr)
     139             : {
     140             :         int i;
     141       10317 :         const char *pos = txt;
     142             : 
     143       72117 :         for (i = 0; i < 6; i++) {
     144             :                 int a, b;
     145             : 
     146      175125 :                 while (*pos == ':' || *pos == '.' || *pos == '-')
     147       51489 :                         pos++;
     148             : 
     149       61818 :                 a = hex2num(*pos++);
     150       61818 :                 if (a < 0)
     151           5 :                         return -1;
     152       61813 :                 b = hex2num(*pos++);
     153       61813 :                 if (b < 0)
     154          13 :                         return -1;
     155       61800 :                 *addr++ = (a << 4) | b;
     156             :         }
     157             : 
     158       10299 :         return pos - txt;
     159             : }
     160             : 
     161             : 
     162             : /**
     163             :  * hexstr2bin - Convert ASCII hex string into binary data
     164             :  * @hex: ASCII hex string (e.g., "01ab")
     165             :  * @buf: Buffer for the binary data
     166             :  * @len: Length of the text to convert in bytes (of buf); hex will be double
     167             :  * this size
     168             :  * Returns: 0 on success, -1 on failure (invalid hex string)
     169             :  */
     170       13209 : int hexstr2bin(const char *hex, u8 *buf, size_t len)
     171             : {
     172             :         size_t i;
     173             :         int a;
     174       13209 :         const char *ipos = hex;
     175       13209 :         u8 *opos = buf;
     176             : 
     177      308852 :         for (i = 0; i < len; i++) {
     178      295739 :                 a = hex2byte(ipos);
     179      295739 :                 if (a < 0)
     180          96 :                         return -1;
     181      295643 :                 *opos++ = a;
     182      295643 :                 ipos += 2;
     183             :         }
     184       13113 :         return 0;
     185             : }
     186             : 
     187             : 
     188          38 : int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask)
     189             : {
     190             :         size_t i;
     191          38 :         int print_mask = 0;
     192             :         int res;
     193             : 
     194         202 :         for (i = 0; i < ETH_ALEN; i++) {
     195         177 :                 if (mask[i] != 0xff) {
     196          13 :                         print_mask = 1;
     197          13 :                         break;
     198             :                 }
     199             :         }
     200             : 
     201          38 :         if (print_mask)
     202         156 :                 res = os_snprintf(buf, len, MACSTR "/" MACSTR,
     203         156 :                                   MAC2STR(addr), MAC2STR(mask));
     204             :         else
     205          25 :                 res = os_snprintf(buf, len, MACSTR, MAC2STR(addr));
     206          38 :         if (os_snprintf_error(len, res))
     207           1 :                 return -1;
     208          37 :         return res;
     209             : }
     210             : 
     211             : 
     212             : /**
     213             :  * inc_byte_array - Increment arbitrary length byte array by one
     214             :  * @counter: Pointer to byte array
     215             :  * @len: Length of the counter in bytes
     216             :  *
     217             :  * This function increments the last byte of the counter by one and continues
     218             :  * rolling over to more significant bytes if the byte was incremented from
     219             :  * 0xff to 0x00.
     220             :  */
     221        7910 : void inc_byte_array(u8 *counter, size_t len)
     222             : {
     223        7910 :         int pos = len - 1;
     224       15830 :         while (pos >= 0) {
     225        7920 :                 counter[pos]++;
     226        7920 :                 if (counter[pos] != 0)
     227        7910 :                         break;
     228          10 :                 pos--;
     229             :         }
     230        7910 : }
     231             : 
     232             : 
     233        6023 : void wpa_get_ntp_timestamp(u8 *buf)
     234             : {
     235             :         struct os_time now;
     236             :         u32 sec, usec;
     237             :         be32 tmp;
     238             : 
     239             :         /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
     240        6023 :         os_get_time(&now);
     241        6023 :         sec = now.sec + 2208988800U; /* Epoch to 1900 */
     242             :         /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
     243        6023 :         usec = now.usec;
     244        6023 :         usec = 4295 * usec - (usec >> 5) - (usec >> 9);
     245        6023 :         tmp = host_to_be32(sec);
     246        6023 :         os_memcpy(buf, (u8 *) &tmp, 4);
     247        6023 :         tmp = host_to_be32(usec);
     248        6023 :         os_memcpy(buf + 4, (u8 *) &tmp, 4);
     249        6023 : }
     250             : 
     251             : /**
     252             :  * wpa_scnprintf - Simpler-to-use snprintf function
     253             :  * @buf: Output buffer
     254             :  * @size: Buffer size
     255             :  * @fmt: format
     256             :  *
     257             :  * Simpler snprintf version that doesn't require further error checks - the
     258             :  * return value only indicates how many bytes were actually written, excluding
     259             :  * the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough).
     260             :  */
     261         111 : int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...)
     262             : {
     263             :         va_list ap;
     264             :         int ret;
     265             : 
     266         111 :         if (!size)
     267           1 :                 return 0;
     268             : 
     269         110 :         va_start(ap, fmt);
     270         110 :         ret = vsnprintf(buf, size, fmt, ap);
     271         110 :         va_end(ap);
     272             : 
     273         110 :         if (ret < 0)
     274           0 :                 return 0;
     275         110 :         if ((size_t) ret >= size)
     276           1 :                 return size - 1;
     277             : 
     278         109 :         return ret;
     279             : }
     280             : 
     281             : 
     282         532 : int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len,
     283             :                          char sep)
     284             : {
     285             :         size_t i;
     286         532 :         char *pos = buf, *end = buf + buf_size;
     287             :         int ret;
     288             : 
     289         532 :         if (buf_size == 0)
     290           1 :                 return 0;
     291             : 
     292        9012 :         for (i = 0; i < len; i++) {
     293       16964 :                 ret = os_snprintf(pos, end - pos, "%02x%c",
     294        8482 :                                   data[i], sep);
     295        8482 :                 if (os_snprintf_error(end - pos, ret)) {
     296           1 :                         end[-1] = '\0';
     297           1 :                         return pos - buf;
     298             :                 }
     299        8481 :                 pos += ret;
     300             :         }
     301         530 :         pos[-1] = '\0';
     302         530 :         return pos - buf;
     303             : }
     304             : 
     305             : 
     306      226046 : static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
     307             :                                     size_t len, int uppercase)
     308             : {
     309             :         size_t i;
     310      226046 :         char *pos = buf, *end = buf + buf_size;
     311             :         int ret;
     312      226046 :         if (buf_size == 0)
     313           1 :                 return 0;
     314     5405719 :         for (i = 0; i < len; i++) {
     315     5179675 :                 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
     316     5179675 :                                   data[i]);
     317     5179675 :                 if (os_snprintf_error(end - pos, ret)) {
     318           1 :                         end[-1] = '\0';
     319           1 :                         return pos - buf;
     320             :                 }
     321     5179674 :                 pos += ret;
     322             :         }
     323      226044 :         end[-1] = '\0';
     324      226044 :         return pos - buf;
     325             : }
     326             : 
     327             : /**
     328             :  * wpa_snprintf_hex - Print data as a hex string into a buffer
     329             :  * @buf: Memory area to use as the output buffer
     330             :  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
     331             :  * @data: Data to be printed
     332             :  * @len: Length of data in bytes
     333             :  * Returns: Number of bytes written
     334             :  */
     335      225671 : int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
     336             : {
     337      225671 :         return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
     338             : }
     339             : 
     340             : 
     341             : /**
     342             :  * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
     343             :  * @buf: Memory area to use as the output buffer
     344             :  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
     345             :  * @data: Data to be printed
     346             :  * @len: Length of data in bytes
     347             :  * Returns: Number of bytes written
     348             :  */
     349         375 : int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
     350             :                                size_t len)
     351             : {
     352         375 :         return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
     353             : }
     354             : 
     355             : 
     356             : #ifdef CONFIG_ANSI_C_EXTRA
     357             : 
     358             : #ifdef _WIN32_WCE
     359             : void perror(const char *s)
     360             : {
     361             :         wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
     362             :                    s, (int) GetLastError());
     363             : }
     364             : #endif /* _WIN32_WCE */
     365             : 
     366             : 
     367             : int optind = 1;
     368             : int optopt;
     369             : char *optarg;
     370             : 
     371             : int getopt(int argc, char *const argv[], const char *optstring)
     372             : {
     373             :         static int optchr = 1;
     374             :         char *cp;
     375             : 
     376             :         if (optchr == 1) {
     377             :                 if (optind >= argc) {
     378             :                         /* all arguments processed */
     379             :                         return EOF;
     380             :                 }
     381             : 
     382             :                 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
     383             :                         /* no option characters */
     384             :                         return EOF;
     385             :                 }
     386             :         }
     387             : 
     388             :         if (os_strcmp(argv[optind], "--") == 0) {
     389             :                 /* no more options */
     390             :                 optind++;
     391             :                 return EOF;
     392             :         }
     393             : 
     394             :         optopt = argv[optind][optchr];
     395             :         cp = os_strchr(optstring, optopt);
     396             :         if (cp == NULL || optopt == ':') {
     397             :                 if (argv[optind][++optchr] == '\0') {
     398             :                         optchr = 1;
     399             :                         optind++;
     400             :                 }
     401             :                 return '?';
     402             :         }
     403             : 
     404             :         if (cp[1] == ':') {
     405             :                 /* Argument required */
     406             :                 optchr = 1;
     407             :                 if (argv[optind][optchr + 1]) {
     408             :                         /* No space between option and argument */
     409             :                         optarg = &argv[optind++][optchr + 1];
     410             :                 } else if (++optind >= argc) {
     411             :                         /* option requires an argument */
     412             :                         return '?';
     413             :                 } else {
     414             :                         /* Argument in the next argv */
     415             :                         optarg = argv[optind++];
     416             :                 }
     417             :         } else {
     418             :                 /* No argument */
     419             :                 if (argv[optind][++optchr] == '\0') {
     420             :                         optchr = 1;
     421             :                         optind++;
     422             :                 }
     423             :                 optarg = NULL;
     424             :         }
     425             :         return *cp;
     426             : }
     427             : #endif /* CONFIG_ANSI_C_EXTRA */
     428             : 
     429             : 
     430             : #ifdef CONFIG_NATIVE_WINDOWS
     431             : /**
     432             :  * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
     433             :  * @str: Pointer to string to convert
     434             :  *
     435             :  * This function converts a unicode string to ASCII using the same
     436             :  * buffer for output. If UNICODE is not set, the buffer is not
     437             :  * modified.
     438             :  */
     439             : void wpa_unicode2ascii_inplace(TCHAR *str)
     440             : {
     441             : #ifdef UNICODE
     442             :         char *dst = (char *) str;
     443             :         while (*str)
     444             :                 *dst++ = (char) *str++;
     445             :         *dst = '\0';
     446             : #endif /* UNICODE */
     447             : }
     448             : 
     449             : 
     450             : TCHAR * wpa_strdup_tchar(const char *str)
     451             : {
     452             : #ifdef UNICODE
     453             :         TCHAR *buf;
     454             :         buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
     455             :         if (buf == NULL)
     456             :                 return NULL;
     457             :         wsprintf(buf, L"%S", str);
     458             :         return buf;
     459             : #else /* UNICODE */
     460             :         return os_strdup(str);
     461             : #endif /* UNICODE */
     462             : }
     463             : #endif /* CONFIG_NATIVE_WINDOWS */
     464             : 
     465             : 
     466      425775 : void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
     467             : {
     468      425775 :         char *end = txt + maxlen;
     469             :         size_t i;
     470             : 
     471     8295422 :         for (i = 0; i < len; i++) {
     472     7869654 :                 if (txt + 4 >= end)
     473           7 :                         break;
     474             : 
     475     7869647 :                 switch (data[i]) {
     476             :                 case '\"':
     477           1 :                         *txt++ = '\\';
     478           1 :                         *txt++ = '\"';
     479           1 :                         break;
     480             :                 case '\\':
     481          30 :                         *txt++ = '\\';
     482          30 :                         *txt++ = '\\';
     483          30 :                         break;
     484             :                 case '\033':
     485           1 :                         *txt++ = '\\';
     486           1 :                         *txt++ = 'e';
     487           1 :                         break;
     488             :                 case '\n':
     489          25 :                         *txt++ = '\\';
     490          25 :                         *txt++ = 'n';
     491          25 :                         break;
     492             :                 case '\r':
     493           1 :                         *txt++ = '\\';
     494           1 :                         *txt++ = 'r';
     495           1 :                         break;
     496             :                 case '\t':
     497           1 :                         *txt++ = '\\';
     498           1 :                         *txt++ = 't';
     499           1 :                         break;
     500             :                 default:
     501     7869588 :                         if (data[i] >= 32 && data[i] <= 126) {
     502     7598323 :                                 *txt++ = data[i];
     503             :                         } else {
     504      271265 :                                 txt += os_snprintf(txt, end - txt, "\\x%02x",
     505      271265 :                                                    data[i]);
     506             :                         }
     507     7869588 :                         break;
     508             :                 }
     509             :         }
     510             : 
     511      425775 :         *txt = '\0';
     512      425775 : }
     513             : 
     514             : 
     515          23 : size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
     516             : {
     517          23 :         const char *pos = str;
     518          23 :         size_t len = 0;
     519             :         int val;
     520             : 
     521         226 :         while (*pos) {
     522         181 :                 if (len + 1 >= maxlen)
     523           1 :                         break;
     524         180 :                 switch (*pos) {
     525             :                 case '\\':
     526          91 :                         pos++;
     527          91 :                         switch (*pos) {
     528             :                         case '\\':
     529           2 :                                 buf[len++] = '\\';
     530           2 :                                 pos++;
     531           2 :                                 break;
     532             :                         case '"':
     533           2 :                                 buf[len++] = '"';
     534           2 :                                 pos++;
     535           2 :                                 break;
     536             :                         case 'n':
     537           8 :                                 buf[len++] = '\n';
     538           8 :                                 pos++;
     539           8 :                                 break;
     540             :                         case 'r':
     541           2 :                                 buf[len++] = '\r';
     542           2 :                                 pos++;
     543           2 :                                 break;
     544             :                         case 't':
     545           2 :                                 buf[len++] = '\t';
     546           2 :                                 pos++;
     547           2 :                                 break;
     548             :                         case 'e':
     549           2 :                                 buf[len++] = '\033';
     550           2 :                                 pos++;
     551           2 :                                 break;
     552             :                         case 'x':
     553          56 :                                 pos++;
     554          56 :                                 val = hex2byte(pos);
     555          56 :                                 if (val < 0) {
     556           2 :                                         val = hex2num(*pos);
     557           2 :                                         if (val < 0)
     558           1 :                                                 break;
     559           1 :                                         buf[len++] = val;
     560           1 :                                         pos++;
     561             :                                 } else {
     562          54 :                                         buf[len++] = val;
     563          54 :                                         pos += 2;
     564             :                                 }
     565          55 :                                 break;
     566             :                         case '0':
     567             :                         case '1':
     568             :                         case '2':
     569             :                         case '3':
     570             :                         case '4':
     571             :                         case '5':
     572             :                         case '6':
     573             :                         case '7':
     574          16 :                                 val = *pos++ - '0';
     575          16 :                                 if (*pos >= '0' && *pos <= '7')
     576          13 :                                         val = val * 8 + (*pos++ - '0');
     577          16 :                                 if (*pos >= '0' && *pos <= '7')
     578          13 :                                         val = val * 8 + (*pos++ - '0');
     579          16 :                                 buf[len++] = val;
     580          16 :                                 break;
     581             :                         default:
     582           1 :                                 break;
     583             :                         }
     584          91 :                         break;
     585             :                 default:
     586          89 :                         buf[len++] = *pos++;
     587          89 :                         break;
     588             :                 }
     589             :         }
     590          23 :         if (maxlen > len)
     591          23 :                 buf[len] = '\0';
     592             : 
     593          23 :         return len;
     594             : }
     595             : 
     596             : 
     597             : /**
     598             :  * wpa_ssid_txt - Convert SSID to a printable string
     599             :  * @ssid: SSID (32-octet string)
     600             :  * @ssid_len: Length of ssid in octets
     601             :  * Returns: Pointer to a printable string
     602             :  *
     603             :  * This function can be used to convert SSIDs into printable form. In most
     604             :  * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
     605             :  * does not limit the used character set, so anything could be used in an SSID.
     606             :  *
     607             :  * This function uses a static buffer, so only one call can be used at the
     608             :  * time, i.e., this is not re-entrant and the returned buffer must be used
     609             :  * before calling this again.
     610             :  */
     611       46190 : const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
     612             : {
     613             :         static char ssid_txt[SSID_MAX_LEN * 4 + 1];
     614             : 
     615       46190 :         if (ssid == NULL) {
     616         219 :                 ssid_txt[0] = '\0';
     617         219 :                 return ssid_txt;
     618             :         }
     619             : 
     620       45971 :         printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
     621       45971 :         return ssid_txt;
     622             : }
     623             : 
     624             : 
     625       37789 : void * __hide_aliasing_typecast(void *foo)
     626             : {
     627       37789 :         return foo;
     628             : }
     629             : 
     630             : 
     631       12313 : char * wpa_config_parse_string(const char *value, size_t *len)
     632             : {
     633       12313 :         if (*value == '"') {
     634             :                 const char *pos;
     635             :                 char *str;
     636       11908 :                 value++;
     637       11908 :                 pos = os_strrchr(value, '"');
     638       11908 :                 if (pos == NULL || pos[1] != '\0')
     639           2 :                         return NULL;
     640       11906 :                 *len = pos - value;
     641       11906 :                 str = dup_binstr(value, *len);
     642       11906 :                 if (str == NULL)
     643          11 :                         return NULL;
     644       11895 :                 return str;
     645         405 :         } else if (*value == 'P' && value[1] == '"') {
     646             :                 const char *pos;
     647             :                 char *tstr, *str;
     648             :                 size_t tlen;
     649          10 :                 value += 2;
     650          10 :                 pos = os_strrchr(value, '"');
     651          10 :                 if (pos == NULL || pos[1] != '\0')
     652           3 :                         return NULL;
     653           7 :                 tlen = pos - value;
     654           7 :                 tstr = dup_binstr(value, tlen);
     655           7 :                 if (tstr == NULL)
     656           1 :                         return NULL;
     657             : 
     658           6 :                 str = os_malloc(tlen + 1);
     659           6 :                 if (str == NULL) {
     660           1 :                         os_free(tstr);
     661           1 :                         return NULL;
     662             :                 }
     663             : 
     664           5 :                 *len = printf_decode((u8 *) str, tlen + 1, tstr);
     665           5 :                 os_free(tstr);
     666             : 
     667           5 :                 return str;
     668             :         } else {
     669             :                 u8 *str;
     670         395 :                 size_t tlen, hlen = os_strlen(value);
     671         395 :                 if (hlen & 1)
     672           4 :                         return NULL;
     673         391 :                 tlen = hlen / 2;
     674         391 :                 str = os_malloc(tlen + 1);
     675         391 :                 if (str == NULL)
     676           2 :                         return NULL;
     677         389 :                 if (hexstr2bin(value, str, tlen)) {
     678           2 :                         os_free(str);
     679           2 :                         return NULL;
     680             :                 }
     681         387 :                 str[tlen] = '\0';
     682         387 :                 *len = tlen;
     683         387 :                 return (char *) str;
     684             :         }
     685             : }
     686             : 
     687             : 
     688          74 : int is_hex(const u8 *data, size_t len)
     689             : {
     690             :         size_t i;
     691             : 
     692         388 :         for (i = 0; i < len; i++) {
     693         320 :                 if (data[i] < 32 || data[i] >= 127)
     694           6 :                         return 1;
     695             :         }
     696          68 :         return 0;
     697             : }
     698             : 
     699             : 
     700         917 : int has_ctrl_char(const u8 *data, size_t len)
     701             : {
     702             :         size_t i;
     703             : 
     704       23807 :         for (i = 0; i < len; i++) {
     705       22892 :                 if (data[i] < 32 || data[i] == 127)
     706           2 :                         return 1;
     707             :         }
     708         915 :         return 0;
     709             : }
     710             : 
     711             : 
     712        1106 : int has_newline(const char *str)
     713             : {
     714       19221 :         while (*str) {
     715       17038 :                 if (*str == '\n' || *str == '\r')
     716          29 :                         return 1;
     717       17009 :                 str++;
     718             :         }
     719        1077 :         return 0;
     720             : }
     721             : 
     722             : 
     723       16643 : size_t merge_byte_arrays(u8 *res, size_t res_len,
     724             :                          const u8 *src1, size_t src1_len,
     725             :                          const u8 *src2, size_t src2_len)
     726             : {
     727       16643 :         size_t len = 0;
     728             : 
     729       16643 :         os_memset(res, 0, res_len);
     730             : 
     731       16643 :         if (src1) {
     732       16642 :                 if (src1_len >= res_len) {
     733           1 :                         os_memcpy(res, src1, res_len);
     734           1 :                         return res_len;
     735             :                 }
     736             : 
     737       16641 :                 os_memcpy(res, src1, src1_len);
     738       16641 :                 len += src1_len;
     739             :         }
     740             : 
     741       16642 :         if (src2) {
     742       15405 :                 if (len + src2_len >= res_len) {
     743           1 :                         os_memcpy(res + len, src2, res_len - len);
     744           1 :                         return res_len;
     745             :                 }
     746             : 
     747       15404 :                 os_memcpy(res + len, src2, src2_len);
     748       15404 :                 len += src2_len;
     749             :         }
     750             : 
     751       16641 :         return len;
     752             : }
     753             : 
     754             : 
     755       21380 : char * dup_binstr(const void *src, size_t len)
     756             : {
     757             :         char *res;
     758             : 
     759       21380 :         if (src == NULL)
     760           1 :                 return NULL;
     761       21379 :         res = os_malloc(len + 1);
     762       21379 :         if (res == NULL)
     763          21 :                 return NULL;
     764       21358 :         os_memcpy(res, src, len);
     765       21358 :         res[len] = '\0';
     766             : 
     767       21358 :         return res;
     768             : }
     769             : 
     770             : 
     771        2299 : int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
     772             : {
     773        2299 :         struct wpa_freq_range *freq = NULL, *n;
     774        2299 :         unsigned int count = 0;
     775             :         const char *pos, *pos2, *pos3;
     776             : 
     777             :         /*
     778             :          * Comma separated list of frequency ranges.
     779             :          * For example: 2412-2432,2462,5000-6000
     780             :          */
     781        2299 :         pos = value;
     782        6889 :         while (pos && pos[0]) {
     783        2295 :                 n = os_realloc_array(freq, count + 1,
     784             :                                      sizeof(struct wpa_freq_range));
     785        2295 :                 if (n == NULL) {
     786           4 :                         os_free(freq);
     787           4 :                         return -1;
     788             :                 }
     789        2291 :                 freq = n;
     790        2291 :                 freq[count].min = atoi(pos);
     791        2291 :                 pos2 = os_strchr(pos, '-');
     792        2291 :                 pos3 = os_strchr(pos, ',');
     793        2291 :                 if (pos2 && (!pos3 || pos2 < pos3)) {
     794          29 :                         pos2++;
     795          29 :                         freq[count].max = atoi(pos2);
     796             :                 } else
     797        2262 :                         freq[count].max = freq[count].min;
     798        2291 :                 pos = pos3;
     799        2291 :                 if (pos)
     800          29 :                         pos++;
     801        2291 :                 count++;
     802             :         }
     803             : 
     804        2295 :         os_free(res->range);
     805        2295 :         res->range = freq;
     806        2295 :         res->num = count;
     807             : 
     808        2295 :         return 0;
     809             : }
     810             : 
     811             : 
     812    14160825 : int freq_range_list_includes(const struct wpa_freq_range_list *list,
     813             :                              unsigned int freq)
     814             : {
     815             :         unsigned int i;
     816             : 
     817    14160825 :         if (list == NULL)
     818           1 :                 return 0;
     819             : 
     820    14294458 :         for (i = 0; i < list->num; i++) {
     821      144908 :                 if (freq >= list->range[i].min && freq <= list->range[i].max)
     822       11274 :                         return 1;
     823             :         }
     824             : 
     825    14149550 :         return 0;
     826             : }
     827             : 
     828             : 
     829           4 : char * freq_range_list_str(const struct wpa_freq_range_list *list)
     830             : {
     831             :         char *buf, *pos, *end;
     832             :         size_t maxlen;
     833             :         unsigned int i;
     834             :         int res;
     835             : 
     836           4 :         if (list->num == 0)
     837           1 :                 return NULL;
     838             : 
     839           3 :         maxlen = list->num * 30;
     840           3 :         buf = os_malloc(maxlen);
     841           3 :         if (buf == NULL)
     842           0 :                 return NULL;
     843           3 :         pos = buf;
     844           3 :         end = buf + maxlen;
     845             : 
     846           9 :         for (i = 0; i < list->num; i++) {
     847           6 :                 struct wpa_freq_range *range = &list->range[i];
     848             : 
     849           6 :                 if (range->min == range->max)
     850           4 :                         res = os_snprintf(pos, end - pos, "%s%u",
     851             :                                           i == 0 ? "" : ",", range->min);
     852             :                 else
     853           2 :                         res = os_snprintf(pos, end - pos, "%s%u-%u",
     854             :                                           i == 0 ? "" : ",",
     855             :                                           range->min, range->max);
     856           6 :                 if (os_snprintf_error(end - pos, res)) {
     857           0 :                         os_free(buf);
     858           0 :                         return NULL;
     859             :                 }
     860           6 :                 pos += res;
     861             :         }
     862             : 
     863           3 :         return buf;
     864             : }
     865             : 
     866             : 
     867        9170 : int int_array_len(const int *a)
     868             : {
     869             :         int i;
     870        9170 :         for (i = 0; a && a[i]; i++)
     871             :                 ;
     872        9170 :         return i;
     873             : }
     874             : 
     875             : 
     876        1472 : void int_array_concat(int **res, const int *a)
     877             : {
     878             :         int reslen, alen, i;
     879             :         int *n;
     880             : 
     881        1472 :         reslen = int_array_len(*res);
     882        1472 :         alen = int_array_len(a);
     883             : 
     884        1472 :         n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
     885        1472 :         if (n == NULL) {
     886           0 :                 os_free(*res);
     887           0 :                 *res = NULL;
     888        1472 :                 return;
     889             :         }
     890        4448 :         for (i = 0; i <= alen; i++)
     891        2976 :                 n[reslen + i] = a[i];
     892        1472 :         *res = n;
     893             : }
     894             : 
     895             : 
     896         106 : static int freq_cmp(const void *a, const void *b)
     897             : {
     898         106 :         int _a = *(int *) a;
     899         106 :         int _b = *(int *) b;
     900             : 
     901         106 :         if (_a == 0)
     902           0 :                 return 1;
     903         106 :         if (_b == 0)
     904           0 :                 return -1;
     905         106 :         return _a - _b;
     906             : }
     907             : 
     908             : 
     909        4158 : void int_array_sort_unique(int *a)
     910             : {
     911             :         int alen;
     912             :         int i, j;
     913             : 
     914        4158 :         if (a == NULL)
     915        6861 :                 return;
     916             : 
     917        1455 :         alen = int_array_len(a);
     918        1455 :         qsort(a, alen, sizeof(int), freq_cmp);
     919             : 
     920        1455 :         i = 0;
     921        1455 :         j = 1;
     922        2971 :         while (a[i] && a[j]) {
     923          61 :                 if (a[i] == a[j]) {
     924          25 :                         j++;
     925          25 :                         continue;
     926             :                 }
     927          36 :                 a[++i] = a[j++];
     928             :         }
     929        1455 :         if (a[i])
     930        1455 :                 i++;
     931        1455 :         a[i] = 0;
     932             : }
     933             : 
     934             : 
     935        4585 : void int_array_add_unique(int **res, int a)
     936             : {
     937             :         int reslen;
     938             :         int *n;
     939             : 
     940        6762 :         for (reslen = 0; *res && (*res)[reslen]; reslen++) {
     941        4377 :                 if ((*res)[reslen] == a)
     942        2200 :                         return; /* already in the list */
     943             :         }
     944             : 
     945        2385 :         n = os_realloc_array(*res, reslen + 2, sizeof(int));
     946        2385 :         if (n == NULL) {
     947           0 :                 os_free(*res);
     948           0 :                 *res = NULL;
     949           0 :                 return;
     950             :         }
     951             : 
     952        2385 :         n[reslen] = a;
     953        2385 :         n[reslen + 1] = 0;
     954             : 
     955        2385 :         *res = n;
     956             : }
     957             : 
     958             : 
     959       41023 : void str_clear_free(char *str)
     960             : {
     961       41023 :         if (str) {
     962        2100 :                 size_t len = os_strlen(str);
     963        2100 :                 os_memset(str, 0, len);
     964        2100 :                 os_free(str);
     965             :         }
     966       41023 : }
     967             : 
     968             : 
     969     2037078 : void bin_clear_free(void *bin, size_t len)
     970             : {
     971     2037078 :         if (bin) {
     972     1978558 :                 os_memset(bin, 0, len);
     973     1978558 :                 os_free(bin);
     974             :         }
     975     2037078 : }
     976             : 
     977             : 
     978           6 : int random_mac_addr(u8 *addr)
     979             : {
     980           6 :         if (os_get_random(addr, ETH_ALEN) < 0)
     981           0 :                 return -1;
     982           6 :         addr[0] &= 0xfe; /* unicast */
     983           6 :         addr[0] |= 0x02; /* locally administered */
     984           6 :         return 0;
     985             : }
     986             : 
     987             : 
     988           4 : int random_mac_addr_keep_oui(u8 *addr)
     989             : {
     990           4 :         if (os_get_random(addr + 3, 3) < 0)
     991           0 :                 return -1;
     992           4 :         addr[0] &= 0xfe; /* unicast */
     993           4 :         addr[0] |= 0x02; /* locally administered */
     994           4 :         return 0;
     995             : }
     996             : 
     997             : 
     998             : /**
     999             :  * cstr_token - Get next token from const char string
    1000             :  * @str: a constant string to tokenize
    1001             :  * @delim: a string of delimiters
    1002             :  * @last: a pointer to a character following the returned token
    1003             :  *      It has to be set to NULL for the first call and passed for any
    1004             :  *      further call.
    1005             :  * Returns: a pointer to token position in str or NULL
    1006             :  *
    1007             :  * This function is similar to str_token, but it can be used with both
    1008             :  * char and const char strings. Differences:
    1009             :  * - The str buffer remains unmodified
    1010             :  * - The returned token is not a NULL terminated string, but a token
    1011             :  *   position in str buffer. If a return value is not NULL a size
    1012             :  *   of the returned token could be calculated as (last - token).
    1013             :  */
    1014        1579 : const char * cstr_token(const char *str, const char *delim, const char **last)
    1015             : {
    1016        1579 :         const char *end, *token = str;
    1017             : 
    1018        1579 :         if (!str || !delim || !last)
    1019           0 :                 return NULL;
    1020             : 
    1021        1579 :         if (*last)
    1022         929 :                 token = *last;
    1023             : 
    1024        3210 :         while (*token && os_strchr(delim, *token))
    1025          52 :                 token++;
    1026             : 
    1027        1579 :         if (!*token)
    1028         564 :                 return NULL;
    1029             : 
    1030        1015 :         end = token + 1;
    1031             : 
    1032       12891 :         while (*end && !os_strchr(delim, *end))
    1033       10861 :                 end++;
    1034             : 
    1035        1015 :         *last = end;
    1036        1015 :         return token;
    1037             : }
    1038             : 
    1039             : 
    1040             : /**
    1041             :  * str_token - Get next token from a string
    1042             :  * @buf: String to tokenize. Note that the string might be modified.
    1043             :  * @delim: String of delimiters
    1044             :  * @context: Pointer to save our context. Should be initialized with
    1045             :  *      NULL on the first call, and passed for any further call.
    1046             :  * Returns: The next token, NULL if there are no more valid tokens.
    1047             :  */
    1048         938 : char * str_token(char *str, const char *delim, char **context)
    1049             : {
    1050         938 :         char *token = (char *) cstr_token(str, delim, (const char **) context);
    1051             : 
    1052         938 :         if (token && **context)
    1053         395 :                 *(*context)++ = '\0';
    1054             : 
    1055         938 :         return token;
    1056             : }
    1057             : 
    1058             : 
    1059         152 : size_t utf8_unescape(const char *inp, size_t in_size,
    1060             :                      char *outp, size_t out_size)
    1061             : {
    1062         152 :         size_t res_size = 0;
    1063             : 
    1064         152 :         if (!inp || !outp)
    1065           2 :                 return 0;
    1066             : 
    1067         150 :         if (!in_size)
    1068           1 :                 in_size = os_strlen(inp);
    1069             : 
    1070             :         /* Advance past leading single quote */
    1071         150 :         if (*inp == '\'' && in_size) {
    1072         145 :                 inp++;
    1073         145 :                 in_size--;
    1074             :         }
    1075             : 
    1076        2227 :         while (in_size--) {
    1077        2073 :                 if (res_size >= out_size)
    1078           1 :                         return 0;
    1079             : 
    1080        2072 :                 switch (*inp) {
    1081             :                 case '\'':
    1082             :                         /* Terminate on bare single quote */
    1083         144 :                         *outp = '\0';
    1084         144 :                         return res_size;
    1085             : 
    1086             :                 case '\\':
    1087           2 :                         if (!in_size--)
    1088           1 :                                 return 0;
    1089           1 :                         inp++;
    1090             :                         /* fall through */
    1091             : 
    1092             :                 default:
    1093        1927 :                         *outp++ = *inp++;
    1094        1927 :                         res_size++;
    1095             :                 }
    1096             :         }
    1097             : 
    1098             :         /* NUL terminate if space allows */
    1099           4 :         if (res_size < out_size)
    1100           3 :                 *outp = '\0';
    1101             : 
    1102           4 :         return res_size;
    1103             : }
    1104             : 
    1105             : 
    1106          53 : size_t utf8_escape(const char *inp, size_t in_size,
    1107             :                    char *outp, size_t out_size)
    1108             : {
    1109          53 :         size_t res_size = 0;
    1110             : 
    1111          53 :         if (!inp || !outp)
    1112           2 :                 return 0;
    1113             : 
    1114             :         /* inp may or may not be NUL terminated, but must be if 0 size
    1115             :          * is specified */
    1116          51 :         if (!in_size)
    1117           1 :                 in_size = os_strlen(inp);
    1118             : 
    1119        1622 :         while (in_size--) {
    1120        1524 :                 if (res_size++ >= out_size)
    1121           3 :                         return 0;
    1122             : 
    1123        1521 :                 switch (*inp) {
    1124             :                 case '\\':
    1125             :                 case '\'':
    1126           2 :                         if (res_size++ >= out_size)
    1127           1 :                                 return 0;
    1128           1 :                         *outp++ = '\\';
    1129             :                         /* fall through */
    1130             : 
    1131             :                 default:
    1132        1520 :                         *outp++ = *inp++;
    1133        1520 :                         break;
    1134             :                 }
    1135             :         }
    1136             : 
    1137             :         /* NUL terminate if space allows */
    1138          47 :         if (res_size < out_size)
    1139          46 :                 *outp = '\0';
    1140             : 
    1141          47 :         return res_size;
    1142             : }
    1143             : 
    1144             : 
    1145       61364 : int is_ctrl_char(char c)
    1146             : {
    1147       61364 :         return c > 0 && c < 32;
    1148             : }
    1149             : 
    1150             : 
    1151             : /**
    1152             :  * ssid_parse - Parse a string that contains SSID in hex or text format
    1153             :  * @buf: Input NULL terminated string that contains the SSID
    1154             :  * @ssid: Output SSID
    1155             :  * Returns: 0 on success, -1 otherwise
    1156             :  *
    1157             :  * The SSID has to be enclosed in double quotes for the text format or space
    1158             :  * or NULL terminated string of hex digits for the hex format. buf can include
    1159             :  * additional arguments after the SSID.
    1160             :  */
    1161          35 : int ssid_parse(const char *buf, struct wpa_ssid_value *ssid)
    1162             : {
    1163             :         char *tmp, *res, *end;
    1164             :         size_t len;
    1165             : 
    1166          35 :         ssid->ssid_len = 0;
    1167             : 
    1168          35 :         tmp = os_strdup(buf);
    1169          35 :         if (!tmp)
    1170           0 :                 return -1;
    1171             : 
    1172          35 :         if (*tmp != '"') {
    1173           2 :                 end = os_strchr(tmp, ' ');
    1174           2 :                 if (end)
    1175           2 :                         *end = '\0';
    1176             :         } else {
    1177          33 :                 end = os_strchr(tmp + 1, '"');
    1178          33 :                 if (!end) {
    1179           0 :                         os_free(tmp);
    1180           0 :                         return -1;
    1181             :                 }
    1182             : 
    1183          33 :                 end[1] = '\0';
    1184             :         }
    1185             : 
    1186          35 :         res = wpa_config_parse_string(tmp, &len);
    1187          35 :         if (res && len <= SSID_MAX_LEN) {
    1188          34 :                 ssid->ssid_len = len;
    1189          34 :                 os_memcpy(ssid->ssid, res, len);
    1190             :         }
    1191             : 
    1192          35 :         os_free(tmp);
    1193          35 :         os_free(res);
    1194             : 
    1195          35 :         return ssid->ssid_len ? 0 : -1;
    1196             : }
    1197             : 
    1198             : 
    1199        1739 : int str_starts(const char *str, const char *start)
    1200             : {
    1201        1739 :         return os_strncmp(str, start, os_strlen(start)) == 0;
    1202             : }

Generated by: LCOV version 1.10