common.c 20 KB

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