ap-mgmt-fuzzer.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * hostapd - Management frame fuzzer
  3. * Copyright (c) 2015, 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 "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "ap/hostapd.h"
  12. #include "ap/hw_features.h"
  13. #include "ap/ieee802_11.h"
  14. #include "ap/sta_info.h"
  15. const struct wpa_driver_ops *const wpa_drivers[] =
  16. {
  17. NULL
  18. };
  19. struct arg_ctx {
  20. const char *fname;
  21. struct hostapd_iface iface;
  22. struct hostapd_data hapd;
  23. struct wpa_driver_ops driver;
  24. struct hostapd_config iconf;
  25. struct hostapd_bss_config conf;
  26. int multi_frame;
  27. };
  28. static void test_send_mgmt(void *eloop_data, void *user_ctx)
  29. {
  30. struct arg_ctx *ctx = eloop_data;
  31. char *data;
  32. size_t len;
  33. struct hostapd_frame_info fi;
  34. wpa_printf(MSG_INFO, "ap-mgmt-fuzzer: Send '%s'", ctx->fname);
  35. data = os_readfile(ctx->fname, &len);
  36. if (!data) {
  37. wpa_printf(MSG_ERROR, "Could not read '%s'", ctx->fname);
  38. goto out;
  39. }
  40. os_memset(&fi, 0, sizeof(fi));
  41. if (ctx->multi_frame) {
  42. u8 *pos, *end;
  43. pos = (u8 *) data;
  44. end = pos + len;
  45. while (end - pos > 2) {
  46. u16 flen;
  47. flen = WPA_GET_BE16(pos);
  48. pos += 2;
  49. if (end - pos < flen)
  50. break;
  51. wpa_hexdump(MSG_MSGDUMP, "fuzzer - frame", pos, flen);
  52. ieee802_11_mgmt(&ctx->hapd, pos, flen, &fi);
  53. pos += flen;
  54. }
  55. } else {
  56. wpa_hexdump(MSG_MSGDUMP, "fuzzer - WNM", data, len);
  57. ieee802_11_mgmt(&ctx->hapd, (u8 *) data, len, &fi);
  58. }
  59. out:
  60. os_free(data);
  61. eloop_terminate();
  62. }
  63. static struct hostapd_hw_modes * gen_modes(void)
  64. {
  65. struct hostapd_hw_modes *mode;
  66. struct hostapd_channel_data *chan;
  67. mode = os_zalloc(sizeof(struct hostapd_hw_modes));
  68. if (!mode)
  69. return NULL;
  70. mode->mode = HOSTAPD_MODE_IEEE80211G;
  71. chan = os_zalloc(sizeof(struct hostapd_channel_data));
  72. if (!chan) {
  73. os_free(mode);
  74. return NULL;
  75. }
  76. chan->chan = 1;
  77. chan->freq = 2412;
  78. mode->channels = chan;
  79. mode->num_channels = 1;
  80. mode->rates = os_zalloc(sizeof(int));
  81. if (!mode->rates) {
  82. os_free(chan);
  83. os_free(mode);
  84. return NULL;
  85. }
  86. mode->rates[0] = 10;
  87. mode->num_rates = 1;
  88. return mode;
  89. }
  90. static int init_hapd(struct arg_ctx *ctx)
  91. {
  92. struct hostapd_data *hapd = &ctx->hapd;
  93. struct sta_info *sta;
  94. struct hostapd_bss_config *bss;
  95. hapd->driver = &ctx->driver;
  96. os_memcpy(hapd->own_addr, "\x02\x00\x00\x00\x03\x00", ETH_ALEN);
  97. hapd->iface = &ctx->iface;
  98. hapd->iface->conf = hostapd_config_defaults();
  99. if (!hapd->iface->conf)
  100. return -1;
  101. hapd->iface->hw_features = gen_modes();
  102. hapd->iface->num_hw_features = 1;
  103. hapd->iface->current_mode = hapd->iface->hw_features;
  104. hapd->iconf = hapd->iface->conf;
  105. hapd->iconf->hw_mode = HOSTAPD_MODE_IEEE80211G;
  106. hapd->iconf->channel = 1;
  107. bss = hapd->conf = hapd->iconf->bss[0];
  108. hostapd_config_defaults_bss(hapd->conf);
  109. os_memcpy(bss->ssid.ssid, "test", 4);
  110. bss->ssid.ssid_len = 4;
  111. bss->ssid.ssid_set = 1;
  112. sta = ap_sta_add(hapd, (u8 *) "\x02\x00\x00\x00\x00\x00");
  113. if (sta)
  114. sta->flags |= WLAN_STA_ASSOC | WLAN_STA_WMM;
  115. return 0;
  116. }
  117. int main(int argc, char *argv[])
  118. {
  119. struct arg_ctx ctx;
  120. int ret = -1;
  121. if (argc < 2) {
  122. printf("usage: %s [-m] <file>\n", argv[0]);
  123. return -1;
  124. }
  125. if (os_program_init())
  126. return -1;
  127. wpa_debug_level = 0;
  128. wpa_debug_show_keys = 1;
  129. if (eloop_init()) {
  130. wpa_printf(MSG_ERROR, "Failed to initialize event loop");
  131. return -1;
  132. }
  133. os_memset(&ctx, 0, sizeof(ctx));
  134. if (argc >= 3 && os_strcmp(argv[1], "-m") == 0) {
  135. ctx.multi_frame = 1;
  136. ctx.fname = argv[2];
  137. } else {
  138. ctx.fname = argv[1];
  139. }
  140. if (init_hapd(&ctx))
  141. goto fail;
  142. eloop_register_timeout(0, 0, test_send_mgmt, &ctx, NULL);
  143. wpa_printf(MSG_DEBUG, "Starting eloop");
  144. eloop_run();
  145. wpa_printf(MSG_DEBUG, "eloop done");
  146. hostapd_free_stas(&ctx.hapd);
  147. hostapd_free_hw_features(ctx.hapd.iface->hw_features,
  148. ctx.hapd.iface->num_hw_features);
  149. ret = 0;
  150. fail:
  151. hostapd_config_free(ctx.hapd.iconf);
  152. eloop_destroy();
  153. os_program_deinit();
  154. return ret;
  155. }