1
0
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:
Matias Fontanini
2011-08-19 10:13:35 -03:00
parent bb3ea10209
commit 3e2168f6fc
17 changed files with 161 additions and 73 deletions

View File

@@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,6 +23,7 @@
#include <sstream>
#include <fstream>
#include <stdexcept>
#include <iostream> //borrame
#include <cassert>
#include <cstring>
#ifndef WIN32