3 #include "manes/error.h"
4 #include "libs/array.h"
8 void ipv4::set_link_layer(p
<link_layer
> x
) {
9 arp_prot
.set_link_layer(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;
21 pkg
->length
= to_be16(x
.get_size() + 28);
23 pkg
->flags_offset
= to_le16(0x40);
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
));
33 for (unsigned int i
= 0; i
< sizeof(ipv4_packet
)/2; i
++)
36 sum
= (sum
& 0xffff) + (sum
>> 16);
39 pkg
->checksum
= to_le16(~sum
);
41 buffer buf
= buffer::to_mem(pkg
);
46 if (addr
.network(mask
) == my_ip
.network(mask
))
47 haddr
= arp_prot
.get_haddr(addr
);
49 haddr
= arp_prot
.get_haddr(gateway
);
51 down
->send_data(haddr
, 0x800, buf
);
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
)));