mirror of
https://github.com/mfontanini/libtins
synced 2026-01-30 05:24:26 +01:00
Added options to IP PDU
This commit is contained in:
69
include/ip.h
69
include/ip.h
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -26,12 +26,41 @@
|
||||
#include <endian.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
class IP : public PDU {
|
||||
public:
|
||||
enum OptionClass {
|
||||
CONTROL = 0,
|
||||
MEASUREMENT = 2
|
||||
};
|
||||
|
||||
enum OptionNumber {
|
||||
IPOPT_END = 0,
|
||||
IPOPT_NOOP = 1,
|
||||
IPOPT_SEC = 2,
|
||||
IPOPT_LSSR = 3,
|
||||
IPOPT_TIMESTAMP = 4,
|
||||
IPOPT_EXTSEC = 5,
|
||||
IPOPT_RR = 7,
|
||||
IPOPT_SID = 8,
|
||||
IPOPT_SSRR = 9,
|
||||
IPOPT_MTUPROBE = 11,
|
||||
IPOPT_MTUREPLY = 12,
|
||||
IPOPT_EIP = 17,
|
||||
IPOPT_TR = 18,
|
||||
IPOPT_ADDEXT = 19,
|
||||
IPOPT_RTRALT = 20,
|
||||
IPOPT_SDB = 21,
|
||||
IPOPT_DPS = 23,
|
||||
IPOPT_UMP = 24,
|
||||
IPOPT_QS = 25
|
||||
};
|
||||
|
||||
IP(const std::string &ip_dst = "", const std::string &ip_src = "", PDU *child = 0);
|
||||
IP(uint32_t ip_dst = 0, uint32_t ip_src = 0, PDU *child = 0);
|
||||
|
||||
@@ -56,6 +85,12 @@ namespace Tins {
|
||||
void source_address(uint32_t ip);
|
||||
void dest_address(const std::string &ip);
|
||||
void dest_address(uint32_t ip);
|
||||
void set_option(uint8_t copied, OptionClass op_class, OptionNumber number, uint8_t* data = 0, uint32_t data_size = 0);
|
||||
|
||||
void set_option_eol();
|
||||
void set_option_noop();
|
||||
void set_option_sec(uint8_t* data, uint32_t data_len);
|
||||
/* Add more option setters */
|
||||
|
||||
/* Virtual methods */
|
||||
uint32_t header_size() const;
|
||||
@@ -81,7 +116,26 @@ namespace Tins {
|
||||
uint32_t saddr;
|
||||
uint32_t daddr;
|
||||
/*The options start here. */
|
||||
} __attribute__((packed));
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct IpOption {
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int number:5;
|
||||
unsigned int op_class:2;
|
||||
unsigned int copied:1;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int copied:1;
|
||||
unsigned int op_class:2;
|
||||
unsigned int number:5;
|
||||
#endif
|
||||
} type;
|
||||
uint8_t* optional_data;
|
||||
uint32_t optional_data_size;
|
||||
|
||||
uint8_t* write(uint8_t* buffer);
|
||||
|
||||
} __attribute__((__packed__));
|
||||
|
||||
static const uint8_t DEFAULT_TTL;
|
||||
|
||||
@@ -89,6 +143,9 @@ namespace Tins {
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
iphdr _ip;
|
||||
std::vector<IpOption> _ip_options;
|
||||
uint32_t _options_size;
|
||||
uint32_t _padded_options_size;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
70
src/ip.cpp
70
src/ip.cpp
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* libtins is a net packet wrapper library for crafting and
|
||||
* interpreting sniffed packets.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2011 Nasel
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -53,6 +53,7 @@ void Tins::IP::init_ip_fields() {
|
||||
_ip.version = 4;
|
||||
_ip.ihl = sizeof(iphdr) / sizeof(uint32_t);
|
||||
_ip.ttl = DEFAULT_TTL;
|
||||
_options_size = 0;
|
||||
}
|
||||
|
||||
/* Setters */
|
||||
@@ -101,10 +102,59 @@ void Tins::IP::dest_address(uint32_t ip) {
|
||||
_ip.daddr = ip;
|
||||
}
|
||||
|
||||
void Tins::IP::set_option_eol() {
|
||||
this->set_option(0, IP::CONTROL, IP::IPOPT_END);
|
||||
}
|
||||
|
||||
void Tins::IP::set_option_noop() {
|
||||
this->set_option(0, IP::CONTROL, IP::IPOPT_NOOP);
|
||||
}
|
||||
|
||||
void Tins::IP::set_option_sec(uint8_t* data, uint32_t data_len) {
|
||||
assert(data_len == 10);
|
||||
this->set_option(1, IP::CONTROL, IP::IPOPT_SEC, data, data_len);
|
||||
}
|
||||
|
||||
void Tins::IP::set_option(uint8_t copied,
|
||||
OptionClass op_class,
|
||||
OptionNumber number,
|
||||
uint8_t* data,
|
||||
uint32_t data_size) {
|
||||
IpOption option;
|
||||
option.type.copied = copied;
|
||||
option.type.op_class = op_class;
|
||||
option.type.number = number;
|
||||
uint8_t* buffer(0);
|
||||
if (data_size) {
|
||||
/* data must be a valid pointer */
|
||||
assert(data);
|
||||
buffer = new uint8_t[data_size];
|
||||
memcpy(buffer, data, data_size);
|
||||
}
|
||||
option.optional_data = buffer;
|
||||
option.optional_data_size = data_size;
|
||||
_ip_options.push_back(option);
|
||||
_options_size += 1 + ((buffer)? (data_size) : 0);
|
||||
uint8_t padding = _options_size & 3;
|
||||
_padded_options_size = padding? (_options_size - padding + 4) : _options_size;
|
||||
}
|
||||
|
||||
uint8_t* Tins::IP::IpOption::write(uint8_t* buffer) {
|
||||
|
||||
memcpy(buffer, &type, 1);
|
||||
buffer += 1;
|
||||
if (optional_data) {
|
||||
memcpy(buffer, optional_data, optional_data_size);
|
||||
buffer += optional_data_size;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Virtual method overriding. */
|
||||
|
||||
uint32_t Tins::IP::header_size() const {
|
||||
return sizeof(iphdr);
|
||||
return sizeof(iphdr) + _padded_options_size;
|
||||
|
||||
}
|
||||
|
||||
bool Tins::IP::send(PacketSender* sender) {
|
||||
@@ -117,11 +167,11 @@ bool Tins::IP::send(PacketSender* sender) {
|
||||
}
|
||||
|
||||
void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t my_sz = header_size() + trailer_size();
|
||||
uint32_t my_sz = header_size();
|
||||
uint32_t new_flag;
|
||||
assert(total_sz >= my_sz);
|
||||
if(inner_pdu()) {
|
||||
new_flag = inner_pdu()->flag();
|
||||
new_flag = inner_pdu()->flag();
|
||||
if(new_flag == IPPROTO_IP)
|
||||
new_flag = IPPROTO_IPIP;
|
||||
}
|
||||
@@ -130,7 +180,11 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz) {
|
||||
flag(new_flag);
|
||||
_ip.protocol = new_flag;
|
||||
_ip.tot_len = total_sz;
|
||||
_ip.ihl = my_sz / sizeof(uint32_t);
|
||||
memcpy(buffer, &_ip, sizeof(iphdr));
|
||||
|
||||
/* IP Options here... */
|
||||
buffer += sizeof(iphdr);
|
||||
for (uint32_t i = 0; i < _ip_options.size(); ++i)
|
||||
buffer = _ip_options[i].write(buffer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user