net: udp sending data routine
[quarnos.git] / resources / net / arp.cpp
blob70f5fc2bb371819c9c4561eb68632b420c1f55fb
1 #include "arp.h"
2 #include "mac_addr.h"
4 using namespace net;
6 void poll(volatile bool *value) {
7 while (!*value) asm volatile("hlt");
10 mac_addr arp::get_haddr(const ipv4_addr &ipaddr) {
11 p<arp_table::arp_record> rec = table->get(ipaddr);
12 if (rec.valid())
13 return rec->haddr;
15 p<arp_packet> pkg = new arp_packet;
17 pkg->htype = to_be16(ethernet);
18 pkg->ptype = to_be16(ipv4);
20 pkg->hlen = mac_addr::in_bytes();
21 pkg->plen = ipv4_addr::in_bytes();
23 pkg->oper = to_be16(request);
25 pkg->sha0 = my_haddr.first_be32();
26 pkg->sha1 = my_haddr.last_be16();
27 pkg->spa = my_paddr.to_be();
29 pkg->tha0 = 0;
30 pkg->tha1 = 0;
31 pkg->tpa = ipaddr.to_be();
33 mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff);
34 down->send_data(broadcast, et_arp, buffer::to_mem(pkg));
36 pkg.dispose();
38 rec = p<arp_table::arp_record>::invalid;
40 do {
41 poll(&received);
42 received = false;
43 rec = table->get(ipaddr);
44 } while (!rec.valid());
46 return rec->haddr;
50 void arp::receive_packet(p<arp_packet> pkg) {
51 if (from_be16(pkg->oper) == request) {
52 if (ipv4_addr::from_be(pkg->tpa) != my_paddr)
53 return;
55 mac_addr mac = mac_addr::from_be(pkg->sha0, pkg->sha1);
57 p<arp_packet> rpl = new arp_packet;
59 rpl->htype = pkg->htype;
60 rpl->ptype = pkg->ptype;
62 rpl->hlen = pkg->hlen;
63 rpl->plen = pkg->plen;
65 rpl->oper = to_be16(reply);
67 rpl->sha0 = my_haddr.first_be32();
68 rpl->sha1 = my_haddr.last_be16();
69 rpl->spa = my_paddr.to_be();
71 rpl->tha0 = mac.first_be16();
72 rpl->tha1 = mac.last_be32();
73 rpl->tpa = pkg->spa;
75 down->send_data(mac, et_arp, buffer::to_mem(rpl));
77 rpl.dispose();
79 } else if (from_be16(pkg->oper) == reply) {
80 p<arp_table::arp_record> rec = new arp_table::arp_record;
81 rec->prot = from_be16(pkg->ptype);
82 rec->paddr = ipv4_addr::from_be(pkg->spa);
83 rec->haddr = mac_addr::from_be(pkg->sha0, pkg->sha1);
85 table->add(rec);
86 received = true;
91 void arp::receive_data(const buffer &x) {
92 receive_packet(x.cast<arp_packet>());