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 #ifndef __APPLE__
11 #include <net/if.h>
12 #include <netpacket/packet.h>
13 #endif /* __APPLE__ */
14 
15 #include "utils/common.h"
16 #include "utils/eloop.h"
17 #include "wlantest.h"
18 
19 
20 #ifdef __APPLE__
21 
monitor_init(struct wlantest * wt,const char * ifname)22 int monitor_init(struct wlantest *wt, const char *ifname)
23 {
24 	return -1;
25 }
26 
27 
monitor_init_wired(struct wlantest * wt,const char * ifname)28 int monitor_init_wired(struct wlantest *wt, const char *ifname)
29 {
30 	return -1;
31 }
32 
33 
monitor_deinit(struct wlantest * wt)34 void monitor_deinit(struct wlantest *wt)
35 {
36 }
37 
38 #else /* __APPLE__ */
39 
monitor_read(int sock,void * eloop_ctx,void * sock_ctx)40 static void monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
41 {
42 	struct wlantest *wt = eloop_ctx;
43 	u8 buf[3000];
44 	int len;
45 
46 	len = recv(sock, buf, sizeof(buf), 0);
47 	if (len < 0) {
48 		wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
49 		return;
50 	}
51 
52 	clear_notes(wt);
53 	os_free(wt->decrypted);
54 	wt->decrypted = NULL;
55 	write_pcap_captured(wt, buf, len);
56 	wlantest_process(wt, buf, len);
57 	write_pcapng_captured(wt, buf, len);
58 }
59 
60 
monitor_read_wired(int sock,void * eloop_ctx,void * sock_ctx)61 static void monitor_read_wired(int sock, void *eloop_ctx, void *sock_ctx)
62 {
63 	struct wlantest *wt = eloop_ctx;
64 	u8 buf[3000];
65 	int len;
66 
67 	len = recv(sock, buf, sizeof(buf), 0);
68 	if (len < 0) {
69 		wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
70 		return;
71 	}
72 
73 	wlantest_process_wired(wt, buf, len);
74 }
75 
76 
monitor_init(struct wlantest * wt,const char * ifname)77 int monitor_init(struct wlantest *wt, const char *ifname)
78 {
79 	struct sockaddr_ll ll;
80 
81 	os_memset(&ll, 0, sizeof(ll));
82 	ll.sll_family = AF_PACKET;
83 	ll.sll_ifindex = if_nametoindex(ifname);
84 	if (ll.sll_ifindex == 0) {
85 		wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
86 			   ifname);
87 		return -1;
88 	}
89 
90 	wt->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
91 	if (wt->monitor_sock < 0) {
92 		wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
93 			   strerror(errno));
94 		return -1;
95 	}
96 
97 	if (bind(wt->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
98 		wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
99 		close(wt->monitor_sock);
100 		wt->monitor_sock = -1;
101 		return -1;
102 	}
103 
104 	if (eloop_register_read_sock(wt->monitor_sock, monitor_read, wt, NULL))
105 	{
106 		wpa_printf(MSG_ERROR, "Could not register monitor read "
107 			   "socket");
108 		close(wt->monitor_sock);
109 		wt->monitor_sock = -1;
110 		return -1;
111 	}
112 
113 	return 0;
114 }
115 
116 
monitor_init_wired(struct wlantest * wt,const char * ifname)117 int monitor_init_wired(struct wlantest *wt, const char *ifname)
118 {
119 	struct sockaddr_ll ll;
120 
121 	os_memset(&ll, 0, sizeof(ll));
122 	ll.sll_family = AF_PACKET;
123 	ll.sll_ifindex = if_nametoindex(ifname);
124 	if (ll.sll_ifindex == 0) {
125 		wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
126 			   ifname);
127 		return -1;
128 	}
129 
130 	wt->monitor_wired = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
131 	if (wt->monitor_wired < 0) {
132 		wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
133 			   strerror(errno));
134 		return -1;
135 	}
136 
137 	if (bind(wt->monitor_wired, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
138 		wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
139 		close(wt->monitor_wired);
140 		wt->monitor_wired = -1;
141 		return -1;
142 	}
143 
144 	if (eloop_register_read_sock(wt->monitor_wired, monitor_read_wired,
145 				     wt, NULL)) {
146 		wpa_printf(MSG_ERROR, "Could not register monitor read "
147 			   "socket");
148 		close(wt->monitor_wired);
149 		wt->monitor_wired = -1;
150 		return -1;
151 	}
152 
153 	return 0;
154 }
155 
156 
monitor_deinit(struct wlantest * wt)157 void monitor_deinit(struct wlantest *wt)
158 {
159 	if (wt->monitor_sock >= 0) {
160 		eloop_unregister_read_sock(wt->monitor_sock);
161 		close(wt->monitor_sock);
162 		wt->monitor_sock = -1;
163 	}
164 
165 	if (wt->monitor_wired >= 0) {
166 		eloop_unregister_read_sock(wt->monitor_wired);
167 		close(wt->monitor_wired);
168 		wt->monitor_wired = -1;
169 	}
170 }
171 
172 #endif /* __APPLE__ */
173