Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentcp_helper.c
Go to the documentation of this file.
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 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 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 00043 struct pbuf* 00044 tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, 00045 u32_t ackno_offset, u8_t headerflags) 00046 { 00047 return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, 00048 data, data_len, pcb->rcv_nxt + seqno_offset, pcb->snd_nxt + ackno_offset, headerflags); 00049 } 00050 00052 struct pbuf* 00053 tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, 00054 u16_t src_port, u16_t dst_port, void* data, size_t data_len, 00055 u32_t seqno, u32_t ackno, u8_t headerflags) 00056 { 00057 struct pbuf* p; 00058 struct ip_hdr* iphdr; 00059 struct tcp_hdr* tcphdr; 00060 u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len); 00061 00062 p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL); 00063 EXPECT_RETNULL(p != NULL); 00064 EXPECT_RETNULL(p->next == NULL); 00065 00066 memset(p->payload, 0, p->len); 00067 00068 iphdr = p->payload; 00069 /* fill IP header */ 00070 iphdr->dest.addr = dst_ip->addr; 00071 iphdr->src.addr = src_ip->addr; 00072 IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0); 00073 IPH_LEN_SET(iphdr, htons(p->tot_len)); 00074 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); 00075 00076 pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); 00077 00078 tcphdr = p->payload; 00079 tcphdr->src = htons(src_port); 00080 tcphdr->dest = htons(dst_port); 00081 tcphdr->seqno = htonl(seqno); 00082 tcphdr->ackno = htonl(ackno); 00083 TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4); 00084 TCPH_FLAGS_SET(tcphdr, headerflags); 00085 tcphdr->wnd = htons(TCP_WND); 00086 00087 /* copy data */ 00088 memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len); 00089 00090 /* calculate checksum */ 00091 00092 tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, 00093 IP_PROTO_TCP, p->tot_len); 00094 00095 pbuf_header(p, sizeof(struct ip_hdr)); 00096 00097 return p; 00098 } 00099 00101 void 00102 tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, 00103 ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port) 00104 { 00105 /* @todo: are these all states? */ 00106 /* @todo: remove from previous list */ 00107 pcb->state = state; 00108 if (state == ESTABLISHED) { 00109 TCP_REG(&tcp_active_pcbs, pcb); 00110 pcb->local_ip.addr = local_ip->addr; 00111 pcb->local_port = local_port; 00112 pcb->remote_ip.addr = remote_ip->addr; 00113 pcb->remote_port = remote_port; 00114 } else if(state == LISTEN) { 00115 TCP_REG(&tcp_listen_pcbs.pcbs, pcb); 00116 pcb->local_ip.addr = local_ip->addr; 00117 pcb->local_port = local_port; 00118 } else if(state == TIME_WAIT) { 00119 TCP_REG(&tcp_tw_pcbs, pcb); 00120 pcb->local_ip.addr = local_ip->addr; 00121 pcb->local_port = local_port; 00122 pcb->remote_ip.addr = remote_ip->addr; 00123 pcb->remote_port = remote_port; 00124 } else { 00125 fail(); 00126 } 00127 } 00128 00129 void 00130 test_tcp_counters_err(void* arg, err_t err) 00131 { 00132 struct test_tcp_counters* counters = arg; 00133 EXPECT_RET(arg != NULL); 00134 counters->err_calls++; 00135 counters->last_err = err; 00136 } 00137 00138 static void 00139 test_tcp_counters_check_rxdata(struct test_tcp_counters* counters, struct pbuf* p) 00140 { 00141 struct pbuf* q; 00142 u32_t i, received; 00143 if(counters->expected_data == NULL) { 00144 /* no data to compare */ 00145 return; 00146 } 00147 EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len); 00148 received = counters->recved_bytes; 00149 for(q = p; q != NULL; q = q->next) { 00150 char *data = q->payload; 00151 for(i = 0; i < q->len; i++) { 00152 EXPECT_RET(data[i] == counters->expected_data[received]); 00153 received++; 00154 } 00155 } 00156 EXPECT(received == counters->recved_bytes + p->tot_len); 00157 } 00158 00159 err_t 00160 test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) 00161 { 00162 struct test_tcp_counters* counters = arg; 00163 EXPECT_RETX(arg != NULL, ERR_OK); 00164 EXPECT_RETX(pcb != NULL, ERR_OK); 00165 EXPECT_RETX(err == ERR_OK, ERR_OK); 00166 00167 if (p != NULL) { 00168 if (counters->close_calls == 0) { 00169 counters->recv_calls++; 00170 test_tcp_counters_check_rxdata(counters, p); 00171 counters->recved_bytes += p->tot_len; 00172 } else { 00173 counters->recv_calls_after_close++; 00174 counters->recved_bytes_after_close += p->tot_len; 00175 } 00176 pbuf_free(p); 00177 } else { 00178 counters->close_calls++; 00179 } 00180 EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0); 00181 return ERR_OK; 00182 } 00183 00185 struct tcp_pcb* 00186 test_tcp_new_counters_pcb(struct test_tcp_counters* counters) 00187 { 00188 struct tcp_pcb* pcb = tcp_new(); 00189 if (pcb != NULL) { 00190 /* set up args and callbacks */ 00191 tcp_arg(pcb, counters); 00192 tcp_recv(pcb, test_tcp_counters_recv); 00193 tcp_err(pcb, test_tcp_counters_err); 00194 } 00195 return pcb; 00196 } 00197 00199 void test_tcp_input(struct pbuf *p, struct netif *inp) 00200 { 00201 struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; 00202 ip_addr_copy(current_iphdr_dest, iphdr->dest); 00203 ip_addr_copy(current_iphdr_src, iphdr->src); 00204 current_netif = inp; 00205 current_header = iphdr; 00206 00207 tcp_input(p, inp); 00208 00209 current_iphdr_dest.addr = 0; 00210 current_iphdr_src.addr = 0; 00211 current_netif = NULL; 00212 current_header = NULL; 00213 } Generated on Sun May 27 2012 04:36:11 for ReactOS by
1.7.6.1
|