ReactOS 0.4.15-dev-7834-g00c4b3d
tcp_helper.c File Reference
#include "tcp_helper.h"
#include "lwip/tcp_impl.h"
#include "lwip/stats.h"
#include "lwip/pbuf.h"
#include "lwip/inet_chksum.h"
Include dependency graph for tcp_helper.c:

Go to the source code of this file.

Functions

static void tcp_remove (struct tcp_pcb *pcb_list)
 
void tcp_remove_all (void)
 
static struct pbuftcp_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)
 
struct pbuftcp_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)
 
struct pbuftcp_create_rx_segment (struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
 
struct pbuftcp_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)
 
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)
 
void test_tcp_counters_err (void *arg, err_t err)
 
static void test_tcp_counters_check_rxdata (struct test_tcp_counters *counters, struct pbuf *p)
 
err_t test_tcp_counters_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
 
struct tcp_pcb * test_tcp_new_counters_pcb (struct test_tcp_counters *counters)
 
void test_tcp_input (struct pbuf *p, struct netif *inp)
 
static err_t test_tcp_netif_output (struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
 
void test_tcp_init_netif (struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
 

Function Documentation

◆ tcp_create_rx_segment()

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 
)

Create a TCP segment usable for passing to tcp_input

  • IP-addresses, ports, seqno and ackno are taken from pcb
  • seqno and ackno can be altered with an offset

Definition at line 118 of file tcp_helper.c.

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}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
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

Referenced by START_TEST(), test_tcp_recv_ooseq_double_FINs(), and test_tcp_tx_full_window_lost().

◆ tcp_create_rx_segment_wnd()

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 
)

Create a TCP segment usable for passing to tcp_input

  • IP-addresses, ports, seqno and ackno are taken from pcb
  • seqno and ackno can be altered with an offset
  • TCP window can be adjusted

Definition at line 130 of file tcp_helper.c.

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}
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

Referenced by test_tcp_tx_full_window_lost().

◆ tcp_create_segment()

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 
)

Create a TCP segment usable for passing to tcp_input

Definition at line 105 of file tcp_helper.c.

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}
#define TCP_WND
Definition: lwipopts.h:67

Referenced by tcp_create_rx_segment().

◆ tcp_create_segment_wnd()

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 
)
static

Create a TCP segment usable for passing to tcp_input

Definition at line 41 of file tcp_helper.c.

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, src_ip, dst_ip,
96 IP_PROTO_TCP, p->tot_len);
97
98 pbuf_header(p, sizeof(struct ip_hdr));
99
100 return p;
101}
#define NULL
Definition: types.h:112
signed short s16_t
Definition: cc.h:29
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_HLEN
Definition: ip.h:50
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip.h:163
#define IPH_TOS_SET(hdr, tos)
Definition: ip.h:157
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLfloat GLfloat p
Definition: glext.h:8902
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 EXPECT_RETNULL(x)
Definition: lwip_check.h:14
#define htons(x)
Definition: module.h:215
#define htonl(x)
Definition: module.h:214
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
Definition: pbuf.c:966
@ PBUF_POOL
Definition: pbuf.h:61
@ PBUF_RAW
Definition: pbuf.h:54
#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: pbuf.h:79
Definition: tcpdef.h:22
__u16 dest
Definition: tcpdef.h:24

Referenced by tcp_create_rx_segment_wnd(), and tcp_create_segment().

◆ tcp_remove()

static void tcp_remove ( struct tcp_pcb *  pcb_list)
static

Remove all pcbs on the given list.

Definition at line 14 of file tcp_helper.c.

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}

Referenced by tcp_remove_all().

◆ tcp_remove_all()

void tcp_remove_all ( void  )

Remove all pcbs on listen-, active- and time-wait-list (bound- isn't exported).

Definition at line 28 of file tcp_helper.c.

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}
static void tcp_remove(struct tcp_pcb *pcb_list)
Definition: tcp_helper.c:14

Referenced by tcp_oos_setup(), tcp_oos_teardown(), tcp_setup(), and tcp_teardown().

◆ tcp_set_state()

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 
)

Safely bring a tcp_pcb into the requested state

Definition at line 139 of file tcp_helper.c.

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}
static int state
Definition: maze.c:121

◆ test_tcp_counters_check_rxdata()

static void test_tcp_counters_check_rxdata ( struct test_tcp_counters counters,
struct pbuf p 
)
static

Definition at line 176 of file tcp_helper.c.

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}
r received
Definition: btrfs.c:3005
unsigned long u32_t
Definition: cc.h:25
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
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
#define EXPECT(x)
Definition: lwip_check.h:11
#define EXPECT_RET(x)
Definition: lwip_check.h:12

