From d640eebb991d48b082bdfbf8ca54ff8faf37ae0d Mon Sep 17 00:00:00 2001 From: Ulf Wetzker Date: Mon, 9 Feb 2015 13:23:03 +0100 Subject: [PATCH] Add Exception for fields that are not present in RadioTap frames. --- include/tins/exceptions.h | 30 ++++++--- include/tins/radiotap.h | 30 ++++----- src/radiotap.cpp | 130 +++++++++++++++++++++++++++++++------- 3 files changed, 144 insertions(+), 46 deletions(-) diff --git a/include/tins/exceptions.h b/include/tins/exceptions.h index be8f0f3..163e056 100644 --- a/include/tins/exceptions.h +++ b/include/tins/exceptions.h @@ -5,14 +5,14 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -55,7 +55,7 @@ class malformed_packet : public std::runtime_error { public: malformed_packet() : std::runtime_error(std::string()) { } - + const char* what() const throw() { return "Malformed packet"; } @@ -68,7 +68,7 @@ class pdu_not_found : public std::runtime_error { public: pdu_not_found() : std::runtime_error(std::string()) { } - + const char* what() const throw() { return "PDU not found"; } @@ -82,18 +82,30 @@ class invalid_interface : public std::runtime_error { public: invalid_interface() : std::runtime_error(std::string()) { } - + const char* what() const throw() { return "Invalid interface"; } }; +/** + * \brief Exception thrown when a field is not present in frame. + */ +class field_not_present : public std::runtime_error { +public: + field_not_present() + : std::runtime_error(std::string()) { } + const char* what() const throw() { + return "Field not present"; + } +}; + /** * \brief Exception thrown when PacketSender fails to open a socket. */ class socket_open_error : public std::runtime_error { public: - socket_open_error(const std::string &msg) + socket_open_error(const std::string &msg) : std::runtime_error(msg) { } }; @@ -102,7 +114,7 @@ public: */ class socket_close_error : public std::runtime_error { public: - socket_close_error(const std::string &msg) + socket_close_error(const std::string &msg) : std::runtime_error(msg) { } }; @@ -111,7 +123,7 @@ public: */ class socket_write_error : public std::runtime_error { public: - socket_write_error(const std::string &msg) + socket_write_error(const std::string &msg) : std::runtime_error(msg) { } }; @@ -127,7 +139,7 @@ public: }; /** - * \brief Exception thrown when an unkown link layer PDU type is + * \brief Exception thrown when an unkown link layer PDU type is * found while sniffing. */ class unknown_link_type : public std::exception { diff --git a/include/tins/radiotap.h b/include/tins/radiotap.h index eb849e5..3d31918 100644 --- a/include/tins/radiotap.h +++ b/include/tins/radiotap.h @@ -220,91 +220,91 @@ namespace Tins { * \brief Getter for the version field. * \return The version field. */ - uint8_t version() const { return _radio.it_version; } + uint8_t version() const; /** * \brief Getter for the padding field. * \return The padding field. */ - uint8_t padding() const { return _radio.it_pad; } + uint8_t padding() const; /** * \brief Getter for the length field. * \return The length field. */ - uint16_t length() const { return Endian::le_to_host(_radio.it_len); } + uint16_t length() const; /** * \brief Getter for the tsft field. * \return The tsft field. */ - uint64_t tsft() const { return Endian::le_to_host(_tsft); } + uint64_t tsft() const; /** * \brief Getter for the flags field. * \return The flags field. */ - FrameFlags flags() const { return (FrameFlags)_flags; } + FrameFlags flags() const; /** * \brief Getter for the rate field. * \return The rate field. */ - uint8_t rate() const { return _rate; } + uint8_t rate() const; /** * \brief Getter for the channel frequency field. * \return The channel frequency field. */ - uint16_t channel_freq() const { return Endian::le_to_host(_channel_freq); } + uint16_t channel_freq() const; /** * \brief Getter for the channel type field. * \return The channel type field. */ - uint16_t channel_type() const { return Endian::le_to_host(_channel_type); } + uint16_t channel_type() const; /** * \brief Getter for the dbm signal field. * \return The dbm signal field. */ - uint8_t dbm_signal() const { return _dbm_signal; } + uint8_t dbm_signal() const; /** * \brief Getter for the dbm noise field. * \return The dbm noise field. */ - uint8_t dbm_noise() const { return _dbm_noise; } + uint8_t dbm_noise() const; /** * \brief Getter for the signal quality field. * \return The signal quality field. */ - uint16_t signal_quality() const { return _signal_quality; } + uint16_t signal_quality() const; /** * \brief Getter for the antenna field. * \return The antenna field. */ - uint8_t antenna() const { return _antenna; } + uint8_t antenna() const; /** * \brief Getter for the db signal field. * \return The db signal field. */ - uint8_t db_signal() const { return _db_signal; } + uint8_t db_signal() const; /** * \brief Getter for the channel+ field. * \return The channel+ field. */ - uint32_t channel_plus() const { return Endian::le_to_host(_channel_type); } + uint32_t channel_plus() const; /** * \brief Getter for the rx flags field. * \return The rx flags field. */ - uint16_t rx_flags() const { return Endian::le_to_host(_rx_flags); } + uint16_t rx_flags() const; /** * \brief Getter for the present bit fields. diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 7bb1166..6d6cdb4 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -5,14 +5,14 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -70,7 +70,7 @@ RadioTap::RadioTap() init(); } -RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) +RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) { check_size(total_sz, sizeof(_radio)); const uint8_t *buffer_start = buffer; @@ -90,15 +90,15 @@ RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) while(true) { _radio.flags_32 |= *(const uint32_t*)current_flags; - if(current_flags->tsft) + if(current_flags->tsft) read_field(buffer, radiotap_hdr_size, _tsft); - - if(current_flags->flags) + + if(current_flags->flags) read_field(buffer, radiotap_hdr_size, _flags); - if(current_flags->rate) + if(current_flags->rate) read_field(buffer, radiotap_hdr_size, _rate); - + if(current_flags->channel) { if(((buffer - buffer_start) & 1) == 1) { buffer++; @@ -107,20 +107,20 @@ RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) read_field(buffer, radiotap_hdr_size, _channel_freq); read_field(buffer, radiotap_hdr_size, _channel_type); } - + if(current_flags->dbm_signal) read_field(buffer, radiotap_hdr_size, _dbm_signal); - - if(current_flags->dbm_noise) + + if(current_flags->dbm_noise) read_field(buffer, radiotap_hdr_size, _dbm_noise); - - if(current_flags->lock_quality) + + if(current_flags->lock_quality) read_field(buffer, radiotap_hdr_size, _signal_quality); - if(current_flags->antenna) + if(current_flags->antenna) read_field(buffer, radiotap_hdr_size, _antenna); - - if(current_flags->db_signal) + + if(current_flags->db_signal) read_field(buffer, radiotap_hdr_size, _db_signal); if(current_flags->rx_flags) { @@ -164,7 +164,7 @@ RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) throw malformed_packet(); } - if(total_sz) + if(total_sz) inner_pdu(Dot11::from_bytes(buffer, total_sz)); } @@ -177,7 +177,7 @@ void RadioTap::init() { antenna(0); } -// This method finds the extra flags field size, taking into account other +// This method finds the extra flags field size, taking into account other // set of flags that may appear if the "ext" bit is on/. uint32_t RadioTap::find_extra_flag_fields_size(const uint8_t* buffer, uint32_t total_sz) { const flags_type* ptr = (const flags_type*)buffer; @@ -191,10 +191,11 @@ uint32_t RadioTap::find_extra_flag_fields_size(const uint8_t* buffer, uint32_t t return (const uint8_t*)ptr - buffer; } +// Setter for RadioTap fields void RadioTap::version(uint8_t new_version) { _radio.it_version = new_version; } - + void RadioTap::padding(uint8_t new_padding) { _radio.it_pad = new_padding; } @@ -287,7 +288,7 @@ uint32_t RadioTap::header_size() const { total_bytes += 4 - offset; total_bytes += 8; } - + return sizeof(_radio) + total_bytes; } @@ -296,11 +297,96 @@ uint32_t RadioTap::trailer_size() const { return ((_flags & 0x10) != 0) ? sizeof(uint32_t) : 0; } +// Getter for RadioTap fields +uint8_t RadioTap::version() const { + return _radio.it_version; +} + +uint8_t RadioTap::padding() const { + return _radio.it_pad; +} + +uint16_t RadioTap::length() const { + return Endian::le_to_host(_radio.it_len); +} + +uint64_t RadioTap::tsft() const { + if(!_radio.flags.tsft) + throw field_not_present(); + return Endian::le_to_host(_tsft); +} + +RadioTap::FrameFlags RadioTap::flags() const { + if(!_radio.flags.flags) + throw field_not_present(); + return (FrameFlags)_flags; +} + +uint8_t RadioTap::rate() const { + if(!_radio.flags.rate) + throw field_not_present(); + return _rate; +} + +uint16_t RadioTap::channel_freq() const { + if(!_radio.flags.channel) + throw field_not_present(); + return Endian::le_to_host(_channel_freq); +} + +uint16_t RadioTap::channel_type() const { + if(!_radio.flags.channel) + throw field_not_present(); + return Endian::le_to_host(_channel_type); +} + +uint8_t RadioTap::dbm_signal() const { + if(!_radio.flags.dbm_signal) + throw field_not_present(); + return _dbm_signal; +} + +uint8_t RadioTap::dbm_noise() const { + if(!_radio.flags.dbm_noise) + throw field_not_present(); + return _dbm_noise; +} + +uint16_t RadioTap::signal_quality() const { + if(!_radio.flags.lock_quality) + throw field_not_present(); + return _signal_quality; +} + +uint8_t RadioTap::antenna() const { + if(!_radio.flags.antenna) + throw field_not_present(); + return _antenna; +} + +uint8_t RadioTap::db_signal() const { + if(!_radio.flags.db_signal) + throw field_not_present(); + return _db_signal; +} + +uint32_t RadioTap::channel_plus() const { + if(!_radio.flags.channel_plus) + throw field_not_present(); + return Endian::le_to_host(_channel_type); +} + +uint16_t RadioTap::rx_flags() const { + if(!_radio.flags.rx_flags) + throw field_not_present(); + return Endian::le_to_host(_rx_flags); +} + #ifndef WIN32 void RadioTap::send(PacketSender &sender, const NetworkInterface &iface) { if(!iface) throw invalid_interface(); - + #if !defined(BSD) && !defined(__FreeBSD_kernel__) struct sockaddr_ll addr; @@ -310,7 +396,7 @@ void RadioTap::send(PacketSender &sender, const NetworkInterface &iface) { addr.sll_protocol = Endian::host_to_be(ETH_P_ALL); addr.sll_halen = 6; addr.sll_ifindex = iface.id(); - + const Tins::Dot11 *wlan = tins_cast(inner_pdu()); if(wlan) { Tins::Dot11::address_type dot11_addr(wlan->addr1());