net: minor improvements in tcp client sockets
[quarnos.git] / resources / net / ipv4_packet.h
blob43e9c043abfca74eabf25ef8f7e9c96f9ea0340f
1 #ifndef _IPV4_PACKET_H_
2 #define _IPV4_PACKET_H_
4 #include "libs/array.h"
6 #include "arch/low/general.h"
7 #include "packet_builder.h"
9 namespace net {
10 class ipv4_packet : public packet_builder {
11 private:
12 enum {
13 default_version_size = 0x45,
14 default_service = 0,
15 default_ttl = 64
18 struct packet {
19 u8 version_size;
20 u8 service;
21 u16 length;
22 u16 id;
23 u16 flags_offset;
24 u8 ttl;
25 u8 prot;
26 u16 checksum;
27 u32 src;
28 u32 dst;
29 } __attribute__((packed));
31 mutable p<packet> pkg;
33 buffer data;
34 public:
35 ipv4_packet() : pkg(new packet) { }
36 ~ipv4_packet() {
37 pkg.dispose();
40 buffer generate() const {
41 /* Set default values */
42 pkg->version_size = default_version_size;
43 pkg->service = default_service;
44 pkg->ttl = default_ttl;
45 pkg->flags_offset = to_le16(0x40);
47 /* Count packet length */
48 pkg->length = to_be16(data.get_size() + sizeof(packet));
50 /* Count checksum */
51 array<u16> words = array<u16>::from_buffer(buffer::to_mem(pkg));
52 u32 sum = 0;
53 for (unsigned int i = 0; i < sizeof(packet) / 2; i++)
54 sum += words[i];
56 sum = (sum & 0xffff) + (sum >> 16);
57 sum += (sum >> 16);
59 pkg->checksum = to_le16(~sum);
61 buffer buf = buffer::to_mem(pkg);
62 buf += data;
64 return buf;
67 void add_data(const buffer &x) {
68 data = x;
71 enum protocol {
72 p_icmp = 1,
73 p_tcp = 6,
74 p_udp = 17
77 void set_ptype(protocol pt) {
78 pkg->prot = pt;
81 void set_source_paddr(const ipv4_addr &addr) {
82 pkg->src = addr.to_be();
85 void set_target_paddr(const ipv4_addr &addr) {
86 pkg->dst = addr.to_be();
89 ipv4_packet(const buffer &x) : pkg(x.cast<packet>()), data(x) { }
91 buffer get_data() const {
92 return data.get_next(from_be16(pkg->length)).cut_first(sizeof(packet));
95 protocol get_ptype() const {
96 return (protocol)pkg->prot;
99 ipv4_addr get_source_paddr() const {
100 return ipv4_addr::from_be(pkg->src);
103 ipv4_addr get_target_paddr() const {
104 return ipv4_addr::from_be(pkg->dst);
109 #endif