ReactOS 0.4.15-dev-5667-ged97270
tcp_helper.c
Go to the documentation of this file.
1#include "tcp_helper.h"
2
3#include "lwip/tcp_impl.h"
4#include "lwip/stats.h"
5#include "lwip/pbuf.h"
6#include "lwip/inet_chksum.h"
7
8#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
9#error "This tests needs TCP- and MEMP-statistics enabled"
10#endif
11
13static void
14tcp_remove(struct tcp_pcb* pcb_list)
15{
16 struct tcp_pcb *pcb = pcb_list;
17 struct tcp_pcb *pcb2;
18
19 while(pcb != NULL) {
20 pcb2 = pcb;
21 pcb = pcb->next;
22 tcp_abort(pcb2);
23 }
24}
25
27void
29{
30 tcp_remove(tcp_listen_pcbs.pcbs);
31 tcp_remove(tcp_active_pcbs);
32 tcp_remove(tcp_tw_pcbs);
33 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
34 fail_unless(lwip_stats.memp[MEMP_TCP_PCB_LISTEN].used == 0);
35 fail_unless(lwip_stats.memp[MEMP_TCP_SEG].used == 0);
36 fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0);
37}
38
40static struct pbuf*
42 u16_t src_port, u16_t dst_port, void* data, size_t data_len,
43 u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd)
44{
45 struct pbuf *p, *q;
46 struct ip_hdr* iphdr;
47 struct tcp_hdr* tcphdr;
48 u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len);
49
50 p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL);
52 /* first pbuf must be big enough to hold the headers */
53 EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
54 if (data_len > 0) {
55 /* first pbuf must be big enough to hold at least 1 data byte, too */
56 EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
57 }
58
59 for(q = p; q != NULL; q = q->next) {
60 memset(q->payload, 0, q->len);
61 }
62
63 iphdr = p->payload;
64 /* fill IP header */
65 iphdr->dest.addr = dst_ip->addr;
66 iphdr->src.addr = src_ip->addr;
67 IPH_VHL_SET(iphdr, 4, IP_HLEN / 4);
68 IPH_TOS_SET(iphdr, 0);
69 IPH_LEN_SET(iphdr, htons(p->tot_len));
70 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
71
72 /* let p point to TCP header */
73 pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
74
75 tcphdr = p->payload;
76 tcphdr->src = htons(src_port);
77 tcphdr->dest = htons(dst_port);
78 tcphdr->seqno = htonl(seqno);
79 tcphdr->ackno = htonl(ackno);
80 TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4);
81 TCPH_FLAGS_SET(tcphdr, headerflags);
82 tcphdr->wnd = htons(wnd);
83
84 if (data_len > 0) {
85 /* let p point to TCP data */
86 pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr));
87 /* copy data */
88 pbuf_take(p, data, data_len);
89 /* let p point to TCP header again */
90 pbuf_header(p, sizeof(struct tcp_hdr));
91 }
92
93 /* calculate checksum */
94
95 tcphdr->chksum = inet_chksum_pseudo(p,
96 IP_PROTO_TCP, p->tot_len, src_ip, dst_ip);
97
98 pbuf_header(p, sizeof(struct ip_hdr));
99
100 return p;
101}
102
104struct pbuf*
106 u16_t src_port, u16_t dst_port, void* data, size_t data_len,
107 u32_t seqno, u32_t ackno, u8_t headerflags)
108{
109 return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data,
110 data_len, seqno, ackno, headerflags, TCP_WND);
111}
112
117struct pbuf*
118tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset,
119 u32_t ackno_offset, u8_t headerflags)
120{
121 return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
122 data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags);
123}
124
130struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len,
131 u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
132{
133 return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
134 data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd);
135}
136
138void
139tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip,
140 ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port)
141{
142 /* @todo: are these all states? */
143 /* @todo: remove from previous list */
144 pcb->state = state;
145 if (state == ESTABLISHED) {
146 TCP_REG(&tcp_active_pcbs, pcb);
147 pcb->local_ip.addr = local_ip->addr;
148 pcb->local_port = local_port;
149 pcb->remote_ip.addr = remote_ip->addr;
150 pcb->remote_port = remote_port;
151 } else if(state == LISTEN) {
152 TCP_REG(&tcp_listen_pcbs.pcbs, pcb);
153 pcb->local_ip.addr = local_ip->addr;
154 pcb->local_port = local_port;
155 } else if(state == TIME_WAIT) {
156 TCP_REG(&tcp_tw_pcbs, pcb);
157 pcb->local_ip.addr = local_ip->addr;
158 pcb->local_port = local_port;
159 pcb->remote_ip.addr = remote_ip->addr;
160 pcb->remote_port = remote_port;
161 } else {
162 fail();
163 }
164}
165
166void
168{
170 EXPECT_RET(arg != NULL);
171 counters->err_calls++;
172 counters->last_err = err;
173}
174
175static void
177{
178 struct pbuf* q;
180 if(counters->expected_data == NULL) {
181 /* no data to compare */
182 return;
183 }
184 EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len);
185 received = counters->recved_bytes;
186 for(q = p; q != NULL; q = q->next) {
187 char *data = q->payload;
188 for(i = 0; i < q->len; i++) {
189 EXPECT_RET(data[i] == counters->expected_data[received]);
190 received++;
191 }
192 }
193 EXPECT(received == counters->recved_bytes + p->tot_len);
194}
195
196err_t
197test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
198{
201 EXPECT_RETX(pcb != NULL, ERR_OK);
203
204 if (p != NULL) {
205 if (counters->close_calls == 0) {
206 counters->recv_calls++;
208 counters->recved_bytes += p->tot_len;
209 } else {
210 counters->recv_calls_after_close++;
211 counters->recved_bytes_after_close += p->tot_len;
212 }
213 pbuf_free(p);
214 } else {
215 counters->close_calls++;
216 }
217 EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0);
218 return ERR_OK;
219}
220
222struct tcp_pcb*
224{
225 struct tcp_pcb* pcb = tcp_new();
226 if (pcb != NULL) {
227 /* set up args and callbacks */
228 tcp_arg(pcb, counters);
230 tcp_err(pcb, test_tcp_counters_err);
231 pcb->snd_wnd = TCP_WND;
232 pcb->snd_wnd_max = TCP_WND;
233 }
234 return pcb;
235}
236
238void test_tcp_input(struct pbuf *p, struct netif *inp)
239{
240 struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
241 /* these lines are a hack, don't use them as an example :-) */
242 ip_addr_copy(*ipX_current_dest_addr(), iphdr->dest);
243 ip_addr_copy(*ipX_current_src_addr(), iphdr->src);
244 ip_current_netif() = inp;
245 ip_current_header() = iphdr;
246
247 /* since adding IPv6, p->payload must point to tcp header, not ip header */
248 pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
249
250 tcp_input(p, inp);
251
252 ipX_current_dest_addr()->addr = 0;
253 ipX_current_src_addr()->addr = 0;
256}
257
258static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p,
259 ip_addr_t *ipaddr)
260{
261 struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state;
262 LWIP_UNUSED_ARG(ipaddr);
263 if (txcounters != NULL)
264 {
265 txcounters->num_tx_calls++;
266 txcounters->num_tx_bytes += p->tot_len;
267 if (txcounters->copy_tx_packets) {
268 struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
269 err_t err;
270 EXPECT(p_copy != NULL);
271 err = pbuf_copy(p_copy, p);
272 EXPECT(err == ERR_OK);
273 if (txcounters->tx_packets == NULL) {
274 txcounters->tx_packets = p_copy;
275 } else {
276 pbuf_cat(txcounters->tx_packets, p_copy);
277 }
278 }
279 }
280 return ERR_OK;
281}
282
283void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters,
284 ip_addr_t *ip_addr, ip_addr_t *netmask)
285{
286 struct netif *n;
287 memset(netif, 0, sizeof(struct netif));
288 if (txcounters != NULL) {
289 memset(txcounters, 0, sizeof(struct test_tcp_txcounters));
290 netif->state = txcounters;
291 }
296 for (n = netif_list; n != NULL; n = n->next) {
297 if (n == netif) {
298 return;
299 }
300 }
301 netif->next = NULL;
303}
static int state
Definition: maze.c:121
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
STREAM tcp_recv(STREAM s, uint32 length)
Definition: tcp.c:344
#define NULL
Definition: types.h:112
r received
Definition: btrfs.c:3005
signed short s16_t
Definition: cc.h:29
unsigned long u32_t
Definition: cc.h:25
unsigned char u8_t
Definition: cc.h:23
unsigned short u16_t
Definition: cc.h:24
#define IPH_VHL_SET(hdr, v, hl)
Definition: ip.h:156
#define IPH_LEN_SET(hdr, len)
Definition: ip.h:158
#define IP_PROTO_TCP
Definition: ip.h:56
#define ip_current_netif()
Definition: ip.h:194
#define IP_HLEN
Definition: ip.h:50
#define ip_current_header()
Definition: ip.h:198
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip.h:163
#define IPH_TOS_SET(hdr, tos)
Definition: ip.h:157
#define ERR_OK
Definition: err.h:52
s8_t err_t
Definition: err.h:47
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
u16_t inet_chksum_pseudo(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len)
Definition: inet_chksum.c:272
u16_t inet_chksum(void *dataptr, u16_t len)
Definition: inet_chksum.c:396
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define EXPECT_RETX(x, y)
Definition: lwip_check.h:13
#define EXPECT(x)
Definition: lwip_check.h:11
#define EXPECT_RETNULL(x)
Definition: lwip_check.h:14
#define EXPECT_RET(x)
Definition: lwip_check.h:12
#define htons(x)
Definition: module.h:213
#define htonl(x)
Definition: module.h:212
struct netif * netif_list
Definition: netif.c:75
#define NETIF_FLAG_UP
Definition: netif.h:69
#define TCP_WND
Definition: opt.h:923
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:745
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
Definition: pbuf.c:966
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:852
@ PBUF_RAM
Definition: pbuf.h:58
@ PBUF_POOL
Definition: pbuf.h:61
@ PBUF_RAW
Definition: pbuf.h:54
@ PBUF_LINK
Definition: pbuf.h:53
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
struct define * next
Definition: compiler.c:65
Definition: ip.h:116
struct ip_addr src dest
Definition: ip.h:96
Definition: netif.h:136
u8_t flags
Definition: netif.h:192
ip_addr_t netmask
Definition: netif.h:142
void * state
Definition: netif.h:172
netif_output_fn output
Definition: netif.h:151
ip_addr_t ip_addr
Definition: netif.h:141
struct netif * next
Definition: netif.h:138
Definition: pbuf.h:79
Definition: tcpdef.h:22
__u16 dest
Definition: tcpdef.h:24
struct pbuf * tx_packets
Definition: tcp_helper.h:26
static struct pbuf * tcp_create_segment_wnd(ip_addr_t *src_ip, ip_addr_t *dst_ip, u16_t src_port, u16_t dst_port, void *data, size_t data_len, u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd)
Definition: tcp_helper.c:41
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
void tcp_set_state(struct tcp_pcb *pcb, enum tcp_state state, ip_addr_t *local_ip, ip_addr_t *remote_ip, u16_t local_port, u16_t remote_port)
Definition: tcp_helper.c:139
void test_tcp_counters_err(void *arg, err_t err)
Definition: tcp_helper.c:167
struct pbuf * tcp_create_rx_segment_wnd(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
Definition: tcp_helper.c:130
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
Definition: tcp_helper.c:258
err_t test_tcp_counters_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
Definition: tcp_helper.c:197
static void test_tcp_counters_check_rxdata(struct test_tcp_counters *counters, struct pbuf *p)
Definition: tcp_helper.c:176
void tcp_remove_all(void)
Definition: tcp_helper.c:28
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
struct pbuf * tcp_create_segment(ip_addr_t *src_ip, ip_addr_t *dst_ip, u16_t src_port, u16_t dst_port, void *data, size_t data_len, u32_t seqno, u32_t ackno, u8_t headerflags)
Definition: tcp_helper.c:105
static void tcp_remove(struct tcp_pcb *pcb_list)
Definition: tcp_helper.c:14
void * arg
Definition: msvc.h:10