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 <cursoragent@cursor.com>
This commit is contained in:
Robert McMahon 2026-02-13 11:54:48 -08:00
parent 2fcc2e9691
commit 122484463f
4 changed files with 72 additions and 12 deletions

View File

@ -41,8 +41,19 @@ int start_capture(const char *interface, packet_callback_t callback, void *user_
capture_running = 1; 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 // Start capture loop
printf("Starting capture loop...\n"); 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) { while (capture_running) {
int ret = pcap_dispatch(pcap_handle, 1, packet_handler, (u_char *)callback); int ret = pcap_dispatch(pcap_handle, 1, packet_handler, (u_char *)callback);
if (ret < 0) { if (ret < 0) {
@ -54,8 +65,17 @@ int start_capture(const char *interface, packet_callback_t callback, void *user_
break; break;
} else if (ret == 0) { } else if (ret == 0) {
// Timeout - continue // 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; continue;
} }
// Got a packet
loop_count = 0;
} }
return 0; return 0;

View File

@ -10,6 +10,7 @@
#include "capture.h" #include "capture.h"
#include "frame_parser.h" #include "frame_parser.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
static volatile int running = 1; static volatile int running = 1;
static uint64_t packet_count = 0; 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 // Parse 802.11 frame
if (parse_80211_frame(packet, len, &frame_info) == 0) { 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) { 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) // Apply MAC filter if enabled (check both TA and RA like ESP32)
bool should_print = true;
if (filter_enabled) { if (filter_enabled) {
should_print = mac_match(frame_info.addr2, filter_mac) || if (!mac_match(frame_info.addr2, filter_mac) &&
mac_match(frame_info.addr1, filter_mac); !mac_match(frame_info.addr1, filter_mac)) {
return; // Filtered out
}
} }
if (should_print) { print_frame_info(&frame_info, timestamp_us);
data_frame_count++;
print_frame_info(&frame_info, timestamp_us);
}
} }
} }
} }
@ -122,8 +135,28 @@ int main(int argc, char **argv) {
} }
// Verify channel was set correctly // Verify channel was set correctly
// Try netlink first, fall back to iw command
uint32_t actual_freq = 0; uint32_t actual_freq = 0;
int actual_channel = get_current_channel(interface, &actual_freq); 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) { if (actual_channel > 0) {
printf("Monitor mode activated\n"); printf("Monitor mode activated\n");
printf("Channel verified: %d (%u MHz)\n", actual_channel, actual_freq); printf("Channel verified: %d (%u MHz)\n", actual_channel, actual_freq);
@ -133,7 +166,7 @@ int main(int argc, char **argv) {
} }
} else { } else {
printf("Monitor mode activated\n"); 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"); printf("Capturing 802.11 frames... (Ctrl+C to stop)\n");

View File

@ -166,7 +166,7 @@ nla_put_failure:
} }
// Convert WiFi channel number to frequency in MHz // 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) { if (channel >= 1 && channel <= 14) {
// 2.4 GHz: 2412 + (channel - 1) * 5 // 2.4 GHz: 2412 + (channel - 1) * 5
return 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; 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) { int get_current_channel(const char *interface, uint32_t *freq_out) {
struct nl_msg *msg; struct nl_msg *msg;
struct nl_cb *cb; struct nl_cb *cb;
@ -256,7 +256,7 @@ int get_current_channel(const char *interface, uint32_t *freq_out) {
return -1; return -1;
} }
// Receive response // Receive response (with timeout)
err = nl_recvmsgs(nl_sock, cb); err = nl_recvmsgs(nl_sock, cb);
nl_cb_put(cb); nl_cb_put(cb);

View File

@ -35,4 +35,11 @@ int set_channel(const char *interface, int channel);
*/ */
int get_current_channel(const char *interface, uint32_t *freq_out); 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 */ #endif /* MONITOR_H */