1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-25 19:51:34 +01:00

IP now fills automatically the sender address when no link layer PDU is present. Made some protocols work when using PacketSender::send_recv.

This commit is contained in:
Matias Fontanini
2013-03-25 14:08:59 -03:00
parent b0dc376494
commit 82ef41dd92
16 changed files with 241 additions and 114 deletions

View File

@@ -48,6 +48,7 @@
#include "utils.h"
#include "packet_sender.h"
#include "constants.h"
#include "network_interface.h"
using std::list;
@@ -351,28 +352,46 @@ uint32_t IP::header_size() const {
return sizeof(iphdr) + _padded_options_size;
}
PacketSender::SocketType pdu_type_to_sender_type(PDU::PDUType type) {
switch(type) {
case PDU::TCP:
return PacketSender::IP_TCP_SOCKET;
case PDU::UDP:
return PacketSender::IP_UDP_SOCKET;
case PDU::ICMP:
return PacketSender::ICMP_SOCKET;
default:
return PacketSender::IP_RAW_SOCKET;
}
}
void IP::send(PacketSender& sender) {
struct sockaddr_in link_addr;
PacketSender::SocketType type = PacketSender::IP_SOCKET;
sockaddr_in link_addr;
PacketSender::SocketType type = PacketSender::IP_RAW_SOCKET;
link_addr.sin_family = AF_INET;
link_addr.sin_port = 0;
link_addr.sin_addr.s_addr = _ip.daddr;
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
type = PacketSender::ICMP_SOCKET;
if(inner_pdu())
type = pdu_type_to_sender_type(inner_pdu()->pdu_type());
sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
}
PDU *IP::recv_response(PacketSender &sender) {
struct sockaddr_in link_addr;
PacketSender::SocketType type = PacketSender::IP_SOCKET;
link_addr.sin_family = AF_INET;
link_addr.sin_port = 0;
link_addr.sin_addr.s_addr = _ip.daddr;
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
type = PacketSender::ICMP_SOCKET;
sockaddr_in link_addr;
PacketSender::SocketType type = PacketSender::IP_RAW_SOCKET;
std::memset(&link_addr, 0, sizeof(link_addr));
if(inner_pdu())
type = pdu_type_to_sender_type(inner_pdu()->pdu_type());
return sender.recv_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
return sender.recv_l3(*this, 0, sizeof(link_addr), type);
}
void IP::prepare_for_serialize(const PDU *parent) {
if(!parent && _ip.saddr == 0) {
NetworkInterface iface(dst_addr());
src_addr(iface.addresses().ip_addr);
}
}
void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* parent) {
@@ -429,7 +448,7 @@ bool IP::matches_response(uint8_t *ptr, uint32_t total_sz) {
return false;
iphdr *ip_ptr = (iphdr*)ptr;
if(_ip.daddr == ip_ptr->saddr && _ip.saddr == ip_ptr->daddr) {
uint32_t sz = _ip.ihl * sizeof(uint32_t);
uint32_t sz = std::min(_ip.ihl * sizeof(uint32_t), total_sz);
return inner_pdu() ? inner_pdu()->matches_response(ptr + sz, total_sz - sz) : true;
}
return false;