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 1422976643 Lines: 419 472 88.8 %
Date: 2015-02-03 Functions: 38 38 100.0 %

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

Generated by: LCOV version 1.10