hostapd/wlantest/monitor.c
Jouni Malinen 64f45d070b wlantest: Add option for writing a PCAP dump file
The output file includes all the capture (or read from wireless PCAP
file) frames in their original contents and another copy of each
frame that is decrypted in wlantest (including EAPOL-Key Key Data
field).
2010-11-12 01:00:31 +02:00

150 lines
3.4 KiB
C

/*
* Linux packet socket monitor
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "utils/includes.h"
#include <net/if.h>
#include <netpacket/packet.h>
#include "utils/common.h"
#include "utils/eloop.h"
#include "wlantest.h"
static void monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
{
struct wlantest *wt = eloop_ctx;
u8 buf[3000];
int len;
len = recv(sock, buf, sizeof(buf), 0);
if (len < 0) {
wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
return;
}
write_pcap_captured(wt, buf, len);
wlantest_process(wt, buf, len);
}
static void monitor_read_wired(int sock, void *eloop_ctx, void *sock_ctx)
{
struct wlantest *wt = eloop_ctx;
u8 buf[3000];
int len;
len = recv(sock, buf, sizeof(buf), 0);
if (len < 0) {
wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
return;
}
wlantest_process_wired(wt, buf, len);
}
int monitor_init(struct wlantest *wt, const char *ifname)
{
struct sockaddr_ll ll;
os_memset(&ll, 0, sizeof(ll));
ll.sll_family = AF_PACKET;
ll.sll_ifindex = if_nametoindex(ifname);
if (ll.sll_ifindex == 0) {
wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
ifname);
return -1;
}
wt->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (wt->monitor_sock < 0) {
wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
strerror(errno));
return -1;
}
if (bind(wt->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
close(wt->monitor_sock);
wt->monitor_sock = -1;
return -1;
}
if (eloop_register_read_sock(wt->monitor_sock, monitor_read, wt, NULL))
{
wpa_printf(MSG_ERROR, "Could not register monitor read "
"socket");
close(wt->monitor_sock);
wt->monitor_sock = -1;
return -1;
}
return 0;
}
int monitor_init_wired(struct wlantest *wt, const char *ifname)
{
struct sockaddr_ll ll;
os_memset(&ll, 0, sizeof(ll));
ll.sll_family = AF_PACKET;
ll.sll_ifindex = if_nametoindex(ifname);
if (ll.sll_ifindex == 0) {
wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
ifname);
return -1;
}
wt->monitor_wired = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (wt->monitor_wired < 0) {
wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
strerror(errno));
return -1;
}
if (bind(wt->monitor_wired, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
close(wt->monitor_wired);
wt->monitor_wired = -1;
return -1;
}
if (eloop_register_read_sock(wt->monitor_wired, monitor_read_wired,
wt, NULL)) {
wpa_printf(MSG_ERROR, "Could not register monitor read "
"socket");
close(wt->monitor_wired);
wt->monitor_wired = -1;
return -1;
}
return 0;
}
void monitor_deinit(struct wlantest *wt)
{
if (wt->monitor_sock >= 0) {
eloop_unregister_read_sock(wt->monitor_sock);
close(wt->monitor_sock);
wt->monitor_sock = -1;
}
if (wt->monitor_wired >= 0) {
eloop_unregister_read_sock(wt->monitor_wired);
close(wt->monitor_wired);
wt->monitor_wired = -1;
}
}