LCOV - code coverage report
Current view: top level - utils - common.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 200 388 51.5 %
Date: 2014-10-09 Functions: 21 32 65.6 %

          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.h"
      12             : 
      13             : 
      14       52571 : static int hex2num(char c)
      15             : {
      16       52571 :         if (c >= '0' && c <= '9')
      17       45158 :                 return c - '0';
      18        7413 :         if (c >= 'a' && c <= 'f')
      19        6779 :                 return c - 'a' + 10;
      20         634 :         if (c >= 'A' && c <= 'F')
      21         610 :                 return c - 'A' + 10;
      22          24 :         return -1;
      23             : }
      24             : 
      25             : 
      26       24070 : int hex2byte(const char *hex)
      27             : {
      28             :         int a, b;
      29       24070 :         a = hex2num(*hex++);
      30       24070 :         if (a < 0)
      31           4 :                 return -1;
      32       24066 :         b = hex2num(*hex++);
      33       24066 :         if (b < 0)
      34          13 :                 return -1;
      35       24053 :         return (a << 4) | b;
      36             : }
      37             : 
      38             : 
      39             : /**
      40             :  * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
      41             :  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
      42             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
      43             :  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
      44             :  */
      45         371 : int hwaddr_aton(const char *txt, u8 *addr)
      46             : {
      47             :         int i;
      48             : 
      49        2554 :         for (i = 0; i < 6; i++) {
      50             :                 int a, b;
      51             : 
      52        2200 :                 a = hex2num(*txt++);
      53        2200 :                 if (a < 0)
      54           3 :                         return -1;
      55        2197 :                 b = hex2num(*txt++);
      56        2197 :                 if (b < 0)
      57           3 :                         return -1;
      58        2194 :                 *addr++ = (a << 4) | b;
      59        2194 :                 if (i < 5 && *txt++ != ':')
      60          11 :                         return -1;
      61             :         }
      62             : 
      63         354 :         return 0;
      64             : }
      65             : 
      66             : /**
      67             :  * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
      68             :  * @txt: MAC address as a string (e.g., "001122334455")
      69             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
      70             :  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
      71             :  */
      72           0 : int hwaddr_compact_aton(const char *txt, u8 *addr)
      73             : {
      74             :         int i;
      75             : 
      76           0 :         for (i = 0; i < 6; i++) {
      77             :                 int a, b;
      78             : 
      79           0 :                 a = hex2num(*txt++);
      80           0 :                 if (a < 0)
      81           0 :                         return -1;
      82           0 :                 b = hex2num(*txt++);
      83           0 :                 if (b < 0)
      84           0 :                         return -1;
      85           0 :                 *addr++ = (a << 4) | b;
      86             :         }
      87             : 
      88           0 :         return 0;
      89             : }
      90             : 
      91             : /**
      92             :  * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
      93             :  * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
      94             :  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
      95             :  * Returns: Characters used (> 0) on success, -1 on failure
      96             :  */
      97           4 : int hwaddr_aton2(const char *txt, u8 *addr)
      98             : {
      99             :         int i;
     100           4 :         const char *pos = txt;
     101             : 
     102          22 :         for (i = 0; i < 6; i++) {
     103             :                 int a, b;
     104             : 
     105          53 :                 while (*pos == ':' || *pos == '.' || *pos == '-')
     106          15 :                         pos++;
     107             : 
     108          19 :                 a = hex2num(*pos++);
     109          19 :                 if (a < 0)
     110           0 :                         return -1;
     111          19 :                 b = hex2num(*pos++);
     112          19 :                 if (b < 0)
     113           1 :                         return -1;
     114          18 :                 *addr++ = (a << 4) | b;
     115             :         }
     116             : 
     117           3 :         return pos - txt;
     118             : }
     119             : 
     120             : 
     121             : /**
     122             :  * hexstr2bin - Convert ASCII hex string into binary data
     123             :  * @hex: ASCII hex string (e.g., "01ab")
     124             :  * @buf: Buffer for the binary data
     125             :  * @len: Length of the text to convert in bytes (of buf); hex will be double
     126             :  * this size
     127             :  * Returns: 0 on success, -1 on failure (invalid hex string)
     128             :  */
     129        1674 : int hexstr2bin(const char *hex, u8 *buf, size_t len)
     130             : {
     131             :         size_t i;
     132             :         int a;
     133        1674 :         const char *ipos = hex;
     134        1674 :         u8 *opos = buf;
     135             : 
     136       25727 :         for (i = 0; i < len; i++) {
     137       24070 :                 a = hex2byte(ipos);
     138       24070 :                 if (a < 0)
     139          17 :                         return -1;
     140       24053 :                 *opos++ = a;
     141       24053 :                 ipos += 2;
     142             :         }
     143        1657 :         return 0;
     144             : }
     145             : 
     146             : 
     147             : /**
     148             :  * inc_byte_array - Increment arbitrary length byte array by one
     149             :  * @counter: Pointer to byte array
     150             :  * @len: Length of the counter in bytes
     151             :  *
     152             :  * This function increments the last byte of the counter by one and continues
     153             :  * rolling over to more significant bytes if the byte was incremented from
     154             :  * 0xff to 0x00.
     155             :  */
     156        2221 : void inc_byte_array(u8 *counter, size_t len)
     157             : {
     158        2221 :         int pos = len - 1;
     159        4447 :         while (pos >= 0) {
     160        2226 :                 counter[pos]++;
     161        2226 :                 if (counter[pos] != 0)
     162        2221 :                         break;
     163           5 :                 pos--;
     164             :         }
     165        2221 : }
     166             : 
     167             : 
     168        1838 : void wpa_get_ntp_timestamp(u8 *buf)
     169             : {
     170             :         struct os_time now;
     171             :         u32 sec, usec;
     172             :         be32 tmp;
     173             : 
     174             :         /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
     175        1838 :         os_get_time(&now);
     176        1838 :         sec = now.sec + 2208988800U; /* Epoch to 1900 */
     177             :         /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
     178        1838 :         usec = now.usec;
     179        1838 :         usec = 4295 * usec - (usec >> 5) - (usec >> 9);
     180        1838 :         tmp = host_to_be32(sec);
     181        1838 :         os_memcpy(buf, (u8 *) &tmp, 4);
     182        1838 :         tmp = host_to_be32(usec);
     183        1838 :         os_memcpy(buf + 4, (u8 *) &tmp, 4);
     184        1838 : }
     185             : 
     186             : 
     187       26433 : static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
     188             :                                     size_t len, int uppercase)
     189             : {
     190             :         size_t i;
     191       26433 :         char *pos = buf, *end = buf + buf_size;
     192             :         int ret;
     193       26433 :         if (buf_size == 0)
     194           0 :                 return 0;
     195      734941 :         for (i = 0; i < len; i++) {
     196      708508 :                 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
     197      708508 :                                   data[i]);
     198      708508 :                 if (ret < 0 || ret >= end - pos) {
     199           0 :                         end[-1] = '\0';
     200           0 :                         return pos - buf;
     201             :                 }
     202      708508 :                 pos += ret;
     203             :         }
     204       26433 :         end[-1] = '\0';
     205       26433 :         return pos - buf;
     206             : }
     207             : 
     208             : /**
     209             :  * wpa_snprintf_hex - Print data as a hex string into a buffer
     210             :  * @buf: Memory area to use as the output buffer
     211             :  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
     212             :  * @data: Data to be printed
     213             :  * @len: Length of data in bytes
     214             :  * Returns: Number of bytes written
     215             :  */
     216       26410 : int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
     217             : {
     218       26410 :         return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
     219             : }
     220             : 
     221             : 
     222             : /**
     223             :  * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
     224             :  * @buf: Memory area to use as the output buffer
     225             :  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
     226             :  * @data: Data to be printed
     227             :  * @len: Length of data in bytes
     228             :  * Returns: Number of bytes written
     229             :  */
     230          23 : int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
     231             :                                size_t len)
     232             : {
     233          23 :         return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
     234             : }
     235             : 
     236             : 
     237             : #ifdef CONFIG_ANSI_C_EXTRA
     238             : 
     239             : #ifdef _WIN32_WCE
     240             : void perror(const char *s)
     241             : {
     242             :         wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
     243             :                    s, (int) GetLastError());
     244             : }
     245             : #endif /* _WIN32_WCE */
     246             : 
     247             : 
     248             : int optind = 1;
     249             : int optopt;
     250             : char *optarg;
     251             : 
     252             : int getopt(int argc, char *const argv[], const char *optstring)
     253             : {
     254             :         static int optchr = 1;
     255             :         char *cp;
     256             : 
     257             :         if (optchr == 1) {
     258             :                 if (optind >= argc) {
     259             :                         /* all arguments processed */
     260             :                         return EOF;
     261             :                 }
     262             : 
     263             :                 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
     264             :                         /* no option characters */
     265             :                         return EOF;
     266             :                 }
     267             :         }
     268             : 
     269             :         if (os_strcmp(argv[optind], "--") == 0) {
     270             :                 /* no more options */
     271             :                 optind++;
     272             :                 return EOF;
     273             :         }
     274             : 
     275             :         optopt = argv[optind][optchr];
     276             :         cp = os_strchr(optstring, optopt);
     277             :         if (cp == NULL || optopt == ':') {
     278             :                 if (argv[optind][++optchr] == '\0') {
     279             :                         optchr = 1;
     280             :                         optind++;
     281             :                 }
     282             :                 return '?';
     283             :         }
     284             : 
     285             :         if (cp[1] == ':') {
     286             :                 /* Argument required */
     287             :                 optchr = 1;
     288             :                 if (argv[optind][optchr + 1]) {
     289             :                         /* No space between option and argument */
     290             :                         optarg = &argv[optind++][optchr + 1];
     291             :                 } else if (++optind >= argc) {
     292             :                         /* option requires an argument */
     293             :                         return '?';
     294             :                 } else {
     295             :                         /* Argument in the next argv */
     296             :                         optarg = argv[optind++];
     297             :                 }
     298             :         } else {
     299             :                 /* No argument */
     300             :                 if (argv[optind][++optchr] == '\0') {
     301             :                         optchr = 1;
     302             :                         optind++;
     303             :                 }
     304             :                 optarg = NULL;
     305             :         }
     306             :         return *cp;
     307             : }
     308             : #endif /* CONFIG_ANSI_C_EXTRA */
     309             : 
     310             : 
     311             : #ifdef CONFIG_NATIVE_WINDOWS
     312             : /**
     313             :  * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
     314             :  * @str: Pointer to string to convert
     315             :  *
     316             :  * This function converts a unicode string to ASCII using the same
     317             :  * buffer for output. If UNICODE is not set, the buffer is not
     318             :  * modified.
     319             :  */
     320             : void wpa_unicode2ascii_inplace(TCHAR *str)
     321             : {
     322             : #ifdef UNICODE
     323             :         char *dst = (char *) str;
     324             :         while (*str)
     325             :                 *dst++ = (char) *str++;
     326             :         *dst = '\0';
     327             : #endif /* UNICODE */
     328             : }
     329             : 
     330             : 
     331             : TCHAR * wpa_strdup_tchar(const char *str)
     332             : {
     333             : #ifdef UNICODE
     334             :         TCHAR *buf;
     335             :         buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
     336             :         if (buf == NULL)
     337             :                 return NULL;
     338             :         wsprintf(buf, L"%S", str);
     339             :         return buf;
     340             : #else /* UNICODE */
     341             :         return os_strdup(str);
     342             : #endif /* UNICODE */
     343             : }
     344             : #endif /* CONFIG_NATIVE_WINDOWS */
     345             : 
     346             : 
     347       16973 : void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
     348             : {
     349       16973 :         char *end = txt + maxlen;
     350             :         size_t i;
     351             : 
     352      300915 :         for (i = 0; i < len; i++) {
     353      283943 :                 if (txt + 4 >= end)
     354           1 :                         break;
     355             : 
     356      283942 :                 switch (data[i]) {
     357             :                 case '\"':
     358           0 :                         *txt++ = '\\';
     359           0 :                         *txt++ = '\"';
     360           0 :                         break;
     361             :                 case '\\':
     362           1 :                         *txt++ = '\\';
     363           1 :                         *txt++ = '\\';
     364           1 :                         break;
     365             :                 case '\033':
     366           0 :                         *txt++ = '\\';
     367           0 :                         *txt++ = 'e';
     368           0 :                         break;
     369             :                 case '\n':
     370           1 :                         *txt++ = '\\';
     371           1 :                         *txt++ = 'n';
     372           1 :                         break;
     373             :                 case '\r':
     374           0 :                         *txt++ = '\\';
     375           0 :                         *txt++ = 'r';
     376           0 :                         break;
     377             :                 case '\t':
     378           0 :                         *txt++ = '\\';
     379           0 :                         *txt++ = 't';
     380           0 :                         break;
     381             :                 default:
     382      283940 :                         if (data[i] >= 32 && data[i] <= 127) {
     383      283884 :                                 *txt++ = data[i];
     384             :                         } else {
     385          56 :                                 txt += os_snprintf(txt, end - txt, "\\x%02x",
     386          56 :                                                    data[i]);
     387             :                         }
     388      283940 :                         break;
     389             :                 }
     390             :         }
     391             : 
     392       16973 :         *txt = '\0';
     393       16973 : }
     394             : 
     395             : 
     396           2 : size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
     397             : {
     398           2 :         const char *pos = str;
     399           2 :         size_t len = 0;
     400             :         int val;
     401             : 
     402          32 :         while (*pos) {
     403          28 :                 if (len + 1 >= maxlen)
     404           0 :                         break;
     405          28 :                 switch (*pos) {
     406             :                 case '\\':
     407           2 :                         pos++;
     408           2 :                         switch (*pos) {
     409             :                         case '\\':
     410           0 :                                 buf[len++] = '\\';
     411           0 :                                 pos++;
     412           0 :                                 break;
     413             :                         case '"':
     414           0 :                                 buf[len++] = '"';
     415           0 :                                 pos++;
     416           0 :                                 break;
     417             :                         case 'n':
     418           1 :                                 buf[len++] = '\n';
     419           1 :                                 pos++;
     420           1 :                                 break;
     421             :                         case 'r':
     422           0 :                                 buf[len++] = '\r';
     423           0 :                                 pos++;
     424           0 :                                 break;
     425             :                         case 't':
     426           0 :                                 buf[len++] = '\t';
     427           0 :                                 pos++;
     428           0 :                                 break;
     429             :                         case 'e':
     430           0 :                                 buf[len++] = '\033';
     431           0 :                                 pos++;
     432           0 :                                 break;
     433             :                         case 'x':
     434           0 :                                 pos++;
     435           0 :                                 val = hex2byte(pos);
     436           0 :                                 if (val < 0) {
     437           0 :                                         val = hex2num(*pos);
     438           0 :                                         if (val < 0)
     439           0 :                                                 break;
     440           0 :                                         buf[len++] = val;
     441           0 :                                         pos++;
     442             :                                 } else {
     443           0 :                                         buf[len++] = val;
     444           0 :                                         pos += 2;
     445             :                                 }
     446           0 :                                 break;
     447             :                         case '0':
     448             :                         case '1':
     449             :                         case '2':
     450             :                         case '3':
     451             :                         case '4':
     452             :                         case '5':
     453             :                         case '6':
     454             :                         case '7':
     455           1 :                                 val = *pos++ - '0';
     456           1 :                                 if (*pos >= '0' && *pos <= '7')
     457           0 :                                         val = val * 8 + (*pos++ - '0');
     458           1 :                                 if (*pos >= '0' && *pos <= '7')
     459           0 :                                         val = val * 8 + (*pos++ - '0');
     460           1 :                                 buf[len++] = val;
     461           1 :                                 break;
     462             :                         default:
     463           0 :                                 break;
     464             :                         }
     465           2 :                         break;
     466             :                 default:
     467          26 :                         buf[len++] = *pos++;
     468          26 :                         break;
     469             :                 }
     470             :         }
     471           2 :         if (maxlen > len)
     472           2 :                 buf[len] = '\0';
     473             : 
     474           2 :         return len;
     475             : }
     476             : 
     477             : 
     478             : /**
     479             :  * wpa_ssid_txt - Convert SSID to a printable string
     480             :  * @ssid: SSID (32-octet string)
     481             :  * @ssid_len: Length of ssid in octets
     482             :  * Returns: Pointer to a printable string
     483             :  *
     484             :  * This function can be used to convert SSIDs into printable form. In most
     485             :  * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
     486             :  * does not limit the used character set, so anything could be used in an SSID.
     487             :  *
     488             :  * This function uses a static buffer, so only one call can be used at the
     489             :  * time, i.e., this is not re-entrant and the returned buffer must be used
     490             :  * before calling this again.
     491             :  */
     492        3034 : const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
     493             : {
     494             :         static char ssid_txt[32 * 4 + 1];
     495             : 
     496        3034 :         if (ssid == NULL) {
     497           0 :                 ssid_txt[0] = '\0';
     498           0 :                 return ssid_txt;
     499             :         }
     500             : 
     501        3034 :         printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
     502        3034 :         return ssid_txt;
     503             : }
     504             : 
     505             : 
     506        1926 : void * __hide_aliasing_typecast(void *foo)
     507             : {
     508        1926 :         return foo;
     509             : }
     510             : 
     511             : 
     512          10 : char * wpa_config_parse_string(const char *value, size_t *len)
     513             : {
     514          10 :         if (*value == '"') {
     515             :                 const char *pos;
     516             :                 char *str;
     517           3 :                 value++;
     518           3 :                 pos = os_strrchr(value, '"');
     519           3 :                 if (pos == NULL || pos[1] != '\0')
     520           0 :                         return NULL;
     521           3 :                 *len = pos - value;
     522           3 :                 str = dup_binstr(value, *len);
     523           3 :                 if (str == NULL)
     524           0 :                         return NULL;
     525           3 :                 return str;
     526           7 :         } else if (*value == 'P' && value[1] == '"') {
     527             :                 const char *pos;
     528             :                 char *tstr, *str;
     529             :                 size_t tlen;
     530           4 :                 value += 2;
     531           4 :                 pos = os_strrchr(value, '"');
     532           4 :                 if (pos == NULL || pos[1] != '\0')
     533           2 :                         return NULL;
     534           2 :                 tlen = pos - value;
     535           2 :                 tstr = dup_binstr(value, tlen);
     536           2 :                 if (tstr == NULL)
     537           0 :                         return NULL;
     538             : 
     539           2 :                 str = os_malloc(tlen + 1);
     540           2 :                 if (str == NULL) {
     541           0 :                         os_free(tstr);
     542           0 :                         return NULL;
     543             :                 }
     544             : 
     545           2 :                 *len = printf_decode((u8 *) str, tlen + 1, tstr);
     546           2 :                 os_free(tstr);
     547             : 
     548           2 :                 return str;
     549             :         } else {
     550             :                 u8 *str;
     551           3 :                 size_t tlen, hlen = os_strlen(value);
     552           3 :                 if (hlen & 1)
     553           1 :                         return NULL;
     554           2 :                 tlen = hlen / 2;
     555           2 :                 str = os_malloc(tlen + 1);
     556           2 :                 if (str == NULL)
     557           0 :                         return NULL;
     558           2 :                 if (hexstr2bin(value, str, tlen)) {
     559           0 :                         os_free(str);
     560           0 :                         return NULL;
     561             :                 }
     562           2 :                 str[tlen] = '\0';
     563           2 :                 *len = tlen;
     564           2 :                 return (char *) str;
     565             :         }
     566             : }
     567             : 
     568             : 
     569           1 : int is_hex(const u8 *data, size_t len)
     570             : {
     571             :         size_t i;
     572             : 
     573           4 :         for (i = 0; i < len; i++) {
     574           3 :                 if (data[i] < 32 || data[i] >= 127)
     575           0 :                         return 1;
     576             :         }
     577           1 :         return 0;
     578             : }
     579             : 
     580             : 
     581           1 : int find_first_bit(u32 value)
     582             : {
     583           1 :         int pos = 0;
     584             : 
     585           2 :         while (value) {
     586           1 :                 if (value & 0x1)
     587           1 :                         return pos;
     588           0 :                 value >>= 1;
     589           0 :                 pos++;
     590             :         }
     591             : 
     592           0 :         return -1;
     593             : }
     594             : 
     595             : 
     596        3976 : size_t merge_byte_arrays(u8 *res, size_t res_len,
     597             :                          const u8 *src1, size_t src1_len,
     598             :                          const u8 *src2, size_t src2_len)
     599             : {
     600        3976 :         size_t len = 0;
     601             : 
     602        3976 :         os_memset(res, 0, res_len);
     603             : 
     604        3976 :         if (src1) {
     605        3976 :                 if (src1_len >= res_len) {
     606           0 :                         os_memcpy(res, src1, res_len);
     607           0 :                         return res_len;
     608             :                 }
     609             : 
     610        3976 :                 os_memcpy(res, src1, src1_len);
     611        3976 :                 len += src1_len;
     612             :         }
     613             : 
     614        3976 :         if (src2) {
     615        3610 :                 if (len + src2_len >= res_len) {
     616           0 :                         os_memcpy(res + len, src2, res_len - len);
     617           0 :                         return res_len;
     618             :                 }
     619             : 
     620        3610 :                 os_memcpy(res + len, src2, src2_len);
     621        3610 :                 len += src2_len;
     622             :         }
     623             : 
     624        3976 :         return len;
     625             : }
     626             : 
     627             : 
     628        1055 : char * dup_binstr(const void *src, size_t len)
     629             : {
     630             :         char *res;
     631             : 
     632        1055 :         if (src == NULL)
     633           0 :                 return NULL;
     634        1055 :         res = os_malloc(len + 1);
     635        1055 :         if (res == NULL)
     636           0 :                 return NULL;
     637        1055 :         os_memcpy(res, src, len);
     638        1055 :         res[len] = '\0';
     639             : 
     640        1055 :         return res;
     641             : }
     642             : 
     643             : 
     644           0 : int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
     645             : {
     646           0 :         struct wpa_freq_range *freq = NULL, *n;
     647           0 :         unsigned int count = 0;
     648             :         const char *pos, *pos2, *pos3;
     649             : 
     650             :         /*
     651             :          * Comma separated list of frequency ranges.
     652             :          * For example: 2412-2432,2462,5000-6000
     653             :          */
     654           0 :         pos = value;
     655           0 :         while (pos && pos[0]) {
     656           0 :                 n = os_realloc_array(freq, count + 1,
     657             :                                      sizeof(struct wpa_freq_range));
     658           0 :                 if (n == NULL) {
     659           0 :                         os_free(freq);
     660           0 :                         return -1;
     661             :                 }
     662           0 :                 freq = n;
     663           0 :                 freq[count].min = atoi(pos);
     664           0 :                 pos2 = os_strchr(pos, '-');
     665           0 :                 pos3 = os_strchr(pos, ',');
     666           0 :                 if (pos2 && (!pos3 || pos2 < pos3)) {
     667           0 :                         pos2++;
     668           0 :                         freq[count].max = atoi(pos2);
     669             :                 } else
     670           0 :                         freq[count].max = freq[count].min;
     671           0 :                 pos = pos3;
     672           0 :                 if (pos)
     673           0 :                         pos++;
     674           0 :                 count++;
     675             :         }
     676             : 
     677           0 :         os_free(res->range);
     678           0 :         res->range = freq;
     679           0 :         res->num = count;
     680             : 
     681           0 :         return 0;
     682             : }
     683             : 
     684             : 
     685           0 : int freq_range_list_includes(const struct wpa_freq_range_list *list,
     686             :                              unsigned int freq)
     687             : {
     688             :         unsigned int i;
     689             : 
     690           0 :         if (list == NULL)
     691           0 :                 return 0;
     692             : 
     693           0 :         for (i = 0; i < list->num; i++) {
     694           0 :                 if (freq >= list->range[i].min && freq <= list->range[i].max)
     695           0 :                         return 1;
     696             :         }
     697             : 
     698           0 :         return 0;
     699             : }
     700             : 
     701             : 
     702           0 : char * freq_range_list_str(const struct wpa_freq_range_list *list)
     703             : {
     704             :         char *buf, *pos, *end;
     705             :         size_t maxlen;
     706             :         unsigned int i;
     707             :         int res;
     708             : 
     709           0 :         if (list->num == 0)
     710           0 :                 return NULL;
     711             : 
     712           0 :         maxlen = list->num * 30;
     713           0 :         buf = os_malloc(maxlen);
     714           0 :         if (buf == NULL)
     715           0 :                 return NULL;
     716           0 :         pos = buf;
     717           0 :         end = buf + maxlen;
     718             : 
     719           0 :         for (i = 0; i < list->num; i++) {
     720           0 :                 struct wpa_freq_range *range = &list->range[i];
     721             : 
     722           0 :                 if (range->min == range->max)
     723           0 :                         res = os_snprintf(pos, end - pos, "%s%u",
     724             :                                           i == 0 ? "" : ",", range->min);
     725             :                 else
     726           0 :                         res = os_snprintf(pos, end - pos, "%s%u-%u",
     727             :                                           i == 0 ? "" : ",",
     728             :                                           range->min, range->max);
     729           0 :                 if (res < 0 || res > end - pos) {
     730           0 :                         os_free(buf);
     731           0 :                         return NULL;
     732             :                 }
     733           0 :                 pos += res;
     734             :         }
     735             : 
     736           0 :         return buf;
     737             : }
     738             : 
     739             : 
     740           0 : int int_array_len(const int *a)
     741             : {
     742             :         int i;
     743           0 :         for (i = 0; a && a[i]; i++)
     744             :                 ;
     745           0 :         return i;
     746             : }
     747             : 
     748             : 
     749           0 : void int_array_concat(int **res, const int *a)
     750             : {
     751             :         int reslen, alen, i;
     752             :         int *n;
     753             : 
     754           0 :         reslen = int_array_len(*res);
     755           0 :         alen = int_array_len(a);
     756             : 
     757           0 :         n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
     758           0 :         if (n == NULL) {
     759           0 :                 os_free(*res);
     760           0 :                 *res = NULL;
     761           0 :                 return;
     762             :         }
     763           0 :         for (i = 0; i <= alen; i++)
     764           0 :                 n[reslen + i] = a[i];
     765           0 :         *res = n;
     766             : }
     767             : 
     768             : 
     769           0 : static int freq_cmp(const void *a, const void *b)
     770             : {
     771           0 :         int _a = *(int *) a;
     772           0 :         int _b = *(int *) b;
     773             : 
     774           0 :         if (_a == 0)
     775           0 :                 return 1;
     776           0 :         if (_b == 0)
     777           0 :                 return -1;
     778           0 :         return _a - _b;
     779             : }
     780             : 
     781             : 
     782           0 : void int_array_sort_unique(int *a)
     783             : {
     784             :         int alen;
     785             :         int i, j;
     786             : 
     787           0 :         if (a == NULL)
     788           0 :                 return;
     789             : 
     790           0 :         alen = int_array_len(a);
     791           0 :         qsort(a, alen, sizeof(int), freq_cmp);
     792             : 
     793           0 :         i = 0;
     794           0 :         j = 1;
     795           0 :         while (a[i] && a[j]) {
     796           0 :                 if (a[i] == a[j]) {
     797           0 :                         j++;
     798           0 :                         continue;
     799             :                 }
     800           0 :                 a[++i] = a[j++];
     801             :         }
     802           0 :         if (a[i])
     803           0 :                 i++;
     804           0 :         a[i] = 0;
     805             : }
     806             : 
     807             : 
     808           0 : void int_array_add_unique(int **res, int a)
     809             : {
     810             :         int reslen;
     811             :         int *n;
     812             : 
     813           0 :         for (reslen = 0; *res && (*res)[reslen]; reslen++) {
     814           0 :                 if ((*res)[reslen] == a)
     815           0 :                         return; /* already in the list */
     816             :         }
     817             : 
     818           0 :         n = os_realloc_array(*res, reslen + 2, sizeof(int));
     819           0 :         if (n == NULL) {
     820           0 :                 os_free(*res);
     821           0 :                 *res = NULL;
     822           0 :                 return;
     823             :         }
     824             : 
     825           0 :         n[reslen] = a;
     826           0 :         n[reslen + 1] = 0;
     827             : 
     828           0 :         *res = n;
     829             : }
     830             : 
     831             : 
     832         658 : void str_clear_free(char *str)
     833             : {
     834         658 :         if (str) {
     835         193 :                 size_t len = os_strlen(str);
     836         193 :                 os_memset(str, 0, len);
     837         193 :                 os_free(str);
     838             :         }
     839         658 : }
     840             : 
     841             : 
     842        9072 : void bin_clear_free(void *bin, size_t len)
     843             : {
     844        9072 :         if (bin) {
     845        1864 :                 os_memset(bin, 0, len);
     846        1864 :                 os_free(bin);
     847             :         }
     848        9072 : }
     849             : 
     850             : 
     851           0 : int random_mac_addr(u8 *addr)
     852             : {
     853           0 :         if (os_get_random(addr, ETH_ALEN) < 0)
     854           0 :                 return -1;
     855           0 :         addr[0] &= 0xfe; /* unicast */
     856           0 :         addr[0] |= 0x02; /* locally administered */
     857           0 :         return 0;
     858             : }
     859             : 
     860             : 
     861           0 : int random_mac_addr_keep_oui(u8 *addr)
     862             : {
     863           0 :         if (os_get_random(addr + 3, 3) < 0)
     864           0 :                 return -1;
     865           0 :         addr[0] &= 0xfe; /* unicast */
     866           0 :         addr[0] |= 0x02; /* locally administered */
     867           0 :         return 0;
     868             : }

Generated by: LCOV version 1.10