Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / wlantest / monitor.c
1 /*
2  * Linux packet socket monitor
3  * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "utils/includes.h"
10 #include <net/if.h>
11 #include <netpacket/packet.h>
12
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "wlantest.h"
16
17
18 static void monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
19 {
20         struct wlantest *wt = eloop_ctx;
21         u8 buf[3000];
22         int len;
23
24         len = recv(sock, buf, sizeof(buf), 0);
25         if (len < 0) {
26                 wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
27                 return;
28         }
29
30         clear_notes(wt);
31         os_free(wt->decrypted);
32         wt->decrypted = NULL;
33         write_pcap_captured(wt, buf, len);
34         wlantest_process(wt, buf, len);
35         write_pcapng_captured(wt, buf, len);
36 }
37
38
39 static void monitor_read_wired(int sock, void *eloop_ctx, void *sock_ctx)
40 {
41         struct wlantest *wt = eloop_ctx;
42         u8 buf[3000];
43         int len;
44
45         len = recv(sock, buf, sizeof(buf), 0);
46         if (len < 0) {
47                 wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
48                 return;
49         }
50
51         wlantest_process_wired(wt, buf, len);
52 }
53
54
55 int monitor_init(struct wlantest *wt, const char *ifname)
56 {
57         struct sockaddr_ll ll;
58
59         os_memset(&ll, 0, sizeof(ll));
60         ll.sll_family = AF_PACKET;
61         ll.sll_ifindex = if_nametoindex(ifname);
62         if (ll.sll_ifindex == 0) {
63                 wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
64                            ifname);
65                 return -1;
66         }
67
68         wt->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
69         if (wt->monitor_sock < 0) {
70                 wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
71                            strerror(errno));
72                 return -1;
73         }
74
75         if (bind(wt->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
76                 wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
77                 close(wt->monitor_sock);
78                 wt->monitor_sock = -1;
79                 return -1;
80         }
81
82         if (eloop_register_read_sock(wt->monitor_sock, monitor_read, wt, NULL))
83         {
84                 wpa_printf(MSG_ERROR, "Could not register monitor read "
85                            "socket");
86                 close(wt->monitor_sock);
87                 wt->monitor_sock = -1;
88                 return -1;
89         }
90
91         return 0;
92 }
93
94
95 int monitor_init_wired(struct wlantest *wt, const char *ifname)
96 {
97         struct sockaddr_ll ll;
98
99         os_memset(&ll, 0, sizeof(ll));
100         ll.sll_family = AF_PACKET;
101         ll.sll_ifindex = if_nametoindex(ifname);
102         if (ll.sll_ifindex == 0) {
103                 wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
104                            ifname);
105                 return -1;
106         }
107
108         wt->monitor_wired = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
109         if (wt->monitor_wired < 0) {
110                 wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
111                            strerror(errno));
112                 return -1;
113         }
114
115         if (bind(wt->monitor_wired, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
116                 wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
117                 close(wt->monitor_wired);
118                 wt->monitor_wired = -1;
119                 return -1;
120         }
121
122         if (eloop_register_read_sock(wt->monitor_wired, monitor_read_wired,
123                                      wt, NULL)) {
124                 wpa_printf(MSG_ERROR, "Could not register monitor read "
125                            "socket");
126                 close(wt->monitor_wired);
127                 wt->monitor_wired = -1;
128                 return -1;
129         }
130
131         return 0;
132 }
133
134
135 void monitor_deinit(struct wlantest *wt)
136 {
137         if (wt->monitor_sock >= 0) {
138                 eloop_unregister_read_sock(wt->monitor_sock);
139                 close(wt->monitor_sock);
140                 wt->monitor_sock = -1;
141         }
142
143         if (wt->monitor_wired >= 0) {
144                 eloop_unregister_read_sock(wt->monitor_wired);
145                 close(wt->monitor_wired);
146                 wt->monitor_wired = -1;
147         }
148 }