00001 #include "tcp_helper.h"
00002
00003 #include "lwip/tcp_impl.h"
00004 #include "lwip/stats.h"
00005 #include "lwip/pbuf.h"
00006 #include "lwip/inet_chksum.h"
00007
00008 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
00009 #error "This tests needs TCP- and MEMP-statistics enabled"
00010 #endif
00011
00012
00013 static void
00014 tcp_remove(struct tcp_pcb* pcb_list)
00015 {
00016 struct tcp_pcb *pcb = pcb_list;
00017 struct tcp_pcb *pcb2;
00018
00019 while(pcb != NULL) {
00020 pcb2 = pcb;
00021 pcb = pcb->next;
00022 tcp_abort(pcb2);
00023 }
00024 }
00025
00026
00027 void
00028 tcp_remove_all(void)
00029 {
00030 tcp_remove(tcp_listen_pcbs.pcbs);
00031 tcp_remove(tcp_active_pcbs);
00032 tcp_remove(tcp_tw_pcbs);
00033 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00034 fail_unless(lwip_stats.memp[MEMP_TCP_PCB_LISTEN].used == 0);
00035 fail_unless(lwip_stats.memp[MEMP_TCP_SEG].used == 0);
00036 fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0);
00037 }
00038
00039
00040 static struct pbuf*
00041 tcp_create_segment_wnd(ip_addr_t* src_ip, ip_addr_t* dst_ip,
00042 u16_t src_port, u16_t dst_port, void* data, size_t data_len,
00043 u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd)
00044 {
00045 struct pbuf *p, *q;
00046 struct ip_hdr* iphdr;
00047 struct tcp_hdr* tcphdr;
00048 u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len);
00049
00050 p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL);
00051 EXPECT_RETNULL(p != NULL);
00052
00053 EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
00054 if (data_len > 0) {
00055
00056 EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)));
00057 }
00058
00059 for(q = p; q != NULL; q = q->next) {
00060 memset(q->payload, 0, q->len);
00061 }
00062
00063 iphdr = p->payload;
00064
00065 iphdr->dest.addr = dst_ip->addr;
00066 iphdr->src.addr = src_ip->addr;
00067 IPH_VHL_SET(iphdr, 4, IP_HLEN / 4);
00068 IPH_TOS_SET(iphdr, 0);
00069 IPH_LEN_SET(iphdr, htons(p->tot_len));
00070 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
00071
00072
00073 pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
00074
00075 tcphdr = p->payload;
00076 tcphdr->src = htons(src_port);
00077 tcphdr->dest = htons(dst_port);
00078 tcphdr->seqno = htonl(seqno);
00079 tcphdr->ackno = htonl(ackno);
00080 TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4);
00081 TCPH_FLAGS_SET(tcphdr, headerflags);
00082 tcphdr->wnd = htons(wnd);
00083
00084 if (data_len > 0) {
00085
00086 pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr));
00087
00088 pbuf_take(p, data, data_len);
00089
00090 pbuf_header(p, sizeof(struct tcp_hdr));
00091 }
00092
00093
00094
00095 tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip,
00096 IP_PROTO_TCP, p->tot_len);
00097
00098 pbuf_header(p, sizeof(struct ip_hdr));
00099
00100 return p;
00101 }
00102
00103
00104 struct pbuf*
00105 tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip,
00106 u16_t src_port, u16_t dst_port, void* data, size_t data_len,
00107 u32_t seqno, u32_t ackno, u8_t headerflags)
00108 {
00109 return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data,
00110 data_len, seqno, ackno, headerflags, TCP_WND);
00111 }
00112
00113
00114
00115
00116
00117 struct pbuf*
00118 tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset,
00119 u32_t ackno_offset, u8_t headerflags)
00120 {
00121 return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
00122 data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags);
00123 }
00124
00125
00126
00127
00128
00129
00130 struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len,
00131 u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
00132 {
00133 return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port,
00134 data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd);
00135 }
00136
00137
00138 void
00139 tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip,
00140 ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port)
00141 {
00142
00143
00144 pcb->state = state;
00145 if (state == ESTABLISHED) {
00146 TCP_REG(&tcp_active_pcbs, pcb);
00147 pcb->local_ip.addr = local_ip->addr;
00148 pcb->local_port = local_port;
00149 pcb->remote_ip.addr = remote_ip->addr;
00150 pcb->remote_port = remote_port;
00151 } else if(state == LISTEN) {
00152 TCP_REG(&tcp_listen_pcbs.pcbs, pcb);
00153 pcb->local_ip.addr = local_ip->addr;
00154 pcb->local_port = local_port;
00155 } else if(state == TIME_WAIT) {
00156 TCP_REG(&tcp_tw_pcbs, pcb);
00157 pcb->local_ip.addr = local_ip->addr;
00158 pcb->local_port = local_port;
00159 pcb->remote_ip.addr = remote_ip->addr;
00160 pcb->remote_port = remote_port;
00161 } else {
00162 fail();
00163 }
00164 }
00165
00166 void
00167 test_tcp_counters_err(void* arg, err_t err)
00168 {
00169 struct test_tcp_counters* counters = arg;
00170 EXPECT_RET(arg != NULL);
00171 counters->err_calls++;
00172 counters->last_err = err;
00173 }
00174
00175 static void
00176 test_tcp_counters_check_rxdata(struct test_tcp_counters* counters, struct pbuf* p)
00177 {
00178 struct pbuf* q;
00179 u32_t i, received;
00180 if(counters->expected_data == NULL) {
00181
00182 return;
00183 }
00184 EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len);
00185 received = counters->recved_bytes;
00186 for(q = p; q != NULL; q = q->next) {
00187 char *data = q->payload;
00188 for(i = 0; i < q->len; i++) {
00189 EXPECT_RET(data[i] == counters->expected_data[received]);
00190 received++;
00191 }
00192 }
00193 EXPECT(received == counters->recved_bytes + p->tot_len);
00194 }
00195
00196 err_t
00197 test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
00198 {
00199 struct test_tcp_counters* counters = arg;
00200 EXPECT_RETX(arg != NULL, ERR_OK);
00201 EXPECT_RETX(pcb != NULL, ERR_OK);
00202 EXPECT_RETX(err == ERR_OK, ERR_OK);
00203
00204 if (p != NULL) {
00205 if (counters->close_calls == 0) {
00206 counters->recv_calls++;
00207 test_tcp_counters_check_rxdata(counters, p);
00208 counters->recved_bytes += p->tot_len;
00209 } else {
00210 counters->recv_calls_after_close++;
00211 counters->recved_bytes_after_close += p->tot_len;
00212 }
00213 pbuf_free(p);
00214 } else {
00215 counters->close_calls++;
00216 }
00217 EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0);
00218 return ERR_OK;
00219 }
00220
00221
00222 struct tcp_pcb*
00223 test_tcp_new_counters_pcb(struct test_tcp_counters* counters)
00224 {
00225 struct tcp_pcb* pcb = tcp_new();
00226 if (pcb != NULL) {
00227
00228 tcp_arg(pcb, counters);
00229 tcp_recv(pcb, test_tcp_counters_recv);
00230 tcp_err(pcb, test_tcp_counters_err);
00231 pcb->snd_wnd = TCP_WND;
00232 pcb->snd_wnd_max = TCP_WND;
00233 }
00234 return pcb;
00235 }
00236
00237
00238 void test_tcp_input(struct pbuf *p, struct netif *inp)
00239 {
00240 struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
00241 ip_addr_copy(current_iphdr_dest, iphdr->dest);
00242 ip_addr_copy(current_iphdr_src, iphdr->src);
00243 current_netif = inp;
00244 current_header = iphdr;
00245
00246 tcp_input(p, inp);
00247
00248 current_iphdr_dest.addr = 0;
00249 current_iphdr_src.addr = 0;
00250 current_netif = NULL;
00251 current_header = NULL;
00252 }
00253
00254 static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p,
00255 ip_addr_t *ipaddr)
00256 {
00257 struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state;
00258 LWIP_UNUSED_ARG(ipaddr);
00259 txcounters->num_tx_calls++;
00260 txcounters->num_tx_bytes += p->tot_len;
00261 if (txcounters->copy_tx_packets) {
00262 struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
00263 err_t err;
00264 EXPECT(p_copy != NULL);
00265 err = pbuf_copy(p_copy, p);
00266 EXPECT(err == ERR_OK);
00267 if (txcounters->tx_packets == NULL) {
00268 txcounters->tx_packets = p_copy;
00269 } else {
00270 pbuf_cat(txcounters->tx_packets, p_copy);
00271 }
00272 }
00273 return ERR_OK;
00274 }
00275
00276 void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters,
00277 ip_addr_t *ip_addr, ip_addr_t *netmask)
00278 {
00279 struct netif *n;
00280 memset(netif, 0, sizeof(struct netif));
00281 memset(txcounters, 0, sizeof(struct test_tcp_txcounters));
00282 netif->output = test_tcp_netif_output;
00283 netif->state = txcounters;
00284 netif->flags |= NETIF_FLAG_UP;
00285 ip_addr_copy(netif->netmask, *netmask);
00286 ip_addr_copy(netif->ip_addr, *ip_addr);
00287 for (n = netif_list; n != NULL; n = n->next) {
00288 if (n == netif) {
00289 return;
00290 }
00291 }
00292 netif->next = NULL;
00293 netif_list = netif;
00294 }