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