1 /*
2 This file is part of Kismet
3
4 Kismet is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 Kismet is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Kismet; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include "config.h"
20
21 #include <unistd.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <time.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
29
30 #ifdef HAVE_LINUX_WIRELESS
31 // Some kernels include ethtool headers in wireless.h and seem to break
32 // terribly if these aren't defined
33 typedef unsigned char u8;
34 typedef unsigned short u16;
35 typedef unsigned int u32;
36 typedef unsigned long u64;
37
38 #include <asm/types.h>
39 #include <linux/if.h>
40 #include <linux/wireless.h>
41 #endif
42
43 #include "util.h"
44 #include "packetsourcetracker.h"
45 #include "packetsource_ipwlive.h"
46
47 #if (defined(HAVE_LIBPCAP) && defined(SYS_LINUX) && defined(HAVE_LINUX_WIRELESS))
48
AutotypeProbe(string in_device)49 int PacketSource_Ipwlive::AutotypeProbe(string in_device) {
50 return 0;
51 }
52
RegisterSources(Packetsourcetracker * tracker)53 int PacketSource_Ipwlive::RegisterSources(Packetsourcetracker *tracker) {
54 tracker->RegisterPacketProto("ipwlivetap", this, "na", 0);
55 return 1;
56 }
57
EnableMonitor()58 int PacketSource_Ipwlive::EnableMonitor() {
59 char errstr[STATUS_MAX];
60
61 #if 0
62 // Pull the hardware address from the device and use it to re-seed
63 // the UUID
64 uint8_t hwnode[6];
65 if (Ifconfig_Get_Hwaddr(interface.c_str(), errstr, hwnode) < 0) {
66 _MSG(errstr, MSGFLAG_ERROR);
67 _MSG("Failed to fetch interface hardware flags for '" + interface + ", "
68 "this will probably fully fail in a moment when we try to configure "
69 "the interface, but we'll keep going.", MSGFLAG_ERROR);
70 }
71 src_uuid.GenerateTimeUUID(hwnode);
72 #endif
73
74 char dynif[32];
75 FILE *sysf;
76 char path[1024];
77 int ifflags;
78
79 if (Ifconfig_Get_Flags(interface.c_str(), errstr, &ifflags) < 0) {
80 _MSG(errstr, MSGFLAG_ERROR);
81 _MSG("Failed to get interface flags for livetap control interface",
82 MSGFLAG_ERROR);
83 return -1;
84 }
85
86 if ((ifflags & IFF_UP) == 0) {
87 _MSG("The ipw control interface (" + interface + ") is not configured "
88 "as 'up'. The ipwlivetap source reports traffic from a currently "
89 "running interface. For pure rfmon, use ipwXXXX instead.",
90 MSGFLAG_ERROR);
91 return -1;
92 }
93
94 // Use the .../net/foo/device symlink into .../bus/pci/drivers
95 snprintf(path, 1024, "/sys/class/net/%s/device/rtap_iface", interface.c_str());
96
97 // Open it in RO mode first and get the current state. I'm not sure how
98 // well frewind works on proc virtual files so we'll close it and re-open
99 // to set modes, instead of opening it in mixed rw
100 if ((sysf = fopen(path, "r")) == NULL) {
101 _MSG("Failed to open ipw sysfs rtap control file. Check that the "
102 "version of the ipw drivers you are using is current enough to "
103 "support livetap mode, and that your system has sysfs set up "
104 "properly", MSGFLAG_ERROR);
105 return -1;
106 }
107
108 if (fgets(dynif, 32, sysf) == NULL) {
109 _MSG("Failed to read from the ipw rtap control file. Check that the "
110 "version of the ipw drivers you are using is current enough to "
111 "support livetap mode, and that your system has sysfs set up "
112 "properly", MSGFLAG_ERROR);
113 fclose(sysf);
114 return -1;
115 }
116
117 // We're done with the ro
118 fclose(sysf);
119
120 // If it's -1 we aren't turned on, so we'll initialize
121 if (strncmp(dynif, "-1", 32) == 0) {
122 if ((sysf = fopen(path, "w")) == NULL) {
123 _MSG("Failed to open the ipw rtap control file for writing "
124 "(" + string(strerror(errno)) + "). Check that Kismet has "
125 "the proper privilege levels (SUID or started as root) and "
126 "that you are running a version of the ipw drivers current "
127 "enough to support livetap mode.", MSGFLAG_ERROR);
128 return -1;
129 }
130
131 fprintf(sysf, "1\n");
132 fclose(sysf);
133
134 // Now open it AGAIN for reading to get the interface out of it
135 if ((sysf = fopen(path, "r")) == NULL) {
136 _MSG("Failed to open ipw sysfs rtap control file. Check that the "
137 "version of the ipw drivers you are using is current enough to "
138 "support livetap mode, and that your system has sysfs set up "
139 "properly", MSGFLAG_ERROR);
140 return -1;
141 }
142
143 if (fgets(dynif, 32, sysf) == NULL) {
144 _MSG("Failed to read from the ipw rtap control file. Check that the "
145 "version of the ipw drivers you are using is current enough to "
146 "support livetap mode, and that your system has sysfs set up "
147 "properly", MSGFLAG_ERROR);
148 fclose(sysf);
149 return -1;
150 }
151
152 // We're done with the ro
153 fclose(sysf);
154
155 // Wait for things to settle if interfaces are getting renamed
156 sleep(1);
157 }
158
159 // Sanity check the interface we were told to use. A 0, 1, -1 probably
160 // means a bad driver version or something
161 if (strncmp(dynif, "-1", 32) == 0 || strncmp(dynif, "0", 32) == 0 ||
162 strncmp(dynif, "1", 32) == 0) {
163 _MSG("Got a nonsense interface from the ipw rtap control file. This "
164 "probably means there is something unexpected happening with the "
165 "ipw drivers. Check your system messages (dmesg)", MSGFLAG_ERROR);
166 return -1;
167 }
168
169 // Bring up the dynamic interface
170 if (Ifconfig_Delta_Flags(dynif, errstr,
171 (IFF_UP | IFF_RUNNING | IFF_PROMISC)) < 0) {
172 _MSG(errstr, MSGFLAG_ERROR);
173 _MSG("Unable to set ipw livetap dynamic interface to 'up'",
174 MSGFLAG_ERROR);
175 return -1;
176 }
177
178 interface = dynif;
179
180 return 0;
181 }
182
DisableMonitor()183 int PacketSource_Ipwlive::DisableMonitor() {
184 return PACKSOURCE_UNMONITOR_RET_SILENCE;
185 }
186
SetChannel(unsigned int in_ch)187 int PacketSource_Ipwlive::SetChannel(unsigned int in_ch) {
188 return 1;
189 }
190
FetchChannel()191 int PacketSource_Ipwlive::FetchChannel() {
192 return 0;
193 }
194
195 #endif
196
197