From 6d1e96866e47996a23cad9db6ca4e83063cdc534 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Sun, 2 Dec 2012 00:45:10 -0300 Subject: [PATCH] libtins now compiles on windows. A couple of features were disabled and need to be fixed though. --- include/endianness.h | 6 +++++- include/radiotap.h | 2 ++ include/timestamp.h | 12 ++++++++++-- src/ipv6.cpp | 2 ++ src/ipv6_address.cpp | 25 +++++++++++++++++++++---- src/network_interface.cpp | 2 +- src/packet_sender.cpp | 27 +++++++++++++++++++-------- src/packet_writer.cpp | 9 +++++++-- src/radiotap.cpp | 2 ++ src/snap.cpp | 2 +- src/utils.cpp | 13 ++++++++++--- 11 files changed, 80 insertions(+), 22 deletions(-) diff --git a/include/endianness.h b/include/endianness.h index 9eb4804..63905b8 100644 --- a/include/endianness.h +++ b/include/endianness.h @@ -43,7 +43,11 @@ #define TINS_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) #define TINS_IS_BIG_ENDIAN (_BYTE_ORDER == _BIG_ENDIAN) #endif -#elif !defined(WIN32) +#elif defined(WIN32) + // Assume windows == little endian. fixme later + #define TINS_IS_LITTLE_ENDIAN 1 + #define TINS_IS_BIG_ENDIAN 0 +#else #include #define TINS_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN) #define TINS_IS_BIG_ENDIAN (__BYTE_ORDER == __BIG_ENDIAN) diff --git a/include/radiotap.h b/include/radiotap.h index 94e5eb5..f294e08 100644 --- a/include/radiotap.h +++ b/include/radiotap.h @@ -124,10 +124,12 @@ namespace Tins { /* Setters */ + #ifndef WIN32 /** * \sa PDU::send() */ void send(PacketSender &sender); + #endif /** * \brief Setter for the version field. diff --git a/include/timestamp.h b/include/timestamp.h index 8e4443d..050ef2b 100644 --- a/include/timestamp.h +++ b/include/timestamp.h @@ -42,6 +42,14 @@ namespace Tins { */ class Timestamp { public: + #ifdef WIN32 + typedef long seconds_type; + typedef long microseconds_type; + #else + typedef time_t seconds_type; + typedef suseconds_t microseconds_type; + #endif + /** * Default constructs the timestamp. */ @@ -56,14 +64,14 @@ public: /** * Returns the amount of seconds in this timestamp. */ - time_t seconds() const { + seconds_type seconds() const { return tv.tv_sec; } /** * Returns the amount of microseconds in this timestamp. */ - suseconds_t microseconds() const { + microseconds_type microseconds() const { return tv.tv_usec; } diff --git a/src/ipv6.cpp b/src/ipv6.cpp index 559fb94..782cdb4 100644 --- a/src/ipv6.cpp +++ b/src/ipv6.cpp @@ -3,6 +3,8 @@ #ifndef WIN32 #include #include +#else + #include #endif #include //borrame #include "ipv6.h" diff --git a/src/ipv6_address.cpp b/src/ipv6_address.cpp index 9064a2e..3b25ff6 100644 --- a/src/ipv6_address.cpp +++ b/src/ipv6_address.cpp @@ -34,6 +34,9 @@ #ifdef BSD #include #endif +#else + #include + #include #endif #include #include // borrame @@ -58,14 +61,28 @@ namespace Tins { } void IPv6Address::init(const char *addr) { - if(inet_pton(AF_INET6, addr, address) == 0) - throw malformed_address(); + #ifdef WIN32 + ULONG dummy1; + USHORT dummy2; + // Maybe change this, mingw doesn't have any other conversion function + if(RtlIpv6StringToAddressExA(addr, (IN6_ADDR*)address, &dummy1, &dummy2) != NO_ERROR) + throw malformed_address(); + #else + if(inet_pton(AF_INET6, addr, address) == 0) + throw malformed_address(); + #endif } std::string IPv6Address::to_string() const { char buffer[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET6, address, buffer, sizeof(buffer)) == 0) - throw malformed_address(); + #ifdef WIN32 + ULONG sz = sizeof(buffer); + if(RtlIpv6AddressToStringExA((const IN6_ADDR*)address, 0, 0, buffer, &sz) != NO_ERROR) + throw malformed_address(); + #else + if(inet_ntop(AF_INET6, address, buffer, sizeof(buffer)) == 0) + throw malformed_address(); + #endif return buffer; } diff --git a/src/network_interface.cpp b/src/network_interface.cpp index cc75490..5c41a71 100644 --- a/src/network_interface.cpp +++ b/src/network_interface.cpp @@ -99,7 +99,7 @@ struct InterfaceInfoCollector { bool operator() (const IP_ADAPTER_ADDRESSES *iface) { using Tins::IPv4Address; // This surely doesn't work - if(iface_id == iface->IfIndex) { + if(iface_id == uint32_t(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++) { diff --git a/src/packet_sender.cpp b/src/packet_sender.cpp index 748e9ac..8502ed3 100644 --- a/src/packet_sender.cpp +++ b/src/packet_sender.cpp @@ -69,12 +69,15 @@ const uint32_t PacketSender::DEFAULT_TIMEOUT = 2; return strerror(errno); } #else - + // fixme + const char *make_error_string() { + return "error"; + } #endif PacketSender::PacketSender(uint32_t recv_timeout, uint32_t usec) : _sockets(SOCKETS_END, INVALID_RAW_SOCKET), -#ifndef BSD +#if !defined(BSD) && !defined(WIN32) _ether_socket(INVALID_RAW_SOCKET), #endif _timeout(recv_timeout), @@ -96,7 +99,7 @@ PacketSender::~PacketSender() { #ifdef BSD for(BSDEtherSockets::iterator it = _ether_socket.begin(); it != _ether_socket.end(); ++it) ::close(it->second); - #else + #elif !defined(WIN32) if(_ether_socket != INVALID_RAW_SOCKET) ::close(_ether_socket); #endif @@ -183,7 +186,7 @@ void PacketSender::close_socket(SocketType type, const NetworkInterface &iface) if(::close(it->second) == -1) throw SocketCloseError(make_error_string()); _ether_socket.erase(it); - #else + #elif !defined(WIN32) if(_ether_socket == INVALID_RAW_SOCKET) throw InvalidSocketTypeError(); if(::close(_ether_socket) == -1) @@ -267,16 +270,24 @@ PDU *PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_add return 0; } if(FD_ISSET(sock, &readfds)) { - ssize_t size = recvfrom(sock, (char*)buffer, 2048, 0, link_addr, &addrlen); + #ifdef WIN32 + int length = addrlen; + #else + socklen_t length = addrlen; + #endif + ssize_t size = recvfrom(sock, (char*)buffer, 2048, 0, link_addr, &length); if(pdu.matches_response(buffer, size)) { return pdu.clone_packet(buffer, size); } } struct timeval this_time, diff; - gettimeofday(&this_time, 0); - if(timeval_subtract(&diff, &end_time, &this_time)) { + #ifdef WIN32 + // fixme + #else + gettimeofday(&this_time, 0); + #endif // WIN32 + if(timeval_subtract(&diff, &end_time, &this_time)) return 0; - } timeout.tv_sec = diff.tv_sec; timeout.tv_usec = diff.tv_usec; } diff --git a/src/packet_writer.cpp b/src/packet_writer.cpp index 9add099..60ba3b7 100644 --- a/src/packet_writer.cpp +++ b/src/packet_writer.cpp @@ -54,8 +54,13 @@ PacketWriter::~PacketWriter() { void PacketWriter::write(PDU &pdu) { PDU::serialization_type buffer = pdu.serialize(); - struct timeval tm; - gettimeofday(&tm, 0); + timeval tm; + #ifndef WIN32 + gettimeofday(&tm, 0); + #else + // fixme + tm = timeval(); + #endif struct pcap_pkthdr header = { tm, static_cast(buffer.size()), diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 293be62..ebe28a5 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -227,6 +227,7 @@ uint32_t RadioTap::trailer_size() const { return ((_flags & 0x10) != 0) ? sizeof(uint32_t) : 0; } +#ifndef WIN32 void RadioTap::send(PacketSender &sender) { if(!_iface) throw std::runtime_error("Interface has not been set"); @@ -252,6 +253,7 @@ void RadioTap::send(PacketSender &sender) { sender.send_l2(*this, 0, 0, _iface); #endif } +#endif void RadioTap::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { uint32_t sz = header_size(); diff --git a/src/snap.cpp b/src/snap.cpp index 011fc09..c7b311a 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -96,7 +96,7 @@ uint32_t Tins::SNAP::header_size() const { void Tins::SNAP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { assert(total_sz >= sizeof(_snap)); if (!_snap.eth_type && inner_pdu()) { - uint16_t type = ETHERTYPE_IP; + uint16_t type = Tins::Constants::Ethernet::IP; switch (inner_pdu()->pdu_type()) { case PDU::IP: type = Tins::Constants::Ethernet::IP; diff --git a/src/utils.cpp b/src/utils.cpp index a42e37d..810beb5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -58,14 +58,21 @@ using namespace std; /** \cond */ struct InterfaceCollector { set ifaces; - + + #ifdef WIN32 + bool operator() (PIP_ADAPTER_ADDRESSES addr) { + ifaces.insert(addr->AdapterName); + return true; + } + #else bool operator() (struct ifaddrs *addr) { ifaces.insert(addr->ifa_name); return true; } + #endif }; -struct IPv4Collector { +/*struct IPv4Collector { uint32_t ip; bool found; const char *iface; @@ -79,7 +86,7 @@ struct IPv4Collector { } return found; } -}; +};*/ namespace Tins {