From 1595a4f8e00d5dc3454b5f7c6fd31f6ecd8efcdc Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Wed, 15 Jul 2009 19:37:10 +0200 Subject: [PATCH] net: arp packet builder and interpreter --- libs/pointer.h | 4 ++ resources/net/arp.cpp | 68 ++++++++++-------------- resources/net/arp.h | 29 +---------- resources/net/arp_packet.h | 115 +++++++++++++++++++++++++++++++++++++++++ resources/net/packet_builder.h | 9 ++++ 5 files changed, 155 insertions(+), 70 deletions(-) create mode 100644 resources/net/arp_packet.h create mode 100644 resources/net/packet_builder.h diff --git a/libs/pointer.h b/libs/pointer.h index 123c51d..74f0e0d 100644 --- a/libs/pointer.h +++ b/libs/pointer.h @@ -93,6 +93,10 @@ public: throw new null_pointer_exception("Attempt to dereference invalid pointer."); } + const T *operator->() const { + return pointer; + } + bool valid() const { return (pointer != (T*)0); } diff --git a/resources/net/arp.cpp b/resources/net/arp.cpp index c971294..96ff36a 100644 --- a/resources/net/arp.cpp +++ b/resources/net/arp.cpp @@ -1,5 +1,6 @@ #include "arp.h" #include "mac_addr.h" +#include "arp_packet.h" using namespace net; @@ -13,25 +14,18 @@ mac_addr arp::get_haddr(const ipv4_addr &ipaddr) { return rec->haddr; p pkg = new arp_packet; + pkg->set_ptype(arp_packet::p_ipv4); + pkg->set_htype(arp_packet::h_ethernet); - pkg->htype = to_be16(ethernet); - pkg->ptype = to_be16(ipv4); + pkg->set_type(arp_packet::arp_request); - pkg->hlen = mac_addr::in_bytes(); - pkg->plen = ipv4_addr::in_bytes(); + pkg->set_source_haddr(my_haddr); + pkg->set_source_paddr(my_paddr); - pkg->oper = to_be16(request); - - pkg->sha0 = my_haddr.first_be32(); - pkg->sha1 = my_haddr.last_be16(); - pkg->spa = my_paddr.to_be(); - - pkg->tha0 = 0; - pkg->tha1 = 0; - pkg->tpa = ipaddr.to_be(); + pkg->set_target_paddr(ipaddr); mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff); - down->send_data(broadcast, et_arp, buffer::to_mem(pkg)); + down->send_data(broadcast, et_arp, pkg->generate()); pkg.dispose(); @@ -47,57 +41,47 @@ mac_addr arp::get_haddr(const ipv4_addr &ipaddr) { return rec->haddr; } - void arp::receive_packet(p pkg) { - if (from_be16(pkg->oper) == request) { - if (ipv4_addr::from_be(pkg->tpa) != my_paddr) + if (pkg->get_type() == arp_packet::arp_request) { + if (pkg->get_target_paddr() != my_paddr) return; /* Add sender to ARP table */ arp_table::arp_record rec; - rec.prot = from_be16(pkg->ptype); - rec.paddr = ipv4_addr::from_be(pkg->spa); - rec.haddr = mac_addr::from_be(pkg->sha0, pkg->sha1); + rec.prot = pkg->get_ptype(); + rec.paddr = pkg->get_source_paddr(); + rec.haddr = pkg->get_source_haddr(); table.add(rec); - //rec.dispose(); - - mac_addr mac = mac_addr::from_be(pkg->sha0, pkg->sha1); p rpl = new arp_packet; - rpl->htype = pkg->htype; - rpl->ptype = pkg->ptype; - - rpl->hlen = pkg->hlen; - rpl->plen = pkg->plen; + rpl->set_htype(pkg->get_htype()); + rpl->set_ptype(pkg->get_ptype()); - rpl->oper = to_be16(reply); + rpl->set_type(arp_packet::arp_reply); - rpl->sha0 = my_haddr.first_be32(); - rpl->sha1 = my_haddr.last_be16(); - rpl->spa = my_paddr.to_be(); + rpl->set_source_haddr(my_haddr); + rpl->set_source_paddr(my_paddr); - rpl->tha0 = mac.first_be16(); - rpl->tha1 = mac.last_be32(); - rpl->tpa = pkg->spa; + rpl->set_target_haddr(pkg->get_source_haddr()); + rpl->set_target_paddr(pkg->get_source_paddr()); - down->send_data(mac, et_arp, buffer::to_mem(rpl)); + down->send_data(pkg->get_source_haddr(), et_arp, rpl->generate()); rpl.dispose(); - } else if (from_be16(pkg->oper) == reply) { + } else if (pkg->get_type() == arp_packet::arp_reply) { arp_table::arp_record rec; - rec.prot = from_be16(pkg->ptype); - rec.paddr = ipv4_addr::from_be(pkg->spa); - rec.haddr = mac_addr::from_be(pkg->sha0, pkg->sha1); + rec.prot = pkg->get_ptype(); + rec.paddr = pkg->get_source_paddr(); + rec.haddr = pkg->get_source_haddr(); table.add(rec); received = true; } } - void arp::receive_data(const buffer &x) { - receive_packet(x.cast()); + receive_packet(new arp_packet(x)); } diff --git a/resources/net/arp.h b/resources/net/arp.h index bcf8698..8ace2ce 100644 --- a/resources/net/arp.h +++ b/resources/net/arp.h @@ -1,52 +1,25 @@ #ifndef _ARP_H_ #define _ARP_H_ -#include "arch/low/general.h" #include "libs/buffer.h" #include "mac_addr.h" #include "arp_table.h" #include "internet_layer.h" #include "link_layer.h" +#include "arp_packet.h" namespace net { class arp : public osi_layer { private: p down; - /* EtherType */ enum { et_arp = 0x806 }; - enum { - ethernet = 1 - }; - enum protocol { - ipv4 = 0x0800 - }; - enum { - request = 1, - reply = 2 - }; - mac_addr my_haddr; ipv4_addr my_paddr; - struct arp_packet { - u16 htype; - u16 ptype; - u8 hlen; - u8 plen; - u16 oper; - u32 sha0; - u16 sha1; - u32 spa; - u16 tha0; - u32 tha1; - u32 tpa; - } __attribute__((packed)); - - volatile bool received; arp_table table; diff --git a/resources/net/arp_packet.h b/resources/net/arp_packet.h new file mode 100644 index 0000000..e96ecce --- /dev/null +++ b/resources/net/arp_packet.h @@ -0,0 +1,115 @@ +#ifndef _ARP_PACKET_H_ +#define _ARP_PACKET_H_ + +#include "arch/low/general.h" +#include "packet_builder.h" + +namespace net { + class arp_packet : public packet_builder { + private: + struct packet { + u16 htype; + u16 ptype; + u8 hlen; + u8 plen; + u16 oper; + u32 sha0; + u16 sha1; + u32 spa; + u16 tha0; + u32 tha1; + u32 tpa; + } __attribute__((packed)); + + + p pkg; + public: + arp_packet() : pkg(new packet) { } + ~arp_packet() { + pkg.dispose(); + } + + buffer generate() const { + return buffer::to_mem(pkg); + } + + void add_data(const buffer&) { } + + enum ptypes { + p_ipv4 = 0x800 + }; + + enum htypes { + h_ethernet = 1 + }; + + void set_ptype(ptypes pt) { + pkg->ptype = to_be16(pt); + pkg->plen = ipv4_addr::in_bytes(); + } + + void set_htype(htypes ht) { + pkg->htype = to_be16(ht); + pkg->hlen = mac_addr::in_bytes(); + } + + enum arp_type { + arp_request = 1, + arp_reply = 2 + }; + + void set_type(arp_type at) { + pkg->oper = to_be16(at); + } + + void set_source_haddr(const mac_addr &addr) { + pkg->sha0 = addr.first_be32(); + pkg->sha1 = addr.last_be16(); + } + + void set_source_paddr(const ipv4_addr &addr) { + pkg->spa = addr.to_be(); + } + + void set_target_haddr(const mac_addr &addr) { + pkg->tha0 = addr.first_be16(); + pkg->tha1 = addr.last_be32(); + } + + void set_target_paddr(const ipv4_addr &addr) { + pkg->tpa = addr.to_be(); + } + + arp_packet(const buffer &x) : pkg(x.cast()) { } + + ptypes get_ptype() const { + return (ptypes)from_be16(pkg->ptype); + } + + htypes get_htype() const { + return (htypes)from_be16(pkg->htype); + } + + arp_type get_type() const { + return (arp_type)from_be16(pkg->oper); + } + + mac_addr get_source_haddr() const { + return mac_addr::from_be(pkg->sha0, pkg->sha1); + } + + ipv4_addr get_source_paddr() const { + return ipv4_addr::from_be(pkg->spa); + } + + mac_addr get_target_haddr() const { + return mac_addr::from_be_r(pkg->tha0, pkg->tha1); + } + + ipv4_addr get_target_paddr() const { + return ipv4_addr::from_be(pkg->tpa); + } + }; +} + +#endif diff --git a/resources/net/packet_builder.h b/resources/net/packet_builder.h new file mode 100644 index 0000000..65c98a9 --- /dev/null +++ b/resources/net/packet_builder.h @@ -0,0 +1,9 @@ +namespace net { + class packet_builder { + public: + virtual ~packet_builder() { } + + virtual buffer generate() const = 0; + virtual void add_data(const buffer&) = 0; + }; +} -- 2.11.4.GIT