1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-30 05:24:26 +01:00

Every test now pass on big endian architectures. Ported about half of the library to windows as well.

This commit is contained in:
Matias Fontanini
2012-10-08 21:14:57 -03:00
parent 1c22dab2dc
commit 73577c744a
19 changed files with 285 additions and 83 deletions

View File

@@ -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. */
};
};

View File

@@ -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<uint16_t>(_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<uint16_t>(_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);

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.
*

View File

@@ -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<uint32_t>(_snap.org_code << 8);
#if TINS_IS_LITTLE_ENDIAN
return Endian::be_to_host<uint32_t>(_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__));

View File

@@ -32,6 +32,10 @@
#ifndef WIN32
#include <ifaddrs.h>
#else
#include <winsock2.h>
#include <iphlpapi.h>
#undef interface
#endif
#include <string>
#include <set>
@@ -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<class Functor>
void generic_iface_loop(Functor &functor) {
struct ifaddrs *ifaddrs = 0;
@@ -199,6 +204,22 @@ namespace Tins {
if(ifaddrs)
freeifaddrs(ifaddrs);
}
#else // WIN32
template<class Functor>
void generic_iface_loop(Functor &functor) {
ULONG size;
::GetAdaptersAddresses(AF_INET, 0, 0, 0, &size);
std::vector<uint8_t> 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);

View File

@@ -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<uint16_t>(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<uint16_t>(new_seq_num << 4) | (_ext_header.frag_seq & 0xf00);
#endif
}
void Dot11Data::addr4(const address_type &new_addr4) {

View File

@@ -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))

View File

@@ -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))

View File

@@ -34,6 +34,8 @@
#ifndef WIN32
#include <netdb.h>
#include <sys/socket.h>
#else
#include <winsock2.h>
#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

View File

@@ -58,6 +58,7 @@ Loopback::Loopback(const uint8_t *buffer, uint32_t total_sz)
_family = *reinterpret_cast<const uint32_t*>(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) {

View File

@@ -34,6 +34,8 @@
#include <linux/if_packet.h>
#include <net/if.h>
#include <netinet/in.h>
#else
#include <winsock2.h>
#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<uint8_t> 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;
}
}

View File

@@ -37,6 +37,9 @@
#include <linux/if_packet.h>
#include <netdb.h>
#include <netinet/in.h>
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include <cassert>
#include <errno.h>
@@ -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);
}

View File

@@ -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<uint32_t>(new_org) >> 8;
#if TINS_IS_LITTLE_ENDIAN
_snap.control_org = Endian::host_to_be<uint32_t>(new_org) | control();
#else
_snap.org_code = Endian::host_to_be<uint32_t>(new_org);
_snap.control_org = new_org | (control() << 24);
#endif
}

View File

@@ -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<PDU> dot11(Dot11::from_bytes(expected_packet, sizeof(expected_packet)));
ASSERT_TRUE(dot11.get());

View File

@@ -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<Dot11Data> dot2(dot1.clone());

View File

@@ -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);