/* 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 __PACKET_H__ #define __PACKET_H__ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #include #include #include #include #include "macaddr.h" #include "endian_magic.h" #define DEVNAME_LEN 16 #define MAX_PACKET_LEN 10240 #define SSID_SIZE 255 #define MAC_LEN 6 #define MAC_STR_LEN ((MAC_LEN * 2) + 6) // Parmeters to the packet info struct packet_parm { int fuzzy_crypt; int fuzzy_decode; }; // Signalling layer info - what protocol are we seeing data on? // Not all of these types are currently supported, of course enum carrier_type { carrier_unknown, carrier_80211b, carrier_80211bplus, carrier_80211a, carrier_80211g, carrier_80211fhss, carrier_80211dsss, carrier_80211n20, carrier_80211n40 }; // Packet encoding info - how are packets encoded? enum encoding_type { encoding_unknown, encoding_cck, encoding_pbcc, encoding_ofdm }; // Very similar to pcap_pkthdr and wtap_pkthdr. This is our // common packet header that we convert everything to. typedef struct { unsigned int len; // The amount of data we've actually got unsigned int caplen; // The amount of data originally captured struct timeval ts; // Capture timestamp int quality; // Signal quality int signal; // Signal strength int noise; // Noise level int error; // Capture source told us this was a bad packet int channel; // Hardware receive channel, if the drivers tell us int modified; // Has moddata been populated? uint8_t *data; // Raw packet data uint8_t *moddata; // Modified packet data char sourcename[32]; // Name of the source that generated the data carrier_type carrier; // Signal carrier encoding_type encoding; // Signal encoding int datarate; // Data rate in units of 100 kbps float gps_lat; // GPS coordinates float gps_lon; float gps_alt; float gps_spd; float gps_heading; int gps_fix; packet_parm parm; // Parameters from the packet source that trickle down } kis_packet; #ifdef WORDS_BIGENDIAN // Byte ordering for bigendian systems. Bitwise strcts are so funky. typedef struct { unsigned short subtype : 4 __attribute__ ((packed)); unsigned short type : 2 __attribute__ ((packed)); unsigned short version : 2 __attribute__ ((packed)); unsigned short order : 1 __attribute__ ((packed)); unsigned short wep : 1 __attribute__ ((packed)); unsigned short more_data : 1 __attribute__ ((packed)); unsigned short power_management : 1 __attribute__ ((packed)); unsigned short retry : 1 __attribute__ ((packed)); unsigned short more_fragments : 1 __attribute__ ((packed)); unsigned short from_ds : 1 __attribute__ ((packed)); unsigned short to_ds : 1 __attribute__ ((packed)); } frame_control; typedef struct { unsigned short frag : 12 __attribute__ ((packed)); unsigned short sequence : 4 __attribute__ ((packed)); } wireless_fragseq; typedef struct { uint8_t timestamp[8]; // This field must be converted to host-endian before being used unsigned int beacon : 16 __attribute__ ((packed)); unsigned short agility : 1 __attribute__ ((packed)); unsigned short pbcc : 1 __attribute__ ((packed)); unsigned short short_preamble : 1 __attribute__ ((packed)); unsigned short wep : 1 __attribute__ ((packed)); unsigned short unused2 : 1 __attribute__ ((packed)); unsigned short unused1 : 1 __attribute__ ((packed)); unsigned short ibss : 1 __attribute__ ((packed)); unsigned short ess : 1 __attribute__ ((packed)); unsigned int coordinator : 8 __attribute__ ((packed)); } fixed_parameters; #else // And 802.11 packet frame header typedef struct { unsigned short version : 2 __attribute__ ((packed)); unsigned short type : 2 __attribute__ ((packed)); unsigned short subtype : 4 __attribute__ ((packed)); unsigned short to_ds : 1 __attribute__ ((packed)); unsigned short from_ds : 1 __attribute__ ((packed)); unsigned short more_fragments : 1 __attribute__ ((packed)); unsigned short retry : 1 __attribute__ ((packed)); unsigned short power_management : 1 __attribute__ ((packed)); unsigned short more_data : 1 __attribute__ ((packed)); unsigned short wep : 1 __attribute__ ((packed)); unsigned short order : 1 __attribute__ ((packed)); } frame_control; typedef struct { unsigned short frag : 4 __attribute__ ((packed)); unsigned short sequence : 12 __attribute__ ((packed)); } wireless_fragseq; typedef struct { uint8_t timestamp[8]; // This field must be converted to host-endian before being used unsigned int beacon : 16 __attribute__ ((packed)); unsigned short ess : 1 __attribute__ ((packed)); unsigned short ibss : 1 __attribute__ ((packed)); unsigned short unused1 : 1 __attribute__ ((packed)); unsigned short unused2 : 1 __attribute__ ((packed)); unsigned short wep : 1 __attribute__ ((packed)); unsigned short short_preamble : 1 __attribute__ ((packed)); unsigned short pbcc : 1 __attribute__ ((packed)); unsigned short agility : 1 __attribute__ ((packed)); unsigned int coordinator : 8 __attribute__ ((packed)); } fixed_parameters; #endif enum protocol_info_type { proto_unknown, proto_udp, proto_misc_tcp, proto_arp, proto_dhcp_server, proto_cdp, proto_netbios, proto_netbios_tcp, proto_ipx, proto_ipx_tcp, proto_turbocell, proto_netstumbler, proto_lucenttest, proto_wellenreiter, proto_iapp, proto_leap, proto_ttls, proto_tls, proto_peap, proto_isakmp, proto_pptp, }; enum protocol_netbios_type { proto_netbios_unknown, proto_netbios_host, proto_netbios_master, proto_netbios_domain, proto_netbios_query, proto_netbios_pdcquery }; // CDP // Cisco Discovery Protocol // This spews a tremendous amount of revealing information about the // internals of a network, if they have cisco equipment. typedef struct { unsigned int : 8 __attribute__ ((packed)); unsigned int : 8 __attribute__ ((packed)); unsigned int : 8 __attribute__ ((packed)); unsigned int : 1 __attribute__ ((packed)); unsigned int level1 : 1 __attribute__ ((packed)); unsigned int igmp_forward : 1 __attribute__ ((packed)); unsigned int nlp : 1 __attribute__ ((packed)); unsigned int level2_switching : 1 __attribute__ ((packed)); unsigned int level2_sourceroute : 1 __attribute__ ((packed)); unsigned int level2_transparent : 1 __attribute__ ((packed)); unsigned int level3 : 1 __attribute__ ((packed)); } cdp_capabilities; typedef struct { char dev_id[128]; uint8_t ip[4]; char interface[128]; cdp_capabilities cap; char software[512]; char platform[128]; } cdp_packet; typedef struct { unsigned int type : 16 __attribute__ ((packed)); unsigned int length : 16 __attribute__ ((packed)); char data; } cdp_element; // 802.1x Header typedef struct dot1x_header { uint8_t version; uint8_t type; uint16_t length; } __attribute__ ((packed)) dot1x_header_t; // EAP Packet header typedef struct eap_packet { uint8_t code; /* 1=request, 2=response, 3=success, 4=failure */ uint8_t identifier; /* Sequential counter, not sure what it's for */ uint16_t length; /* Length of the entire EAP message */ uint8_t type; /* 0x11 for LEAP */ /* The fields that follow the type octet are variable, depending on the type and code values. This information isn't important for us. */ } __attribute__ ((packed)) eap_packet_t; // ISAKMP packet header typedef struct isakmp_packet { uint8_t init_cookie[8]; uint8_t resp_cookie[8]; uint8_t next_payload; uint8_t version; uint8_t exchtype; uint8_t flags; uint32_t messageid; uint32_t length; } __attribute__ ((packed)) isakmp_packet_t; typedef struct { unsigned int type : 8 __attribute__ ((packed)); unsigned int length : 8 __attribute__ ((packed)); unsigned int proto : 8 __attribute__ ((packed)); unsigned int : 8 __attribute__ ((packed)); unsigned int proto_length : 8 __attribute__ ((packed)); char addr; } cdp_proto_element; // Info about a protocol struct proto_info { protocol_info_type type; uint8_t source_ip[4]; uint8_t dest_ip[4]; uint8_t misc_ip[4]; uint8_t mask[4]; uint8_t gate_ip[4]; uint16_t sport, dport; cdp_packet cdp; char netbios_source[17]; protocol_netbios_type nbtype; // Extra versioning/details of the proto type int prototype_extra; }; // packet conversion and extraction utilities // Packet types, these should correspond to the frame header types enum packet_type { packet_noise = -2, // We're too short or otherwise corrupted packet_unknown = -1, // What are we? packet_management = 0, // LLC management packet_phy = 1, // Physical layer packets, most drivers can't provide these packet_data = 2 // Data frames }; // Subtypes are a little odd because we re-use values depending on the type enum packet_sub_type { packet_sub_unknown = -1, // Management subtypes packet_sub_association_req = 0, packet_sub_association_resp = 1, packet_sub_reassociation_req = 2, packet_sub_reassociation_resp = 3, packet_sub_probe_req = 4, packet_sub_probe_resp = 5, packet_sub_beacon = 8, packet_sub_atim = 9, packet_sub_disassociation = 10, packet_sub_authentication = 11, packet_sub_deauthentication = 12, // Phy subtypes packet_sub_rts = 11, packet_sub_cts = 12, packet_sub_ack = 13, packet_sub_cf_end = 14, packet_sub_cf_end_ack = 15, // Data subtypes packet_sub_data = 0, packet_sub_data_cf_ack = 1, packet_sub_data_cf_poll = 2, packet_sub_data_cf_ack_poll = 3, packet_sub_data_null = 4, packet_sub_cf_ack = 5, packet_sub_cf_ack_poll = 6, packet_sub_data_qos_data = 8, packet_sub_data_qos_data_cf_ack = 9, packet_sub_data_qos_data_cf_poll = 10, packet_sub_data_qos_data_cf_ack_poll = 11, packet_sub_data_qos_null = 12, packet_sub_data_qos_cf_poll_nod = 14, packet_sub_data_qos_cf_ack_poll = 15 }; // distribution directions enum distribution_type { no_distribution, from_distribution, to_distribution, inter_distribution, adhoc_distribution }; // Turbocell modes enum turbocell_type { turbocell_unknown, turbocell_ispbase, // 0xA0 turbocell_pollbase, // 0x80 turbocell_nonpollbase, // 0x00 turbocell_base // 0x40 }; // IAPP stuff enum iapp_type { iapp_announce_request = 0, iapp_announce_response = 1, iapp_handover_request = 2, iapp_handover_response = 3 }; enum iapp_pdu { iapp_pdu_ssid = 0x00, iapp_pdu_bssid = 0x01, iapp_pdu_oldbssid = 0x02, iapp_pdu_msaddr = 0x03, iapp_pdu_capability = 0x04, iapp_pdu_announceint = 0x05, iapp_pdu_hotimeout = 0x06, iapp_pdu_messageid = 0x07, iapp_pdu_phytype = 0x10, iapp_pdu_regdomain = 0x11, iapp_pdu_channel = 0x12, iapp_pdu_beaconint = 0x13, iapp_pdu_ouiident = 0x80, iapp_pdu_authinfo = 0x81 }; enum iapp_cap { iapp_cap_forwarding = 0x40, iapp_cap_wep = 0x20 }; enum iapp_phy { iapp_phy_prop = 0x00, iapp_phy_fhss = 0x01, iapp_phy_dsss = 0x02, iapp_phy_ir = 0x03, iapp_phy_ofdm = 0x04 }; enum iapp_dom { iapp_dom_fcc = 0x10, iapp_dom_ic = 0x20, iapp_dom_etsi = 0x30, iapp_dom_spain = 0x31, iapp_dom_france = 0x32, iapp_dom_mkk = 0x40 }; enum iapp_auth { iapp_auth_status = 0x01, iapp_auth_username = 0x02, iapp_auth_provname = 0x03, iapp_auth_rxpkts = 0x04, iapp_auth_txpkts = 0x05, iapp_auth_rxbytes = 0x06, iapp_auth_txbytes = 0x07, iapp_auth_logintime = 0x08, iapp_auth_timelimit = 0x09, iapp_auth_vollimit = 0x0a, iapp_auth_acccycle = 0x0b, iapp_auth_rxgwords = 0x0c, iapp_auth_txgwords = 0x0d, iapp_auth_ipaddr = 0x0e, iapp_auth_trailer = 0xff }; typedef struct { unsigned iapp_version : 8 __attribute__ ((packed)); unsigned iapp_type : 8 __attribute__ ((packed)); } iapp_header; typedef struct { unsigned pdu_type : 8 __attribute__ ((packed)); unsigned pdu_len : 16 __attribute__ ((packed)); } iapp_pdu_header; enum crypt_type { crypt_none = 0, crypt_unknown = 1, crypt_wep = 2, crypt_layer3 = 4, // Derived from WPA headers crypt_wep40 = 8, crypt_wep104 = 16, crypt_tkip = 32, crypt_wpa = 64, crypt_psk = 128, crypt_aes_ocb = 256, crypt_aes_ccm = 512, // Derived from data traffic crypt_leap = 1024, crypt_ttls = 2048, crypt_tls = 4096, crypt_peap = 8192, crypt_isakmp = 16384, crypt_pptp = 32768, crypt_ccmp = 65536 }; // Info about a packet typedef struct { // Packet info type packet_type type; packet_sub_type subtype; // Packet QoS Data uint16_t qos; // Is it a corrupt packet? We might want to know what type it is // even if it's corrupt int corrupt; // reason code for some management protocols int reason_code; // Timestamp. Second precision is fine. struct timeval ts; // Connection info int quality; int signal; int noise; // SSID char ssid[SSID_SIZE+1]; int ssid_len; // Source name char sourcename[32]; // Where did it come from? distribution_type distrib; // What crypt set is used? int crypt_set; // Was the encryption detection fuzzy? int fuzzy; // Was it flagged as ess? (ap) int ess; // What channel? int channel; // Is this encrypted? int encrypted; // Did we decode it? int decoded; // Is it weak crypto? int interesting; // What carrier brought us this packet? carrier_type carrier; // What encoding? encoding_type encoding; // What data rate? int datarate; mac_addr source_mac; mac_addr dest_mac; mac_addr bssid_mac; // Beacon interval if this is a beacon packet, raw 16bit format int beacon; // Cisco tacks extra info into the beacon. This is nice. char beacon_info[SSID_SIZE+1]; // Offset of the header unsigned int header_offset; proto_info proto; double maxrate; uint64_t timestamp; int sequence_number; int frag_number; int duration; int datasize; // Turbocell tracking info int turbocell_nid; turbocell_type turbocell_mode; int turbocell_sat; // Location info float gps_lat, gps_lon, gps_alt, gps_spd, gps_heading; int gps_fix; // ICV and key number uint32_t ivset; // IDS hooks kluged into stable int ids_msfdlinkrate; int ids_msfnetgearbeacon; } packet_info; typedef struct { int fragile; mac_addr bssid; unsigned char key[WEPKEY_MAX]; unsigned int len; unsigned int decrypted; unsigned int failed; } wep_key_info; // ---------------------------------- // String munger string MungeToPrintable(char *in_data, int len); // Info extraction functions int GetTagOffset(int init_offset, int tagnum, kis_packet *packet, map > *tag_cache_map); void GetPacketInfo(kis_packet *packet, packet_info *ret_packinfo, macmap *bssid_wep_map, unsigned char *identity); void ProcessPacketCrypto(kis_packet *packet, packet_info *ret_packinfo, macmap *bssid_wep_map, unsigned char *identity); void GetProtoInfo(kis_packet *packet, packet_info *in_info); void DecryptPacket(kis_packet *packet, packet_info *in_info, macmap *bssid_wep_map, unsigned char *identity); int MangleDeCryptPacket(const kis_packet *packet, const packet_info *in_info, kis_packet *outpack, uint8_t *data, uint8_t *moddata); int MangleFuzzyCryptPacket(const kis_packet *packet, const packet_info *in_info, kis_packet *outpack, uint8_t *data, uint8_t *moddata); vector GetPacketStrings(const packet_info *in_info, const kis_packet *packet); // Sort packet_infos class SortPacketInfos { public: inline bool operator() (const packet_info x, const packet_info y) const { if (x.ts.tv_sec < y.ts.tv_sec || (x.ts.tv_sec == y.ts.tv_sec && x.ts.tv_usec < y.ts.tv_usec)) return 1; return 0; } }; #endif