net: data reception system, fixed bugs in rtl8139
[quarnos.git] / resources / net / ipv4.cpp
blobe718f89a38984de54fe7e2468a6134c51d899889
1 #include "ipv4.h"
3 #include "manes/error.h"
4 #include "libs/array.h"
6 using namespace net;
8 void ipv4::set_link_layer(p<link_layer> x) {
9 arp_prot.set_link_layer(x);
11 down = x;
12 x->add_handler(0x800, delegate<void, const buffer&>::method(this, &ipv4::receive_data));
15 void ipv4::send_data(const ipv4_addr &addr, int prot, const buffer &x) {
16 assert("ipv4: packet cannot be smaller than 20 bytes", x.get_size() < 20);
18 p<ipv4_packet> pkg = new ipv4_packet;
19 pkg->version_size = 0x45;
20 pkg->service = 0;
21 pkg->length = to_be16(x.get_size() + 28);
22 pkg->id = 0;
23 pkg->flags_offset = to_le16(0x40);
24 pkg->ttl = 64;
25 pkg->prot = prot;
26 pkg->checksum = 0;
27 pkg->src = my_ip.to_be();
28 pkg->dst = addr.to_be();
30 array<u16> words = array<u16>::from_buffer(buffer::to_mem(pkg));
31 u32 sum = 0;
33 for (unsigned int i = 0; i < sizeof(ipv4_packet)/2; i++)
34 sum += words[i];
36 sum = (sum & 0xffff) + (sum >> 16);
37 sum += (sum >> 16);
39 pkg->checksum = to_le16(~sum);
41 buffer buf = buffer::to_mem(pkg);
43 buf += x;
45 mac_addr haddr;
46 if (addr.network(mask) == my_ip.network(mask))
47 haddr = arp_prot.get_haddr(addr);
48 else
49 haddr = arp_prot.get_haddr(gateway);
51 down->send_data(haddr, 0x800, buf);
53 pkg.dispose();
56 void ipv4::receive_data(const buffer &data) {
57 p<ipv4_packet> pkg = data.cast<ipv4_packet>();
59 for (int i = 0; i < protocols.get_count(); i++)
60 if (protocols[i] == pkg->prot)
61 listeners[i](ipv4_addr::from_be(pkg->src), data.cut_first(sizeof(ipv4_packet)));