ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcp_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.