Referenced by test_tcp_counters_recv().

◆ test_tcp_counters_err()

void test_tcp_counters_err ( void arg,
err_t  err 
)

Definition at line 167 of file tcp_helper.c.

168{
170 EXPECT_RET(arg != NULL);
171 counters->err_calls++;
172 counters->last_err = err;
173}
#define err(...)
void * arg
Definition: msvc.h:10

Referenced by test_tcp_new_counters_pcb().

◆ test_tcp_counters_recv()

err_t test_tcp_counters_recv ( void arg,
struct tcp_pcb *  pcb,
struct pbuf p,
err_t  err 
)

Definition at line 197 of file tcp_helper.c.

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}
#define ERR_OK
Definition: err.h:52
#define EXPECT_RETX(x, y)
Definition: lwip_check.h:13
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
static void test_tcp_counters_check_rxdata(struct test_tcp_counters *counters, struct pbuf *p)
Definition: tcp_helper.c:176

Referenced by test_tcp_new_counters_pcb().

◆ test_tcp_init_netif()

void test_tcp_init_netif ( struct netif netif,
struct test_tcp_txcounters txcounters,
ip_addr_t ip_addr,
ip_addr_t netmask 
)

Definition at line 276 of file tcp_helper.c.

278{
279 struct netif *n;
280 memset(netif, 0, sizeof(struct netif));
281 memset(txcounters, 0, sizeof(struct test_tcp_txcounters));
283 netif->state = txcounters;
287 for (n = netif_list; n != NULL; n = n->next) {
288 if (n == netif) {
289 return;
290 }
291 }
292 netif->next = NULL;
294}
GLdouble n
Definition: glext.h:7729
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
struct netif * netif_list
Definition: netif.c:75
#define NETIF_FLAG_UP
Definition: netif.h:69
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
static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
Definition: tcp_helper.c:254

Referenced by START_TEST(), and test_tcp_tx_full_window_lost().

◆ test_tcp_input()

void test_tcp_input ( struct pbuf p,
struct netif inp 
)

Calls tcp_input() after adjusting current_iphdr_dest

Definition at line 238 of file tcp_helper.c.

239{
240 struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
242 ip_addr_copy(current_iphdr_src, iphdr->src);
243 current_netif = inp;
244 current_header = iphdr;
245
246 tcp_input(p, inp);
247
248 current_iphdr_dest.addr = 0;
249 current_iphdr_src.addr = 0;
252}
const struct ip_hdr * current_header
Definition: ip.c:105
ip_addr_t current_iphdr_src
Definition: ip.c:107
ip_addr_t current_iphdr_dest
Definition: ip.c:109
struct netif * current_netif
Definition: ip.c:100

Referenced by START_TEST(), test_tcp_recv_ooseq_double_FINs(), and test_tcp_tx_full_window_lost().

◆ test_tcp_netif_output()

static err_t test_tcp_netif_output ( struct netif netif,
struct pbuf p,
ip_addr_t ipaddr 
)
static

Definition at line 254 of file tcp_helper.c.

256{
257 struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state;
258 LWIP_UNUSED_ARG(ipaddr);
259 txcounters->num_tx_calls++;
260 txcounters->num_tx_bytes += p->tot_len;
261 if (txcounters->copy_tx_packets) {
262 struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
263 err_t err;
264 EXPECT(p_copy != NULL);
265 err = pbuf_copy(p_copy, p);
266 EXPECT(err == ERR_OK);
267 if (txcounters->tx_packets == NULL) {
268 txcounters->tx_packets = p_copy;
269 } else {
270 pbuf_cat(txcounters->tx_packets, p_copy);
271 }
272 }
273 return ERR_OK;
274}
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
s8_t err_t
Definition: err.h:47
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:745
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:852
@ PBUF_RAM
Definition: pbuf.h:58
@ PBUF_LINK
Definition: pbuf.h:53
struct pbuf * tx_packets
Definition: tcp_helper.h:26

Referenced by test_tcp_init_netif().

◆ test_tcp_new_counters_pcb()

struct tcp_pcb * test_tcp_new_counters_pcb ( struct test_tcp_counters counters)

Allocate a pcb and set up the test_tcp_counters_* callbacks

Definition at line 223 of file tcp_helper.c.

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}
STREAM tcp_recv(STREAM s, uint32 length)
Definition: tcp.c:344
void test_tcp_counters_err(void *arg, err_t err)
Definition: tcp_helper.c:167
err_t test_tcp_counters_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
Definition: tcp_helper.c:197

Referenced by START_TEST(), test_tcp_recv_ooseq_double_FINs(), and test_tcp_tx_full_window_lost().