wpa_debug.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /*
  2. * wpa_supplicant/hostapd / Debug prints
  3. * Copyright (c) 2002-2013, 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. #ifdef CONFIG_DEBUG_SYSLOG
  11. #include <syslog.h>
  12. static int wpa_debug_syslog = 0;
  13. #endif /* CONFIG_DEBUG_SYSLOG */
  14. #ifdef CONFIG_DEBUG_LINUX_TRACING
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20. static FILE *wpa_debug_tracing_file = NULL;
  21. #define WPAS_TRACE_PFX "wpas <%d>: "
  22. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  23. int wpa_debug_level = MSG_INFO;
  24. int wpa_debug_show_keys = 0;
  25. int wpa_debug_timestamp = 0;
  26. #ifdef CONFIG_ANDROID_LOG
  27. #include <android/log.h>
  28. #ifndef ANDROID_LOG_NAME
  29. #define ANDROID_LOG_NAME "wpa_supplicant"
  30. #endif /* ANDROID_LOG_NAME */
  31. static int wpa_to_android_level(int level)
  32. {
  33. if (level == MSG_ERROR)
  34. return ANDROID_LOG_ERROR;
  35. if (level == MSG_WARNING)
  36. return ANDROID_LOG_WARN;
  37. if (level == MSG_INFO)
  38. return ANDROID_LOG_INFO;
  39. return ANDROID_LOG_DEBUG;
  40. }
  41. #endif /* CONFIG_ANDROID_LOG */
  42. #ifndef CONFIG_NO_STDOUT_DEBUG
  43. #ifdef CONFIG_DEBUG_FILE
  44. static FILE *out_file = NULL;
  45. #endif /* CONFIG_DEBUG_FILE */
  46. void wpa_debug_print_timestamp(void)
  47. {
  48. #ifndef CONFIG_ANDROID_LOG
  49. struct os_time tv;
  50. if (!wpa_debug_timestamp)
  51. return;
  52. os_get_time(&tv);
  53. #ifdef CONFIG_DEBUG_FILE
  54. if (out_file) {
  55. fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
  56. (unsigned int) tv.usec);
  57. } else
  58. #endif /* CONFIG_DEBUG_FILE */
  59. printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
  60. #endif /* CONFIG_ANDROID_LOG */
  61. }
  62. #ifdef CONFIG_DEBUG_SYSLOG
  63. #ifndef LOG_HOSTAPD
  64. #define LOG_HOSTAPD LOG_DAEMON
  65. #endif /* LOG_HOSTAPD */
  66. void wpa_debug_open_syslog(void)
  67. {
  68. openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
  69. wpa_debug_syslog++;
  70. }
  71. void wpa_debug_close_syslog(void)
  72. {
  73. if (wpa_debug_syslog)
  74. closelog();
  75. }
  76. static int syslog_priority(int level)
  77. {
  78. switch (level) {
  79. case MSG_MSGDUMP:
  80. case MSG_DEBUG:
  81. return LOG_DEBUG;
  82. case MSG_INFO:
  83. return LOG_NOTICE;
  84. case MSG_WARNING:
  85. return LOG_WARNING;
  86. case MSG_ERROR:
  87. return LOG_ERR;
  88. }
  89. return LOG_INFO;
  90. }
  91. #endif /* CONFIG_DEBUG_SYSLOG */
  92. #ifdef CONFIG_DEBUG_LINUX_TRACING
  93. int wpa_debug_open_linux_tracing(void)
  94. {
  95. int mounts, trace_fd;
  96. char buf[4096] = {};
  97. ssize_t buflen;
  98. char *line, *tmp1, *path = NULL;
  99. mounts = open("/proc/mounts", O_RDONLY);
  100. if (mounts < 0) {
  101. printf("no /proc/mounts\n");
  102. return -1;
  103. }
  104. buflen = read(mounts, buf, sizeof(buf) - 1);
  105. close(mounts);
  106. if (buflen < 0) {
  107. printf("failed to read /proc/mounts\n");
  108. return -1;
  109. }
  110. line = strtok_r(buf, "\n", &tmp1);
  111. while (line) {
  112. char *tmp2, *tmp_path, *fstype;
  113. /* "<dev> <mountpoint> <fs type> ..." */
  114. strtok_r(line, " ", &tmp2);
  115. tmp_path = strtok_r(NULL, " ", &tmp2);
  116. fstype = strtok_r(NULL, " ", &tmp2);
  117. if (strcmp(fstype, "debugfs") == 0) {
  118. path = tmp_path;
  119. break;
  120. }
  121. line = strtok_r(NULL, "\n", &tmp1);
  122. }
  123. if (path == NULL) {
  124. printf("debugfs mountpoint not found\n");
  125. return -1;
  126. }
  127. snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
  128. trace_fd = open(buf, O_WRONLY);
  129. if (trace_fd < 0) {
  130. printf("failed to open trace_marker file\n");
  131. return -1;
  132. }
  133. wpa_debug_tracing_file = fdopen(trace_fd, "w");
  134. if (wpa_debug_tracing_file == NULL) {
  135. close(trace_fd);
  136. printf("failed to fdopen()\n");
  137. return -1;
  138. }
  139. return 0;
  140. }
  141. void wpa_debug_close_linux_tracing(void)
  142. {
  143. if (wpa_debug_tracing_file == NULL)
  144. return;
  145. fclose(wpa_debug_tracing_file);
  146. wpa_debug_tracing_file = NULL;
  147. }
  148. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  149. /**
  150. * wpa_printf - conditional printf
  151. * @level: priority level (MSG_*) of the message
  152. * @fmt: printf format string, followed by optional arguments
  153. *
  154. * This function is used to print conditional debugging and error messages. The
  155. * output may be directed to stdout, stderr, and/or syslog based on
  156. * configuration.
  157. *
  158. * Note: New line '\n' is added to the end of the text when printing to stdout.
  159. */
  160. void wpa_printf(int level, const char *fmt, ...)
  161. {
  162. va_list ap;
  163. va_start(ap, fmt);
  164. if (level >= wpa_debug_level) {
  165. #ifdef CONFIG_ANDROID_LOG
  166. __android_log_vprint(wpa_to_android_level(level),
  167. ANDROID_LOG_NAME, fmt, ap);
  168. #else /* CONFIG_ANDROID_LOG */
  169. #ifdef CONFIG_DEBUG_SYSLOG
  170. if (wpa_debug_syslog) {
  171. vsyslog(syslog_priority(level), fmt, ap);
  172. } else {
  173. #endif /* CONFIG_DEBUG_SYSLOG */
  174. wpa_debug_print_timestamp();
  175. #ifdef CONFIG_DEBUG_FILE
  176. if (out_file) {
  177. vfprintf(out_file, fmt, ap);
  178. fprintf(out_file, "\n");
  179. } else {
  180. #endif /* CONFIG_DEBUG_FILE */
  181. vprintf(fmt, ap);
  182. printf("\n");
  183. #ifdef CONFIG_DEBUG_FILE
  184. }
  185. #endif /* CONFIG_DEBUG_FILE */
  186. #ifdef CONFIG_DEBUG_SYSLOG
  187. }
  188. #endif /* CONFIG_DEBUG_SYSLOG */
  189. #endif /* CONFIG_ANDROID_LOG */
  190. }
  191. va_end(ap);
  192. #ifdef CONFIG_DEBUG_LINUX_TRACING
  193. if (wpa_debug_tracing_file != NULL) {
  194. va_start(ap, fmt);
  195. fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
  196. vfprintf(wpa_debug_tracing_file, fmt, ap);
  197. fprintf(wpa_debug_tracing_file, "\n");
  198. fflush(wpa_debug_tracing_file);
  199. va_end(ap);
  200. }
  201. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  202. }
  203. static void _wpa_hexdump(int level, const char *title, const u8 *buf,
  204. size_t len, int show)
  205. {
  206. size_t i;
  207. #ifdef CONFIG_DEBUG_LINUX_TRACING
  208. if (wpa_debug_tracing_file != NULL) {
  209. fprintf(wpa_debug_tracing_file,
  210. WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
  211. level, title, (unsigned long) len);
  212. if (buf == NULL) {
  213. fprintf(wpa_debug_tracing_file, " [NULL]\n");
  214. } else if (!show) {
  215. fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
  216. } else {
  217. for (i = 0; i < len; i++)
  218. fprintf(wpa_debug_tracing_file,
  219. " %02x", buf[i]);
  220. }
  221. fflush(wpa_debug_tracing_file);
  222. }
  223. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  224. if (level < wpa_debug_level)
  225. return;
  226. #ifdef CONFIG_ANDROID_LOG
  227. {
  228. const char *display;
  229. char *strbuf = NULL;
  230. size_t slen = len;
  231. if (buf == NULL) {
  232. display = " [NULL]";
  233. } else if (len == 0) {
  234. display = "";
  235. } else if (show && len) {
  236. /* Limit debug message length for Android log */
  237. if (slen > 32)
  238. slen = 32;
  239. strbuf = os_malloc(1 + 3 * slen);
  240. if (strbuf == NULL) {
  241. wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
  242. "allocate message buffer");
  243. return;
  244. }
  245. for (i = 0; i < slen; i++)
  246. os_snprintf(&strbuf[i * 3], 4, " %02x",
  247. buf[i]);
  248. display = strbuf;
  249. } else {
  250. display = " [REMOVED]";
  251. }
  252. __android_log_print(wpa_to_android_level(level),
  253. ANDROID_LOG_NAME,
  254. "%s - hexdump(len=%lu):%s%s",
  255. title, (long unsigned int) len, display,
  256. len > slen ? " ..." : "");
  257. bin_clear_free(strbuf, 1 + 3 * slen);
  258. return;
  259. }
  260. #else /* CONFIG_ANDROID_LOG */
  261. #ifdef CONFIG_DEBUG_SYSLOG
  262. if (wpa_debug_syslog) {
  263. const char *display;
  264. char *strbuf = NULL;
  265. if (buf == NULL) {
  266. display = " [NULL]";
  267. } else if (len == 0) {
  268. display = "";
  269. } else if (show && len) {
  270. strbuf = os_malloc(1 + 3 * len);
  271. if (strbuf == NULL) {
  272. wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
  273. "allocate message buffer");
  274. return;
  275. }
  276. for (i = 0; i < len; i++)
  277. os_snprintf(&strbuf[i * 3], 4, " %02x",
  278. buf[i]);
  279. display = strbuf;
  280. } else {
  281. display = " [REMOVED]";
  282. }
  283. syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
  284. title, (unsigned long) len, display);
  285. bin_clear_free(strbuf, 1 + 3 * len);
  286. return;
  287. }
  288. #endif /* CONFIG_DEBUG_SYSLOG */
  289. wpa_debug_print_timestamp();
  290. #ifdef CONFIG_DEBUG_FILE
  291. if (out_file) {
  292. fprintf(out_file, "%s - hexdump(len=%lu):",
  293. title, (unsigned long) len);
  294. if (buf == NULL) {
  295. fprintf(out_file, " [NULL]");
  296. } else if (show) {
  297. for (i = 0; i < len; i++)
  298. fprintf(out_file, " %02x", buf[i]);
  299. } else {
  300. fprintf(out_file, " [REMOVED]");
  301. }
  302. fprintf(out_file, "\n");
  303. } else {
  304. #endif /* CONFIG_DEBUG_FILE */
  305. printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
  306. if (buf == NULL) {
  307. printf(" [NULL]");
  308. } else if (show) {
  309. for (i = 0; i < len; i++)
  310. printf(" %02x", buf[i]);
  311. } else {
  312. printf(" [REMOVED]");
  313. }
  314. printf("\n");
  315. #ifdef CONFIG_DEBUG_FILE
  316. }
  317. #endif /* CONFIG_DEBUG_FILE */
  318. #endif /* CONFIG_ANDROID_LOG */
  319. }
  320. void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
  321. {
  322. _wpa_hexdump(level, title, buf, len, 1);
  323. }
  324. void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
  325. {
  326. _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
  327. }
  328. static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
  329. size_t len, int show)
  330. {
  331. size_t i, llen;
  332. const u8 *pos = buf;
  333. const size_t line_len = 16;
  334. #ifdef CONFIG_DEBUG_LINUX_TRACING
  335. if (wpa_debug_tracing_file != NULL) {
  336. fprintf(wpa_debug_tracing_file,
  337. WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
  338. level, title, (unsigned long) len);
  339. if (buf == NULL) {
  340. fprintf(wpa_debug_tracing_file, " [NULL]\n");
  341. } else if (!show) {
  342. fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
  343. } else {
  344. /* can do ascii processing in userspace */
  345. for (i = 0; i < len; i++)
  346. fprintf(wpa_debug_tracing_file,
  347. " %02x", pos[i]);
  348. }
  349. fflush(wpa_debug_tracing_file);
  350. }
  351. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  352. if (level < wpa_debug_level)
  353. return;
  354. #ifdef CONFIG_ANDROID_LOG
  355. _wpa_hexdump(level, title, buf, len, show);
  356. #else /* CONFIG_ANDROID_LOG */
  357. wpa_debug_print_timestamp();
  358. #ifdef CONFIG_DEBUG_FILE
  359. if (out_file) {
  360. if (!show) {
  361. fprintf(out_file,
  362. "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
  363. title, (unsigned long) len);
  364. return;
  365. }
  366. if (buf == NULL) {
  367. fprintf(out_file,
  368. "%s - hexdump_ascii(len=%lu): [NULL]\n",
  369. title, (unsigned long) len);
  370. return;
  371. }
  372. fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
  373. title, (unsigned long) len);
  374. while (len) {
  375. llen = len > line_len ? line_len : len;
  376. fprintf(out_file, " ");
  377. for (i = 0; i < llen; i++)
  378. fprintf(out_file, " %02x", pos[i]);
  379. for (i = llen; i < line_len; i++)
  380. fprintf(out_file, " ");
  381. fprintf(out_file, " ");
  382. for (i = 0; i < llen; i++) {
  383. if (isprint(pos[i]))
  384. fprintf(out_file, "%c", pos[i]);
  385. else
  386. fprintf(out_file, "_");
  387. }
  388. for (i = llen; i < line_len; i++)
  389. fprintf(out_file, " ");
  390. fprintf(out_file, "\n");
  391. pos += llen;
  392. len -= llen;
  393. }
  394. } else {
  395. #endif /* CONFIG_DEBUG_FILE */
  396. if (!show) {
  397. printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
  398. title, (unsigned long) len);
  399. return;
  400. }
  401. if (buf == NULL) {
  402. printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
  403. title, (unsigned long) len);
  404. return;
  405. }
  406. printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
  407. while (len) {
  408. llen = len > line_len ? line_len : len;
  409. printf(" ");
  410. for (i = 0; i < llen; i++)
  411. printf(" %02x", pos[i]);
  412. for (i = llen; i < line_len; i++)
  413. printf(" ");
  414. printf(" ");
  415. for (i = 0; i < llen; i++) {
  416. if (isprint(pos[i]))
  417. printf("%c", pos[i]);
  418. else
  419. printf("_");
  420. }
  421. for (i = llen; i < line_len; i++)
  422. printf(" ");
  423. printf("\n");
  424. pos += llen;
  425. len -= llen;
  426. }
  427. #ifdef CONFIG_DEBUG_FILE
  428. }
  429. #endif /* CONFIG_DEBUG_FILE */
  430. #endif /* CONFIG_ANDROID_LOG */
  431. }
  432. void wpa_hexdump_ascii(int level, const char *title, const void *buf,
  433. size_t len)
  434. {
  435. _wpa_hexdump_ascii(level, title, buf, len, 1);
  436. }
  437. void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
  438. size_t len)
  439. {
  440. _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
  441. }
  442. #ifdef CONFIG_DEBUG_FILE
  443. static char *last_path = NULL;
  444. #endif /* CONFIG_DEBUG_FILE */
  445. int wpa_debug_reopen_file(void)
  446. {
  447. #ifdef CONFIG_DEBUG_FILE
  448. int rv;
  449. if (last_path) {
  450. char *tmp = os_strdup(last_path);
  451. wpa_debug_close_file();
  452. rv = wpa_debug_open_file(tmp);
  453. os_free(tmp);
  454. } else {
  455. wpa_printf(MSG_ERROR, "Last-path was not set, cannot "
  456. "re-open log file.");
  457. rv = -1;
  458. }
  459. return rv;
  460. #else /* CONFIG_DEBUG_FILE */
  461. return 0;
  462. #endif /* CONFIG_DEBUG_FILE */
  463. }
  464. int wpa_debug_open_file(const char *path)
  465. {
  466. #ifdef CONFIG_DEBUG_FILE
  467. if (!path)
  468. return 0;
  469. if (last_path == NULL || os_strcmp(last_path, path) != 0) {
  470. /* Save our path to enable re-open */
  471. os_free(last_path);
  472. last_path = os_strdup(path);
  473. }
  474. out_file = fopen(path, "a");
  475. if (out_file == NULL) {
  476. wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
  477. "output file, using standard output");
  478. return -1;
  479. }
  480. #ifndef _WIN32
  481. setvbuf(out_file, NULL, _IOLBF, 0);
  482. #endif /* _WIN32 */
  483. #else /* CONFIG_DEBUG_FILE */
  484. (void)path;
  485. #endif /* CONFIG_DEBUG_FILE */
  486. return 0;
  487. }
  488. void wpa_debug_close_file(void)
  489. {
  490. #ifdef CONFIG_DEBUG_FILE
  491. if (!out_file)
  492. return;
  493. fclose(out_file);
  494. out_file = NULL;
  495. os_free(last_path);
  496. last_path = NULL;
  497. #endif /* CONFIG_DEBUG_FILE */
  498. }
  499. void wpa_debug_setup_stdout(void)
  500. {
  501. #ifndef _WIN32
  502. setvbuf(stdout, NULL, _IOLBF, 0);
  503. #endif /* _WIN32 */
  504. }
  505. #endif /* CONFIG_NO_STDOUT_DEBUG */
  506. #ifndef CONFIG_NO_WPA_MSG
  507. static wpa_msg_cb_func wpa_msg_cb = NULL;
  508. void wpa_msg_register_cb(wpa_msg_cb_func func)
  509. {
  510. wpa_msg_cb = func;
  511. }
  512. static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
  513. void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
  514. {
  515. wpa_msg_ifname_cb = func;
  516. }
  517. void wpa_msg(void *ctx, int level, const char *fmt, ...)
  518. {
  519. va_list ap;
  520. char *buf;
  521. int buflen;
  522. int len;
  523. char prefix[130];
  524. va_start(ap, fmt);
  525. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  526. va_end(ap);
  527. buf = os_malloc(buflen);
  528. if (buf == NULL) {
  529. wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
  530. "buffer");
  531. return;
  532. }
  533. va_start(ap, fmt);
  534. prefix[0] = '\0';
  535. if (wpa_msg_ifname_cb) {
  536. const char *ifname = wpa_msg_ifname_cb(ctx);
  537. if (ifname) {
  538. int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
  539. ifname);
  540. if (os_snprintf_error(sizeof(prefix), res))
  541. prefix[0] = '\0';
  542. }
  543. }
  544. len = vsnprintf(buf, buflen, fmt, ap);
  545. va_end(ap);
  546. wpa_printf(level, "%s%s", prefix, buf);
  547. if (wpa_msg_cb)
  548. wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
  549. bin_clear_free(buf, buflen);
  550. }
  551. void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
  552. {
  553. va_list ap;
  554. char *buf;
  555. int buflen;
  556. int len;
  557. if (!wpa_msg_cb)
  558. return;
  559. va_start(ap, fmt);
  560. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  561. va_end(ap);
  562. buf = os_malloc(buflen);
  563. if (buf == NULL) {
  564. wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
  565. "message buffer");
  566. return;
  567. }
  568. va_start(ap, fmt);
  569. len = vsnprintf(buf, buflen, fmt, ap);
  570. va_end(ap);
  571. wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
  572. bin_clear_free(buf, buflen);
  573. }
  574. void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
  575. {
  576. va_list ap;
  577. char *buf;
  578. int buflen;
  579. int len;
  580. va_start(ap, fmt);
  581. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  582. va_end(ap);
  583. buf = os_malloc(buflen);
  584. if (buf == NULL) {
  585. wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
  586. "message buffer");
  587. return;
  588. }
  589. va_start(ap, fmt);
  590. len = vsnprintf(buf, buflen, fmt, ap);
  591. va_end(ap);
  592. wpa_printf(level, "%s", buf);
  593. if (wpa_msg_cb)
  594. wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
  595. bin_clear_free(buf, buflen);
  596. }
  597. void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
  598. {
  599. va_list ap;
  600. char *buf;
  601. int buflen;
  602. int len;
  603. if (!wpa_msg_cb)
  604. return;
  605. va_start(ap, fmt);
  606. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  607. va_end(ap);
  608. buf = os_malloc(buflen);
  609. if (buf == NULL) {
  610. wpa_printf(MSG_ERROR,
  611. "wpa_msg_global_ctrl: Failed to allocate message buffer");
  612. return;
  613. }
  614. va_start(ap, fmt);
  615. len = vsnprintf(buf, buflen, fmt, ap);
  616. va_end(ap);
  617. wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
  618. bin_clear_free(buf, buflen);
  619. }
  620. void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
  621. {
  622. va_list ap;
  623. char *buf;
  624. int buflen;
  625. int len;
  626. va_start(ap, fmt);
  627. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  628. va_end(ap);
  629. buf = os_malloc(buflen);
  630. if (buf == NULL) {
  631. wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
  632. "message buffer");
  633. return;
  634. }
  635. va_start(ap, fmt);
  636. len = vsnprintf(buf, buflen, fmt, ap);
  637. va_end(ap);
  638. wpa_printf(level, "%s", buf);
  639. if (wpa_msg_cb)
  640. wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
  641. bin_clear_free(buf, buflen);
  642. }
  643. void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
  644. {
  645. va_list ap;
  646. char *buf;
  647. int buflen;
  648. int len;
  649. va_start(ap, fmt);
  650. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  651. va_end(ap);
  652. buf = os_malloc(buflen);
  653. if (buf == NULL) {
  654. wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
  655. __func__);
  656. return;
  657. }
  658. va_start(ap, fmt);
  659. len = vsnprintf(buf, buflen, fmt, ap);
  660. va_end(ap);
  661. wpa_printf(level, "%s", buf);
  662. if (wpa_msg_cb)
  663. wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
  664. os_free(buf);
  665. }
  666. #endif /* CONFIG_NO_WPA_MSG */
  667. #ifndef CONFIG_NO_HOSTAPD_LOGGER
  668. static hostapd_logger_cb_func hostapd_logger_cb = NULL;
  669. void hostapd_logger_register_cb(hostapd_logger_cb_func func)
  670. {
  671. hostapd_logger_cb = func;
  672. }
  673. void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
  674. const char *fmt, ...)
  675. {
  676. va_list ap;
  677. char *buf;
  678. int buflen;
  679. int len;
  680. va_start(ap, fmt);
  681. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  682. va_end(ap);
  683. buf = os_malloc(buflen);
  684. if (buf == NULL) {
  685. wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
  686. "message buffer");
  687. return;
  688. }
  689. va_start(ap, fmt);
  690. len = vsnprintf(buf, buflen, fmt, ap);
  691. va_end(ap);
  692. if (hostapd_logger_cb)
  693. hostapd_logger_cb(ctx, addr, module, level, buf, len);
  694. else if (addr)
  695. wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
  696. MAC2STR(addr), buf);
  697. else
  698. wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
  699. bin_clear_free(buf, buflen);
  700. }
  701. #endif /* CONFIG_NO_HOSTAPD_LOGGER */