diff --git a/include/constants.h b/include/constants.h index e9cccdb..2e1aca3 100644 --- a/include/constants.h +++ b/include/constants.h @@ -146,7 +146,7 @@ namespace Tins { IEEE80211_RADIOTAP = 803, /* IEEE 802.11 + radiotap header. */ IEEE802154 = 804, /* IEEE 802.15.4 header. */ IEEE802154_PHY = 805, /* IEEE 802.15.4 PHY header. */ - VOID = 0xFFFF, /* Void type, nothing is known. */ + VOID_TYPE = 0xFFFF, /* Void type, nothing is known. */ NONE = 0xFFFE, /* Zero header length. */ }; }; diff --git a/include/dot11.h b/include/dot11.h index 1bf429e..446ee2f 100644 --- a/include/dot11.h +++ b/include/dot11.h @@ -381,11 +381,13 @@ namespace Tins { * \sa PDU::header_size() */ uint32_t header_size() const; - + + #ifndef WIN32 /** * \sa PDU::send() */ bool send(PacketSender &sender); + #endif // WIN32 /** * \brief Adds a new option to this Dot11 PDU. @@ -955,16 +957,28 @@ namespace Tins { /** * \brief Getter for the fragment number. * - * \return uint8_t containing the fragment number. + * \return The stored fragment number. */ - uint8_t frag_num() const { return _ext_header.seq_control.frag_number; } + small_uint<4> frag_num() const { + #if TINS_IS_LITTLE_ENDIAN + return _ext_header.frag_seq & 0xf; + #else + return (_ext_header.frag_seq >> 8) & 0xf; + #endif + } /** - * \brief Getter for the sequence number. + * \brief Getter for the sequence number field. * - * \return uint16_t containing the sequence number. + * \return The stored sequence number. */ - uint16_t seq_num() const { return Endian::le_to_host(_ext_header.seq_control.seq_number); } + small_uint<12> seq_num() const { + #if TINS_IS_LITTLE_ENDIAN + return (_ext_header.frag_seq >> 4) & 0xfff; + #else + return (Endian::le_to_host(_ext_header.frag_seq) >> 4) & 0xfff; + #endif + } /** * \brief Getter for the fourth address. @@ -992,14 +1006,14 @@ namespace Tins { * * \param new_frag_num The new fragment number. */ - void frag_num(uint8_t new_frag_num); + void frag_num(small_uint<4> new_frag_num); /** * \brief Setter for the sequence number. * * \param new_seq_num The new sequence number. */ - void seq_num(uint16_t new_seq_num); + void seq_num(small_uint<12> new_seq_num); /** * \brief Setter for the fourth address. @@ -1430,15 +1444,7 @@ namespace Tins { struct ExtendedHeader { uint8_t addr2[address_type::address_size]; uint8_t addr3[address_type::address_size]; - struct { - #if __BYTE_ORDER == __LITTLE_ENDIAN - uint16_t frag_number:4, - seq_number:12; - #elif __BYTE_ORDER == __BIG_ENDIAN - uint16_t seq_number:12, - frag_number:4; - #endif - } __attribute__((__packed__)) seq_control; + uint16_t frag_seq; } __attribute__((__packed__)); @@ -2570,14 +2576,26 @@ namespace Tins { * * \return The stored fragment number. */ - uint8_t frag_num() const { return _ext_header.seq_control.frag_number; } + small_uint<4> frag_num() const { + #if TINS_IS_LITTLE_ENDIAN + return _ext_header.frag_seq & 0xf; + #else + return (_ext_header.frag_seq >> 8) & 0xf; + #endif + } /** * \brief Getter for the sequence number field. * * \return The stored sequence number. */ - uint16_t seq_num() const { return Endian::le_to_host(_ext_header.seq_control.seq_number); } + small_uint<12> seq_num() const { + #if TINS_IS_LITTLE_ENDIAN + return (_ext_header.frag_seq >> 4) & 0xfff; + #else + return (Endian::le_to_host(_ext_header.frag_seq) >> 4) & 0xfff; + #endif + } /** * \brief Getter for the fourth address. @@ -2605,14 +2623,14 @@ namespace Tins { * * \param new_frag_num The fragment number to be set. */ - void frag_num(uint8_t new_frag_num); + void frag_num(small_uint<4> new_frag_num); /** * \brief Setter for the sequence number field. * * \param new_seq_num The sequence number to be set. */ - void seq_num(uint16_t new_seq_num); + void seq_num(small_uint<12> new_seq_num); /** * \brief Setter for the fourth address field. @@ -2656,15 +2674,7 @@ namespace Tins { struct ExtendedHeader { uint8_t addr2[address_type::address_size]; uint8_t addr3[address_type::address_size]; - struct { - #if TINS_IS_LITTLE_ENDIAN - uint16_t frag_number:4, - seq_number:12; - #elif TINS_IS_BIG_ENDIAN - uint16_t frag_number:4, - seq_number:12; - #endif - } __attribute__((__packed__)) seq_control; + uint16_t frag_seq; } __attribute__((__packed__)); uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); diff --git a/include/ethernetII.h b/include/ethernetII.h index e9d4962..1ee4d67 100644 --- a/include/ethernetII.h +++ b/include/ethernetII.h @@ -151,11 +151,14 @@ namespace Tins { * \sa PDU::header_size() */ uint32_t header_size() const; - + + // Windows does not support sending L2 PDUs. + #ifndef WIN32 /** * \sa PDU::send() */ bool send(PacketSender &sender); + #endif // WIN32 /** \brief Check wether ptr points to a valid response for this PDU. * @@ -165,12 +168,14 @@ namespace Tins { */ bool matches_response(uint8_t *ptr, uint32_t total_sz); + #ifndef WIN32 /** \brief Receives a matching response for this packet. * * \sa PDU::recv_response * \param sender The packet sender which will receive the packet. */ PDU *recv_response(PacketSender &sender); + #endif // WIN32 /** * \brief Getter for the PDU's type. diff --git a/include/ieee802_3.h b/include/ieee802_3.h index 64e0bdb..7a95d4b 100644 --- a/include/ieee802_3.h +++ b/include/ieee802_3.h @@ -149,11 +149,13 @@ namespace Tins { * \sa PDU::header_size() */ uint32_t header_size() const; - + + #ifndef WIN32 /** * \sa PDU::send() */ bool send(PacketSender &sender); + #endif // WIN32 /** \brief Check wether ptr points to a valid response for this PDU. * @@ -163,12 +165,14 @@ namespace Tins { */ bool matches_response(uint8_t *ptr, uint32_t total_sz); + #ifndef WIN32 /** \brief Receives a matching response for this packet. * * \sa PDU::recv_response * \param sender The packet sender which will receive the packet. */ PDU *recv_response(PacketSender &sender); + #endif // WIN32 /** * \brief Getter for the PDU's type. diff --git a/include/ip.h b/include/ip.h index 0a5e6cc..f5e06f8 100644 --- a/include/ip.h +++ b/include/ip.h @@ -114,7 +114,12 @@ namespace Tins { * * Initializes every field to 0. */ - option_identifier() : number(0), op_class(0), copied(0) {} + option_identifier() + #if TINS_IS_LITTLE_ENDIAN + : number(0), op_class(0), copied(0) {} + #else + : copied(0), op_class(0), number(0) {} + #endif /** * \brief Constructs this option from a single uint8_t value. @@ -144,7 +149,11 @@ namespace Tins { */ option_identifier(OptionNumber number, OptionClass op_class, small_uint<1> copied) + #if TINS_IS_LITTLE_ENDIAN : number(number), op_class(op_class), copied(copied) {} + #else + : copied(copied), op_class(op_class), number(number) {} + #endif /** * \brief Equality operator. diff --git a/include/packet_sender.h b/include/packet_sender.h index fc90645..333c228 100644 --- a/include/packet_sender.h +++ b/include/packet_sender.h @@ -75,11 +75,13 @@ namespace Tins { */ ~PacketSender(); + #ifndef WIN32 /** \brief Opens a layer y socket. * * \return Returns true if the socket was open successfully, false otherwise. */ bool open_l2_socket(); + #endif // WIN32 /** \brief Opens a layer 3 socket, using the corresponding protocol * for the given flag. @@ -118,6 +120,7 @@ namespace Tins { */ PDU *send_recv(PDU &pdu); + #ifndef WIN32 /** \brief Receives a layer 2 PDU response to a previously sent PDU. * * This PacketSender will receive data from a raw socket, open using the corresponding flag, @@ -141,6 +144,7 @@ namespace Tins { * \return Returns true if the PDU was successfully sent, false otherwise. */ bool send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr); + #endif // WIN32 /** \brief Receives a layer 3 PDU response to a previously sent PDU. * diff --git a/include/snap.h b/include/snap.h index c739f36..15a112e 100644 --- a/include/snap.h +++ b/include/snap.h @@ -105,17 +105,23 @@ namespace Tins { * \brief Getter for the control field. * \return The control field. */ - uint8_t control() const { return _snap.control; } + uint8_t control() const { + #if TINS_IS_LITTLE_ENDIAN + return (_snap.control_org) & 0xff; + #else + return (_snap.control_org >> 24) & 0xff; + #endif + } /** * \brief Getter for the org code field. * \return The org code field. */ small_uint<24> org_code() const { - #ifdef TINS_IS_LITTLE_ENDIAN - return Endian::be_to_host(_snap.org_code << 8); + #if TINS_IS_LITTLE_ENDIAN + return Endian::be_to_host(_snap.control_org & 0xffffff00); #else - return Endian::be_to_host(_snap.org_code); + return _snap.control_org & 0xffffff; #endif } @@ -151,13 +157,14 @@ namespace Tins { struct snaphdr { uint8_t dsap; uint8_t ssap; - #if TINS_IS_LITTLE_ENDIAN + /*#if TINS_IS_LITTLE_ENDIAN uint32_t control:8, org_code:24; #elif TINS_IS_BIG_ENDIAN uint32_t org_code:24, control:8; - #endif + #endif*/ + uint32_t control_org; uint16_t eth_type; } __attribute__((__packed__)); diff --git a/include/utils.h b/include/utils.h index 643caa0..bdfa5d7 100644 --- a/include/utils.h +++ b/include/utils.h @@ -32,6 +32,10 @@ #ifndef WIN32 #include +#else + #include + #include + #undef interface #endif #include #include @@ -187,6 +191,7 @@ namespace Tins { * the object to collect data from them. * \param functor An instance of an class which implements operator(struct ifaddrs*). */ + #ifndef WIN32 template void generic_iface_loop(Functor &functor) { struct ifaddrs *ifaddrs = 0; @@ -199,6 +204,22 @@ namespace Tins { if(ifaddrs) freeifaddrs(ifaddrs); } + #else // WIN32 + template + void generic_iface_loop(Functor &functor) { + ULONG size; + ::GetAdaptersAddresses(AF_INET, 0, 0, 0, &size); + std::vector buffer(size); + if (::GetAdaptersAddresses(AF_INET, 0, 0, (IP_ADAPTER_ADDRESSES *)&buffer[0], &size) == ERROR_SUCCESS) { + PIP_ADAPTER_ADDRESSES iface = (IP_ADAPTER_ADDRESSES *)&buffer[0]; + while(iface) { + if(functor(iface)) + break; + iface = iface->Next; + } + } + } + #endif // WIN32 namespace Internals { void skip_line(std::istream &input); diff --git a/src/dot11.cpp b/src/dot11.cpp index fda311d..17427e1 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -166,6 +166,7 @@ uint32_t Dot11::header_size() const { return sz; } +#ifndef WIN32 bool Dot11::send(PacketSender &sender) { struct sockaddr_ll addr; @@ -179,6 +180,7 @@ bool Dot11::send(PacketSender &sender) { return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } +#endif // WIN32 void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { uint32_t my_sz = header_size(); @@ -299,12 +301,20 @@ void Dot11ManagementFrame::addr3(const address_type &new_addr3) { std::copy(new_addr3.begin(), new_addr3.end(), _ext_header.addr3); } -void Dot11ManagementFrame::frag_num(uint8_t new_frag_num) { - this->_ext_header.seq_control.frag_number = new_frag_num; +void Dot11ManagementFrame::frag_num(small_uint<4> new_frag_num) { + #if TINS_IS_LITTLE_ENDIAN + _ext_header.frag_seq = new_frag_num | (_ext_header.frag_seq & 0xfff0); + #else + _ext_header.frag_seq = (new_frag_num << 8) | (_ext_header.frag_seq & 0xf0ff); + #endif } -void Dot11ManagementFrame::seq_num(uint16_t new_seq_num) { - this->_ext_header.seq_control.seq_number = Endian::host_to_le(new_seq_num); +void Dot11ManagementFrame::seq_num(small_uint<12> new_seq_num) { + #if TINS_IS_LITTLE_ENDIAN + _ext_header.frag_seq = (new_seq_num << 4) | (_ext_header.frag_seq & 0xf); + #else + _ext_header.frag_seq = Endian::host_to_le(new_seq_num << 4) | (_ext_header.frag_seq & 0xf00); + #endif } void Dot11ManagementFrame::addr4(const address_type &new_addr4) { @@ -530,12 +540,22 @@ void Dot11ManagementFrame::bss_load(const bss_load_type &data) { uint16_t dummy = Endian::host_to_le(data.station_count); //*(uint16_t*)buffer = Endian::host_to_le(data.station_count); + #if TINS_IS_LITTLE_ENDIAN buffer[0] = dummy & 0xff; buffer[1] = (dummy >> 8) & 0xff; + #else + buffer[0] = (dummy >> 8) & 0xff; + buffer[1] = dummy & 0xff; + #endif buffer[2] = data.channel_utilization; dummy = Endian::host_to_le(data.available_capacity); + #if TINS_IS_LITTLE_ENDIAN buffer[3] = dummy & 0xff; buffer[4] = (dummy >> 8) & 0xff; + #else + buffer[3] = (dummy >> 8) & 0xff; + buffer[4] = dummy & 0xff; + #endif //*(uint16_t*)(buffer + 3) = Endian::host_to_le(data.available_capacity); add_tagged_option(BSS_LOAD, sizeof(buffer), buffer); } @@ -1242,12 +1262,20 @@ void Dot11Data::addr3(const address_type &new_addr3) { std::copy(new_addr3.begin(), new_addr3.end(), _ext_header.addr3); } -void Dot11Data::frag_num(uint8_t new_frag_num) { - _ext_header.seq_control.frag_number = new_frag_num; +void Dot11Data::frag_num(small_uint<4> new_frag_num) { + #if TINS_IS_LITTLE_ENDIAN + _ext_header.frag_seq = new_frag_num | (_ext_header.frag_seq & 0xfff0); + #else + _ext_header.frag_seq = (new_frag_num << 8) | (_ext_header.frag_seq & 0xf0ff); + #endif } -void Dot11Data::seq_num(uint16_t new_seq_num) { - _ext_header.seq_control.seq_number = Endian::host_to_le(new_seq_num); +void Dot11Data::seq_num(small_uint<12> new_seq_num) { + #if TINS_IS_LITTLE_ENDIAN + _ext_header.frag_seq = (new_seq_num << 4) | (_ext_header.frag_seq & 0xf); + #else + _ext_header.frag_seq = Endian::host_to_le(new_seq_num << 4) | (_ext_header.frag_seq & 0xf00); + #endif } void Dot11Data::addr4(const address_type &new_addr4) { diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index b819758..89d51af 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -41,6 +41,7 @@ #include "rawpdu.h" #include "ip.h" #include "arp.h" +#include "constants.h" namespace Tins { const EthernetII::address_type EthernetII::BROADCAST("ff:ff:ff:ff:ff:ff"); @@ -68,10 +69,10 @@ EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) total_sz -= sizeof(ethhdr); if(total_sz) { switch(payload_type()) { - case ETHERTYPE_IP: + case Constants::Ethernet::IP: next = new Tins::IP(buffer, total_sz); break; - case ETHERTYPE_ARP: + case Constants::Ethernet::ARP: next = new Tins::ARP(buffer, total_sz); break; default: @@ -102,6 +103,7 @@ uint32_t EthernetII::header_size() const { return sizeof(ethhdr); } +#ifndef WIN32 bool EthernetII::send(PacketSender &sender) { if(!_iface) throw std::runtime_error("Interface has not been set"); @@ -117,6 +119,7 @@ bool EthernetII::send(PacketSender &sender) { return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } +#endif // WIN32 bool EthernetII::matches_response(uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(ethhdr)) @@ -135,13 +138,13 @@ void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const P /* Inner type defaults to IP */ if ((_eth.payload_type == 0) && inner_pdu()) { - uint16_t type = ETHERTYPE_IP; + uint16_t type = Constants::Ethernet::IP; switch (inner_pdu()->pdu_type()) { case PDU::IP: - type = ETHERTYPE_IP; + type = Constants::Ethernet::IP; break; case PDU::ARP: - type = ETHERTYPE_ARP; + type = Constants::Ethernet::ARP; break; default: type = 0; @@ -151,6 +154,7 @@ void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const P memcpy(buffer, &_eth, sizeof(ethhdr)); } +#ifndef WIN32 PDU *EthernetII::recv_response(PacketSender &sender) { struct sockaddr_ll addr; memset(&addr, 0, sizeof(struct sockaddr_ll)); @@ -163,6 +167,7 @@ PDU *EthernetII::recv_response(PacketSender &sender) { return sender.recv_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } +#endif // WIN32 PDU *EthernetII::clone_packet(const uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(_eth)) diff --git a/src/ieee802_3.cpp b/src/ieee802_3.cpp index d909435..b9dacf9 100644 --- a/src/ieee802_3.cpp +++ b/src/ieee802_3.cpp @@ -87,6 +87,7 @@ uint32_t IEEE802_3::header_size() const { return sizeof(ethhdr); } +#ifndef WIN32 bool IEEE802_3::send(PacketSender &sender) { struct sockaddr_ll addr; @@ -100,6 +101,7 @@ bool IEEE802_3::send(PacketSender &sender) { return sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } +#endif // WIN32 bool IEEE802_3::matches_response(uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(ethhdr)) @@ -125,6 +127,7 @@ void IEEE802_3::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD _eth.length = 0; } +#ifndef WIN32 PDU *IEEE802_3::recv_response(PacketSender &sender) { struct sockaddr_ll addr; memset(&addr, 0, sizeof(struct sockaddr_ll)); @@ -137,6 +140,7 @@ PDU *IEEE802_3::recv_response(PacketSender &sender) { return sender.recv_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } +#endif // WIN32 PDU *IEEE802_3::clone_packet(const uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(_eth)) diff --git a/src/ip.cpp b/src/ip.cpp index 3bbdb7a..46c3842 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -34,6 +34,8 @@ #ifndef WIN32 #include #include +#else + #include #endif #include "ip.h" #include "tcp.h" @@ -128,13 +130,13 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz) total_sz -= head_len() * sizeof(uint32_t); if (total_sz) { switch(_ip.protocol) { - case IPPROTO_TCP: + case Constants::IP::PROTO_TCP: inner_pdu(new Tins::TCP(buffer, total_sz)); break; - case IPPROTO_UDP: + case Constants::IP::PROTO_UDP: inner_pdu(new Tins::UDP(buffer, total_sz)); break; - case IPPROTO_ICMP: + case Constants::IP::PROTO_ICMP: inner_pdu(new Tins::ICMP(buffer, total_sz)); break; default: @@ -361,16 +363,16 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare uint32_t new_flag; switch(inner_pdu()->pdu_type()) { case PDU::IP: - new_flag = IPPROTO_IPIP; + new_flag = Constants::IP::PROTO_IPIP; break; case PDU::TCP: - new_flag = IPPROTO_TCP; + new_flag = Constants::IP::PROTO_TCP; break; case PDU::UDP: - new_flag = IPPROTO_UDP; + new_flag = Constants::IP::PROTO_UDP; break; case PDU::ICMP: - new_flag = IPPROTO_ICMP; + new_flag = Constants::IP::PROTO_ICMP; break; default: // check for other protos diff --git a/src/loopback.cpp b/src/loopback.cpp index cdf2f7c..1bdb048 100644 --- a/src/loopback.cpp +++ b/src/loopback.cpp @@ -58,6 +58,7 @@ Loopback::Loopback(const uint8_t *buffer, uint32_t total_sz) _family = *reinterpret_cast(buffer); buffer += sizeof(uint32_t); total_sz -= sizeof(uint32_t); + #ifndef WIN32 if(total_sz) { switch(_family) { case PF_INET: @@ -71,6 +72,7 @@ Loopback::Loopback(const uint8_t *buffer, uint32_t total_sz) break; }; } + #endif // WIN32 } void Loopback::family(uint32_t family_id) { diff --git a/src/network_interface.cpp b/src/network_interface.cpp index f7d0582..d593e95 100644 --- a/src/network_interface.cpp +++ b/src/network_interface.cpp @@ -34,6 +34,8 @@ #include #include #include +#else + #include #endif #include "network_interface.h" #include "utils.h" @@ -49,8 +51,9 @@ struct InterfaceInfoCollector { InterfaceInfoCollector(info_type *res, int id, const char* if_name) : info(res), iface_id(id), iface_name(if_name), found(false) { } - - bool operator() (struct ifaddrs *addr) { + + #ifndef WIN32 + bool operator() (const struct ifaddrs *addr) { using Tins::Endian::host_to_be; using Tins::IPv4Address; const struct sockaddr_ll* addr_ptr = ((struct sockaddr_ll*)addr->ifa_addr); @@ -68,13 +71,33 @@ struct InterfaceInfoCollector { } return found; } + #else // WIN32 + bool operator() (const IP_ADAPTER_ADDRESSES *iface) { + using Tins::IPv4Address; + // This surely doesn't work + if(iface_id == iface->IfIndex) { + std::copy(iface->PhysicalAddress, iface->PhysicalAddress + 6, info->hw_addr.begin()); + const IP_ADAPTER_PREFIX *prefix_ptr = iface->FirstPrefix; + for(size_t i = 0; prefix_ptr; prefix_ptr = prefix_ptr->Next, i++) { + if(i == 0) + info->ip_addr = IPv4Address(((const struct sockaddr_in *)prefix_ptr->Address.lpSockaddr)->sin_addr.s_addr); + else if(i == 2) + info->bcast_addr = IPv4Address(((const struct sockaddr_in *)prefix_ptr->Address.lpSockaddr)->sin_addr.s_addr); + } + // (?????) + info->netmask = IPv4Address(info->ip_addr - info->bcast_addr); + found = true; + } + return found; + } + #endif // WIN32 }; /** \endcond */ namespace Tins { // static NetworkInterface NetworkInterface::default_interface() { - return NetworkInterface(0); + return NetworkInterface(IPv4Address(uint32_t(0))); } NetworkInterface::NetworkInterface() : iface_id(0) { @@ -102,7 +125,7 @@ NetworkInterface::NetworkInterface(IPv4Address ip) : iface_id(0) { for(entries_type::const_iterator it(entries.begin()); it != entries.end(); ++it) { if((ip_int & it->mask) == it->destination) { if(!best_match || it->mask > best_match->mask) - iface_id = if_nametoindex(it->interface.c_str()); + iface_id = resolve_index(it->interface.c_str()); } } if(best_match) @@ -111,10 +134,14 @@ NetworkInterface::NetworkInterface(IPv4Address ip) : iface_id(0) { } std::string NetworkInterface::name() const { + #ifndef WIN32 char iface_name[IF_NAMESIZE]; if(!if_indextoname(iface_id, iface_name)) throw std::runtime_error("Error fetching this interface's name"); return iface_name; + #else // WIN32 + return "Not implemented"; + #endif // WIN32 } NetworkInterface::Info NetworkInterface::addresses() const { @@ -128,9 +155,26 @@ NetworkInterface::Info NetworkInterface::addresses() const { } NetworkInterface::id_type NetworkInterface::resolve_index(const char *name) { + #ifndef WIN32 id_type id = if_nametoindex(name); if(!id) throw std::runtime_error("Invalid interface error"); + #else // WIN32 + id_type id; + ULONG size; + GetAdaptersInfo(0, &size); + std::vector buffer(size); + if ( GetAdaptersInfo((IP_ADAPTER_INFO *)&buffer[0], &size) == ERROR_SUCCESS) { + PIP_ADAPTER_INFO iface = (IP_ADAPTER_INFO *)&buffer[0]; + while(iface) { + if(!strcmp(iface->AdapterName, name)) { + id = iface->Index; + break; + } + iface = iface->Next; + } + } + #endif // WIN32 return id; } } diff --git a/src/packet_sender.cpp b/src/packet_sender.cpp index e23d2ee..c068578 100644 --- a/src/packet_sender.cpp +++ b/src/packet_sender.cpp @@ -37,6 +37,9 @@ #include #include #include +#else + #include + #include #endif #include #include @@ -57,11 +60,16 @@ Tins::PacketSender::PacketSender(uint32_t recv_timeout, uint32_t usec) : Tins::PacketSender::~PacketSender() { for(unsigned i(0); i < _sockets.size(); ++i) { - if(_sockets[i] != INVALID_RAW_SOCKET) + if(_sockets[i] != INVALID_RAW_SOCKET) + #ifndef WIN32 ::close(_sockets[i]); + #else + ::closesocket(_sockets[i]); + #endif } } +#ifndef WIN32 bool Tins::PacketSender::open_l2_socket() { if (_sockets[ETHER_SOCKET] != INVALID_RAW_SOCKET) return true; @@ -71,6 +79,7 @@ bool Tins::PacketSender::open_l2_socket() { _sockets[ETHER_SOCKET] = sock; return true; } +#endif // WIN32 bool Tins::PacketSender::open_l3_socket(SocketType type) { int socktype = find_type(type); @@ -84,7 +93,12 @@ bool Tins::PacketSender::open_l3_socket(SocketType type) { return false; const int on = 1; - setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL,(const void *)&on,sizeof(on)); + #ifndef WIN32 + typedef const void* option_ptr; + #else + typedef const char* option_ptr; + #endif + setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL,(option_ptr)&on,sizeof(on)); _sockets[type] = sockfd; return true; @@ -93,7 +107,11 @@ bool Tins::PacketSender::open_l3_socket(SocketType type) { bool Tins::PacketSender::close_socket(uint32_t flag) { if(flag >= SOCKETS_END || _sockets[flag] == INVALID_RAW_SOCKET) return false; + #ifndef WIN32 close(_sockets[flag]); + #else + closesocket(_sockets[flag]); + #endif _sockets[flag] = INVALID_RAW_SOCKET; return true; } @@ -107,7 +125,7 @@ Tins::PDU *Tins::PacketSender::send_recv(PDU &pdu) { return 0; return pdu.recv_response(*this); } - +#ifndef WIN32 bool Tins::PacketSender::send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr) { if(!open_l2_socket()) return false; @@ -126,6 +144,7 @@ Tins::PDU *Tins::PacketSender::recv_l2(PDU &pdu, struct sockaddr *link_addr, uin return 0; return recv_match_loop(_sockets[ETHER_SOCKET], pdu, link_addr, len_addr); } +#endif // WIN32 Tins::PDU *Tins::PacketSender::recv_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr, SocketType type) { if(!open_l3_socket(type)) @@ -140,7 +159,7 @@ bool Tins::PacketSender::send_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t if (ret_val) { int sock = _sockets[type]; PDU::serialization_type buffer = pdu.serialize(); - ret_val = (sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) != -1); + ret_val = (sendto(sock, (const char*)&buffer[0], buffer.size(), 0, link_addr, len_addr) != -1); } return ret_val; } @@ -160,7 +179,7 @@ Tins::PDU *Tins::PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockad return 0; } if(FD_ISSET(sock, &readfds)) { - ssize_t size = recvfrom(sock, buffer, 2048, 0, link_addr, &addrlen); + ssize_t size = recvfrom(sock, (char*)buffer, 2048, 0, link_addr, &addrlen); if(pdu.matches_response(buffer, size)) { return pdu.clone_packet(buffer, size); } diff --git a/src/snap.cpp b/src/snap.cpp index 1dbdaf5..011fc09 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -44,7 +44,7 @@ Tins::SNAP::SNAP(PDU *child) : PDU(child) { std::memset(&_snap, 0, sizeof(_snap)); _snap.dsap = _snap.ssap = 0xaa; - _snap.control = 3; + control(3); } Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) @@ -70,16 +70,18 @@ Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) } void Tins::SNAP::control(uint8_t new_control) { - _snap.control = new_control; + #if TINS_IS_LITTLE_ENDIAN + _snap.control_org = (_snap.control_org & 0xffffff00) | (new_control); + #else + _snap.control_org = (_snap.control_org & 0xffffff) | (new_control << 24); + #endif } void Tins::SNAP::org_code(small_uint<24> new_org) { - // little endian fix, it was the only way to make it work. - // check on big endian? - #ifdef TINS_IS_LITTLE_ENDIAN - _snap.org_code = Endian::host_to_be(new_org) >> 8; + #if TINS_IS_LITTLE_ENDIAN + _snap.control_org = Endian::host_to_be(new_org) | control(); #else - _snap.org_code = Endian::host_to_be(new_org); + _snap.control_org = new_org | (control() << 24); #endif } diff --git a/tests/src/dot11/beacon.cpp b/tests/src/dot11/beacon.cpp index 6973784..899ed95 100644 --- a/tests/src/dot11/beacon.cpp +++ b/tests/src/dot11/beacon.cpp @@ -97,6 +97,20 @@ TEST_F(Dot11BeaconTest, CopyAssignmentOperator) { test_equals(dot1, dot2); } +TEST_F(Dot11BeaconTest, FragNum) { + Dot11Beacon dot11; + dot11.frag_num(0x3); + EXPECT_EQ(0x3, dot11.frag_num()); + EXPECT_EQ(0, dot11.seq_num()); +} + +TEST_F(Dot11BeaconTest, SeqNum) { + Dot11Beacon dot11; + dot11.seq_num(0x1f2); + EXPECT_EQ(0x1f2, dot11.seq_num()); + EXPECT_EQ(0, dot11.frag_num()); +} + TEST_F(Dot11BeaconTest, FromBytes) { std::auto_ptr dot11(Dot11::from_bytes(expected_packet, sizeof(expected_packet))); ASSERT_TRUE(dot11.get()); diff --git a/tests/src/dot11/data.cpp b/tests/src/dot11/data.cpp index 4a9cf5f..653a980 100644 --- a/tests/src/dot11/data.cpp +++ b/tests/src/dot11/data.cpp @@ -26,7 +26,6 @@ const uint8_t Dot11DataTest::expected_packet[] = { TEST_F(Dot11DataTest, Constructor) { Dot11Data dot11; test_equals_empty(dot11); - } TEST_F(Dot11DataTest, ConstructorFromBuffer) { @@ -47,6 +46,20 @@ TEST_F(Dot11DataTest, CopyAssignmentOperator) { test_equals(dot1, dot2); } +TEST_F(Dot11DataTest, FragNum) { + Dot11Data dot11; + dot11.frag_num(0x3); + EXPECT_EQ(0x3, dot11.frag_num()); + EXPECT_EQ(0, dot11.seq_num()); +} + +TEST_F(Dot11DataTest, SeqNum) { + Dot11Data dot11; + dot11.seq_num(0x1f2); + EXPECT_EQ(0x1f2, dot11.seq_num()); + EXPECT_EQ(0, dot11.frag_num()); +} + TEST_F(Dot11DataTest, ClonePDU) { Dot11Data dot1(expected_packet, sizeof(expected_packet)); std::auto_ptr dot2(dot1.clone()); diff --git a/tests/src/snap.cpp b/tests/src/snap.cpp index 126a79d..40aefa1 100644 --- a/tests/src/snap.cpp +++ b/tests/src/snap.cpp @@ -16,7 +16,7 @@ public: }; const uint8_t SNAPTest::expected_packet[] = { - '\xaa', '\xaa', '\x03', '\x00', '\x00', '\x00', '\x08', '\x00' + '\xaa', '\xaa', '\x03', '\x00', '\x00', '\x01', '\x08', '\x00' }; TEST_F(SNAPTest, DefaultConstructor) { @@ -52,6 +52,15 @@ TEST_F(SNAPTest, OrgCode) { snap.org_code(0xfab1c3); EXPECT_EQ(snap.org_code(), 0xfab1c3); + EXPECT_EQ(snap.control(), 3); +} + +TEST_F(SNAPTest, Control) { + SNAP snap; + snap.control(0xfa); + + EXPECT_EQ(snap.control(), 0xfa); + EXPECT_EQ(snap.org_code(), 0); } TEST_F(SNAPTest, EthType) { @@ -89,11 +98,11 @@ TEST_F(SNAPTest, ConstructorFromBuffer) { SNAP snap1(expected_packet, sizeof(expected_packet)); PDU::serialization_type buffer = snap1.serialize(); - EXPECT_EQ(snap1.control(), 3); - EXPECT_EQ(snap1.dsap(), 0xaa); - EXPECT_EQ(snap1.ssap(), 0xaa); - EXPECT_EQ(snap1.eth_type(), 0x0800); - EXPECT_EQ(snap1.org_code(), 0); + EXPECT_EQ(3, snap1.control()); + EXPECT_EQ(0xaa, snap1.dsap()); + EXPECT_EQ(0xaa, snap1.ssap()); + EXPECT_EQ(0x0800, snap1.eth_type()); + EXPECT_EQ(1, snap1.org_code()); SNAP snap2(&buffer[0], buffer.size()); test_equals(snap1, snap2);