1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
/*
This file is part of Kismet
Kismet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kismet is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Kismet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PACKETSOURCE_H__
#define __PACKETSOURCE_H__
#include "config.h"
#include <string>
#include <errno.h>
#include "util.h"
#include "uuid.h"
#include "globalregistry.h"
#include "messagebus.h"
#include "packet.h"
#include "timetracker.h"
#include "gpsdclient.h"
#include "configfile.h"
#include "packetchain.h"
#include "getopt.h"
// Packet capture source superclass
// This defines the methods used to go in and out of monitor mode, channel
// control, and manages the lists of channels this source will hop to.
//
// This class will become somewhat absurdly subclassed at times. This is
// a necessary evil, and better than the previous method of having tons of
// random C function pointers to do work with no coherent ties to the class
// itself.
//
// The constructor is passed the type, name, and device from the source=
// line (or is manually built).
//
// Packet sources are not themselves pollable items. They are monitored and
// called via the packetsourcetracker.
//
// Packet sources can exist in multiple processes: A defined but not opened
// source is created before the fork() for IPC controls.
//
// Packet sources are registered as a new object w/ no parameters, which is
// used to later generate the real packetsource via CreateSource(...)
//
// What that boils down to is:
// 1. A subclass should provide the CreateSource(...) function, which returns
// a new Subclass(...);
// 2. A class should blow up on the new() operator and assign GlobalReg on the
// new(GlobalRegistry *) opertor
// 3. A class should provide the RegisterSources(...) function in such a way
// that it works on a generic/weak instance
// 4. A class should provide the AutotypeProbe(...) function in such a way
// that it can be called on a generic instance (ie, one made with new() )
// It should return 1 or 0 for "claimed as this type" or "not claimed"
// Forward definition of sourcetracker for the RegisterPacketSource function
class Packetsourcetracker;
// Return code definitions for DisableMonitor (since we want to tell the
// sourcetracker how to report errors. Negative returns are always an error.)
// Say nothing -- we don't do anything to a source that requires the warning
// (like pcapfile)
#define PACKSOURCE_UNMONITOR_RET_SILENCE 0
// We unmonitored OK but print a friendly warning anyhow
#define PACKSOURCE_UNMONITOR_RET_OKWITHWARN 1
// We can't unmonitor this source, but it isn't a fatal error
#define PACKSOURCE_UNMONITOR_RET_CANTUNMON 2
// Parmeters to the packet info. These get set by the packet source controller
// so they need to go here. Every packet source shares these generic types, but
// they may have more specifc types of their own as well. Only generic types
// can be used by other components
struct packet_parm {
packet_parm() {
fuzzy_crypt = 0;
weak_dissect = 0;
legal_paranoia = 0;
}
int fuzzy_crypt;
int weak_dissect;
int legal_paranoia;
};
// parsed option
struct packetsource_option {
string opt;
string val;
};
// We don't do anything smart with this yet but plan ahead
enum packetsource_channel_mod {
channel_mod_none = 0,
channel_mod_11b = 1,
channel_mod_11g = 2,
channel_mod_11a = 3,
channel_mod_11n = 4,
channel_mod_40mhz = 5
};
class KisPacketSource {
public:
// This is still bad, even for weak sources
KisPacketSource() {
fprintf(stderr, "FATAL OOPS: KisPacketSource() with no parameters\n");
exit(1);
}
// ------------ WEAK PACKETSOURCE -----------------
KisPacketSource(GlobalRegistry *in_globalreg) {
// Nothing happens here. This just lets us new() a weak packetsource
// used for calling CreateSource(...) and RegisterSources(...)
// We just grab globalreg so that we can generate messages
globalreg = in_globalreg;
source_id = 0;
}
// This should call our own constructor and return a packet source of our
// own type, for each subclass
virtual KisPacketSource *CreateSource(GlobalRegistry *in_globalreg,
string in_interface,
vector<opt_pair> *in_opts) = 0;
virtual int RegisterSources(Packetsourcetracker *tracker) = 0;
virtual int AutotypeProbe(string in_device) = 0;
// Create a strong packet source
KisPacketSource(GlobalRegistry *in_globalreg, string in_interface,
vector<opt_pair> *in_opts) {
name = in_interface;
interface = in_interface;
source_id = 0;
type = "auto";
globalreg = in_globalreg;
// Invalidate the UUID to begin with
src_uuid.error = 1;
dlt_mangle = 0;
fcsbytes = 0;
validate_fcs = 0;
crc32_table = NULL;
carrier_set = 0;
consec_error = 0;
num_packets = 0;
error = 0;
if (ParseOptions(in_opts) < 0)
error = 1;
}
virtual ~KisPacketSource() { }
// Parse the options -- override any existing options we have
virtual int ParseOptions(vector<opt_pair> *in_opts) {
if (FetchOpt("name", in_opts) != "")
name = FetchOpt("name", in_opts);
if (FetchOpt("type", in_opts) != "")
type = FetchOpt("type", in_opts);
// Get the UUID from options if we have it, otherwise generate one
// TODO: Pull from cache
if (FetchOpt("uuid", in_opts) != "") {
src_uuid = uuid(FetchOpt("uuid", in_opts));
if (src_uuid.error)
_MSG("Invalid UUID=... on packet source " + interface + ". "
"A new UUID will be generated.", MSGFLAG_ERROR);
}
if (src_uuid.error) {
// Generate a UUID if we don't have one
// This is mostly just crap. Hash the type and name, then
// hash the device, and make a 6 byte field out of it to seed
// the device attribute. If a subclass wants to seed this with the MAC
// of the capture source in the future, thats fine too
uint8_t unode[6];
uint32_t unode_hash;
string combo = type + name;
unode_hash = Adler32Checksum(combo.c_str(), combo.length());
memcpy(unode, &unode_hash, 4);
unode_hash = Adler32Checksum(interface.c_str(), interface.length());
memcpy(&(unode[4]), &unode_hash, 2);
src_uuid.GenerateTimeUUID(unode);
}
// if (StrLower(FetchOpt("weakvalidate", in_opts)) == "true") {
if (FetchOptBoolean("weakvalidate", in_opts, 0)) {
genericparms.weak_dissect = 1;
_MSG("Enabling weak frame validation on packet source '" +
interface + "'", MSGFLAG_INFO);
}
// if (StrLower(FetchOpt("validatefcs", in_opts)) == "true") {
if (FetchOptBoolean("validatefcs", in_opts, 0)) {
SetValidateCRC(1);
_MSG("Enabling FCS frame validation on packet source '" +
interface + "'", MSGFLAG_INFO);
}
// if (FetchOpt("fcs", in_opts) == "true") {
if (FetchOptBoolean("fcs", in_opts, 0)) {
_MSG("Forcing assumption that source '" + interface + "' contains "
"four trailing bytes of FCS checksum data", MSGFLAG_INFO);
SetFCSBytes(4);
}
return 1;
}
// Fetch the UUID
virtual uuid FetchUUID() {
return src_uuid;
}
// Data placeholder for the packet source tracker to record who we are for
// much faster per-packet handling (per-frame map lookups = bad)
virtual void SetSourceID(uint16_t in_id) { source_id = in_id; }
virtual uint16_t FetchSourceID() { return source_id; }
// Set DLT de-mangling
virtual void SetDLTMangle(int in_mangle) { dlt_mangle = in_mangle; }
// Mangle a packet from capture to 80211 pure + chain elements
virtual int ManglePacket(kis_packet *packet, kis_datachunk *linkchunk) { return 0; }
// Manage the interface
virtual int EnableMonitor() = 0;
virtual int DisableMonitor() = 0;
// Set the card to a channel w/ a given modulation
virtual int SetChannel(unsigned int in_ch) = 0;
// Fetch supported channels from hardware, if we can
virtual vector<unsigned int> FetchSupportedChannels(string in_interface) {
vector<unsigned int> ret;
return ret;
}
// Open the packet source
virtual int OpenSource() = 0;
virtual int CloseSource() = 0;
// Get the last channel we know we set
virtual int FetchChannel() { return last_channel; }
virtual int FetchChannelMod() { return last_mod; }
// Get the hardware channel
virtual int FetchHardwareChannel() { return 0; }
// Get a pollable file descriptor (usually from pcap)
virtual int FetchDescriptor() = 0;
// Trigger a fetch of a pending packet(s) and inject it into
// the packet chain, may inject multiple packets for one call
virtual int Poll() = 0;
// Fetch info about how we were built
virtual string FetchName() { return name; }
virtual string FetchInterface() { return interface; }
virtual string FetchType() { return type; }
// Fetch number of packets we've processed
virtual int FetchNumPackets() { return num_packets; }
// Add a packet to the count (for packetsourcetracker to increment us for IPC
// packets)
virtual void AddPacketCount() { num_packets++; }
// Pause/resume listening to this source (what this means depends on
// the implementation of polling)
void Pause() { paused = 1; };
void Resume() { paused = 0; };
virtual void SetFCSBytes(int in_bytes) { fcsbytes = in_bytes; }
virtual unsigned int FetchFCSBytes() { return fcsbytes; }
virtual void SetValidateCRC(int in_validate) {
validate_fcs = in_validate;
}
virtual unsigned int FetchValidateCRC() { return validate_fcs; }
// Set and fetch the carriers this source understands
virtual void SetCarrierSet(int in_set) { carrier_set = in_set; }
virtual int FetchCarrierSet() { return carrier_set; }
// Generic-level per packet parameters
virtual packet_parm FetchGenericParms() { return genericparms; }
// Return if we're channel capable or not, used for deriving hop
virtual int FetchChannelCapable() { return channel_capable; }
// Return the maximum hop velocity we support (if the source is known
// to have problems at higher velocities, this can be used to limit it)
// By default all sources can hop as fast as the Kismet timer, 10x a second
virtual int FetchChannelMaxVelocity() { return 10; }
virtual int FetchSkipChanhop() { return 0; }
virtual int FetchError() { return error; }
virtual string FetchWarning() { return warning; }
protected:
virtual void FetchRadioData(kis_packet *in_packet) = 0;
GlobalRegistry *globalreg;
int die_on_fatal;
int paused;
int error;
uint16_t source_id;
// Name, interface
string name;
string interface;
string type;
// Unique identifier for this capture source
uuid src_uuid;
int dlt_mangle;
// Bytes in the FCS
unsigned int fcsbytes;
// Are we channel capable?
int channel_capable;
// Are the FCS bytes coming from this source valid?
// (ie, do we validate FCS and log FCS bytes?)
unsigned int validate_fcs;
unsigned int *crc32_table;
// Total packets
unsigned int num_packets;
// Last channel & mod we set
int last_channel;
packetsource_channel_mod last_mod;
int consec_error;
// Set of carrier types
int carrier_set;
// Generic packetsource optional parameters
packet_parm genericparms;
// Warning state
string warning;
};
// Packetchain reference for packet sources to be attached to the
// item captured
class kis_ref_capsource : public packet_component {
public:
KisPacketSource *ref_source;
kis_ref_capsource() {
self_destruct = 1; // We're just a ptr container
ref_source = NULL;
}
~kis_ref_capsource() { };
};
#endif
|