common.c 22 KB

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