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