diff --git a/src/main.c b/src/main.c index 978f430..e1304df 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "monitor.h" #include "capture.h" #include "frame_parser.h" +#include static volatile int running = 1; static uint64_t packet_count = 0; @@ -120,7 +121,21 @@ int main(int argc, char **argv) { 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("This output can be compared with ESP32 monitor debug logs\n"); if (filter_enabled) { diff --git a/src/monitor.c b/src/monitor.c index 92ad6b4..f53c87c 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -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) { struct nl_msg *msg; int ifindex; diff --git a/src/monitor.h b/src/monitor.h index 8e88dff..d1707a6 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -27,4 +27,12 @@ int restore_managed_mode(const char *interface); */ 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 */