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

Added DHCP class. It's now working yet.

This commit is contained in:
Matias Fontanini
2011-08-17 12:16:48 -03:00
parent bdadcbb47d
commit c49806603b
8 changed files with 269 additions and 17 deletions

View File

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

View File

@@ -20,6 +20,7 @@
*/
#include <cassert>
#include <iostream> //borrame
#include "utils.h"
#include "pdu.h"
#include "rawpdu.h"

View File

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