injector classes interface, no compiler errors
[quarnos.git] / resources / arp.cpp
blob9c1eb30c9bacbe836a63ecc26c1f912ef1debaab
1 #include "arp.h"
2 #include "mac_addr.h"
4 using namespace resources;
6 mac_addr arp::get_haddr(ipv4_addr ipaddr) {
7 p<arp_table::arp_record> rec = table.get(ipaddr);
8 if (rec.valid())
9 return rec->haddr;
11 p<arp_packet> pkg = new arp_packet;
13 pkg->htype = to_be16(ethernet);
14 pkg->ptype = to_be16(ipv4);
16 pkg->hlen = sizeof(mac_addr);
17 pkg->plen = sizeof(ipv4_addr);
19 pkg->oper = to_be16(request);
21 pkg->sha0 = my_haddr.first_be32();
22 pkg->sha1 = my_haddr.last_be16();
23 pkg->spa = to_be32(my_paddr);
25 pkg->tha0 = 0;
26 pkg->tha1 = 0;
27 pkg->tpa = to_be32(ipaddr);
29 mac_addr broadcast = mac_addr::from_be(0xffffffff, 0xffff);
30 network->send_data(broadcast, et_arp, buffer::to_mem(pkg));
32 rec = 0;//p<arp_table::arp_record>::invalid;
33 do {
34 while (!received) __asm__("hlt");
35 received = false;
37 rec = table.get(ipaddr);
38 } while (!rec.valid());
40 return rec->haddr;
44 void arp::receive_packet(p<arp_packet> pkg) {
45 if (from_be16(pkg->oper) == request) {
46 if (from_be32(pkg->tpa) != my_paddr)
47 return;
49 mac_addr mac = mac_addr::from_be(pkg->sha0, pkg->sha1);
51 p<arp_packet> rpl = new arp_packet;
53 rpl->htype = pkg->htype;
54 rpl->ptype = pkg->ptype;
56 rpl->hlen = pkg->hlen;
57 rpl->plen = pkg->plen;
59 rpl->oper = to_be16(reply);
61 rpl->sha0 = my_haddr.first_be32();
62 rpl->sha1 = my_haddr.last_be16();
63 rpl->spa = to_be32(my_paddr);
65 rpl->tha0 = mac.first_be16();
66 rpl->tha1 = mac.last_be32();
67 rpl->tpa = pkg->spa;
69 network->send_data(mac, et_arp, buffer::to_mem(rpl));
71 } else if (from_be16(pkg->oper) == reply) {
72 p<arp_table::arp_record> rec = new arp_table::arp_record;
73 rec->prot = from_be16(pkg->ptype);
74 rec->paddr = from_be32(pkg->spa);
75 rec->haddr = mac_addr::from_be(pkg->sha0, pkg->sha1);
77 table.add(rec);
78 received = true;
83 void arp::receive_data(const buffer &x) {
84 if ((unsigned int)x.get_size() >= sizeof(arp_packet))
85 receive_packet(x.cast<arp_packet>());