From be7ad82766648202f69afea3f59b672319124dcc Mon Sep 17 00:00:00 2001 From: dragorn Date: Sat, 21 Nov 2009 21:20:06 +0000 Subject: [PATCH] v2 of Kismet plugin, initial commit (semi-working state) git-svn-id: https://dedected.org/svn/trunk@90 8d8ab74c-27aa-4a3d-9bde-523a2bc1f624 --- kismet-dect-v2/Makefile | 41 ++++ kismet-dect-v2/README | 3 + kismet-dect-v2/kismet_dect.cc | 203 ++++++++++++++++++++ kismet-dect-v2/packet_dect.h | 70 +++++++ kismet-dect-v2/packetsource_dect.cc | 277 ++++++++++++++++++++++++++++ kismet-dect-v2/packetsource_dect.h | 124 +++++++++++++ kismet-dect-v2/tracker_dect.cc | 203 ++++++++++++++++++++ kismet-dect-v2/tracker_dect.h | 75 ++++++++ 8 files changed, 996 insertions(+) create mode 100644 kismet-dect-v2/Makefile create mode 100644 kismet-dect-v2/README create mode 100644 kismet-dect-v2/kismet_dect.cc create mode 100644 kismet-dect-v2/packet_dect.h create mode 100644 kismet-dect-v2/packetsource_dect.cc create mode 100644 kismet-dect-v2/packetsource_dect.h create mode 100644 kismet-dect-v2/tracker_dect.cc create mode 100644 kismet-dect-v2/tracker_dect.h diff --git a/kismet-dect-v2/Makefile b/kismet-dect-v2/Makefile new file mode 100644 index 0000000..6afe87b --- /dev/null +++ b/kismet-dect-v2/Makefile @@ -0,0 +1,41 @@ +# You will need kismet newcore sources +KIS_SRC_DIR ?= /usr/src/kismet +KIS_INC_DIR ?= $(KIS_SRC_DIR) + +include $(KIS_SRC_DIR)/Makefile.inc + +BLDHOME = . +top_builddir = $(BLDHOME) + +PLUGINLDFLAGS ?= $(LDFLAGS) +PLUGINLDFLAGS += -shared -rdynamic +LIBS += -lstdc++ +CFLAGS += -I/usr/include -I$(KIS_INC_DIR) -g -fPIC + +SRVOBJS = packetsource_dect.o tracker_dect.o kismet_dect.o +SRVOUT = dedected.so + +all: $(SRVOUT) + +$(SRVOUT): $(SRVOBJS) + $(LD) $(PLUGINLDFLAGS) $(SRVOBJS) -o $(SRVOUT) $(LIBS) + +install: $(SRVOUT) + mkdir -p $(DESTDIR)$(prefix)/lib/kismet/ + install -o $(INSTUSR) -g $(INSTGRP) -m 644 $(SRVOUT) $(DESTDIR)$(prefix)/lib/kismet/$(SRVOUT) + +userinstall: $(SRVOUT) + mkdir -p ${HOME}/.kismet/plugins/ + install -v $(SRVOUT) ${HOME}/.kismet/plugins/$(SRVOUT) + +clean: + @-rm -f *.o + @-rm -f *.so + +.c.o: + $(CC) $(CFLAGS) -c $*.c -o $@ + +.cc.o: + $(CXX) $(CFLAGS) -c $*.cc -o $@ + +.SUFFIXES: .c .cc .o diff --git a/kismet-dect-v2/README b/kismet-dect-v2/README new file mode 100644 index 0000000..ed79cb0 --- /dev/null +++ b/kismet-dect-v2/README @@ -0,0 +1,3 @@ +Kismet-Dect v2 + +*** Currently under development, not intended for use yet diff --git a/kismet-dect-v2/kismet_dect.cc b/kismet-dect-v2/kismet_dect.cc new file mode 100644 index 0000000..811aad7 --- /dev/null +++ b/kismet-dect-v2/kismet_dect.cc @@ -0,0 +1,203 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "packetsource_dect.h" +#include "tracker_dect.h" + +GlobalRegistry *globalreg = NULL; + +int pack_comp_dect; + +kis_datachunk *dumpfile_dect_filter(DUMPFILE_PCAP_FILTER_PARMS) { + kis_datachunk *link = (kis_datachunk *) in_pack->fetch(_PCM(PACK_COMP_LINKFRAME)); + + if (link == NULL) + return NULL; + + if (link->dlt == KDLT_DECT) + return link; + + return NULL; +} + +int cmd_SETDECTMODE(CLIENT_PARMS) { + if (parsedcmdline->size() < 2) { + snprintf(errstr, 1024, "Illegal SETDECTMODE command, expected UUID, mode"); + return -1; + } + + uuid inuuid = uuid((*parsedcmdline)[0].word); + + if (inuuid.error) { + snprintf(errstr, 1024, "Invalid UUID in SETDECTMODE command"); + return -1; + } + + pst_packetsource *pstsource = + globalreg->sourcetracker->FindLivePacketSourceUUID(inuuid); + + if (pstsource == NULL || pstsource->strong_source == NULL) { + snprintf(errstr, 1024, "Invalid UUID in SETDECTMODE command, couldn't find " + "source with UUID %s", inuuid.UUID2String().c_str()); + return -1; + } + + if (pstsource->strong_source->FetchType() != "dect" && + pstsource->strong_source->FetchType() != "dectus") { + snprintf(errstr, 1024, "Invalid source in SETDECTMODE, source with UUID %s " + "doesn't look like a DECT device", inuuid.UUID2String().c_str()); + return -1; + } + + string mode = StrLower((*parsedcmdline)[1].word); + + if (mode == "fpscan") { + if (((PacketSource_Dect *) pstsource->strong_source)->StartScanFp() < 0) { + snprintf(errstr, 1024, "DECT source failed to start FP scan mode on " + "source %s", inuuid.UUID2String().c_str()); + return -1; + } + + if (globalreg->sourcetracker->SetSourceHopping(inuuid, 1, 0) < 0) { + snprintf(errstr, 1024, "DECT source failed to turn on hopping for FP " + "scan mode on source %s", inuuid.UUID2String().c_str()); + return -1; + } + + return 1; + } else if (mode == "ppscan") { + if (parsedcmdline->size() < 4) { + snprintf(errstr, 1024, "Illegal SETDECTMODE command, expected UUID " + "ppscan rfpi channel"); + return -1; + } + + // Hack into a macaddr + mac_addr inrfpi = mac_addr(string((*parsedcmdline)[2].word + ":00")); + + if (inrfpi.error) { + snprintf(errstr, 1024, "Invalid RFPI in SETDECTMODE ppscan command"); + return -1; + } + + unsigned int inchan; + if (sscanf((*parsedcmdline)[3].word.c_str(), "%u", &inchan) != 1) { + snprintf(errstr, 1024, "Invalid channel in SETDECTMODE ppscan command"); + } + + if (((PacketSource_Dect *) pstsource->strong_source)->StartScanPp(inrfpi) < 0) { + snprintf(errstr, 1024, "DECT source failed to start PP scan mode on " + "source %s", inuuid.UUID2String().c_str()); + return -1; + } + + if (globalreg->sourcetracker->SetSourceHopping(inuuid, 0, inchan) < 0) { + snprintf(errstr, 1024, "DECT source failed to turn off hopping for PP " + "scan mode on source %s", inuuid.UUID2String().c_str()); + return -1; + } + + return 1; + } +} + +int dect_unregister(GlobalRegistry *in_globalreg) { + return 0; +} + +int dect_register(GlobalRegistry *in_globalreg) { + globalreg = in_globalreg; + + globalreg->sourcetracker->AddChannelList("DECT:0,1,2,3,4,5,6,7,8,9"); + globalreg->sourcetracker->AddChannelList("DECTUS:0,1,2,3,4,5,6,7,8,9,23,24,25,26,27"); + + if (globalreg->sourcetracker->RegisterPacketSource(new PacketSource_Dect(globalreg)) < 0 || globalreg->fatal_condition) { + return -1; + } + + pack_comp_dect = + globalreg->packetchain->RegisterPacketComponent("DECT"); + + // dumpfile that inherits from the global one, with a hack in the matcher to + // pick the dect packets out but log them as EN10MB + Dumpfile_Pcap *dectdump; + dectdump = + new Dumpfile_Pcap(globalreg, "pcapdect", DLT_EN10MB, + globalreg->pcapdump, dumpfile_dect_filter, NULL); + dectdump->SetVolatile(1); + + Tracker_Dect *trackdect; + trackdect = new Tracker_Dect(globalreg); + + return 1; +} + +extern "C" { + int kis_plugin_info(plugin_usrdata *data) { + data->pl_name = "DECT"; + data->pl_version = "2.0.0"; + data->pl_description = "DECT phy plugin"; + data->pl_unloadable = 0; // We can't be unloaded because we defined a source + data->plugin_register = dect_register; + data->plugin_unregister = dect_unregister; + + return 1; + } + + void kis_revision_info(plugin_revision *prev) { + if (prev->version_api_revision >= 1) { + prev->version_api_revision = 1; + prev->major = string(VERSION_MAJOR); + prev->minor = string(VERSION_MINOR); + prev->tiny = string(VERSION_TINY); + } + } +} + + diff --git a/kismet-dect-v2/packet_dect.h b/kismet-dect-v2/packet_dect.h new file mode 100644 index 0000000..65f998b --- /dev/null +++ b/kismet-dect-v2/packet_dect.h @@ -0,0 +1,70 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw + +// Internal DLT - -0xDEC +#define KDLT_DECT -3564 + +extern int pack_comp_dect; + +/* This is the 7 bytes we read while scanning */ +typedef struct { + uint8_t channel; + uint8_t RSSI; + uint8_t RFPI[5]; +} dect_data_scan_t; + +typedef struct { + unsigned char rssi; + unsigned char channel; + unsigned char slot; + struct timespec timestamp; + unsigned char data[53]; +} pp_packet_t; + +class dect_packinfo : public packet_component { +public: + dect_packinfo() { + self_destruct = 1; + memset(&sdata, 0, sizeof(dect_data_scan_t)); + memset(&pdata, 0, sizeof(pp_packet_t)); + scanmode = -1; + sync = false; + channel = 0; + } + + dect_data_scan_t sdata; + pp_packet_t pdata; + int scanmode; + bool sync; + uint16_t channel; +}; + +#endif + diff --git a/kismet-dect-v2/packetsource_dect.cc b/kismet-dect-v2/packetsource_dect.cc new file mode 100644 index 0000000..85d2269 --- /dev/null +++ b/kismet-dect-v2/packetsource_dect.cc @@ -0,0 +1,277 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw +#include "packet_dect.h" +#include "packetsource_dect.h" + +PacketSource_Dect::PacketSource_Dect(GlobalRegistry *in_globalreg): + KisPacketSource(in_globalreg) { + + serial_fd = -1; + sync = false; + scan_mode = MODE_ASYNC_FP_SCAN; +} + +PacketSource_Dect::PacketSource_Dect(GlobalRegistry *in_globalreg, string in_interface, + vector *in_opts) : + KisPacketSource(in_globalreg, in_interface, in_opts) { + + serial_fd = -1; + sync = false; + scan_mode = MODE_ASYNC_FP_SCAN; + + ParseOptions(in_opts); +} + +PacketSource_Dect::~PacketSource_Dect() { + if (serial_fd >= 0) { + close(serial_fd); + serial_fd = -1; + } +} + +int PacketSource_Dect::AutotypeProbe(string in_device) { + if (StrLower(in_device) == "dect") { + type = "dect"; + return 1; + } + + if (StrLower(in_device) == "dectus") { + type = "dectus"; + return 1; + } + + return 0; +} + +int PacketSource_Dect::ParseOptions(vector *in_opts) { + if ((serialdevice = FetchOpt("device", in_opts)) == "") { + _MSG("DECT packet source defaulting to default serial /dev/coa", + MSGFLAG_INFO); + serialdevice = "/dev/coa"; + } else { + _MSG("DECT packet source using serial device " + serialdevice, + MSGFLAG_INFO); + } + + return 1; +} + +int PacketSource_Dect::FetchDescriptor() { + return serial_fd; +} + +int PacketSource_Dect::SetChannel(unsigned int in_ch) { + if (ioctl(serial_fd, COA_IOCTL_CHAN, &in_ch)) { + _MSG("DECT packet source '" + name + "': Failed to set channel: " + + string(strerror(errno)), MSGFLAG_ERROR); + return 0; + } + + last_channel = in_ch; + + // printf("debug - dect set channel %u\n", in_ch); + + return 1; +} + +int PacketSource_Dect::StartScanPp(mac_addr in_rfpi) { + if (serial_fd == -1) + return -1; + + /* always accept mode set since we might change RFPI */ + /* remove the sync early since we've disrupted the state of the world */ + + if (sync) { + sync = false; + } + + /* Set sync sniff mode */ + uint16_t val; + val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SYNC; + if (ioctl(serial_fd, COA_IOCTL_MODE, &val)) { + _MSG("DECT packet source '" + name + "': Failed to set sniffer mode PP: " + + string(strerror(errno)), MSGFLAG_ERROR); + return -1; + } + + /* set RFPI to sync with */ + uint8_t mrfpi[5]; + for (unsigned int x = 0; x < 5; x++) + mrfpi[x] = in_rfpi[x]; + + if (ioctl(serial_fd, COA_IOCTL_SETRFPI, mrfpi)) { + _MSG("DECT packet source '" + name + "': Failed to set PP RFPI: " + + string(strerror(errno)), MSGFLAG_ERROR); + return -1; + } + + scan_mode = MODE_ASYNC_PP_SCAN; + + // Caller should turn off PST channel hopping and set channel + // globalreg->sourcetracker->SetSourceHopping(FetchUUID(), 0, 0); + + return 1; +} + +int PacketSource_Dect::StartScanCalls(mac_addr in_rfpi, int in_channel) { + if (serial_fd == -1) + return -1; + + if (sync) + sync = false; + + /* Set sync sniff mode */ + uint16_t val; + + val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SYNC; + + if (ioctl(serial_fd, COA_IOCTL_MODE, &val)) { + _MSG("DECT packet source '" + name + "': Failed to set sniffer mode SYNC: " + + string(strerror(errno)), MSGFLAG_ERROR); + return -1; + } + + /* set RFPI we're syncing to */ + uint8_t mrfpi[5]; + for (unsigned int x = 0; x < 5; x++) + mrfpi[x] = in_rfpi[x]; + + if (ioctl(serial_fd, COA_IOCTL_SETRFPI, mrfpi)) { + _MSG("DECT packet source '" + name + "': Failed to set sniffer sync RFPI: " + + string(strerror(errno)), MSGFLAG_ERROR); + return -1; + } + + scan_mode = MODE_SYNC_CALL_SCAN; + + // Caller should turn off PST channel hopping + // globalreg->sourcetracker->SetSourceHopping(FetchUUID(), 0, in_channel); + + return 1; +} + +int PacketSource_Dect::StartScanFp() { + if (serial_fd == -1) + return -1; + + if (scan_mode == MODE_ASYNC_FP_SCAN) + return 0; + + /* start sniffer mode */ + int val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SCANFP; + + if (ioctl(serial_fd, COA_IOCTL_MODE, &val)) { + _MSG("DECT packet source '" + name + "': Failed to set sniffer scan FP: " + + string(strerror(errno)), MSGFLAG_ERROR); + return -1; + } + + scan_mode = MODE_ASYNC_FP_SCAN; + + if (sync) + sync = false; + + // Caller should turn on hopping + // globalreg->sourcetracker->SetSourceHopping(FetchUUID(), 1, 0); + + return 1; +} + +int PacketSource_Dect::OpenSource() { + if ((serial_fd = open(serialdevice.c_str(), O_RDONLY)) == -1) { + _MSG("DECT packet source '" + name + "': Failed to open DECT serial device: " + + string(strerror(errno)), MSGFLAG_ERROR); + return 0; + } + + return StartScanFp(); +} + +int PacketSource_Dect::CloseSource() { + if (serial_fd >= 0) { + close(serial_fd); + serial_fd = -1; + } + + return 1; +} + +int PacketSource_Dect::Poll() { + unsigned char buf[7]; + int rbytes = -1; + dect_packinfo *pi = new dect_packinfo; + kis_packet *newpack; + kis_datachunk *callchunk = NULL; + + pi->sync = sync; + pi->scanmode = scan_mode; + pi->channel = FetchChannel(); + + if (scan_mode == MODE_ASYNC_FP_SCAN || scan_mode == MODE_ASYNC_PP_SCAN) { + if ((rbytes = read(serial_fd, &(pi->sdata), sizeof(dect_data_scan_t))) != + sizeof(dect_data_scan_t)) { + _MSG("DECT packet source '" + name + "': Failed to read scan data: " + + string(strerror(errno)), MSGFLAG_ERROR); + delete(pi); + return 0; + } + } else if (scan_mode == MODE_SYNC_CALL_SCAN) { + if ((rbytes = read(serial_fd, &(pi->pdata), sizeof(pp_packet_t))) != + sizeof(pp_packet_t)) { + _MSG("DECT packet source '" + name + "': Failed to read scan data: " + + string(strerror(errno)), MSGFLAG_ERROR); + delete(pi); + return 0; + } else { + if (!sync) { + _MSG("DECT packet source '" + name + "': Synced to call", MSGFLAG_INFO); + sync = true; + } + + // Make a data chunk + callchunk = new kis_datachunk; + callchunk->length = 53; + callchunk->data = new uint8_t[callchunk->length]; + memcpy(callchunk->data, pi->pdata.data, callchunk->length); + callchunk->source_id = source_id; + callchunk->dlt = KDLT_DECT; + } + } else { + // Unknown mode during poll + delete(pi); + return 0; + } + + newpack = globalreg->packetchain->GeneratePacket(); + newpack->insert(pack_comp_dect, pi); + if (callchunk) + newpack->insert(_PCM(PACK_COMP_LINKFRAME), callchunk); + globalreg->packetchain->ProcessPacket(newpack); + + return 1; +} + diff --git a/kismet-dect-v2/packetsource_dect.h b/kismet-dect-v2/packetsource_dect.h new file mode 100644 index 0000000..ed1ecc7 --- /dev/null +++ b/kismet-dect-v2/packetsource_dect.h @@ -0,0 +1,124 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw +#include + +#define USE_PACKETSOURCE_DECT + +#define MODE_ASYNC_FP_SCAN 0 +#define MODE_ASYNC_PP_SCAN 1 +#define MODE_SYNC_CALL_SCAN 2 + +#define COA_IOCTL_MODE 0xD000 +#define COA_IOCTL_CHAN 0xD004 +#define COA_IOCTL_SETRFPI 0xD008 +#define COA_MODE_SNIFF 0x0300 +#define COA_SUBMODE_SNIFF_ALL 0x0000 +#define COA_SUBMODE_SNIFF_SCANFP 0x0001 +#define COA_SUBMODE_SNIFF_SCANPP 0x0002 +#define COA_SUBMODE_SNIFF_SYNC 0x0003 + + +/* DECT Client Command Defs */ +#define DECT_CMD_START 0 +#define DECT_CMD_END 9 +#define DECT_SUBCMD_START 0 +#define DECT_SUBCMD_END 9 + +/* Commands */ +#define DECT_CMD_CHANHOP 0 +#define DECT_CMD_SCAN 1 + +/* Subcommands */ +#define DECT_SUBCMD_CHANHOP_ENABLE 1 +#define DECT_SUBCMD_CHANHOP_DISABLE 0 +#define DECT_SUBCMD_SCAN_FP 0 +#define DECT_SUBCMD_SCAN_PP 1 +#define DECT_SUBCMD_SCAN_CALLS 2 + +class PacketSource_Dect : public KisPacketSource { +public: + PacketSource_Dect() { + fprintf(stderr, "FATAL OOPS: Packetsource_Raven()\n"); + exit(1); + } + + PacketSource_Dect(GlobalRegistry *in_globalreg); + + virtual KisPacketSource *CreateSource(GlobalRegistry *in_globalreg, + string in_interface, + vector *in_opts) { + return new PacketSource_Dect(in_globalreg, in_interface, in_opts); + } + + virtual int AutotypeProbe(string in_device); + + virtual int RegisterSources(Packetsourcetracker *tracker) { + tracker->RegisterPacketProto("dect", this, "DECT", 0); + tracker->RegisterPacketProto("dectus", this, "DECTUS", 0); + return 1; + } + + PacketSource_Dect(GlobalRegistry *in_globalreg, string in_interface, + vector *in_opts); + + virtual ~PacketSource_Dect(); + + virtual int ParseOptions(vector *in_opts); + + virtual int OpenSource(); + virtual int CloseSource(); + + virtual int FetchChannelCapable() { return 1; } + virtual int EnableMonitor() { return 1; } + virtual int DisableMonitor() { return 1; } + + virtual int SetChannel(unsigned int in_ch); + + virtual int FetchDescriptor(); + virtual int Poll(); + + int StartScanFp(); + int StartScanPp(mac_addr in_rfpi); + int StartScanCalls(mac_addr in_rfpi, int in_channel); + +protected: + virtual void FetchRadioData(kis_packet *in_packet) { }; + + int dect_packet_id; + + int scan_mode; + + string serialdevice; + int serial_fd; + bool sync; + +}; + +#endif diff --git a/kismet-dect-v2/tracker_dect.cc b/kismet-dect-v2/tracker_dect.cc new file mode 100644 index 0000000..78a1805 --- /dev/null +++ b/kismet-dect-v2/tracker_dect.cc @@ -0,0 +1,203 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw +#include +#include + +#include "packet_dect.h" +#include "tracker_dect.h" +#include "packetsource_dect.h" + +enum DECTFP_fields { + DECTFP_rfpi, DECTFP_firsttime, DECTFP_lasttime, DECTFP_lastrssi, + DECTFP_num, DECTFP_channel, + DECTFP_maxfield +}; + +const char *DECTFP_fields_text[] = { + "rfpi", "firsttime", "lasttime", "lastrssi", + "num", "channel", + NULL +}; + +int Protocol_DECTFP(PROTO_PARMS) { + dect_tracked_fp *fp = (dect_tracked_fp *) data; + ostringstream osstr; + + cache->Filled(field_vec->size()); + + for (unsigned int x = 0; x < field_vec->size(); x++) { + unsigned int fnum = (*field_vec)[x]; + + if (fnum >= DECTFP_maxfield) { + out_string = "Unknown field requested."; + return -1; + } + + osstr.str(""); + + if (cache->Filled(fnum)) { + out_string += cache->GetCache(fnum) + " "; + continue; + } + + switch (fnum) { + case DECTFP_rfpi: + osstr << fp->rfpi.Mac2String().substr(0, 14); + break; + case DECTFP_firsttime: + osstr << fp->first_time; + break; + case DECTFP_lasttime: + osstr << fp->last_time; + break; + case DECTFP_lastrssi: + osstr << fp->last_rssi; + break; + case DECTFP_num: + osstr << fp->num_seen; + break; + case DECTFP_channel: + osstr << fp->channel; + break; + } + + out_string += osstr.str() + " "; + cache->Cache(fnum, osstr.str()); + } + + return 1; +} + +void Protocol_DECTFP_enable(PROTO_ENABLE_PARMS) { + ((Tracker_Dect *) data)->BlitFP(in_fd); +} + +int decttracktimer(TIMEEVENT_PARMS) { + ((Tracker_Dect *) parm)->BlitFP(-1); + return 1; +} + +int dect_chain_hook(CHAINCALL_PARMS) { + return ((Tracker_Dect *) auxdata)->chain_handler(in_pack); +} + +Tracker_Dect::Tracker_Dect(GlobalRegistry *in_globalreg) { + globalreg = in_globalreg; + + globalreg->packetchain->RegisterHandler(&dect_chain_hook, this, + CHAINPOS_CLASSIFIER, 0); + + DECTFP_ref = + globalreg->kisnetserver->RegisterProtocol("DECTFP", 0, 1, + DECTFP_fields_text, + &Protocol_DECTFP, + &Protocol_DECTFP_enable, + this); + + timer_ref = + globalreg->timetracker->RegisterTimer(SERVER_TIMESLICES_SEC, NULL, 1, + &decttracktimer, this); +} + +int Tracker_Dect::chain_handler(kis_packet *in_pack) { + dect_packinfo *di = (dect_packinfo *) in_pack->fetch(pack_comp_dect); + dect_tracked_fp *fp = NULL; + + if (di == NULL) + return 0; + + mac_addr rfpi_mac; + uint8_t mod_mac[6]; + + // If we're call data, don't process us (for now) + if (di->scanmode == MODE_SYNC_CALL_SCAN) { + return 0; + } + + // If we have a FP or PP packet, get the rfpi as mac address + if (di->scanmode == MODE_ASYNC_FP_SCAN || + di->scanmode == MODE_ASYNC_PP_SCAN) { + memcpy(mod_mac, di->sdata.RFPI, 5); + mod_mac[5] = 0; + rfpi_mac = mac_addr(mod_mac); + } else { + return 0; + } + + map::iterator dtfi = tracked_fp.find(rfpi_mac); + + if (dtfi == tracked_fp.end()) { + fp = new dect_tracked_fp; + + fp->first_time = globalreg->timestamp.tv_sec; + fp->channel = di->sdata.channel; + fp->rfpi = rfpi_mac; + tracked_fp[rfpi_mac] = fp; + // printf("debug - dect, new tracked FP %s\n", rfpi_mac.Mac2String().substr(0, 14).c_str()); + } else { + fp = dtfi->second; + } + + if (fp->channel != di->sdata.channel) { + _MSG("DECT Station " + rfpi_mac.Mac2String().substr(0, 14) + " changed channel " + "from " + IntToString(fp->channel) + " to " + + IntToString(di->sdata.channel), MSGFLAG_INFO); + fp->channel = di->sdata.channel; + } + + fp->last_time = globalreg->timestamp.tv_sec; + fp->num_seen++; + fp->last_rssi = di->sdata.RSSI; + fp->dirty = 1; + + return 0; +} + + +void Tracker_Dect::BlitFP(int in_fd) { + map::iterator x; + + for (x = tracked_fp.begin(); x != tracked_fp.end(); x++) { + kis_protocol_cache cache; + + if (in_fd == -1) { + if (x->second->dirty == 0) + continue; + + x->second->dirty = 0; + + if (globalreg->kisnetserver->SendToAll(DECTFP_ref, + (void *) x->second) < 0) + break; + } else { + if (globalreg->kisnetserver->SendToClient(in_fd, DECTFP_ref, + (void *) x->second, + &cache) < 0) + break; + } + } +} diff --git a/kismet-dect-v2/tracker_dect.h b/kismet-dect-v2/tracker_dect.h new file mode 100644 index 0000000..5a6ad5e --- /dev/null +++ b/kismet-dect-v2/tracker_dect.h @@ -0,0 +1,75 @@ +/* + 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 + + DECT source v2 + (c) 2008 by Mike Kershaw +#include + +#include "packet_dect.h" + +// Dect basestation +class dect_tracked_fp { +public: + dect_tracked_fp() { + first_time = last_time = 0; + last_rssi = 0; + num_seen = 0; + channel = 0; + dirty = 0; + } + + mac_addr rfpi; + time_t first_time, last_time; + unsigned int last_rssi; + unsigned int num_seen; + unsigned int channel; + unsigned int dirty; + + kis_gps_data gpsdata; +}; + +class Tracker_Dect { +public: + Tracker_Dect() { fprintf(stderr, "FATAL OOPS: tracker_dect()\n"); exit(1); } + Tracker_Dect(GlobalRegistry *in_globalreg); + + int chain_handler(kis_packet *in_pack); + + void BlitFP(int in_fd); + +protected: + GlobalRegistry *globalreg; + + map tracked_fp; + + int DECTFP_ref; + int timer_ref; + +}; + +#endif +