Skip to content

Commit

Permalink
Split prism2 DLT out of packetsource_pcap
Browse files Browse the repository at this point in the history
Fix DLTs to use dynamically sourced packcomp_... refs instead of old style
 array (better example for non-integrated plugins)
Fix radiotype to put FCS data in the checksum packet component
Remove debug output on broken fcs in radiotap
  • Loading branch information
dragorn committed Dec 22, 2011
1 parent c6aaa1d commit 4732916
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 231 deletions.
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ PSO = util.o cygwin_utils.o globalregistry.o ringbuf.o \
packetchain.o \
plugintracker.o alertracker.o timetracker.o \
devicetracker.o netracker.o channeltracker.o \
kis_dlt.o kis_dlt_ppi.o kis_dlt_radiotap.o \
kis_dlt.o kis_dlt_ppi.o kis_dlt_radiotap.o kis_dlt_prism2.o \
phy_80211.o phy_80211_dissectors.o \
manuf.o \
dumpfile.o dumpfile_pcap.o dumpfile_gpsxml.o \
Expand Down
7 changes: 7 additions & 0 deletions kis_dlt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ Kis_DLT_Handler::Kis_DLT_Handler(GlobalRegistry *in_globalreg) {
globalreg->packetchain->RegisterPacketComponent("DECAP");
pack_comp_capsrc =
globalreg->packetchain->RegisterPacketComponent("KISCAPSRC");
pack_comp_radiodata =
globalreg->packetchain->RegisterPacketComponent("RADIODATA");
pack_comp_gps =
globalreg->packetchain->RegisterPacketComponent("GPS");
pack_comp_checksum =
globalreg->packetchain->RegisterPacketComponent("CHECKSUM");

}

