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 1388240082 Lines: 192 365 52.6 %
Date: 2013-12-28 Functions: 22 28 78.6 %
Branches: 103 224 46.0 %

           Branch data     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                 :      32835 : static int hex2num(char c)
      15                 :            : {
      16 [ +  - ][ +  + ]:      32835 :         if (c >= '0' && c <= '9')
      17                 :      28131 :                 return c - '0';
      18 [ +  + ][ +  - ]:       4704 :         if (c >= 'a' && c <= 'f')
      19                 :       4036 :                 return c - 'a' + 10;
      20 [ +  + ][ +  - ]:        668 :         if (c >= 'A' && c <= 'F')
      21                 :        667 :                 return c - 'A' + 10;
      22                 :      32835 :         return -1;
      23                 :            : }
      24                 :            : 
      25                 :            : 
      26                 :       8834 : int hex2byte(const char *hex)
      27                 :            : {
      28                 :            :         int a, b;
      29                 :       8834 :         a = hex2num(*hex++);
      30         [ +  + ]:       8834 :         if (a < 0)
      31                 :          1 :                 return -1;
      32                 :       8833 :         b = hex2num(*hex++);
      33         [ -  + ]:       8833 :         if (b < 0)
      34                 :          0 :                 return -1;
      35                 :       8834 :         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                 :        633 : int hwaddr_aton(const char *txt, u8 *addr)
      46                 :            : {
      47                 :            :         int i;
      48                 :            : 
      49         [ +  + ]:       4431 :         for (i = 0; i < 6; i++) {
      50                 :            :                 int a, b;
      51                 :            : 
      52                 :       3798 :                 a = hex2num(*txt++);
      53         [ -  + ]:       3798 :                 if (a < 0)
      54                 :          0 :                         return -1;
      55                 :       3798 :                 b = hex2num(*txt++);
      56         [ -  + ]:       3798 :                 if (b < 0)
      57                 :          0 :                         return -1;
      58                 :       3798 :                 *addr++ = (a << 4) | b;
      59 [ +  + ][ -  + ]:       3798 :                 if (i < 5 && *txt++ != ':')
      60                 :          0 :                         return -1;
      61                 :            :         }
      62                 :            : 
      63                 :        633 :         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                 :        631 : int hwaddr_aton2(const char *txt, u8 *addr)
      98                 :            : {
      99                 :            :         int i;
     100                 :        631 :         const char *pos = txt;
     101                 :            : 
     102         [ +  + ]:       4417 :         for (i = 0; i < 6; i++) {
     103                 :            :                 int a, b;
     104                 :            : 
     105 [ +  + ][ -  + ]:       6931 :                 while (*pos == ':' || *pos == '.' || *pos == '-')
                 [ -  + ]
     106                 :       3145 :                         pos++;
     107                 :            : 
     108                 :       3786 :                 a = hex2num(*pos++);
     109         [ -  + ]:       3786 :                 if (a < 0)
     110                 :          0 :                         return -1;
     111                 :       3786 :                 b = hex2num(*pos++);
     112         [ -  + ]:       3786 :                 if (b < 0)
     113                 :          0 :                         return -1;
     114                 :       3786 :                 *addr++ = (a << 4) | b;
     115                 :            :         }
     116                 :            : 
     117                 :        631 :         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                 :        959 : int hexstr2bin(const char *hex, u8 *buf, size_t len)
     130                 :            : {
     131                 :            :         size_t i;
     132                 :            :         int a;
     133                 :        959 :         const char *ipos = hex;
     134                 :        959 :         u8 *opos = buf;
     135                 :            : 
     136         [ +  + ]:       9792 :         for (i = 0; i < len; i++) {
     137                 :       8834 :                 a = hex2byte(ipos);
     138         [ +  + ]:       8834 :                 if (a < 0)
     139                 :          1 :                         return -1;
     140                 :       8833 :                 *opos++ = a;
     141                 :       8833 :                 ipos += 2;
     142                 :            :         }
     143                 :        959 :         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                 :        931 : void inc_byte_array(u8 *counter, size_t len)
     157                 :            : {
     158                 :        931 :         int pos = len - 1;
     159         [ +  - ]:        933 :         while (pos >= 0) {
     160                 :        933 :                 counter[pos]++;
     161         [ +  + ]:        933 :                 if (counter[pos] != 0)
     162                 :        931 :                         break;
     163                 :          2 :                 pos--;
     164                 :            :         }
     165                 :        931 : }
     166                 :            : 
     167                 :            : 
     168                 :        796 : 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                 :        796 :         os_get_time(&now);
     176                 :        796 :         sec = now.sec + 2208988800U; /* Epoch to 1900 */
     177                 :            :         /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
     178                 :        796 :         usec = now.usec;
     179                 :        796 :         usec = 4295 * usec - (usec >> 5) - (usec >> 9);
     180                 :        796 :         tmp = host_to_be32(sec);
     181                 :        796 :         os_memcpy(buf, (u8 *) &tmp, 4);
     182                 :        796 :         tmp = host_to_be32(usec);
     183                 :        796 :         os_memcpy(buf + 4, (u8 *) &tmp, 4);
     184                 :        796 : }
     185                 :            : 
     186                 :            : 
     187                 :        607 : 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                 :        607 :         char *pos = buf, *end = buf + buf_size;
     192                 :            :         int ret;
     193         [ -  + ]:        607 :         if (buf_size == 0)
     194                 :          0 :                 return 0;
     195         [ +  + ]:      13235 :         for (i = 0; i < len; i++) {
     196         [ +  + ]:      12628 :                 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
     197                 :      12628 :                                   data[i]);
     198 [ +  - ][ -  + ]:      12628 :                 if (ret < 0 || ret >= end - pos) {
     199                 :          0 :                         end[-1] = '\0';
     200                 :          0 :                         return pos - buf;
     201                 :            :                 }
     202                 :      12628 :                 pos += ret;
     203                 :            :         }
     204                 :        607 :         end[-1] = '\0';
     205                 :        607 :         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                 :        567 : int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
     217                 :            : {
     218                 :        567 :         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                 :         40 : int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
     231                 :            :                                size_t len)
     232                 :            : {
     233                 :         40 :         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                 :       6583 : void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
     348                 :            : {
     349                 :       6583 :         char *end = txt + maxlen;
     350                 :            :         size_t i;
     351                 :            : 
     352         [ +  + ]:      71208 :         for (i = 0; i < len; i++) {
     353         [ -  + ]:      64625 :                 if (txt + 4 > end)
     354                 :          0 :                         break;
     355                 :            : 
     356   [ -  -  -  -  :      64625 :                 switch (data[i]) {
                -  -  + ]
     357                 :            :                 case '\"':
     358                 :          0 :                         *txt++ = '\\';
     359                 :          0 :                         *txt++ = '\"';
     360                 :          0 :                         break;
     361                 :            :                 case '\\':
     362                 :          0 :                         *txt++ = '\\';
     363                 :          0 :                         *txt++ = '\\';
     364                 :          0 :                         break;
     365                 :            :                 case '\e':
     366                 :          0 :                         *txt++ = '\\';
     367                 :          0 :                         *txt++ = 'e';
     368                 :          0 :                         break;
     369                 :            :                 case '\n':
     370                 :          0 :                         *txt++ = '\\';
     371                 :          0 :                         *txt++ = 'n';
     372                 :          0 :                         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 [ +  - ][ +  - ]:      64625 :                         if (data[i] >= 32 && data[i] <= 127) {
     383                 :      64625 :                                 *txt++ = data[i];
     384                 :            :                         } else {
     385                 :          0 :                                 txt += os_snprintf(txt, end - txt, "\\x%02x",
     386                 :          0 :                                                    data[i]);
     387                 :            :                         }
     388                 :      64625 :                         break;
     389                 :            :                 }
     390                 :            :         }
     391                 :            : 
     392                 :       6583 :         *txt = '\0';
     393                 :       6583 : }
     394                 :            : 
     395                 :            : 
     396                 :          0 : size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
     397                 :            : {
     398                 :          0 :         const char *pos = str;
     399                 :          0 :         size_t len = 0;
     400                 :            :         int val;
     401                 :            : 
     402         [ #  # ]:          0 :         while (*pos) {
     403         [ #  # ]:          0 :                 if (len + 1 >= maxlen)
     404                 :          0 :                         break;
     405         [ #  # ]:          0 :                 switch (*pos) {
     406                 :            :                 case '\\':
     407                 :          0 :                         pos++;
     408   [ #  #  #  #  :          0 :                         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                 :          0 :                                 buf[len++] = '\n';
     419                 :          0 :                                 pos++;
     420                 :          0 :                                 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++] = '\e';
     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                 :          0 :                                 val = *pos++ - '0';
     456 [ #  # ][ #  # ]:          0 :                                 if (*pos >= '0' && *pos <= '7')
     457                 :          0 :                                         val = val * 8 + (*pos++ - '0');
     458 [ #  # ][ #  # ]:          0 :                                 if (*pos >= '0' && *pos <= '7')
     459                 :          0 :                                         val = val * 8 + (*pos++ - '0');
     460                 :          0 :                                 buf[len++] = val;
     461                 :          0 :                                 break;
     462                 :            :                         default:
     463                 :          0 :                                 break;
     464                 :            :                         }
     465                 :          0 :                         break;
     466                 :            :                 default:
     467                 :          0 :                         buf[len++] = *pos++;
     468                 :          0 :                         break;
     469                 :            :                 }
     470                 :            :         }
     471         [ #  # ]:          0 :         if (maxlen > len)
     472                 :          0 :                 buf[len] = '\0';
     473                 :            : 
     474                 :          0 :         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                 :       6583 : const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
     493                 :            : {
     494                 :            :         static char ssid_txt[32 * 4 + 1];
     495                 :            : 
     496         [ -  + ]:       6583 :         if (ssid == NULL) {
     497                 :          0 :                 ssid_txt[0] = '\0';
     498                 :          0 :                 return ssid_txt;
     499                 :            :         }
     500                 :            : 
     501                 :       6583 :         printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
     502                 :       6583 :         return ssid_txt;
     503                 :            : }
     504                 :            : 
     505                 :            : 
     506                 :       2986 : void * __hide_aliasing_typecast(void *foo)
     507                 :            : {
     508                 :       2986 :         return foo;
     509                 :            : }
     510                 :            : 
     511                 :            : 
     512                 :        644 : char * wpa_config_parse_string(const char *value, size_t *len)
     513                 :            : {
     514         [ +  + ]:        644 :         if (*value == '"') {
     515                 :            :                 const char *pos;
     516                 :            :                 char *str;
     517                 :        630 :                 value++;
     518                 :        630 :                 pos = os_strrchr(value, '"');
     519 [ +  - ][ -  + ]:        630 :                 if (pos == NULL || pos[1] != '\0')
     520                 :          0 :                         return NULL;
     521                 :        630 :                 *len = pos - value;
     522                 :        630 :                 str = dup_binstr(value, *len);
     523         [ -  + ]:        630 :                 if (str == NULL)
     524                 :          0 :                         return NULL;
     525                 :        630 :                 return str;
     526 [ -  + ][ #  # ]:         14 :         } else if (*value == 'P' && value[1] == '"') {
     527                 :            :                 const char *pos;
     528                 :            :                 char *tstr, *str;
     529                 :            :                 size_t tlen;
     530                 :          0 :                 value += 2;
     531                 :          0 :                 pos = os_strrchr(value, '"');
     532 [ #  # ][ #  # ]:          0 :                 if (pos == NULL || pos[1] != '\0')
     533                 :          0 :                         return NULL;
     534                 :          0 :                 tlen = pos - value;
     535                 :          0 :                 tstr = dup_binstr(value, tlen);
     536         [ #  # ]:          0 :                 if (tstr == NULL)
     537                 :          0 :                         return NULL;
     538                 :            : 
     539                 :          0 :                 str = os_malloc(tlen + 1);
     540         [ #  # ]:          0 :                 if (str == NULL) {
     541                 :          0 :                         os_free(tstr);
     542                 :          0 :                         return NULL;
     543                 :            :                 }
     544                 :            : 
     545                 :          0 :                 *len = printf_decode((u8 *) str, tlen + 1, tstr);
     546                 :          0 :                 os_free(tstr);
     547                 :            : 
     548                 :          0 :                 return str;
     549                 :            :         } else {
     550                 :            :                 u8 *str;
     551                 :         14 :                 size_t tlen, hlen = os_strlen(value);
     552         [ -  + ]:         14 :                 if (hlen & 1)
     553                 :          0 :                         return NULL;
     554                 :         14 :                 tlen = hlen / 2;
     555                 :         14 :                 str = os_malloc(tlen + 1);
     556         [ -  + ]:         14 :                 if (str == NULL)
     557                 :          0 :                         return NULL;
     558         [ -  + ]:         14 :                 if (hexstr2bin(value, str, tlen)) {
     559                 :          0 :                         os_free(str);
     560                 :          0 :                         return NULL;
     561                 :            :                 }
     562                 :         14 :                 str[tlen] = '\0';
     563                 :         14 :                 *len = tlen;
     564                 :        644 :                 return (char *) str;
     565                 :            :         }
     566                 :            : }
     567                 :            : 
     568                 :            : 
     569                 :          0 : int is_hex(const u8 *data, size_t len)
     570                 :            : {
     571                 :            :         size_t i;
     572                 :            : 
     573         [ #  # ]:          0 :         for (i = 0; i < len; i++) {
     574 [ #  # ][ #  # ]:          0 :                 if (data[i] < 32 || data[i] >= 127)
     575                 :          0 :                         return 1;
     576                 :            :         }
     577                 :          0 :         return 0;
     578                 :            : }
     579                 :            : 
     580                 :            : 
     581                 :          0 : int find_first_bit(u32 value)
     582                 :            : {
     583                 :          0 :         int pos = 0;
     584                 :            : 
     585         [ #  # ]:          0 :         while (value) {
     586         [ #  # ]:          0 :                 if (value & 0x1)
     587                 :          0 :                         return pos;
     588                 :          0 :                 value >>= 1;
     589                 :          0 :                 pos++;
     590                 :            :         }
     591                 :            : 
     592                 :          0 :         return -1;
     593                 :            : }
     594                 :            : 
     595                 :            : 
     596                 :       1728 : 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                 :       1728 :         size_t len = 0;
     601                 :            : 
     602                 :       1728 :         os_memset(res, 0, res_len);
     603                 :            : 
     604         [ +  - ]:       1728 :         if (src1) {
     605         [ -  + ]:       1728 :                 if (src1_len >= res_len) {
     606                 :          0 :                         os_memcpy(res, src1, res_len);
     607                 :          0 :                         return res_len;
     608                 :            :                 }
     609                 :            : 
     610                 :       1728 :                 os_memcpy(res, src1, src1_len);
     611                 :       1728 :                 len += src1_len;
     612                 :            :         }
     613                 :            : 
     614         [ +  + ]:       1728 :         if (src2) {
     615         [ -  + ]:       1442 :                 if (len + src2_len >= res_len) {
     616                 :          0 :                         os_memcpy(res + len, src2, res_len - len);
     617                 :          0 :                         return res_len;
     618                 :            :                 }
     619                 :            : 
     620                 :       1442 :                 os_memcpy(res + len, src2, src2_len);
     621                 :       1442 :                 len += src2_len;
     622                 :            :         }
     623                 :            : 
     624                 :       1728 :         return len;
     625                 :            : }
     626                 :            : 
     627                 :            : 
     628                 :       1660 : char * dup_binstr(const void *src, size_t len)
     629                 :            : {
     630                 :            :         char *res;
     631                 :            : 
     632         [ -  + ]:       1660 :         if (src == NULL)
     633                 :          0 :                 return NULL;
     634                 :       1660 :         res = os_malloc(len + 1);
     635         [ -  + ]:       1660 :         if (res == NULL)
     636                 :          0 :                 return NULL;
     637                 :       1660 :         os_memcpy(res, src, len);
     638                 :       1660 :         res[len] = '\0';
     639                 :            : 
     640                 :       1660 :         return res;
     641                 :            : }
     642                 :            : 
     643                 :            : 
     644                 :        625 : int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
     645                 :            : {
     646                 :        625 :         struct wpa_freq_range *freq = NULL, *n;
     647                 :        625 :         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                 :        625 :         pos = value;
     655 [ +  + ][ +  + ]:        651 :         while (pos && pos[0]) {
     656                 :         26 :                 n = os_realloc_array(freq, count + 1,
     657                 :            :                                      sizeof(struct wpa_freq_range));
     658         [ -  + ]:         26 :                 if (n == NULL) {
     659                 :          0 :                         os_free(freq);
     660                 :          0 :                         return -1;
     661                 :            :                 }
     662                 :         26 :                 freq = n;
     663                 :         26 :                 freq[count].min = atoi(pos);
     664                 :         26 :                 pos2 = os_strchr(pos, '-');
     665                 :         26 :                 pos3 = os_strchr(pos, ',');
     666 [ +  + ][ +  + ]:         26 :                 if (pos2 && (!pos3 || pos2 < pos3)) {
                 [ +  + ]
     667                 :          5 :                         pos2++;
     668                 :          5 :                         freq[count].max = atoi(pos2);
     669                 :            :                 } else
     670                 :         21 :                         freq[count].max = freq[count].min;
     671                 :         26 :                 pos = pos3;
     672         [ +  + ]:         26 :                 if (pos)
     673                 :          4 :                         pos++;
     674                 :         26 :                 count++;
     675                 :            :         }
     676                 :            : 
     677                 :        625 :         os_free(res->range);
     678                 :        625 :         res->range = freq;
     679                 :        625 :         res->num = count;
     680                 :            : 
     681                 :        625 :         return 0;
     682                 :            : }
     683                 :            : 
     684                 :            : 
     685                 :      66415 : int freq_range_list_includes(const struct wpa_freq_range_list *list,
     686                 :            :                              unsigned int freq)
     687                 :            : {
     688                 :            :         unsigned int i;
     689                 :            : 
     690         [ -  + ]:      66415 :         if (list == NULL)
     691                 :          0 :                 return 0;
     692                 :            : 
     693         [ +  + ]:      67202 :         for (i = 0; i < list->num; i++) {
     694 [ +  + ][ +  + ]:        881 :                 if (freq >= list->range[i].min && freq <= list->range[i].max)
     695                 :         94 :                         return 1;
     696                 :            :         }
     697                 :            : 
     698                 :      66415 :         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                 :        519 : int int_array_len(const int *a)
     741                 :            : {
     742                 :            :         int i;
     743 [ +  + ][ +  + ]:        865 :         for (i = 0; a && a[i]; i++)
     744                 :            :                 ;
     745                 :        519 :         return i;
     746                 :            : }
     747                 :            : 
     748                 :            : 
     749                 :        173 : void int_array_concat(int **res, const int *a)
     750                 :            : {
     751                 :            :         int reslen, alen, i;
     752                 :            :         int *n;
     753                 :            : 
     754                 :        173 :         reslen = int_array_len(*res);
     755                 :        173 :         alen = int_array_len(a);
     756                 :            : 
     757                 :        173 :         n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
     758         [ -  + ]:        173 :         if (n == NULL) {
     759                 :          0 :                 os_free(*res);
     760                 :          0 :                 *res = NULL;
     761                 :        173 :                 return;
     762                 :            :         }
     763         [ +  + ]:        519 :         for (i = 0; i <= alen; i++)
     764                 :        346 :                 n[reslen + i] = a[i];
     765                 :        173 :         *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                 :        308 : void int_array_sort_unique(int *a)
     783                 :            : {
     784                 :            :         int alen;
     785                 :            :         int i, j;
     786                 :            : 
     787         [ +  + ]:        308 :         if (a == NULL)
     788                 :        308 :                 return;
     789                 :            : 
     790                 :        173 :         alen = int_array_len(a);
     791                 :        173 :         qsort(a, alen, sizeof(int), freq_cmp);
     792                 :            : 
     793                 :        173 :         i = 0;
     794                 :        173 :         j = 1;
     795 [ +  - ][ -  + ]:        173 :         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         [ +  - ]:        173 :         if (a[i])
     803                 :        173 :                 i++;
     804                 :        173 :         a[i] = 0;
     805                 :            : }
     806                 :            : 
     807                 :            : 
     808                 :         82 : void int_array_add_unique(int **res, int a)
     809                 :            : {
     810                 :            :         int reslen;
     811                 :            :         int *n;
     812                 :            : 
     813 [ +  + ][ +  + ]:        324 :         for (reslen = 0; *res && (*res)[reslen]; reslen++) {
     814         [ +  + ]:        282 :                 if ((*res)[reslen] == a)
     815                 :         40 :                         return; /* already in the list */
     816                 :            :         }
     817                 :            : 
     818                 :         42 :         n = os_realloc_array(*res, reslen + 2, sizeof(int));
     819         [ -  + ]:         42 :         if (n == NULL) {
     820                 :          0 :                 os_free(*res);
     821                 :          0 :                 *res = NULL;
     822                 :          0 :                 return;
     823                 :            :         }
     824                 :            : 
     825                 :         42 :         n[reslen] = a;
     826                 :         42 :         n[reslen + 1] = 0;
     827                 :            : 
     828                 :         82 :         *res = n;
     829                 :            : }

Generated by: LCOV version 1.9