Haka: modules/protocol/ipv4/haka/ipv4.h Source File

Haka

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ipv4.h
Go to the documentation of this file.
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
10 #ifndef HAKA_PROTO_IPV4_IPV4_H
11 #define HAKA_PROTO_IPV4_IPV4_H
12
13 #include <haka/packet.h>
14 #include <haka/types.h>
15 #include <haka/compiler.h>
16 #include <haka/error.h>
17 #include <haka/vbuffer_stream.h>
18 #include <haka/lua/object.h>
19 #include <haka/container/list2.h>
20
21 #include "haka/ipv4-addr.h"
22 #include "haka/ipv4-network.h"
23
25 #define SWAP_TO_IPV4(type, x) SWAP_TO_BE(type, x)
26 #define SWAP_FROM_IPV4(type, x) SWAP_FROM_BE(type, x)
27 #define IPV4_GET_BIT(type, v, i) GET_BIT(SWAP_FROM_BE(type, v), i)
28 #define IPV4_SET_BIT(type, v, i, x) SWAP_TO_BE(type, SET_BIT(SWAP_FROM_BE(type, v), i, x))
29 #define IPV4_GET_BITS(type, v, r) GET_BITS(SWAP_FROM_BE(type, v), r)
30 #define IPV4_SET_BITS(type, v, r, x) SWAP_TO_BE(type, SET_BITS(SWAP_FROM_BE(type, v), r, x))
31
32 #define IPV4_CHECK(ip, ...) if (!(ip) || !(ip)->packet) { error("invalid ipv4 packet"); return __VA_ARGS__; }
33
34 #define IPV4_FLAG_RB 15
35 #define IPV4_FLAG_DF 15-1
36 #define IPV4_FLAG_MF 15-2
37 #define IPV4_FLAG_BITS 16-3, 16
38 #define IPV4_FRAGMENTOFFSET_BITS 0, 16-3
39 #define IPV4_FRAGMENTOFFSET_OFFSET 3 /* Fragment offset is a multiple of 8 bytes */
40 #define IPV4_HDR_LEN_OFFSET 2 /* Header length is a multiple of 4 bytes */
41
42
43 struct ipv4_header {
44 #ifdef HAKA_LITTLEENDIAN
45 uint8 hdr_len:4;
46 uint8 version:4;
47 #else
48 uint8 version:4;
49 uint8 hdr_len:4;
50 #endif
51 uint8 tos;
52 uint16 len;
53 uint16 id;
54 uint16 fragment;
55 uint8 ttl;
56 uint8 proto;
57 uint16 checksum;
58 ipv4addr src;
59 ipv4addr dst;
60 };
66 struct ipv4 {
67 struct packet *packet;
68 struct lua_object lua_object;
69 struct list2_elem frag_list;
70 struct vbuffer_iterator select;
71 struct vbuffer *payload;
72 struct vbuffer packet_payload;
73 struct vbuffer_stream reassembled_payload;
74 size_t reassembled_offset;
75 bool invalid_checksum:1;
76 bool reassembled:1;
77 };
78
80 struct ipv4 *ipv4_dissect(struct packet *packet);
81 struct ipv4 *ipv4_reassemble(struct ipv4 *ip);
82 struct ipv4 *ipv4_create(struct packet *packet);
83 struct packet *ipv4_forge(struct ipv4 *ip);
84 struct ipv4_header *ipv4_header(struct ipv4 *ip, bool write);
85 void ipv4_release(struct ipv4 *ip);
86 bool ipv4_verify_checksum(struct ipv4 *ip);
87 void ipv4_compute_checksum(struct ipv4 *ip);
88 size_t ipv4_get_payload_length(struct ipv4 *ip);
89 const char *ipv4_get_proto_dissector(struct ipv4 *ip);
90 void ipv4_register_proto_dissector(uint8 proto, const char *dissector);
91 void ipv4_action_drop(struct ipv4 *ip);
92
93 struct checksum_partial {
94 bool odd;
95 uint8 leftover;
96 int32 csum;
97 };
98
99 extern struct checksum_partial checksum_partial_init;
100
101 int16 inet_checksum(const uint8 *ptr, size_t size);
102 int16 inet_checksum_vbuffer(struct vbuffer_sub *buf);
103 void inet_checksum_partial(struct checksum_partial *csum, const uint8 *ptr, size_t size);
104 void inet_checksum_vbuffer_partial(struct checksum_partial *csum, struct vbuffer_sub *buf);
105 int16 inet_checksum_reduce(struct checksum_partial *csum);
106
107
108 #define IPV4_GETSET_FIELD(type, field) \
109 INLINE type ipv4_get_##field(struct ipv4 *ip) { IPV4_CHECK(ip, 0); return SWAP_FROM_IPV4(type, ipv4_header(ip, false)->field); } \
110 INLINE void ipv4_set_##field(struct ipv4 *ip, type v) { IPV4_CHECK(ip); \
111 struct ipv4_header *header = ipv4_header(ip, true); if (header) { header->field = SWAP_TO_IPV4(type, v); } }
112
113 IPV4_GETSET_FIELD(uint8, version);
114 IPV4_GETSET_FIELD(uint8, tos);
115 IPV4_GETSET_FIELD(uint16, len);
116 IPV4_GETSET_FIELD(uint16, id);
117 IPV4_GETSET_FIELD(uint8, ttl);
118 IPV4_GETSET_FIELD(uint8, proto);
119 IPV4_GETSET_FIELD(uint16, checksum);
120 IPV4_GETSET_FIELD(ipv4addr, src);
121 IPV4_GETSET_FIELD(ipv4addr, dst);
122
123 INLINE uint8 ipv4_get_hdr_len(struct ipv4 *ip)
124 {
125 IPV4_CHECK(ip, 0);
126 return ipv4_header(ip, false)->hdr_len << IPV4_HDR_LEN_OFFSET;
127 }
128
129 INLINE void ipv4_set_hdr_len(struct ipv4 *ip, uint8 v)
130 {
131 IPV4_CHECK(ip);
132 struct ipv4_header *header = ipv4_header(ip, true);
133 if (header)
134 ipv4_header(ip, true)->hdr_len = v >> IPV4_HDR_LEN_OFFSET;
135 }
136
137 INLINE uint16 ipv4_get_frag_offset(struct ipv4 *ip)
138 {
139 struct ipv4_header *header;
140 IPV4_CHECK(ip, 0);
141 header = ipv4_header(ip, false);
142 return (IPV4_GET_BITS(uint16, header->fragment, IPV4_FRAGMENTOFFSET_BITS)) << IPV4_FRAGMENTOFFSET_OFFSET;
143 }
144
145 INLINE void ipv4_set_frag_offset(struct ipv4 *ip, uint16 v)
146 {
147 IPV4_CHECK(ip);
148 struct ipv4_header *header = ipv4_header(ip, true);
149 if (header)
150 header->fragment = IPV4_SET_BITS(uint16, header->fragment, IPV4_FRAGMENTOFFSET_BITS, v >> IPV4_FRAGMENTOFFSET_OFFSET);
151 }
152
153 INLINE uint16 ipv4_get_flags(struct ipv4 *ip)
154 {
155 struct ipv4_header *header;
156 IPV4_CHECK(ip, 0);
157 header = ipv4_header(ip, false);
158 return IPV4_GET_BITS(uint16, header->fragment, IPV4_FLAG_BITS);
159 }
160
161 INLINE void ipv4_set_flags(struct ipv4 *ip, uint16 v)
162 {
163 IPV4_CHECK(ip);
164 struct ipv4_header *header = ipv4_header(ip, true);
165 if (header)
166 header->fragment = IPV4_SET_BITS(uint16, header->fragment, IPV4_FLAG_BITS, v);
167 }
168
169 #define IPV4_GETSET_FLAG(name, flag) \
170 INLINE bool ipv4_get_flags_##name(struct ipv4 *ip) { \
171 struct ipv4_header *header; \
172 IPV4_CHECK(ip, 0); \
173 header = ipv4_header(ip, false); \
174 return IPV4_GET_BIT(uint16, header->fragment, flag); \
175 } \
176 INLINE void ipv4_set_flags_##name(struct ipv4 *ip, bool v) { \
177 IPV4_CHECK(ip); \
178 struct ipv4_header *header = ipv4_header(ip, true); \
179 if (header) { \
180 header->fragment = IPV4_SET_BIT(uint16, header->fragment, flag, v); \
181 } \
182 }
183
184 IPV4_GETSET_FLAG(df, IPV4_FLAG_DF);
185 IPV4_GETSET_FLAG(mf, IPV4_FLAG_MF);
186 IPV4_GETSET_FLAG(rb, IPV4_FLAG_RB);
189 #endif /* HAKA_PROTO_IPV4_IPV4_H */
ipv4
Definition: ipv4.h:66
types.h
vbuffer
Definition: vbuffer.h:64
vbuffer_iterator
Definition: vbuffer.h:77
ipv4addr
uint32 ipv4addr
Definition: ipv4-addr.h:25
uint16
unsigned HAKA_16BIT_TYPE uint16
Definition: types.h:28
vbuffer_stream
Definition: vbuffer_stream.h:23
error.h
packet
Definition: packet.h:24
int16
HAKA_16BIT_TYPE int16
Definition: types.h:23
ipv4-network.h
int32
HAKA_32BIT_TYPE int32
Definition: types.h:24
vbuffer_stream.h
uint8
unsigned char uint8
Definition: types.h:27
ipv4-addr.h
packet.h
vbuffer_sub
Definition: vbuffer.h:91