Kis_DLT_Handler::~Kis_DLT_Handler() {
Expand Down
3 changes: 2 additions & 1 deletion kis_dlt.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class Kis_DLT_Handler {
string dlt_name;
int dlt;
int chainid;
int pack_comp_linkframe, pack_comp_decap, pack_comp_capsrc;
int pack_comp_linkframe, pack_comp_decap, pack_comp_capsrc,
pack_comp_radiodata, pack_comp_gps, pack_comp_checksum;
};

#endif
Expand Down
9 changes: 4 additions & 5 deletions kis_dlt_ppi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ int Kis_DLT_PPI::HandlePacket(kis_packet *in_pack) {
data_offt += 4;
}

in_pack->insert(_PCM(PACK_COMP_GPS), gpsinfo);
in_pack->insert(pack_comp_gps, gpsinfo);
}
}
}
Expand All @@ -274,8 +274,8 @@ int Kis_DLT_PPI::HandlePacket(kis_packet *in_pack) {
memcpy(decapchunk->data, linkchunk->data + ph_len, decapchunk->length);

if (radioheader != NULL)
in_pack->insert(_PCM(PACK_COMP_RADIODATA), radioheader);
in_pack->insert(_PCM(PACK_COMP_DECAP), decapchunk);
in_pack->insert(pack_comp_radiodata, radioheader);
in_pack->insert(pack_comp_decap, decapchunk);

kis_packet_checksum *fcschunk = NULL;
if (applyfcs && linkchunk->length > 4) {
Expand All @@ -290,7 +290,7 @@ int Kis_DLT_PPI::HandlePacket(kis_packet *in_pack) {
else
fcschunk->checksum_valid = 1;

in_pack->insert(_PCM(PACK_COMP_CHECKSUM), fcschunk);
in_pack->insert(pack_comp_checksum, fcschunk);
}

// If we're validating the FCS
Expand All @@ -303,7 +303,6 @@ int Kis_DLT_PPI::HandlePacket(kis_packet *in_pack) {
if (memcmp(fcschunk->checksum_ptr, &calc_crc, 4)) {
in_pack->error = 1;
fcschunk->checksum_valid = 0;
fprintf(stderr, "debug - rtap to kis, fcs invalid\n");
} else {
fcschunk->checksum_valid = 1;
}
Expand Down
278 changes: 278 additions & 0 deletions kis_dlt_prism2.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
/*
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
*/

/* DLT handler framework */

#include "config.h"

#include "globalregistry.h"
#include "util.h"
#include "endian_magic.h"
#include "messagebus.h"
#include "packet.h"
#include "packetchain.h"
#include "packetsource.h"
#include "gpscore.h"

#include "kis_dlt_prism2.h"

#define WLAN_DEVNAMELEN_MAX 16

// Prism 802.11 headers from wlan-ng tacked on to the beginning of a
// pcap packet... Snagged from the wlan-ng source
typedef struct {
uint32_t did;
uint16_t status;
uint16_t len;
uint32_t data;
} __attribute__((__packed__)) p80211item_uint32_t;

typedef struct {
uint32_t msgcode;
uint32_t msglen;
uint8_t devname[WLAN_DEVNAMELEN_MAX];
p80211item_uint32_t hosttime;
p80211item_uint32_t mactime;
p80211item_uint32_t channel;
p80211item_uint32_t rssi;
p80211item_uint32_t sq;
p80211item_uint32_t signal;
p80211item_uint32_t noise;
p80211item_uint32_t rate;
p80211item_uint32_t istx;
p80211item_uint32_t frmlen;
} __attribute__((__packed__)) wlan_ng_prism2_header;

// wlan-ng (and hopefully others) AVS header, version one. Fields in
// network byte order.
typedef struct {
uint32_t version;
uint32_t length;
uint64_t mactime;
uint64_t hosttime;
uint32_t phytype;
uint32_t channel;
uint32_t datarate;
uint32_t antenna;
uint32_t priority;
uint32_t ssi_type;
int32_t ssi_signal;
int32_t ssi_noise;
uint32_t preamble;
uint32_t encoding;
} avs_80211_1_header;

Kis_DLT_Prism2::Kis_DLT_Prism2(GlobalRegistry *in_globalreg) :
Kis_DLT_Handler(in_globalreg) {

dlt_name = "Prism2";
dlt = DLT_PRISM_HEADER;

globalreg->InsertGlobal("DLT_PRISM2", this);

_MSG("Registering support for DLT_Prism2 packet header decoding", MSGFLAG_INFO);
}

Kis_DLT_Prism2::~Kis_DLT_Prism2() {
globalreg->InsertGlobal("DLT_Prism2", NULL);
}

int Kis_DLT_Prism2::HandlePacket(kis_packet *in_pack) {
kis_datachunk *decapchunk =
(kis_datachunk *) in_pack->fetch(pack_comp_decap);

if (decapchunk != NULL) {
// printf("debug - dltPrism2 frame already decapped\n");
return 1;
}

kis_datachunk *linkchunk =
(kis_datachunk *) in_pack->fetch(pack_comp_linkframe);

if (linkchunk == NULL) {
// printf("debug - dltPrism2 no link\n");
return 1;
}

if (linkchunk->dlt != dlt) {
return 1;
}

kis_ref_capsource *capsrc =
(kis_ref_capsource *) in_pack->fetch(pack_comp_capsrc);

if (capsrc == NULL) {
// printf("debug - no capsrc?\n");
return 1;
}

int callback_offset = 0;
char errstr[STATUS_MAX] = "";

// Make a datachunk for the reformatted frame
kis_layer1_packinfo *radioheader = NULL;

int fcsbytes = capsrc->ref_source->FetchFCSBytes();

// See if we have an AVS wlan header...
avs_80211_1_header *v1hdr = (avs_80211_1_header *) linkchunk->data;
if (linkchunk->length >= sizeof(avs_80211_1_header) &&
ntohl(v1hdr->version) == 0x80211001) {

if (ntohl(v1hdr->length) > linkchunk->length ||
linkchunk->length < (ntohl(v1hdr->length) + fcsbytes)) {
snprintf(errstr, STATUS_MAX, "pcap prism2 converter got corrupted "
"AVS header length");
globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR);
return 0;
}

decapchunk = new kis_datachunk;
radioheader = new kis_layer1_packinfo;

decapchunk->dlt = KDLT_IEEE802_11;

// Subtract the packet FCS since kismet doesn't do anything terribly bright
// with it right now, also subtract the avs header. We have to obey the
// header length here since avs could change
decapchunk->length = kismin((linkchunk->length - ntohl(v1hdr->length) -
fcsbytes), (uint32_t) MAX_PACKET_LEN);
callback_offset = ntohl(v1hdr->length);

// We REALLY need to do something smarter about this and handle the RSSI
// type instead of just copying
radioheader->signal_rssi = ntohl(v1hdr->ssi_signal);
radioheader->noise_rssi = ntohl(v1hdr->ssi_noise);

radioheader->freq_mhz = ChanToFreq(ntohl(v1hdr->channel));

switch (ntohl(v1hdr->phytype)) {
case 1:
radioheader->carrier = carrier_80211fhss;
break;
case 2:
radioheader->carrier = carrier_80211dsss;
break;
case 4:
case 5:
radioheader->carrier = carrier_80211b;
break;
case 6:
case 7:
radioheader->carrier = carrier_80211g;
break;
case 8:
radioheader->carrier = carrier_80211a;
break;
default:
radioheader->carrier = carrier_unknown;
break;
}

radioheader->encoding = (phy_encoding_type) ntohl(v1hdr->encoding);

radioheader->datarate = (int) ntohl(v1hdr->datarate);
}

// See if we have a prism2 header
wlan_ng_prism2_header *p2head = (wlan_ng_prism2_header *) linkchunk->data;
if (linkchunk->length >= (sizeof(wlan_ng_prism2_header) + fcsbytes) &&
radioheader == NULL) {

decapchunk = new kis_datachunk;
radioheader = new kis_layer1_packinfo;

decapchunk->dlt = KDLT_IEEE802_11;

#if 0
// Subtract the packet FCS since kismet doesn't do anything terribly bright
// with it right now
if (p2head->frmlen.data < fcsbytes) {
snprintf(errstr, STATUS_MAX, "pcap prism2 converter got corrupted "
"wlanng-header frame length");
globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR);
return 0;
}
#endif

// We don't pay attention to the length provided by prism2hdr, since
// some drivers get it wrong
decapchunk->length = kismin((linkchunk->length -
sizeof(wlan_ng_prism2_header) - fcsbytes),
(uint32_t) MAX_PACKET_LEN);

#if 0
decapchunk->length = kismin((p2head->frmlen.data - fcsbytes),
(uint32_t) MAX_PACKET_LEN);
#endif

// Set our offset for extracting the actual data
callback_offset = sizeof(wlan_ng_prism2_header);

radioheader->signal_rssi = p2head->signal.data;
radioheader->noise_rssi = p2head->noise.data;

radioheader->freq_mhz = ChanToFreq(p2head->channel.data);
}

if (radioheader == NULL) {
snprintf(errstr, STATUS_MAX, "pcap prism2 converter saw strange "
"capture frame (PRISM80211 linktype, unable to determine "
"prism headers)");
globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR);
return 0;
}

decapchunk->data = new uint8_t[decapchunk->length];
memcpy(decapchunk->data, linkchunk->data + callback_offset, decapchunk->length);

in_pack->insert(pack_comp_radiodata, radioheader);
in_pack->insert(pack_comp_decap, decapchunk);

kis_packet_checksum *fcschunk = NULL;
if (fcsbytes && linkchunk->length > 4) {
fcschunk = new kis_packet_checksum;

fcschunk->set_data(&(linkchunk->data[linkchunk->length - 4]), 4);
// Valid until proven otherwise
fcschunk->checksum_valid = 1;

in_pack->insert(pack_comp_checksum, fcschunk);
}

// If we're validating the FCS
if (capsrc->ref_source->FetchValidateCRC() && fcschunk != NULL) {
// Compare it and flag the packet
uint32_t calc_crc =
crc32_le_80211(globalreg->crc32_table, decapchunk->data,
decapchunk->length);

if (memcmp(fcschunk->checksum_ptr, &calc_crc, 4)) {
in_pack->error = 1;
fcschunk->checksum_valid = 0;
// fprintf(stderr, "debug - rtap to kis, fcs invalid\n");
} else {
fcschunk->checksum_valid = 1;
}
}


return 1;
}


Loading

0 comments on commit 4732916

Please sign in to comment.