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