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 1443382998 Lines: 478 492 97.2 %
Date: 2015-09-27 Functions: 41 41 100.0 %

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

Generated by: LCOV version 1.10