mirror of
https://github.com/mfontanini/libtins
synced 2026-01-29 13:04:28 +01:00
Added DHCP and BootP constructors from uint8_t buffer. Normalized IP destination and source address getters/setters.
This commit is contained in:
@@ -200,11 +200,7 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface,
|
||||
const uint8_t* hw_snd) {
|
||||
|
||||
/* Create ARP packet and set its attributes */
|
||||
ARP* arp = new ARP();
|
||||
arp->target_ip_addr(target);
|
||||
arp->sender_ip_addr(sender);
|
||||
arp->target_hw_addr(hw_tgt);
|
||||
arp->sender_hw_addr(hw_snd);
|
||||
ARP* arp = new ARP(target, sender, hw_tgt, hw_snd);
|
||||
arp->opcode(REPLY);
|
||||
|
||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "bootp.h"
|
||||
@@ -10,6 +11,19 @@ Tins::BootP::BootP() : PDU(255), _vend_size(64) {
|
||||
std::memset(_vend, 0, 64);
|
||||
}
|
||||
|
||||
Tins::BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size) : PDU(255), _vend(0), _vend_size(vend_field_size) {
|
||||
if(total_sz < sizeof(bootphdr) + vend_field_size)
|
||||
throw std::runtime_error("Not enought size for a BootP header in the buffer.");
|
||||
std::memcpy(&_bootp, buffer, sizeof(bootphdr));
|
||||
buffer += sizeof(bootphdr);
|
||||
total_sz -= sizeof(bootphdr);
|
||||
if(_vend_size) {
|
||||
_vend = new uint8_t[_vend_size];
|
||||
std::memcpy(_vend, buffer, _vend_size);
|
||||
}
|
||||
// Maybe RawPDU on what is left on the buffer?...
|
||||
}
|
||||
|
||||
Tins::BootP::~BootP() {
|
||||
delete[] _vend;
|
||||
}
|
||||
|
||||
21
src/dhcp.cpp
21
src/dhcp.cpp
@@ -19,6 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "utils.h"
|
||||
@@ -36,6 +37,26 @@ Tins::DHCP::DHCP() : _size(sizeof(uint32_t) + 1) {
|
||||
hlen(6);
|
||||
}
|
||||
|
||||
Tins::DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz) : BootP(buffer, total_sz, 0) {
|
||||
buffer += BootP::header_size();
|
||||
total_sz -= BootP::header_size();
|
||||
uint8_t args[2];
|
||||
while(total_sz) {
|
||||
for(unsigned i(0); i < 2; ++i) {
|
||||
args[i] = *(buffer++);
|
||||
total_sz--;
|
||||
if(!total_sz)
|
||||
throw std::runtime_error("Not enought size for a DHCP header in the buffer.");
|
||||
}
|
||||
// Not enough size for this option
|
||||
if(total_sz < args[1])
|
||||
throw std::runtime_error("Not enought size for a DHCP header in the buffer.");
|
||||
add_option((Options)args[0], args[1], buffer);
|
||||
buffer += args[1];
|
||||
total_sz -= args[1];
|
||||
}
|
||||
}
|
||||
|
||||
Tins::DHCP::~DHCP() {
|
||||
while(_options.size()) {
|
||||
delete[] _options.front().value;
|
||||
|
||||
@@ -73,7 +73,7 @@ Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH
|
||||
inner_pdu(next);
|
||||
}
|
||||
|
||||
Tins::EthernetII::EthernetII(ethhdr *eth_ptr) : PDU(ETHERTYPE_IP) {
|
||||
Tins::EthernetII::EthernetII(const ethhdr *eth_ptr) : PDU(ETHERTYPE_IP) {
|
||||
memcpy(&_eth, eth_ptr, sizeof(ethhdr));
|
||||
}
|
||||
|
||||
@@ -163,10 +163,10 @@ Tins::PDU *Tins::EthernetII::recv_response(PacketSender *sender) {
|
||||
return sender->recv_l2(this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::EthernetII::clone_packet(uint8_t *ptr, uint32_t total_sz) {
|
||||
Tins::PDU *Tins::EthernetII::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
return 0;
|
||||
ethhdr *eth_ptr = (ethhdr*)ptr;
|
||||
const ethhdr *eth_ptr = (ethhdr*)ptr;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sizeof(ethhdr)) {
|
||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(ethhdr), total_sz - sizeof(ethhdr))) == 0)
|
||||
|
||||
@@ -126,19 +126,19 @@ void Tins::IP::check(uint16_t new_check) {
|
||||
_ip.check = Utils::net_to_host_s(new_check);
|
||||
}
|
||||
|
||||
void Tins::IP::source_address(const string &ip) {
|
||||
void Tins::IP::src_addr(const string &ip) {
|
||||
_ip.saddr = Utils::resolve_ip(ip);
|
||||
}
|
||||
|
||||
void Tins::IP::source_address(uint32_t ip) {
|
||||
void Tins::IP::src_addr(uint32_t ip) {
|
||||
_ip.saddr = ip;
|
||||
}
|
||||
|
||||
void Tins::IP::dest_address(const string &ip) {
|
||||
void Tins::IP::dst_addr(const string &ip) {
|
||||
_ip.daddr = Utils::resolve_ip(ip);
|
||||
}
|
||||
|
||||
void Tins::IP::dest_address(uint32_t ip) {
|
||||
void Tins::IP::dst_addr(uint32_t ip) {
|
||||
_ip.daddr = ip;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,12 @@ Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
|
||||
handle = pcap_open_live(device.c_str(), max_packet_size, 0, 0, error);
|
||||
if(!handle)
|
||||
throw runtime_error(error);
|
||||
actual_filter.bf_insns = 0;
|
||||
}
|
||||
|
||||
Tins::Sniffer::~Sniffer() {
|
||||
if(actual_filter.bf_insns)
|
||||
pcap_freecode(&actual_filter);
|
||||
if(handle)
|
||||
pcap_close(handle);
|
||||
}
|
||||
@@ -58,9 +61,12 @@ bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog)
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Sniffer::next_pdu(const string &filter) {
|
||||
bpf_program prog;
|
||||
if(!compile_set_filter(filter, prog))
|
||||
return 0;
|
||||
if(filter.size()) {
|
||||
if(actual_filter.bf_insns)
|
||||
pcap_freecode(&actual_filter);
|
||||
if(!compile_set_filter(filter, actual_filter))
|
||||
return 0;
|
||||
}
|
||||
pcap_pkthdr header;
|
||||
PDU *ret = 0;
|
||||
while(!ret) {
|
||||
@@ -72,7 +78,6 @@ Tins::PDU *Tins::Sniffer::next_pdu(const string &filter) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
pcap_freecode(&prog);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -80,13 +85,15 @@ void Tins::Sniffer::stop_sniff() {
|
||||
pcap_breakloop(handle);
|
||||
}
|
||||
|
||||
void Tins::Sniffer::sniff_loop(const std::string &filter, AbstractSnifferHandler *cback_handler, uint32_t max_packets) {
|
||||
bpf_program prog;
|
||||
if(compile_set_filter(filter, prog)) {
|
||||
LoopData data(handle, cback_handler);
|
||||
pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
|
||||
pcap_freecode(&prog);
|
||||
void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) {
|
||||
if(filter.size()) {
|
||||
if(actual_filter.bf_insns)
|
||||
pcap_freecode(&actual_filter);
|
||||
if(!compile_set_filter(filter, actual_filter))
|
||||
return;
|
||||
}
|
||||
LoopData data(handle, cback_handler);
|
||||
pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
|
||||
}
|
||||
|
||||
// Static
|
||||
|
||||
@@ -198,7 +198,7 @@ void Tins::TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
|
||||
memcpy(tcp_start, &_tcp, sizeof(tcphdr));
|
||||
if(!_tcp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_TCP) +
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_TCP) +
|
||||
PDU::do_checksum(tcp_start, tcp_start + total_sz);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
|
||||
@@ -73,7 +73,7 @@ void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
length(sizeof(udphdr) + inner_pdu()->size());
|
||||
std::memcpy(buffer, &_udp, sizeof(udphdr));
|
||||
if(!_udp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->source_address(), ip_packet->dest_address(), size(), IPPROTO_UDP) +
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_UDP) +
|
||||
PDU::do_checksum(buffer, buffer + total_sz);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff)+(checksum >> 16);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <iostream> //borrame
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#ifndef WIN32
|
||||
|
||||
Reference in New Issue
Block a user