Haka
tcp.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef HAKA_PROTO_TCP_H
6 #define HAKA_PROTO_TCP_H
7 
8 #include <haka/types.h>
9 #include <haka/ipv4.h>
10 #include <haka/lua/object.h>
11 
13 #define SWAP_TO_TCP(type, x) SWAP_TO_BE(type, x)
14 #define SWAP_FROM_TCP(type, x) SWAP_FROM_BE(type, x)
15 #define TCP_GET_BIT(type, v, i) GET_BIT(SWAP_FROM_BE(type, v), i)
16 #define TCP_SET_BIT(type, v, i, x) SWAP_TO_BE(type, SET_BIT(SWAP_FROM_BE(type, v), i, x))
17 #define TCP_GET_BITS(type, v, r) GET_BITS(SWAP_FROM_BE(type, v), r)
18 #define TCP_SET_BITS(type, v, r, x) SWAP_TO_BE(type, SET_BITS(SWAP_FROM_BE(type, v), r, x))
19 
20 #define TCP_CHECK(tcp, ...) if (!(tcp) || !(tcp)->packet) { error("invalid tcp packet"); return __VA_ARGS__; }
21 
22 #define TCP_FLAGS_BITS 0, 8
23 #define TCP_FLAGS_START 13
24 #define TCP_HDR_LEN 2 /* Header length is a multiple of 4 bytes */
25 
26 #define TCP_PROTO 6
27 
28 struct tcp_header {
29  uint16 srcport;
30  uint16 dstport;
31  uint32 seq;
32  uint32 ack_seq;
33 #ifdef HAKA_LITTLEENDIAN
34  uint16 res:4,
35  hdr_len:4,
36  fin:1,
37  syn:1,
38  rst:1,
39  psh:1,
40  ack:1,
41  urg:1,
42  ecn:1,
43  cwr:1;
44 #else
45  uint16 hdr_len:4,
46  res:4,
47  cwr:1,
48  ecn:1,
49  urg:1,
50  ack:1,
51  psh:1,
52  rst:1,
53  syn:1,
54  fin:1;
55 #endif
56  uint16 window_size;
57  uint16 checksum;
58  uint16 urgent_pointer;
59 };
65 struct tcp {
66  struct ipv4 *packet;
67  struct lua_object lua_object;
68  struct vbuffer payload;
69  struct vbuffer_iterator select;
70  bool modified:1;
71  bool invalid_checksum:1;
72 };
73 
75 struct tcp *tcp_dissect(struct ipv4 *packet);
76 struct tcp *tcp_create(struct ipv4 *packet);
77 struct ipv4 *tcp_forge(struct tcp *packet);
78 struct tcp_header *tcp_header(struct tcp *packet, bool write);
79 void tcp_release(struct tcp *packet);
80 void tcp_compute_checksum(struct tcp *packet);
81 bool tcp_verify_checksum(struct tcp *packet);
82 size_t tcp_get_payload_length(struct tcp *packet);
83 void tcp_action_drop(struct tcp *packet);
84 
85 
86 #define TCP_GETSET_FIELD(type, field) \
87  INLINE type tcp_get_##field(struct tcp *tcp) { TCP_CHECK(tcp, 0); return SWAP_FROM_TCP(type, tcp_header(tcp, false)->field); } \
88  INLINE void tcp_set_##field(struct tcp *tcp, type v) { TCP_CHECK(tcp); \
89  struct tcp_header *header = tcp_header(tcp, true); if (header) { header->field = SWAP_TO_TCP(type, v); } }
90 
91 TCP_GETSET_FIELD(uint16, srcport);
92 TCP_GETSET_FIELD(uint16, dstport);
93 TCP_GETSET_FIELD(uint32, seq);
94 TCP_GETSET_FIELD(uint32, ack_seq);
95 TCP_GETSET_FIELD(uint8, res);
96 TCP_GETSET_FIELD(uint16, window_size);
97 TCP_GETSET_FIELD(uint16, urgent_pointer);
98 TCP_GETSET_FIELD(uint16, checksum);
99 
100 INLINE uint8 tcp_get_hdr_len(struct tcp *tcp)
101 {
102  TCP_CHECK(tcp, 0);
103  return tcp_header(tcp, false)->hdr_len << TCP_HDR_LEN;
104 }
105 
106 INLINE void tcp_set_hdr_len(struct tcp *tcp, uint8 v)
107 {
108  TCP_CHECK(tcp);
109  struct tcp_header *header = tcp_header(tcp, true);
110  if (header)
111  header->hdr_len = v >> TCP_HDR_LEN;
112 }
113 
114 INLINE uint16 tcp_get_flags(struct tcp *tcp)
115 {
116  TCP_CHECK(tcp, 0);
117  struct tcp_header *header = tcp_header(tcp, false);
118  return TCP_GET_BITS(uint8, *(((uint8 *)header) + TCP_FLAGS_START), TCP_FLAGS_BITS);
119 }
120 
121 INLINE void tcp_set_flags(struct tcp *tcp, uint8 v)
122 {
123  TCP_CHECK(tcp);
124  struct tcp_header *header = tcp_header(tcp, true);
125  if (header)
126  *(((uint8 *)header) + TCP_FLAGS_START) = TCP_SET_BITS(uint8, *(((uint8 *)header) + TCP_FLAGS_START), TCP_FLAGS_BITS, v);
127 }
128 
129 
130 #define TCP_GETSET_FLAG(name) \
131  INLINE bool tcp_get_flags_##name(struct tcp *tcp) { TCP_CHECK(tcp, 0); return tcp_header(tcp, false)->name; } \
132  INLINE void tcp_set_flags_##name(struct tcp *tcp, bool v) { TCP_CHECK(tcp); \
133  struct tcp_header *header = tcp_header(tcp, true); if (header) { tcp_header(tcp, true)->name = v; } }
134 
135 TCP_GETSET_FLAG(fin);
136 TCP_GETSET_FLAG(syn);
137 TCP_GETSET_FLAG(rst);
138 TCP_GETSET_FLAG(psh);
139 TCP_GETSET_FLAG(ack);
140 TCP_GETSET_FLAG(urg);
141 TCP_GETSET_FLAG(ecn);
142 TCP_GETSET_FLAG(cwr);
145 #endif /* HAKA_PROTO_TCP_H */
Definition: ipv4.h:66
Definition: vbuffer.h:64
Definition: vbuffer.h:77
unsigned HAKA_16BIT_TYPE uint16
Definition: types.h:28
unsigned HAKA_32BIT_TYPE uint32
Definition: types.h:29
Definition: packet.h:24
Definition: tcp.h:65
unsigned char uint8
Definition: types.h:27