Add channel verification after setting monitor mode

- Add get_current_channel() function to query actual channel/frequency
- Add freq_to_channel() helper to convert frequency back to channel
- Display verified channel and frequency after setting monitor mode
- Warn if requested channel doesn't match actual channel

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Robert McMahon 2026-02-13 11:52:56 -08:00
parent f9acd111f6
commit 2fcc2e9691
3 changed files with 126 additions and 1 deletions

View File

@ -9,6 +9,7 @@
#include "monitor.h" #include "monitor.h"
#include "capture.h" #include "capture.h"
#include "frame_parser.h" #include "frame_parser.h"
#include <stdint.h>
static volatile int running = 1; static volatile int running = 1;
static uint64_t packet_count = 0; static uint64_t packet_count = 0;
@ -120,7 +121,21 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
printf("Monitor mode activated\n"); // Verify channel was set correctly
uint32_t actual_freq = 0;
int actual_channel = get_current_channel(interface, &actual_freq);
if (actual_channel > 0) {
printf("Monitor mode activated\n");
printf("Channel verified: %d (%u MHz)\n", actual_channel, actual_freq);
if (actual_channel != channel) {
fprintf(stderr, "Warning: Channel mismatch! Requested %d, got %d\n",
channel, actual_channel);
}
} else {
printf("Monitor mode activated\n");
printf("Warning: Could not verify channel (may still be correct)\n");
}
printf("Capturing 802.11 frames... (Ctrl+C to stop)\n"); printf("Capturing 802.11 frames... (Ctrl+C to stop)\n");
printf("This output can be compared with ESP32 monitor debug logs\n"); printf("This output can be compared with ESP32 monitor debug logs\n");
if (filter_enabled) { if (filter_enabled) {

View File

@ -179,6 +179,108 @@ static uint32_t channel_to_freq(int channel) {
} }
} }
// Convert frequency in MHz to WiFi channel number
static int freq_to_channel(uint32_t freq_mhz) {
if (freq_mhz >= 2412 && freq_mhz <= 2484) {
// 2.4 GHz: channel = (freq - 2412) / 5 + 1
return (int)((freq_mhz - 2412) / 5) + 1;
} else if (freq_mhz >= 5000 && freq_mhz <= 5825) {
// 5 GHz: channel = (freq - 5000) / 5
return (int)((freq_mhz - 5000) / 5);
} else {
// Invalid frequency
return 0;
}
}
// Callback to extract frequency from GET_INTERFACE response
static int get_interface_cb(struct nl_msg *msg, void *arg) {
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
uint32_t *freq_out = (uint32_t *)arg;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (tb[NL80211_ATTR_WIPHY_FREQ]) {
*freq_out = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
}
return NL_OK;
}
// Get current channel from interface
int get_current_channel(const char *interface, uint32_t *freq_out) {
struct nl_msg *msg;
struct nl_cb *cb;
int ifindex;
int err = 0;
uint32_t freq = 0;
if (nl80211_init() < 0) {
return -1;
}
ifindex = if_nametoindex(interface);
if (ifindex == 0) {
nl80211_cleanup();
return -1;
}
msg = nlmsg_alloc();
if (!msg) {
nl80211_cleanup();
return -1;
}
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nl80211_id, 0,
NLM_F_REQUEST, NL80211_CMD_GET_INTERFACE, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!cb) {
nlmsg_free(msg);
nl80211_cleanup();
return -1;
}
// Set up callback to receive response
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_interface_cb, &freq);
err = nl_send_auto_complete(nl_sock, msg);
if (err < 0) {
nl_cb_put(cb);
nlmsg_free(msg);
nl80211_cleanup();
return -1;
}
// Receive response
err = nl_recvmsgs(nl_sock, cb);
nl_cb_put(cb);
nlmsg_free(msg);
if (err < 0 || freq == 0) {
nl80211_cleanup();
return -1;
}
if (freq_out) {
*freq_out = freq;
}
nl80211_cleanup();
return freq_to_channel(freq);
nla_put_failure:
nl_cb_put(cb);
nlmsg_free(msg);
nl80211_cleanup();
return -1;
}
int set_channel(const char *interface, int channel) { int set_channel(const char *interface, int channel) {
struct nl_msg *msg; struct nl_msg *msg;
int ifindex; int ifindex;

View File

@ -27,4 +27,12 @@ int restore_managed_mode(const char *interface);
*/ */
int set_channel(const char *interface, int channel); int set_channel(const char *interface, int channel);
/**
* @brief Get current channel from interface
* @param interface Interface name
* @param freq_out Optional pointer to receive frequency in MHz
* @return Channel number on success, -1 on error
*/
int get_current_channel(const char *interface, uint32_t *freq_out);
#endif /* MONITOR_H */ #endif /* MONITOR_H */