From 8f5b5d0b06e9483f5c7d515718c0d2bdaefcdce6 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Thu, 9 Jul 2009 17:40:35 +0200 Subject: [PATCH] net: udp sending data routine --- libs/array.h | 5 ++++ manes/start.cpp | 6 +++++ resources/Makefile | 2 +- resources/net/arp.cpp | 1 + resources/net/internet_layer.h | 2 ++ resources/net/ipv4.h | 4 ++++ resources/net/transport_layer.h | 2 ++ resources/net/udp.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ resources/net/udp.h | 31 ++++++++++++++++++++++++ 9 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 resources/net/udp.cpp create mode 100644 resources/net/udp.h diff --git a/libs/array.h b/libs/array.h index e2db144..0aa9753 100644 --- a/libs/array.h +++ b/libs/array.h @@ -45,6 +45,11 @@ public: throw new index_out_of_range_exception(); } + template + array cast() { + return array(reinterpret_cast(data), size); + } + static array from_buffer(const buffer &x) { return array((T*)x.get_address(), x.get_size()); } diff --git a/manes/start.cpp b/manes/start.cpp index 8695e8b..f2f563b 100644 --- a/manes/start.cpp +++ b/manes/start.cpp @@ -68,6 +68,7 @@ #include "resources/ne2k.h" #include "resources/net/ipv4.h" #include "resources/net/arp.h" +#include "resources/net/udp.h" #include "resources/net/icmp.h" using namespace services; @@ -174,6 +175,11 @@ extern "C" void _start() { ip.set_link_layer(ð); ip.configure_ipv4(ipv4_addr::from_le(192 << 24 | 168 << 16 | 1 << 8 | 50), ipv4_addr::from_le(255 << 24 | 255 << 16 | 255 << 8), ipv4_addr::from_le(192 << 24 | 168 << 16 | 1 << 8 | 1)); + udp u; + u.set_internet_layer(&ip); + string str = "zuooooooooooooooooooooooooooooooooooooooooooa"; + u.send(ipv4_addr::from_le(192 << 24 | 168 << 16 | 1 << 8 | 3), 41300, 47438, str.to_mem()); + icmp ping; ping.set_internet_layer(&ip); ping.ping(ipv4_addr::from_le(192 << 24 | 168 << 16 | 1 << 8 | 1)); diff --git a/resources/Makefile b/resources/Makefile index 375844a..6128316 100644 --- a/resources/Makefile +++ b/resources/Makefile @@ -19,7 +19,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -RESOURCE = isa.o pci.o device.o keybscr.o x86_keybscr.o fdc.o speaker.o prvl.o foma.o fat.o fs.o file.o virtual_bus.o pio.o physmem.o unknown.o ne2k.o usb.o uhci.o bus.o net/arp.o net/mac_addr.o net/arp_table.o net/ethernet.o net/link_layer.o net/ipv4.o net/icmp.o net/ipv4_addr.o rtl8139.o slob.o # rs232.o +RESOURCE = isa.o pci.o device.o keybscr.o x86_keybscr.o fdc.o speaker.o prvl.o foma.o fat.o fs.o file.o virtual_bus.o pio.o physmem.o unknown.o ne2k.o usb.o uhci.o bus.o net/arp.o net/mac_addr.o net/arp_table.o net/ethernet.o net/link_layer.o net/ipv4.o net/icmp.o net/ipv4_addr.o net/udp.o rtl8139.o slob.o # rs232.o OBJS = $(MANES) $(RESOURCE) diff --git a/resources/net/arp.cpp b/resources/net/arp.cpp index 6b2913f..70f5fc2 100644 --- a/resources/net/arp.cpp +++ b/resources/net/arp.cpp @@ -39,6 +39,7 @@ mac_addr arp::get_haddr(const ipv4_addr &ipaddr) { do { poll(&received); + received = false; rec = table->get(ipaddr); } while (!rec.valid()); diff --git a/resources/net/internet_layer.h b/resources/net/internet_layer.h index 4cc056b..83b7b5e 100644 --- a/resources/net/internet_layer.h +++ b/resources/net/internet_layer.h @@ -4,6 +4,8 @@ #include "osi_layer.h" #include "link_layer.h" +#include "ipv4_addr.h" + namespace net { class internet_layer : public osi_layer { protected: diff --git a/resources/net/ipv4.h b/resources/net/ipv4.h index ae807b0..1386e48 100644 --- a/resources/net/ipv4.h +++ b/resources/net/ipv4.h @@ -43,6 +43,10 @@ namespace net { gateway = gate; } + ipv4_addr get_my_ip() { + return my_ip; + } + void set_link_layer(p x); void send_data(const ipv4_addr &addr, int prot, const buffer &x); }; diff --git a/resources/net/transport_layer.h b/resources/net/transport_layer.h index 62ccf24..ea0be02 100644 --- a/resources/net/transport_layer.h +++ b/resources/net/transport_layer.h @@ -1,6 +1,8 @@ #ifndef _TRANSPORT_LAYER_H_ #define _TRANSPORT_LAYER_H_ +#include "internet_layer.h" + namespace net { class transport_layer : public osi_layer { protected: diff --git a/resources/net/udp.cpp b/resources/net/udp.cpp new file mode 100644 index 0000000..5bae27c --- /dev/null +++ b/resources/net/udp.cpp @@ -0,0 +1,52 @@ +/* Based on RFC768 */ + +#include "udp.h" +#include "ipv4.h" +#include "arch/low/general.h" + +#include "libs/array.h" + +using namespace net; + +void udp::send(ipv4_addr addr, u16 dst_port, u16 src_port, const buffer &data) { + p pkg = new udp_packet; + pkg->sender_port = to_be16(src_port); + pkg->receiver_port = to_be16(dst_port); + pkg->length = to_be16(data.get_size() + sizeof(udp_packet)); + pkg->checksum = 0; + + p ph = new pseudo_header; + ph->source = down.cast()->get_my_ip().to_be(); + ph->destination = addr.to_be(); + ph->zero = 0; + ph->protocol = 17; + ph->length = to_be16(sizeof(udp_packet) + data.get_size()); + array ph_words = array::from_buffer(buffer::to_mem(ph)); + + buffer buf = buffer::to_mem(pkg); + buf += data; + + array words = array::from_buffer(buf); + u32 sum = 0; + + for (unsigned int i = 0; i < (sizeof(udp_packet) + data.get_size()) / 2; i++) + sum += words[i]; + + if (data.get_size() % 2) + sum += (u16)data[data.get_size() - 1]; + + for (unsigned int i = 0; i < sizeof(pseudo_header) / 2; i++) + sum += ph_words[i]; + +// ph.dispose(); + + sum = (sum & 0xffff) + (sum >> 16); + sum += (sum >> 16); + + buf.cast()->checksum = to_le16(~sum); + + down->send_data(addr, 17, buf); + +// pkg.dispose(); +} + diff --git a/resources/net/udp.h b/resources/net/udp.h new file mode 100644 index 0000000..b41e066 --- /dev/null +++ b/resources/net/udp.h @@ -0,0 +1,31 @@ +#ifndef _UDP_H_ +#define _UDP_H_ + +#include "transport_layer.h" + +namespace net { + class udp : public transport_layer { + private: + struct pseudo_header { + u32 source; + u32 destination; + u8 zero; + u8 protocol; + u16 length; + } __attribute__((packed)); + + struct udp_packet { + u16 sender_port; + u16 receiver_port; + u16 length; + u16 checksum; + } __attribute__((packed)); + + void receive(const buffer&); + public: + void send(ipv4_addr, u16, u16, const buffer &); + void listen(u16, delegate); + }; +} + +#endif -- 2.11.4.GIT