From 122484463f337ebff42c601b1c1963fb46ae36f0 Mon Sep 17 00:00:00 2001 From: Robert McMahon Date: Fri, 13 Feb 2026 11:54:48 -0800 Subject: [PATCH] Improve channel verification and add debug output - Add fallback channel verification using 'iw' command - Show data link type on startup - Print first 10 non-data frames for debugging - Add periodic status during capture loop Co-authored-by: Cursor --- src/capture.c | 20 ++++++++++++++++++++ src/main.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- src/monitor.c | 6 +++--- src/monitor.h | 7 +++++++ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/capture.c b/src/capture.c index 2f78c5d..f8fbae9 100644 --- a/src/capture.c +++ b/src/capture.c @@ -41,8 +41,19 @@ int start_capture(const char *interface, packet_callback_t callback, void *user_ capture_running = 1; + // Verify we're in monitor mode + int dlt = pcap_datalink(pcap_handle); + if (dlt != DLT_IEEE802_11_RADIO && dlt != DLT_IEEE802_11) { + fprintf(stderr, "Warning: Interface may not be in monitor mode (DLT=%d, expected DLT_IEEE802_11_RADIO=%d or DLT_IEEE802_11=%d)\n", + dlt, DLT_IEEE802_11_RADIO, DLT_IEEE802_11); + } + // Start capture loop printf("Starting capture loop...\n"); + printf("Data link type: %d (DLT_IEEE802_11_RADIO=%d, DLT_IEEE802_11=%d)\n", + dlt, DLT_IEEE802_11_RADIO, DLT_IEEE802_11); + + uint64_t loop_count = 0; while (capture_running) { int ret = pcap_dispatch(pcap_handle, 1, packet_handler, (u_char *)callback); if (ret < 0) { @@ -54,8 +65,17 @@ int start_capture(const char *interface, packet_callback_t callback, void *user_ break; } else if (ret == 0) { // Timeout - continue + loop_count++; + if (loop_count % 1000 == 0) { + // Print periodic status every 1000 timeouts (~1 second) + fprintf(stderr, "Waiting for packets... (timeouts: %llu)\r", + (unsigned long long)loop_count); + fflush(stderr); + } continue; } + // Got a packet + loop_count = 0; } return 0; diff --git a/src/main.c b/src/main.c index e1304df..f34fdb4 100644 --- a/src/main.c +++ b/src/main.c @@ -10,6 +10,7 @@ #include "capture.h" #include "frame_parser.h" #include +#include static volatile int running = 1; static uint64_t packet_count = 0; @@ -42,19 +43,31 @@ static void packet_callback(const uint8_t *packet, size_t len, void *user_data) // Parse 802.11 frame if (parse_80211_frame(packet, len, &frame_info) == 0) { - // Only print data frames (for comparison with ESP32) + // Count data frames if (frame_info.type == FRAME_TYPE_DATA) { + data_frame_count++; + } + + // Print data frames (for comparison with ESP32) + // Also print first few non-data frames for debugging + bool should_print = false; + if (frame_info.type == FRAME_TYPE_DATA) { + should_print = true; + } else if (packet_count <= 10) { + // Print first 10 non-data frames for debugging + should_print = true; + } + + if (should_print) { // Apply MAC filter if enabled (check both TA and RA like ESP32) - bool should_print = true; if (filter_enabled) { - should_print = mac_match(frame_info.addr2, filter_mac) || - mac_match(frame_info.addr1, filter_mac); + if (!mac_match(frame_info.addr2, filter_mac) && + !mac_match(frame_info.addr1, filter_mac)) { + return; // Filtered out + } } - if (should_print) { - data_frame_count++; - print_frame_info(&frame_info, timestamp_us); - } + print_frame_info(&frame_info, timestamp_us); } } } @@ -122,8 +135,28 @@ int main(int argc, char **argv) { } // Verify channel was set correctly + // Try netlink first, fall back to iw command uint32_t actual_freq = 0; int actual_channel = get_current_channel(interface, &actual_freq); + + if (actual_channel <= 0) { + // Fallback: use iw command to verify + char cmd[256]; + FILE *fp; + snprintf(cmd, sizeof(cmd), "iw dev %s info 2>/dev/null | grep -oP 'channel \\K[0-9]+'", interface); + fp = popen(cmd, "r"); + if (fp) { + char line[32]; + if (fgets(line, sizeof(line), fp)) { + actual_channel = atoi(line); + if (actual_channel > 0) { + actual_freq = channel_to_freq(actual_channel); + } + } + pclose(fp); + } + } + if (actual_channel > 0) { printf("Monitor mode activated\n"); printf("Channel verified: %d (%u MHz)\n", actual_channel, actual_freq); @@ -133,7 +166,7 @@ int main(int argc, char **argv) { } } else { printf("Monitor mode activated\n"); - printf("Warning: Could not verify channel (may still be correct)\n"); + printf("Note: Could not verify channel. Use 'iw dev %s info' to check manually.\n", interface); } printf("Capturing 802.11 frames... (Ctrl+C to stop)\n"); diff --git a/src/monitor.c b/src/monitor.c index f53c87c..7f1ca1e 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -166,7 +166,7 @@ nla_put_failure: } // Convert WiFi channel number to frequency in MHz -static uint32_t channel_to_freq(int channel) { +uint32_t channel_to_freq(int channel) { if (channel >= 1 && channel <= 14) { // 2.4 GHz: 2412 + (channel - 1) * 5 return 2412 + (channel - 1) * 5; @@ -209,7 +209,7 @@ static int get_interface_cb(struct nl_msg *msg, void *arg) { return NL_OK; } -// Get current channel from interface +// Get current channel from interface using netlink int get_current_channel(const char *interface, uint32_t *freq_out) { struct nl_msg *msg; struct nl_cb *cb; @@ -256,7 +256,7 @@ int get_current_channel(const char *interface, uint32_t *freq_out) { return -1; } - // Receive response + // Receive response (with timeout) err = nl_recvmsgs(nl_sock, cb); nl_cb_put(cb); diff --git a/src/monitor.h b/src/monitor.h index d1707a6..8ab97f8 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -35,4 +35,11 @@ int set_channel(const char *interface, int channel); */ int get_current_channel(const char *interface, uint32_t *freq_out); +/** + * @brief Convert WiFi channel number to frequency in MHz + * @param channel Channel number (1-165) + * @return Frequency in MHz, or 0 if invalid + */ +uint32_t channel_to_freq(int channel); + #endif /* MONITOR_H */