5 #include "arch/low/general.h"
7 #include "libs/array.h"
11 void udp::send(ipv4_addr addr
, u16 dst_port
, u16 src_port
, const buffer
&data
) {
12 p
<udp_packet
> pkg
= new udp_packet
;
13 pkg
->sender_port
= to_be16(src_port
);
14 pkg
->receiver_port
= to_be16(dst_port
);
15 pkg
->length
= to_be16(data
.get_size() + sizeof(udp_packet
));
18 p
<pseudo_header
> ph
= new pseudo_header
;
19 ph
->source
= down
.cast
<ipv4
>()->get_my_ip().to_be();
20 ph
->destination
= addr
.to_be();
23 ph
->length
= to_be16(sizeof(udp_packet
) + data
.get_size());
24 array
<u16
> ph_words
= array
<u16
>::from_buffer(buffer::to_mem(ph
));
26 buffer buf
= buffer::to_mem(pkg
);
29 array
<u16
> words
= array
<u16
>::from_buffer(buf
);
32 for (unsigned int i
= 0; i
< (sizeof(udp_packet
) + data
.get_size()) / 2; i
++)
35 if (data
.get_size() % 2)
36 sum
+= (u16
)data
[data
.get_size() - 1];
38 for (unsigned int i
= 0; i
< sizeof(pseudo_header
) / 2; i
++)
43 sum
= (sum
& 0xffff) + (sum
>> 16);
46 buf
.cast
<udp_packet
>()->checksum
= to_le16(~sum
);
48 down
->send_data(addr
, 17, buf
);
53 void udp::receive(const ipv4_addr
&sender
, const buffer
&data
) {
54 p
<udp_packet
> pkg
= data
.cast
<udp_packet
>();
56 for (int i
= 0; i
< ports
.get_count(); i
++)
57 if (ports
[i
] == from_be16(pkg
->receiver_port
))
58 listeners
[i
](sender
, from_be16(pkg
->sender_port
), data
.cut_first(sizeof(udp_packet
)));
61 void udp::listen(u16 port
, delegate
<void, const ipv4_addr
&, u16
, const buffer
&> listener
) {
62 asm("cli\nhlt"::"a"(0xb0000f));
63 for (int i
= 0; i
< ports
.get_count();) {
64 if (ports
[i
] == port
) {
72 listeners
.add(listener
);