mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added DHCP class. It's now working yet.
This commit is contained in:
@@ -133,14 +133,14 @@ namespace Tins {
|
||||
/** \brief Getter for the vend field.
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
uint8_t *vend() { return _bootp.vend; }
|
||||
uint8_t *vend() { return _vend; }
|
||||
|
||||
/** \brief Getter for the vend field.
|
||||
*/
|
||||
uint32_t vend_size() const { return _vend_size; }
|
||||
|
||||
/** \brief Getter for the header size.
|
||||
* \return Returns the ARP header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
@@ -221,6 +221,8 @@ namespace Tins {
|
||||
* \param size The size of the new vend field.
|
||||
*/
|
||||
void vend(uint8_t *new_vend, uint32_t size);
|
||||
protected:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the Bootp datagram.
|
||||
@@ -242,7 +244,6 @@ namespace Tins {
|
||||
uint8_t file[128];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
bootphdr _bootp;
|
||||
uint8_t *_vend;
|
||||
|
||||
184
include/dhcp.h
Normal file
184
include/dhcp.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __DHCP_H
|
||||
#define __DHCP_H
|
||||
|
||||
|
||||
#include <list>
|
||||
#include "bootp.h"
|
||||
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \brief Class that represents the DHCP PDU.
|
||||
*
|
||||
* The end option is added automatically at the end of the option list.
|
||||
*/
|
||||
class DHCP : public BootP {
|
||||
public:
|
||||
/** \brief DHCP flags.
|
||||
*/
|
||||
enum Flags {
|
||||
DHCPDISCOVER = 1,
|
||||
DHCPOFFER = 2,
|
||||
DHCPREQUEST = 3,
|
||||
DHCPDECLINE = 4,
|
||||
DHCPACK = 5,
|
||||
DHCPNAK = 6,
|
||||
DHCPRELEASE = 7,
|
||||
DHCPINFORM = 8
|
||||
};
|
||||
|
||||
/** \brief DHCP options enum.
|
||||
*/
|
||||
enum Options {
|
||||
PAD,
|
||||
SUBNET_MASK,
|
||||
TIME_OFFSET,
|
||||
ROUTERS,
|
||||
TIME_SERVERS,
|
||||
NAME_SERVERS,
|
||||
DOMAIN_NAME_SERVERS,
|
||||
LOG_SERVERS,
|
||||
COOKIE_SERVERS,
|
||||
LPR_SERVERS,
|
||||
IMPRESS_SERVERS,
|
||||
RESOURCE_LOCATION_SERVERS,
|
||||
HOST_NAME,
|
||||
BOOT_SIZE,
|
||||
MERIT_DUMP,
|
||||
DOMAIN_NAME,
|
||||
SWAP_SERVER,
|
||||
ROOT_PATH,
|
||||
EXTENSIONS_PATH,
|
||||
IP_FORWARDING,
|
||||
NON_LOCAL_SOURCE_ROUTING,
|
||||
POLICY_FILTER,
|
||||
MAX_DGRAM_REASSEMBLY,
|
||||
DEFAULT_IP_TTL,
|
||||
PATH_MTU_AGING_TIMEOUT,
|
||||
PATH_MTU_PLATEAU_TABLE,
|
||||
INTERFACE_MTU,
|
||||
ALL_SUBNETS_LOCAL,
|
||||
BROADCAST_ADDRESS,
|
||||
PERFORM_MASK_DISCOVERY,
|
||||
MASK_SUPPLIER,
|
||||
ROUTER_DISCOVERY,
|
||||
ROUTER_SOLICITATION_ADDRESS,
|
||||
STATIC_ROUTES,
|
||||
TRAILER_ENCAPSULATION,
|
||||
ARP_CACHE_TIMEOUT,
|
||||
IEEE802_3_ENCAPSULATION,
|
||||
DEFAULT_TCP_TTL,
|
||||
TCP_KEEPALIVE_INTERVAL,
|
||||
TCP_KEEPALIVE_GARBAGE,
|
||||
NIS_DOMAIN,
|
||||
NIS_SERVERS,
|
||||
NTP_SERVERS,
|
||||
VENDOR_ENCAPSULATED_OPTIONS,
|
||||
NETBIOS_NAME_SERVERS,
|
||||
NETBIOS_DD_SERVER,
|
||||
NETBIOS_NODE_TYPE,
|
||||
NETBIOS_SCOPE,
|
||||
FONT_SERVERS,
|
||||
X_DISPLAY_MANAGER,
|
||||
DHCP_REQUESTED_ADDRESS,
|
||||
DHCP_LEASE_TIME,
|
||||
DHCP_OPTION_OVERLOAD,
|
||||
DHCP_MESSAGE_TYPE,
|
||||
DHCP_SERVER_IDENTIFIER,
|
||||
DHCP_PARAMETER_REQUEST_LIST,
|
||||
DHCP_MESSAGE,
|
||||
DHCP_MAX_MESSAGE_SIZE,
|
||||
DHCP_RENEWAL_TIME,
|
||||
DHCP_REBINDING_TIME,
|
||||
VENDOR_CLASS_IDENTIFIER,
|
||||
DHCP_CLIENT_IDENTIFIER,
|
||||
NWIP_DOMAIN_NAME,
|
||||
NWIP_SUBOPTIONS,
|
||||
USER_CLASS = 77,
|
||||
FQDN = 81,
|
||||
DHCP_AGENT_OPTIONS = 82,
|
||||
SUBNET_SELECTION = 118,
|
||||
AUTHENTICATE = 210,
|
||||
END = 255
|
||||
};
|
||||
|
||||
/** \brief DHCP options struct.
|
||||
*/
|
||||
struct DHCPOption {
|
||||
uint8_t option, length;
|
||||
uint8_t *value;
|
||||
|
||||
DHCPOption(uint8_t opt, uint8_t len, uint8_t *val);
|
||||
};
|
||||
|
||||
/** \brief Creates an instance of DHCP.
|
||||
*
|
||||
* This sets the hwtype and hlen fields to match the ethernet
|
||||
* type and length.
|
||||
*/
|
||||
DHCP();
|
||||
|
||||
/** \brief Adds a new option to this DHCP PDU.
|
||||
*
|
||||
* This copies the value buffer. Adding options may fail if
|
||||
* there's not enough size to hold a new option.
|
||||
* \param opt The option identifier.
|
||||
* \param len The length of the value field.
|
||||
* \param val The value of this option.
|
||||
* \return True if the option was added successfully.
|
||||
*/
|
||||
bool add_option(Options opt, uint8_t len, uint8_t *val);
|
||||
|
||||
/** \brief Adds a type option the the option list.
|
||||
* \param type The type of this DHCP PDU.
|
||||
*/
|
||||
void add_type_option(Flags type);
|
||||
|
||||
/** \brief Getter for the options list.
|
||||
* \return The option list.
|
||||
*/
|
||||
const std::list<DHCPOption> options() const { return _options; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::UDP; }
|
||||
|
||||
/** \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
private:
|
||||
static const uint32_t MAX_DHCP_SIZE;
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
std::list<DHCPOption> _options;
|
||||
uint32_t _size;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -56,7 +56,8 @@ namespace Tins {
|
||||
ARP,
|
||||
TCP,
|
||||
UDP,
|
||||
ICMP
|
||||
ICMP,
|
||||
DHCP
|
||||
};
|
||||
|
||||
/** \brief PDU constructor
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Tins {
|
||||
* \param dport Destination port.
|
||||
* \param sport Source port.
|
||||
* */
|
||||
UDP(uint16_t sport = 0, uint16_t dport = 0);
|
||||
UDP(uint16_t dport = 0, uint16_t sport = 0, PDU *child = 0);
|
||||
|
||||
|
||||
/** \brief Returns the destination port
|
||||
@@ -63,6 +63,12 @@ namespace Tins {
|
||||
* \param new_sport The new source port.
|
||||
*/
|
||||
void sport(uint16_t new_sport);
|
||||
|
||||
/** \brief Getter for the length field.
|
||||
* \param new_len The new length field.
|
||||
* \return The length field.
|
||||
*/
|
||||
void length(uint16_t new_len);
|
||||
|
||||
/** \brief Set the payload.
|
||||
*
|
||||
@@ -88,7 +94,6 @@ namespace Tins {
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::UDP; }
|
||||
|
||||
private:
|
||||
struct udphdr {
|
||||
uint16_t sport;
|
||||
|
||||
@@ -4,16 +4,18 @@
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
Tins::BootP::BootP() : PDU(255) {
|
||||
Tins::BootP::BootP() : PDU(255), _vend_size(64) {
|
||||
_vend = new uint8_t[64];
|
||||
std::memset(&_bootp, 0, sizeof(bootphdr));
|
||||
std::memset(_vend, 0, 64);
|
||||
}
|
||||
|
||||
Tins::BootP::~BootP() {
|
||||
delete[] vend;
|
||||
delete[] _vend;
|
||||
}
|
||||
|
||||
uint32_t Tins::BootP::header_size() const {
|
||||
return sizeof(bootphdr);
|
||||
return sizeof(bootphdr) + _vend_size;
|
||||
}
|
||||
|
||||
void Tins::BootP::opcode(uint8_t new_opcode) {
|
||||
@@ -61,7 +63,7 @@ void Tins::BootP::giaddr(uint32_t new_giaddr) {
|
||||
}
|
||||
|
||||
void Tins::BootP::chaddr(uint8_t *new_chaddr) {
|
||||
std::memcpy(_bootp.chaddr, new_chaddr, sizeof(_bootp.chaddr));
|
||||
std::memcpy(_bootp.chaddr, new_chaddr, _bootp.hlen);
|
||||
}
|
||||
|
||||
void Tins::BootP::sname(uint8_t *new_sname) {
|
||||
@@ -80,6 +82,7 @@ void Tins::BootP::vend(uint8_t *new_vend, uint32_t size) {
|
||||
}
|
||||
|
||||
void Tins::BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
assert(total_sz >= sizeof(bootphdr));
|
||||
assert(total_sz >= sizeof(bootphdr) + _vend_size);
|
||||
std::memcpy(buffer, &_bootp, sizeof(bootphdr));
|
||||
std::memcpy(buffer + sizeof(bootphdr), _vend, _vend_size);
|
||||
}
|
||||
|
||||
52
src/dhcp.cpp
Normal file
52
src/dhcp.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iostream> //borrame
|
||||
#include "utils.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
const uint32_t Tins::DHCP::MAX_DHCP_SIZE = 312;
|
||||
|
||||
/* Magic cookie: uint32_t.
|
||||
* end of options: 1 byte. */
|
||||
Tins::DHCP::DHCP() : _size(sizeof(uint32_t) + 1) {
|
||||
opcode(BOOTREQUEST);
|
||||
htype(1); //ethernet
|
||||
hlen(6);
|
||||
}
|
||||
|
||||
Tins::DHCP::DHCPOption::DHCPOption(uint8_t opt, uint8_t len, uint8_t *val) : option(opt), length(len) {
|
||||
value = new uint8_t[len];
|
||||
std::memcpy(value, val, len);
|
||||
}
|
||||
|
||||
bool Tins::DHCP::add_option(Options opt, uint8_t len, uint8_t *val) {
|
||||
uint32_t opt_size = len + (sizeof(uint8_t) << 1);
|
||||
if(_size + opt_size > MAX_DHCP_SIZE)
|
||||
return false;
|
||||
_options.push_back(DHCPOption((uint8_t)opt, len, val));
|
||||
_size += opt_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tins::DHCP::add_type_option(Flags type) {
|
||||
add_option(DHCP_MESSAGE_TYPE, 1, (uint8_t*)&type);
|
||||
}
|
||||
|
||||
uint32_t Tins::DHCP::header_size() const {
|
||||
return BootP::header_size() - vend_size() + _size;
|
||||
}
|
||||
|
||||
void Tins::DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
assert(total_sz >= header_size());
|
||||
uint8_t *result = new uint8_t[_size], *ptr = result + sizeof(uint32_t);
|
||||
*((uint32_t*)result) = Utils::net_to_host_l(0x63825363);
|
||||
for(std::list<DHCPOption>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
*(ptr++) = it->option;
|
||||
*(ptr++) = it->length;
|
||||
std::memcpy(ptr++, it->value, it->length);
|
||||
}
|
||||
result[_size-1] = END;
|
||||
vend(result, _size);
|
||||
BootP::write_serialization(buffer, total_sz, parent);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream> //borrame
|
||||
#include "utils.h"
|
||||
#include "pdu.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
17
src/udp.cpp
17
src/udp.cpp
@@ -29,24 +29,27 @@
|
||||
#include "ip.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
Tins::UDP::UDP(uint16_t sport, uint16_t dport) : PDU(IPPROTO_UDP) {
|
||||
_udp.sport = sport;
|
||||
_udp.dport = dport;
|
||||
Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) : PDU(IPPROTO_UDP, child) {
|
||||
this->dport(dport);
|
||||
this->sport(sport);
|
||||
_udp.check = 0;
|
||||
_udp.len = 0;
|
||||
}
|
||||
|
||||
void Tins::UDP::payload(uint8_t *new_payload, uint32_t new_payload_size) {
|
||||
inner_pdu(new RawPDU(new_payload, new_payload_size));
|
||||
_udp.len = Utils::net_to_host_s(sizeof(udphdr) + new_payload_size);
|
||||
}
|
||||
|
||||
void Tins::UDP::dport(uint16_t new_dport) {
|
||||
_udp.dport = new_dport;
|
||||
_udp.dport = Utils::net_to_host_s(new_dport);
|
||||
}
|
||||
|
||||
void Tins::UDP::sport(uint16_t new_sport) {
|
||||
_udp.sport = new_sport;
|
||||
_udp.sport = Utils::net_to_host_s(new_sport);
|
||||
}
|
||||
|
||||
void Tins::UDP::length(uint16_t new_len) {
|
||||
_udp.len = Utils::net_to_host_s(new_len);
|
||||
}
|
||||
|
||||
uint32_t Tins::UDP::header_size() const {
|
||||
@@ -56,6 +59,8 @@ uint32_t Tins::UDP::header_size() const {
|
||||
void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
assert(total_sz >= sizeof(udphdr));
|
||||
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
|
||||
if(inner_pdu())
|
||||
length(sizeof(udphdr) + inner_pdu()->size());
|
||||
if(!_udp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_UDP) +
|
||||
PDU::do_checksum(buffer + sizeof(udphdr), buffer + total_sz) + PDU::do_checksum((uint8_t*)&_udp, ((uint8_t*)&_udp) + sizeof(udphdr));
|
||||
|
||||
Reference in New Issue
Block a user