net: partial implementation of tcp
[quarnos.git] / resources / net / udp.cpp
blob019191fac0f19bd2e30c13a4c2174093acd3ca2d
1 /* Based on RFC768 */
3 #include "udp.h"
4 #include "ipv4.h"
5 #include "udp_client_socket.h"
6 #include "udp_server_socket.h"
8 #include "arch/low/general.h"
10 #include "libs/array.h"
12 using namespace net;
14 void udp::send(const ipv4_addr &addr, u16 dst_port, u16 src_port, const buffer &data) {
15 p<udp_packet> pkg = new udp_packet;
16 pkg->sender_port = to_be16(src_port);
17 pkg->receiver_port = to_be16(dst_port);
18 pkg->length = to_be16(data.get_size() + sizeof(udp_packet));
19 pkg->checksum = 0;
21 p<pseudo_header> ph = new pseudo_header;
22 ph->source = down.cast<ipv4>()->get_my_ip().to_be();
23 ph->destination = addr.to_be();
24 ph->zero = 0;
25 ph->protocol = 17;
26 ph->length = to_be16(sizeof(udp_packet) + data.get_size());
27 array<u16> ph_words = array<u16>::from_buffer(buffer::to_mem(ph));
29 buffer buf = buffer::to_mem(pkg);
30 buf += data;
32 array<u16> words = array<u16>::from_buffer(buf);
33 u32 sum = 0;
35 for (unsigned int i = 0; i < (sizeof(udp_packet) + data.get_size()) / 2; i++)
36 sum += words[i];
38 if (data.get_size() % 2)
39 sum += (u16)data[data.get_size() - 1];
41 for (unsigned int i = 0; i < sizeof(pseudo_header) / 2; i++)
42 sum += ph_words[i];
44 // ph.dispose();
46 sum = (sum & 0xffff) + (sum >> 16);
47 sum += (sum >> 16);
49 buf.cast<udp_packet>()->checksum = to_le16(~sum);
51 down->send_data(addr, 17, buf);
53 // pkg.dispose();
56 void udp::receive(const ipv4_addr &sender, const buffer &data) {
57 return;
58 p<udp_packet> pkg = data.cast<udp_packet>();
60 for (int i = 0; i < ports.get_count(); i++)
61 if (ports[i] == from_be16(pkg->receiver_port))
62 listeners[i](sender, from_be16(pkg->sender_port), data.cut_first(sizeof(udp_packet)));
65 void udp::listen(u16 port, delegate<void, const ipv4_addr &, u16, const buffer &> listener) {
66 for (int i = 0; i < ports.get_count();) {
67 if (ports[i] == port) {
68 ports.remove(i);
69 listeners.remove(i);
70 } else
71 i++;
74 ports.add(port);
75 listeners.add(listener);
78 void udp::remove_listener(u16 port, port_listener listener) {}
80 p<client_socket> udp::create_client() {
81 return (client_socket*)new udp_client_socket(this);
84 p<server_socket> udp::create_server(int port) {
85 return (server_socket*)new udp_server_socket(this, port);