These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
uip.c
00001 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ 00002 /** @addtogroup EMAC_uIP 00003 * @{ 00004 */ 00005 00006 /** 00007 * \defgroup uip The uIP TCP/IP stack 00008 * @{ 00009 * 00010 * uIP is an implementation of the TCP/IP protocol stack intended for 00011 * small 8-bit and 16-bit microcontrollers. 00012 * 00013 * uIP provides the necessary protocols for Internet communication, 00014 * with a very small code footprint and RAM requirements - the uIP 00015 * code size is on the order of a few kilobytes and RAM usage is on 00016 * the order of a few hundred bytes. 00017 */ 00018 00019 /** @addtogroup EMAC_uIP 00020 * @{ 00021 */ 00022 00023 /** 00024 * \file 00025 * The uIP TCP/IP stack code. 00026 * \author Adam Dunkels <adam@dunkels.com> 00027 */ 00028 00029 /* 00030 * Copyright (c) 2001-2003, Adam Dunkels. 00031 * All rights reserved. 00032 * 00033 * Redistribution and use in source and binary forms, with or without 00034 * modification, are permitted provided that the following conditions 00035 * are met: 00036 * 1. Redistributions of source code must retain the above copyright 00037 * notice, this list of conditions and the following disclaimer. 00038 * 2. Redistributions in binary form must reproduce the above copyright 00039 * notice, this list of conditions and the following disclaimer in the 00040 * documentation and/or other materials provided with the distribution. 00041 * 3. The name of the author may not be used to endorse or promote 00042 * products derived from this software without specific prior 00043 * written permission. 00044 * 00045 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00046 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00047 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00048 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00049 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00050 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00051 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00052 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00053 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00054 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00055 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00056 * 00057 * This file is part of the uIP TCP/IP stack. 00058 * 00059 * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ 00060 * 00061 */ 00062 00063 /* 00064 * uIP is a small implementation of the IP, UDP and TCP protocols (as 00065 * well as some basic ICMP stuff). The implementation couples the IP, 00066 * UDP, TCP and the application layers very tightly. To keep the size 00067 * of the compiled code down, this code frequently uses the goto 00068 * statement. While it would be possible to break the uip_process() 00069 * function into many smaller functions, this would increase the code 00070 * size because of the overhead of parameter passing and the fact that 00071 * the optimier would not be as efficient. 00072 * 00073 * The principle is that we have a small buffer, called the uip_buf, 00074 * in which the device driver puts an incoming packet. The TCP/IP 00075 * stack parses the headers in the packet, and calls the 00076 * application. If the remote host has sent data to the application, 00077 * this data is present in the uip_buf and the application read the 00078 * data from there. It is up to the application to put this data into 00079 * a byte stream if needed. The application will not be fed with data 00080 * that is out of sequence. 00081 * 00082 * If the application whishes to send data to the peer, it should put 00083 * its data into the uip_buf. The uip_appdata pointer points to the 00084 * first available byte. The TCP/IP stack will calculate the 00085 * checksums, and fill in the necessary header fields and finally send 00086 * the packet back to the peer. 00087 */ 00088 00089 #include "uip.h" 00090 #include "uipopt.h" 00091 #include "uip_arch.h" 00092 00093 #if UIP_CONF_IPV6 00094 #include "uip-neighbor.h" 00095 #endif /* UIP_CONF_IPV6 */ 00096 00097 #include <string.h> 00098 00099 /*---------------------------------------------------------------------------*/ 00100 /* Variable definitions. */ 00101 00102 00103 /* The IP address of this host. If it is defined to be fixed (by 00104 setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set 00105 here. Otherwise, the address */ 00106 #if UIP_FIXEDADDR > 0 00107 const uip_ipaddr_t uip_hostaddr = 00108 {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), 00109 HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; 00110 const uip_ipaddr_t uip_draddr = 00111 {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), 00112 HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; 00113 const uip_ipaddr_t uip_netmask = 00114 {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), 00115 HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; 00116 #else 00117 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; 00118 #endif /* UIP_FIXEDADDR */ 00119 00120 static const uip_ipaddr_t all_ones_addr = 00121 #if UIP_CONF_IPV6 00122 {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; 00123 #else /* UIP_CONF_IPV6 */ 00124 {0xffff,0xffff}; 00125 #endif /* UIP_CONF_IPV6 */ 00126 static const uip_ipaddr_t all_zeroes_addr = 00127 #if UIP_CONF_IPV6 00128 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; 00129 #else /* UIP_CONF_IPV6 */ 00130 {0x0000,0x0000}; 00131 #endif /* UIP_CONF_IPV6 */ 00132 00133 #if UIP_FIXEDETHADDR 00134 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, 00135 UIP_ETHADDR1, 00136 UIP_ETHADDR2, 00137 UIP_ETHADDR3, 00138 UIP_ETHADDR4, 00139 UIP_ETHADDR5}}; 00140 #else 00141 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; 00142 #endif 00143 00144 #ifndef UIP_CONF_EXTERNAL_BUFFER 00145 00146 #if defined ( __CC_ARM ) 00147 u8_t __align(4) uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */ 00148 #elif defined ( __ICCARM__ ) 00149 #pragma data_alignment=4 00150 u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */ 00151 #elif defined ( __GNUC__ ) 00152 u8_t __attribute__ ((aligned (4))) uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */ 00153 #endif 00154 00155 /*ALIGN_STRUCT_END*/ 00156 00157 #endif /* UIP_CONF_EXTERNAL_BUFFER */ 00158 00159 void *uip_appdata; /* The uip_appdata pointer points to 00160 application data. */ 00161 void *uip_sappdata; /* The uip_appdata pointer points to 00162 the application data which is to 00163 be sent. */ 00164 #if UIP_URGDATA > 0 00165 void *uip_urgdata; /* The uip_urgdata pointer points to 00166 urgent data (out-of-band data), if 00167 present. */ 00168 u16_t uip_urglen, uip_surglen; 00169 #endif /* UIP_URGDATA > 0 */ 00170 00171 u16_t uip_len, uip_slen; 00172 /* The uip_len is either 8 or 16 bits, 00173 depending on the maximum packet 00174 size. */ 00175 00176 u8_t uip_flags; /* The uip_flags variable is used for 00177 communication between the TCP/IP stack 00178 and the application program. */ 00179 struct uip_conn *uip_conn; /* uip_conn always points to the current 00180 connection. */ 00181 00182 struct uip_conn uip_conns[UIP_CONNS]; 00183 /* The uip_conns array holds all TCP 00184 connections. */ 00185 u16_t uip_listenports[UIP_LISTENPORTS]; 00186 /* The uip_listenports list all currently 00187 listning ports. */ 00188 #if UIP_UDP 00189 struct uip_udp_conn *uip_udp_conn; 00190 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; 00191 #endif /* UIP_UDP */ 00192 00193 static u16_t ipid; /* Ths ipid variable is an increasing 00194 number that is used for the IP ID 00195 field. */ 00196 00197 void uip_setipid(u16_t id) { ipid = id; } 00198 00199 static u8_t iss[4]; /* The iss variable is used for the TCP 00200 initial sequence number. */ 00201 00202 #if UIP_ACTIVE_OPEN 00203 static u16_t lastport; /* Keeps track of the last port used for 00204 a new connection. */ 00205 #endif /* UIP_ACTIVE_OPEN */ 00206 00207 /* Temporary variables. */ 00208 u8_t uip_acc32[4]; 00209 static u8_t c, opt; 00210 static u16_t tmp16; 00211 00212 /* Structures and definitions. */ 00213 #define TCP_FIN 0x01 00214 #define TCP_SYN 0x02 00215 #define TCP_RST 0x04 00216 #define TCP_PSH 0x08 00217 #define TCP_ACK 0x10 00218 #define TCP_URG 0x20 00219 #define TCP_CTL 0x3f 00220 00221 #define TCP_OPT_END 0 /* End of TCP options list */ 00222 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ 00223 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ 00224 00225 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ 00226 00227 #define ICMP_ECHO_REPLY 0 00228 #define ICMP_ECHO 8 00229 00230 #define ICMP6_ECHO_REPLY 129 00231 #define ICMP6_ECHO 128 00232 #define ICMP6_NEIGHBOR_SOLICITATION 135 00233 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136 00234 00235 #define ICMP6_FLAG_S (1 << 6) 00236 00237 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 00238 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 00239 00240 00241 /* Macros. */ 00242 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00243 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) 00244 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00245 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00246 00247 00248 #if UIP_STATISTICS == 1 00249 struct uip_stats uip_stat; 00250 #define UIP_STAT(s) s 00251 #else 00252 #define UIP_STAT(s) 00253 #endif /* UIP_STATISTICS == 1 */ 00254 00255 #if UIP_LOGGING == 1 00256 #include <stdio.h> 00257 void uip_log(char *msg); 00258 #define UIP_LOG(m) uip_log(m) 00259 #else 00260 #define UIP_LOG(m) 00261 #endif /* UIP_LOGGING == 1 */ 00262 00263 #if ! UIP_ARCH_ADD32 00264 void 00265 uip_add32(u8_t *op32, u16_t op16) 00266 { 00267 uip_acc32[3] = op32[3] + (op16 & 0xff); 00268 uip_acc32[2] = op32[2] + (op16 >> 8); 00269 uip_acc32[1] = op32[1]; 00270 uip_acc32[0] = op32[0]; 00271 00272 if(uip_acc32[2] < (op16 >> 8)) { 00273 ++uip_acc32[1]; 00274 if(uip_acc32[1] == 0) { 00275 ++uip_acc32[0]; 00276 } 00277 } 00278 00279 00280 if(uip_acc32[3] < (op16 & 0xff)) { 00281 ++uip_acc32[2]; 00282 if(uip_acc32[2] == 0) { 00283 ++uip_acc32[1]; 00284 if(uip_acc32[1] == 0) { 00285 ++uip_acc32[0]; 00286 } 00287 } 00288 } 00289 } 00290 00291 #endif /* UIP_ARCH_ADD32 */ 00292 00293 #if ! UIP_ARCH_CHKSUM 00294 /*---------------------------------------------------------------------------*/ 00295 static u16_t 00296 chksum(u16_t sum, const u8_t *data, u16_t len) 00297 { 00298 u16_t t; 00299 const u8_t *dataptr; 00300 const u8_t *last_byte; 00301 00302 dataptr = data; 00303 last_byte = data + len - 1; 00304 00305 while(dataptr < last_byte) { /* At least two more bytes */ 00306 t = (dataptr[0] << 8) + dataptr[1]; 00307 sum += t; 00308 if(sum < t) { 00309 sum++; /* carry */ 00310 } 00311 dataptr += 2; 00312 } 00313 00314 if(dataptr == last_byte) { 00315 t = (dataptr[0] << 8) + 0; 00316 sum += t; 00317 if(sum < t) { 00318 sum++; /* carry */ 00319 } 00320 } 00321 00322 /* Return sum in host byte order. */ 00323 return sum; 00324 } 00325 /*---------------------------------------------------------------------------*/ 00326 u16_t 00327 uip_chksum(u16_t *data, u16_t len) 00328 { 00329 return htons(chksum(0, (u8_t *)data, len)); 00330 } 00331 /*---------------------------------------------------------------------------*/ 00332 #ifndef UIP_ARCH_IPCHKSUM 00333 u16_t 00334 uip_ipchksum(void) 00335 { 00336 u16_t sum; 00337 00338 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); 00339 DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); 00340 return (sum == 0) ? 0xffff : htons(sum); 00341 } 00342 #endif 00343 /*---------------------------------------------------------------------------*/ 00344 static u16_t 00345 upper_layer_chksum(u8_t proto) 00346 { 00347 u16_t upper_layer_len; 00348 u16_t sum; 00349 00350 #if UIP_CONF_IPV6 00351 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); 00352 #else /* UIP_CONF_IPV6 */ 00353 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; 00354 #endif /* UIP_CONF_IPV6 */ 00355 00356 /* First sum pseudoheader. */ 00357 00358 /* IP protocol and length fields. This addition cannot carry. */ 00359 sum = upper_layer_len + proto; 00360 /* Sum IP source and destination addresses. */ 00361 sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); 00362 00363 /* Sum TCP header and data. */ 00364 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], 00365 upper_layer_len); 00366 00367 return (sum == 0) ? 0xffff : htons(sum); 00368 } 00369 /*---------------------------------------------------------------------------*/ 00370 #if UIP_CONF_IPV6 00371 u16_t 00372 uip_icmp6chksum(void) 00373 { 00374 return upper_layer_chksum(UIP_PROTO_ICMP6); 00375 00376 } 00377 #endif /* UIP_CONF_IPV6 */ 00378 /*---------------------------------------------------------------------------*/ 00379 u16_t 00380 uip_tcpchksum(void) 00381 { 00382 return upper_layer_chksum(UIP_PROTO_TCP); 00383 } 00384 /*---------------------------------------------------------------------------*/ 00385 #if UIP_UDP_CHECKSUMS 00386 u16_t 00387 uip_udpchksum(void) 00388 { 00389 return upper_layer_chksum(UIP_PROTO_UDP); 00390 } 00391 #endif /* UIP_UDP_CHECKSUMS */ 00392 #endif /* UIP_ARCH_CHKSUM */ 00393 /*---------------------------------------------------------------------------*/ 00394 void 00395 uip_init(void) 00396 { 00397 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00398 uip_listenports[c] = 0; 00399 } 00400 for(c = 0; c < UIP_CONNS; ++c) { 00401 uip_conns[c].tcpstateflags = UIP_CLOSED; 00402 } 00403 #if UIP_ACTIVE_OPEN 00404 lastport = 1024; 00405 #endif /* UIP_ACTIVE_OPEN */ 00406 00407 #if UIP_UDP 00408 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00409 uip_udp_conns[c].lport = 0; 00410 } 00411 #endif /* UIP_UDP */ 00412 00413 00414 /* IPv4 initialization. */ 00415 #if UIP_FIXEDADDR == 0 00416 /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ 00417 #endif /* UIP_FIXEDADDR */ 00418 00419 } 00420 /*---------------------------------------------------------------------------*/ 00421 #if UIP_ACTIVE_OPEN 00422 struct uip_conn * 00423 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) 00424 { 00425 register struct uip_conn *conn, *cconn; 00426 00427 /* Find an unused local port. */ 00428 again: 00429 ++lastport; 00430 00431 if(lastport >= 32000) { 00432 lastport = 4096; 00433 } 00434 00435 /* Check if this port is already in use, and if so try to find 00436 another one. */ 00437 for(c = 0; c < UIP_CONNS; ++c) { 00438 conn = &uip_conns[c]; 00439 if(conn->tcpstateflags != UIP_CLOSED && 00440 conn->lport == htons(lastport)) { 00441 goto again; 00442 } 00443 } 00444 00445 conn = 0; 00446 for(c = 0; c < UIP_CONNS; ++c) { 00447 cconn = &uip_conns[c]; 00448 if(cconn->tcpstateflags == UIP_CLOSED) { 00449 conn = cconn; 00450 break; 00451 } 00452 if(cconn->tcpstateflags == UIP_TIME_WAIT) { 00453 if(conn == 0 || 00454 cconn->timer > conn->timer) { 00455 conn = cconn; 00456 } 00457 } 00458 } 00459 00460 if(conn == 0) { 00461 return 0; 00462 } 00463 00464 conn->tcpstateflags = UIP_SYN_SENT; 00465 00466 conn->snd_nxt[0] = iss[0]; 00467 conn->snd_nxt[1] = iss[1]; 00468 conn->snd_nxt[2] = iss[2]; 00469 conn->snd_nxt[3] = iss[3]; 00470 00471 conn->initialmss = conn->mss = UIP_TCP_MSS; 00472 00473 conn->len = 1; /* TCP length of the SYN is one. */ 00474 conn->nrtx = 0; 00475 conn->timer = 1; /* Send the SYN next time around. */ 00476 conn->rto = UIP_RTO; 00477 conn->sa = 0; 00478 conn->sv = 16; /* Initial value of the RTT variance. */ 00479 conn->lport = htons(lastport); 00480 conn->rport = rport; 00481 uip_ipaddr_copy(&conn->ripaddr, ripaddr); 00482 00483 return conn; 00484 } 00485 #endif /* UIP_ACTIVE_OPEN */ 00486 /*---------------------------------------------------------------------------*/ 00487 #if UIP_UDP 00488 struct uip_udp_conn * 00489 uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) 00490 { 00491 register struct uip_udp_conn *conn; 00492 00493 /* Find an unused local port. */ 00494 again: 00495 ++lastport; 00496 00497 if(lastport >= 32000) { 00498 lastport = 4096; 00499 } 00500 00501 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00502 if(uip_udp_conns[c].lport == htons(lastport)) { 00503 goto again; 00504 } 00505 } 00506 00507 00508 conn = 0; 00509 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00510 if(uip_udp_conns[c].lport == 0) { 00511 conn = &uip_udp_conns[c]; 00512 break; 00513 } 00514 } 00515 00516 if(conn == 0) { 00517 return 0; 00518 } 00519 00520 conn->lport = HTONS(lastport); 00521 conn->rport = rport; 00522 if(ripaddr == NULL) { 00523 memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); 00524 } else { 00525 uip_ipaddr_copy(&conn->ripaddr, ripaddr); 00526 } 00527 conn->ttl = UIP_TTL; 00528 00529 return conn; 00530 } 00531 #endif /* UIP_UDP */ 00532 /*---------------------------------------------------------------------------*/ 00533 void 00534 uip_unlisten(u16_t port) 00535 { 00536 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00537 if(uip_listenports[c] == port) { 00538 uip_listenports[c] = 0; 00539 return; 00540 } 00541 } 00542 } 00543 /*---------------------------------------------------------------------------*/ 00544 void 00545 uip_listen(u16_t port) 00546 { 00547 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00548 if(uip_listenports[c] == 0) { 00549 uip_listenports[c] = port; 00550 return; 00551 } 00552 } 00553 } 00554 /*---------------------------------------------------------------------------*/ 00555 /* XXX: IP fragment reassembly: not well-tested. */ 00556 00557 #if UIP_REASSEMBLY && !UIP_CONF_IPV6 00558 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) 00559 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; 00560 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; 00561 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, 00562 0x0f, 0x07, 0x03, 0x01}; 00563 static u16_t uip_reasslen; 00564 static u8_t uip_reassflags; 00565 #define UIP_REASS_FLAG_LASTFRAG 0x01 00566 static u8_t uip_reasstmr; 00567 00568 #define IP_MF 0x20 00569 00570 static u8_t 00571 uip_reass(void) 00572 { 00573 u16_t offset, len; 00574 u16_t i; 00575 00576 /* If ip_reasstmr is zero, no packet is present in the buffer, so we 00577 write the IP header of the fragment into the reassembly 00578 buffer. The timer is updated with the maximum age. */ 00579 if(uip_reasstmr == 0) { 00580 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); 00581 uip_reasstmr = UIP_REASS_MAXAGE; 00582 uip_reassflags = 0; 00583 /* Clear the bitmap. */ 00584 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); 00585 } 00586 00587 /* Check if the incoming fragment matches the one currently present 00588 in the reasembly buffer. If so, we proceed with copying the 00589 fragment into the buffer. */ 00590 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && 00591 BUF->srcipaddr[1] == FBUF->srcipaddr[1] && 00592 BUF->destipaddr[0] == FBUF->destipaddr[0] && 00593 BUF->destipaddr[1] == FBUF->destipaddr[1] && 00594 BUF->ipid[0] == FBUF->ipid[0] && 00595 BUF->ipid[1] == FBUF->ipid[1]) { 00596 00597 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; 00598 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; 00599 00600 /* If the offset or the offset + fragment length overflows the 00601 reassembly buffer, we discard the entire packet. */ 00602 if(offset > UIP_REASS_BUFSIZE || 00603 offset + len > UIP_REASS_BUFSIZE) { 00604 uip_reasstmr = 0; 00605 goto nullreturn; 00606 } 00607 00608 /* Copy the fragment into the reassembly buffer, at the right 00609 offset. */ 00610 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], 00611 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), 00612 len); 00613 00614 /* Update the bitmap. */ 00615 if(offset / (8 * 8) == (offset + len) / (8 * 8)) { 00616 /* If the two endpoints are in the same byte, we only update 00617 that byte. */ 00618 00619 uip_reassbitmap[offset / (8 * 8)] |= 00620 bitmap_bits[(offset / 8 ) & 7] & 00621 ~bitmap_bits[((offset + len) / 8 ) & 7]; 00622 } else { 00623 /* If the two endpoints are in different bytes, we update the 00624 bytes in the endpoints and fill the stuff inbetween with 00625 0xff. */ 00626 uip_reassbitmap[offset / (8 * 8)] |= 00627 bitmap_bits[(offset / 8 ) & 7]; 00628 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { 00629 uip_reassbitmap[i] = 0xff; 00630 } 00631 uip_reassbitmap[(offset + len) / (8 * 8)] |= 00632 ~bitmap_bits[((offset + len) / 8 ) & 7]; 00633 } 00634 00635 /* If this fragment has the More Fragments flag set to zero, we 00636 know that this is the last fragment, so we can calculate the 00637 size of the entire packet. We also set the 00638 IP_REASS_FLAG_LASTFRAG flag to indicate that we have received 00639 the final fragment. */ 00640 00641 if((BUF->ipoffset[0] & IP_MF) == 0) { 00642 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; 00643 uip_reasslen = offset + len; 00644 } 00645 00646 /* Finally, we check if we have a full packet in the buffer. We do 00647 this by checking if we have the last fragment and if all bits 00648 in the bitmap are set. */ 00649 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { 00650 /* Check all bytes up to and including all but the last byte in 00651 the bitmap. */ 00652 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { 00653 if(uip_reassbitmap[i] != 0xff) { 00654 goto nullreturn; 00655 } 00656 } 00657 /* Check the last byte in the bitmap. It should contain just the 00658 right amount of bits. */ 00659 if(uip_reassbitmap[uip_reasslen / (8 * 8)] != 00660 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { 00661 goto nullreturn; 00662 } 00663 00664 /* If we have come this far, we have a full packet in the 00665 buffer, so we allocate a pbuf and copy the packet into it. We 00666 also reset the timer. */ 00667 uip_reasstmr = 0; 00668 memcpy(BUF, FBUF, uip_reasslen); 00669 00670 /* Pretend to be a "normal" (i.e., not fragmented) IP packet 00671 from now on. */ 00672 BUF->ipoffset[0] = BUF->ipoffset[1] = 0; 00673 BUF->len[0] = uip_reasslen >> 8; 00674 BUF->len[1] = uip_reasslen & 0xff; 00675 BUF->ipchksum = 0; 00676 BUF->ipchksum = ~(uip_ipchksum()); 00677 00678 return uip_reasslen; 00679 } 00680 } 00681 00682 nullreturn: 00683 return 0; 00684 } 00685 #endif /* UIP_REASSEMBLY */ 00686 /*---------------------------------------------------------------------------*/ 00687 static void 00688 uip_add_rcv_nxt(u16_t n) 00689 { 00690 uip_add32(uip_conn->rcv_nxt, n); 00691 uip_conn->rcv_nxt[0] = uip_acc32[0]; 00692 uip_conn->rcv_nxt[1] = uip_acc32[1]; 00693 uip_conn->rcv_nxt[2] = uip_acc32[2]; 00694 uip_conn->rcv_nxt[3] = uip_acc32[3]; 00695 } 00696 /*---------------------------------------------------------------------------*/ 00697 void 00698 uip_process(u8_t flag) 00699 { 00700 register struct uip_conn *uip_connr = uip_conn; 00701 00702 #if UIP_UDP 00703 if(flag == UIP_UDP_SEND_CONN) { 00704 goto udp_send; 00705 } 00706 #endif /* UIP_UDP */ 00707 00708 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; 00709 00710 /* Check if we were invoked because of a poll request for a 00711 particular connection. */ 00712 if(flag == UIP_POLL_REQUEST) { 00713 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && 00714 !uip_outstanding(uip_connr)) { 00715 uip_flags = UIP_POLL; 00716 UIP_APPCALL(); 00717 goto appsend; 00718 } 00719 goto drop; 00720 00721 /* Check if we were invoked because of the perodic timer fireing. */ 00722 } else if(flag == UIP_TIMER) { 00723 #if UIP_REASSEMBLY 00724 if(uip_reasstmr != 0) { 00725 --uip_reasstmr; 00726 } 00727 #endif /* UIP_REASSEMBLY */ 00728 /* Increase the initial sequence number. */ 00729 if(++iss[3] == 0) { 00730 if(++iss[2] == 0) { 00731 if(++iss[1] == 0) { 00732 ++iss[0]; 00733 } 00734 } 00735 } 00736 00737 /* Reset the length variables. */ 00738 uip_len = 0; 00739 uip_slen = 0; 00740 00741 /* Check if the connection is in a state in which we simply wait 00742 for the connection to time out. If so, we increase the 00743 connection's timer and remove the connection if it times 00744 out. */ 00745 if(uip_connr->tcpstateflags == UIP_TIME_WAIT || 00746 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { 00747 ++(uip_connr->timer); 00748 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { 00749 uip_connr->tcpstateflags = UIP_CLOSED; 00750 } 00751 } else if(uip_connr->tcpstateflags != UIP_CLOSED) { 00752 /* If the connection has outstanding data, we increase the 00753 connection's timer and see if it has reached the RTO value 00754 in which case we retransmit. */ 00755 if(uip_outstanding(uip_connr)) { 00756 uip_connr->timer = uip_connr->timer - 1; 00757 if(uip_connr->timer == 0) { 00758 if(uip_connr->nrtx == UIP_MAXRTX || 00759 ((uip_connr->tcpstateflags == UIP_SYN_SENT || 00760 uip_connr->tcpstateflags == UIP_SYN_RCVD) && 00761 uip_connr->nrtx == UIP_MAXSYNRTX)) { 00762 uip_connr->tcpstateflags = UIP_CLOSED; 00763 00764 /* We call UIP_APPCALL() with uip_flags set to 00765 UIP_TIMEDOUT to inform the application that the 00766 connection has timed out. */ 00767 uip_flags = UIP_TIMEDOUT; 00768 UIP_APPCALL(); 00769 00770 /* We also send a reset packet to the remote host. */ 00771 BUF->flags = TCP_RST | TCP_ACK; 00772 goto tcp_send_nodata; 00773 } 00774 00775 /* Exponential backoff. */ 00776 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? 00777 4: 00778 uip_connr->nrtx); 00779 ++(uip_connr->nrtx); 00780 00781 /* Ok, so we need to retransmit. We do this differently 00782 depending on which state we are in. In ESTABLISHED, we 00783 call upon the application so that it may prepare the 00784 data for the retransmit. In SYN_RCVD, we resend the 00785 SYNACK that we sent earlier and in LAST_ACK we have to 00786 retransmit our FINACK. */ 00787 UIP_STAT(++uip_stat.tcp.rexmit); 00788 switch(uip_connr->tcpstateflags & UIP_TS_MASK) { 00789 case UIP_SYN_RCVD: 00790 /* In the SYN_RCVD state, we should retransmit our 00791 SYNACK. */ 00792 goto tcp_send_synack; 00793 00794 #if UIP_ACTIVE_OPEN 00795 case UIP_SYN_SENT: 00796 /* In the SYN_SENT state, we retransmit out SYN. */ 00797 BUF->flags = 0; 00798 goto tcp_send_syn; 00799 #endif /* UIP_ACTIVE_OPEN */ 00800 00801 case UIP_ESTABLISHED: 00802 /* In the ESTABLISHED state, we call upon the application 00803 to do the actual retransmit after which we jump into 00804 the code for sending out the packet (the apprexmit 00805 label). */ 00806 uip_flags = UIP_REXMIT; 00807 UIP_APPCALL(); 00808 goto apprexmit; 00809 00810 case UIP_FIN_WAIT_1: 00811 case UIP_CLOSING: 00812 case UIP_LAST_ACK: 00813 /* In all these states we should retransmit a FINACK. */ 00814 goto tcp_send_finack; 00815 00816 } 00817 } 00818 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { 00819 /* If there was no need for a retransmission, we poll the 00820 application for new data. */ 00821 uip_flags = UIP_POLL; 00822 UIP_APPCALL(); 00823 goto appsend; 00824 } 00825 } 00826 goto drop; 00827 } 00828 #if UIP_UDP 00829 if(flag == UIP_UDP_TIMER) { 00830 if(uip_udp_conn->lport != 0) { 00831 uip_conn = NULL; 00832 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; 00833 uip_len = uip_slen = 0; 00834 uip_flags = UIP_POLL; 00835 UIP_UDP_APPCALL(); 00836 goto udp_send; 00837 } else { 00838 goto drop; 00839 } 00840 } 00841 #endif 00842 00843 /* This is where the input processing starts. */ 00844 UIP_STAT(++uip_stat.ip.recv); 00845 00846 /* Start of IP input header processing code. */ 00847 00848 #if UIP_CONF_IPV6 00849 /* Check validity of the IP header. */ 00850 if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ 00851 UIP_STAT(++uip_stat.ip.drop); 00852 UIP_STAT(++uip_stat.ip.vhlerr); 00853 UIP_LOG("ipv6: invalid version."); 00854 goto drop; 00855 } 00856 #else /* UIP_CONF_IPV6 */ 00857 /* Check validity of the IP header. */ 00858 if(BUF->vhl != 0x45) { /* IP version and header length. */ 00859 UIP_STAT(++uip_stat.ip.drop); 00860 UIP_STAT(++uip_stat.ip.vhlerr); 00861 UIP_LOG("ip: invalid version or header length."); 00862 goto drop; 00863 } 00864 #endif /* UIP_CONF_IPV6 */ 00865 00866 /* Check the size of the packet. If the size reported to us in 00867 uip_len is smaller the size reported in the IP header, we assume 00868 that the packet has been corrupted in transit. If the size of 00869 uip_len is larger than the size reported in the IP packet header, 00870 the packet has been padded and we set uip_len to the correct 00871 value.. */ 00872 00873 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { 00874 uip_len = (BUF->len[0] << 8) + BUF->len[1]; 00875 #if UIP_CONF_IPV6 00876 uip_len += 40; /* The length reported in the IPv6 header is the 00877 length of the payload that follows the 00878 header. However, uIP uses the uip_len variable 00879 for holding the size of the entire packet, 00880 including the IP header. For IPv4 this is not a 00881 problem as the length field in the IPv4 header 00882 contains the length of the entire packet. But 00883 for IPv6 we need to add the size of the IPv6 00884 header (40 bytes). */ 00885 #endif /* UIP_CONF_IPV6 */ 00886 } else { 00887 UIP_LOG("ip: packet shorter than reported in IP header."); 00888 goto drop; 00889 } 00890 00891 #if !UIP_CONF_IPV6 00892 /* Check the fragment flag. */ 00893 if((BUF->ipoffset[0] & 0x3f) != 0 || 00894 BUF->ipoffset[1] != 0) { 00895 #if UIP_REASSEMBLY 00896 uip_len = uip_reass(); 00897 if(uip_len == 0) { 00898 goto drop; 00899 } 00900 #else /* UIP_REASSEMBLY */ 00901 UIP_STAT(++uip_stat.ip.drop); 00902 UIP_STAT(++uip_stat.ip.fragerr); 00903 UIP_LOG("ip: fragment dropped."); 00904 goto drop; 00905 #endif /* UIP_REASSEMBLY */ 00906 } 00907 #endif /* UIP_CONF_IPV6 */ 00908 00909 if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { 00910 /* If we are configured to use ping IP address configuration and 00911 hasn't been assigned an IP address yet, we accept all ICMP 00912 packets. */ 00913 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6 00914 if(BUF->proto == UIP_PROTO_ICMP) { 00915 UIP_LOG("ip: possible ping config packet received."); 00916 goto icmp_input; 00917 } else { 00918 UIP_LOG("ip: packet dropped since no address assigned."); 00919 goto drop; 00920 } 00921 #endif /* UIP_PINGADDRCONF */ 00922 00923 } else { 00924 /* If IP broadcast support is configured, we check for a broadcast 00925 UDP packet, which may be destined to us. */ 00926 #if UIP_BROADCAST 00927 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); 00928 if(BUF->proto == UIP_PROTO_UDP && 00929 uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) 00930 /*&& 00931 uip_ipchksum() == 0xffff*/) { 00932 goto udp_input; 00933 } 00934 #endif /* UIP_BROADCAST */ 00935 00936 /* Check if the packet is destined for our IP address. */ 00937 #if !UIP_CONF_IPV6 00938 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { 00939 UIP_STAT(++uip_stat.ip.drop); 00940 goto drop; 00941 } 00942 #else /* UIP_CONF_IPV6 */ 00943 /* For IPv6, packet reception is a little trickier as we need to 00944 make sure that we listen to certain multicast addresses (all 00945 hosts multicast address, and the solicited-node multicast 00946 address) as well. However, we will cheat here and accept all 00947 multicast packets that are sent to the ff02::/16 addresses. */ 00948 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && 00949 BUF->destipaddr[0] != HTONS(0xff02)) { 00950 UIP_STAT(++uip_stat.ip.drop); 00951 goto drop; 00952 } 00953 #endif /* UIP_CONF_IPV6 */ 00954 } 00955 00956 #if !UIP_CONF_IPV6 00957 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header 00958 checksum. */ 00959 UIP_STAT(++uip_stat.ip.drop); 00960 UIP_STAT(++uip_stat.ip.chkerr); 00961 UIP_LOG("ip: bad checksum."); 00962 goto drop; 00963 } 00964 #endif /* UIP_CONF_IPV6 */ 00965 00966 if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, 00967 proceed with TCP input 00968 processing. */ 00969 goto tcp_input; 00970 } 00971 00972 #if UIP_UDP 00973 if(BUF->proto == UIP_PROTO_UDP) { 00974 goto udp_input; 00975 } 00976 #endif /* UIP_UDP */ 00977 00978 #if !UIP_CONF_IPV6 00979 /* ICMPv4 processing code follows. */ 00980 if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from 00981 here. */ 00982 UIP_STAT(++uip_stat.ip.drop); 00983 UIP_STAT(++uip_stat.ip.protoerr); 00984 UIP_LOG("ip: neither tcp nor icmp."); 00985 goto drop; 00986 } 00987 00988 #if UIP_PINGADDRCONF 00989 icmp_input: 00990 #endif /* UIP_PINGADDRCONF */ 00991 UIP_STAT(++uip_stat.icmp.recv); 00992 00993 /* ICMP echo (i.e., ping) processing. This is simple, we only change 00994 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP 00995 checksum before we return the packet. */ 00996 if(ICMPBUF->type != ICMP_ECHO) { 00997 UIP_STAT(++uip_stat.icmp.drop); 00998 UIP_STAT(++uip_stat.icmp.typeerr); 00999 UIP_LOG("icmp: not icmp echo."); 01000 goto drop; 01001 } 01002 01003 /* If we are configured to use ping IP address assignment, we use 01004 the destination IP address of this ping packet and assign it to 01005 ourself. */ 01006 #if UIP_PINGADDRCONF 01007 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { 01008 uip_hostaddr[0] = BUF->destipaddr[0]; 01009 uip_hostaddr[1] = BUF->destipaddr[1]; 01010 } 01011 #endif /* UIP_PINGADDRCONF */ 01012 01013 ICMPBUF->type = ICMP_ECHO_REPLY; 01014 01015 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { 01016 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; 01017 } else { 01018 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); 01019 } 01020 01021 /* Swap IP addresses. */ 01022 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); 01023 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); 01024 01025 UIP_STAT(++uip_stat.icmp.sent); 01026 goto send; 01027 01028 /* End of IPv4 input header processing code. */ 01029 #else /* !UIP_CONF_IPV6 */ 01030 01031 /* This is IPv6 ICMPv6 processing code. */ 01032 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); 01033 01034 if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from 01035 here. */ 01036 UIP_STAT(++uip_stat.ip.drop); 01037 UIP_STAT(++uip_stat.ip.protoerr); 01038 UIP_LOG("ip: neither tcp nor icmp6."); 01039 goto drop; 01040 } 01041 01042 UIP_STAT(++uip_stat.icmp.recv); 01043 01044 /* If we get a neighbor solicitation for our address we should send 01045 a neighbor advertisement message back. */ 01046 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { 01047 if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { 01048 01049 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { 01050 /* Save the sender's address in our neighbor list. */ 01051 uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); 01052 } 01053 01054 /* We should now send a neighbor advertisement back to where the 01055 neighbor solicication came from. */ 01056 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; 01057 ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ 01058 01059 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; 01060 01061 uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); 01062 uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); 01063 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; 01064 ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ 01065 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); 01066 ICMPBUF->icmpchksum = 0; 01067 ICMPBUF->icmpchksum = ~uip_icmp6chksum(); 01068 goto send; 01069 01070 } 01071 goto drop; 01072 } else if(ICMPBUF->type == ICMP6_ECHO) { 01073 /* ICMP echo (i.e., ping) processing. This is simple, we only 01074 change the ICMP type from ECHO to ECHO_REPLY and update the 01075 ICMP checksum before we return the packet. */ 01076 01077 ICMPBUF->type = ICMP6_ECHO_REPLY; 01078 01079 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); 01080 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); 01081 ICMPBUF->icmpchksum = 0; 01082 ICMPBUF->icmpchksum = ~uip_icmp6chksum(); 01083 01084 UIP_STAT(++uip_stat.icmp.sent); 01085 goto send; 01086 } else { 01087 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); 01088 UIP_STAT(++uip_stat.icmp.drop); 01089 UIP_STAT(++uip_stat.icmp.typeerr); 01090 UIP_LOG("icmp: unknown ICMP message."); 01091 goto drop; 01092 } 01093 01094 /* End of IPv6 ICMP processing. */ 01095 01096 #endif /* !UIP_CONF_IPV6 */ 01097 01098 #if UIP_UDP 01099 /* UDP input processing. */ 01100 udp_input: 01101 /* UDP processing is really just a hack. We don't do anything to the 01102 UDP/IP headers, but let the UDP application do all the hard 01103 work. If the application sets uip_slen, it has a packet to 01104 send. */ 01105 #if UIP_UDP_CHECKSUMS 01106 uip_len = uip_len - UIP_IPUDPH_LEN; 01107 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; 01108 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { 01109 UIP_STAT(++uip_stat.udp.drop); 01110 UIP_STAT(++uip_stat.udp.chkerr); 01111 UIP_LOG("udp: bad checksum."); 01112 goto drop; 01113 } 01114 #else /* UIP_UDP_CHECKSUMS */ 01115 uip_len = uip_len - UIP_IPUDPH_LEN; 01116 #endif /* UIP_UDP_CHECKSUMS */ 01117 01118 /* Demultiplex this UDP packet between the UDP "connections". */ 01119 for(uip_udp_conn = &uip_udp_conns[0]; 01120 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; 01121 ++uip_udp_conn) { 01122 /* If the local UDP port is non-zero, the connection is considered 01123 to be used. If so, the local port number is checked against the 01124 destination port number in the received packet. If the two port 01125 numbers match, the remote port number is checked if the 01126 connection is bound to a remote port. Finally, if the 01127 connection is bound to a remote IP address, the source IP 01128 address of the packet is checked. */ 01129 if(uip_udp_conn->lport != 0 && 01130 UDPBUF->destport == uip_udp_conn->lport && 01131 (uip_udp_conn->rport == 0 || 01132 UDPBUF->srcport == uip_udp_conn->rport) && 01133 (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || 01134 uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || 01135 uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { 01136 goto udp_found; 01137 } 01138 } 01139 UIP_LOG("udp: no matching connection found"); 01140 goto drop; 01141 01142 udp_found: 01143 UIP_STAT(++uip_stat.udp.recv); 01144 uip_conn = NULL; 01145 uip_flags = UIP_NEWDATA; 01146 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; 01147 uip_slen = 0; 01148 UIP_UDP_APPCALL(); 01149 udp_send: 01150 if(uip_slen == 0) { 01151 goto drop; 01152 } 01153 uip_len = uip_slen + UIP_IPUDPH_LEN; 01154 01155 #if UIP_CONF_IPV6 01156 /* For IPv6, the IP length field does not include the IPv6 IP header 01157 length. */ 01158 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 01159 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 01160 #else /* UIP_CONF_IPV6 */ 01161 BUF->len[0] = (uip_len >> 8); 01162 BUF->len[1] = (uip_len & 0xff); 01163 #endif /* UIP_CONF_IPV6 */ 01164 01165 BUF->ttl = uip_udp_conn->ttl; 01166 BUF->proto = UIP_PROTO_UDP; 01167 01168 UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); 01169 UDPBUF->udpchksum = 0; 01170 01171 BUF->srcport = uip_udp_conn->lport; 01172 BUF->destport = uip_udp_conn->rport; 01173 01174 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); 01175 uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); 01176 01177 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; 01178 01179 #if UIP_UDP_CHECKSUMS 01180 /* Calculate UDP checksum. */ 01181 UDPBUF->udpchksum = ~(uip_udpchksum()); 01182 if(UDPBUF->udpchksum == 0) { 01183 UDPBUF->udpchksum = 0xffff; 01184 } 01185 #endif /* UIP_UDP_CHECKSUMS */ 01186 UIP_STAT(++uip_stat.udp.sent); 01187 goto ip_send_nolen; 01188 #endif /* UIP_UDP */ 01189 01190 /* TCP input processing. */ 01191 tcp_input: 01192 UIP_STAT(++uip_stat.tcp.recv); 01193 01194 /* Start of TCP input header processing code. */ 01195 01196 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP 01197 checksum. */ 01198 UIP_STAT(++uip_stat.tcp.drop); 01199 UIP_STAT(++uip_stat.tcp.chkerr); 01200 UIP_LOG("tcp: bad checksum."); 01201 goto drop; 01202 } 01203 01204 01205 /* Demultiplex this segment. */ 01206 /* First check any active connections. */ 01207 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; 01208 ++uip_connr) { 01209 if(uip_connr->tcpstateflags != UIP_CLOSED && 01210 BUF->destport == uip_connr->lport && 01211 BUF->srcport == uip_connr->rport && 01212 uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { 01213 goto found; 01214 } 01215 } 01216 01217 /* If we didn't find and active connection that expected the packet, 01218 either this packet is an old duplicate, or this is a SYN packet 01219 destined for a connection in LISTEN. If the SYN flag isn't set, 01220 it is an old packet and we send a RST. */ 01221 if((BUF->flags & TCP_CTL) != TCP_SYN) { 01222 goto reset; 01223 } 01224 01225 tmp16 = BUF->destport; 01226 /* Next, check listening connections. */ 01227 for(c = 0; c < UIP_LISTENPORTS; ++c) { 01228 if(tmp16 == uip_listenports[c]) 01229 goto found_listen; 01230 } 01231 01232 /* No matching connection found, so we send a RST packet. */ 01233 UIP_STAT(++uip_stat.tcp.synrst); 01234 reset: 01235 01236 /* We do not send resets in response to resets. */ 01237 if(BUF->flags & TCP_RST) { 01238 goto drop; 01239 } 01240 01241 UIP_STAT(++uip_stat.tcp.rst); 01242 01243 BUF->flags = TCP_RST | TCP_ACK; 01244 uip_len = UIP_IPTCPH_LEN; 01245 BUF->tcpoffset = 5 << 4; 01246 01247 /* Flip the seqno and ackno fields in the TCP header. */ 01248 c = BUF->seqno[3]; 01249 BUF->seqno[3] = BUF->ackno[3]; 01250 BUF->ackno[3] = c; 01251 01252 c = BUF->seqno[2]; 01253 BUF->seqno[2] = BUF->ackno[2]; 01254 BUF->ackno[2] = c; 01255 01256 c = BUF->seqno[1]; 01257 BUF->seqno[1] = BUF->ackno[1]; 01258 BUF->ackno[1] = c; 01259 01260 c = BUF->seqno[0]; 01261 BUF->seqno[0] = BUF->ackno[0]; 01262 BUF->ackno[0] = c; 01263 01264 /* We also have to increase the sequence number we are 01265 acknowledging. If the least significant byte overflowed, we need 01266 to propagate the carry to the other bytes as well. */ 01267 if(++BUF->ackno[3] == 0) { 01268 if(++BUF->ackno[2] == 0) { 01269 if(++BUF->ackno[1] == 0) { 01270 ++BUF->ackno[0]; 01271 } 01272 } 01273 } 01274 01275 /* Swap port numbers. */ 01276 tmp16 = BUF->srcport; 01277 BUF->srcport = BUF->destport; 01278 BUF->destport = tmp16; 01279 01280 /* Swap IP addresses. */ 01281 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); 01282 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); 01283 01284 /* And send out the RST packet! */ 01285 goto tcp_send_noconn; 01286 01287 /* This label will be jumped to if we matched the incoming packet 01288 with a connection in LISTEN. In that case, we should create a new 01289 connection and send a SYNACK in return. */ 01290 found_listen: 01291 /* First we check if there are any connections avaliable. Unused 01292 connections are kept in the same table as used connections, but 01293 unused ones have the tcpstate set to CLOSED. Also, connections in 01294 TIME_WAIT are kept track of and we'll use the oldest one if no 01295 CLOSED connections are found. Thanks to Eddie C. Dost for a very 01296 nice algorithm for the TIME_WAIT search. */ 01297 uip_connr = 0; 01298 for(c = 0; c < UIP_CONNS; ++c) { 01299 if(uip_conns[c].tcpstateflags == UIP_CLOSED) { 01300 uip_connr = &uip_conns[c]; 01301 break; 01302 } 01303 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { 01304 if(uip_connr == 0 || 01305 uip_conns[c].timer > uip_connr->timer) { 01306 uip_connr = &uip_conns[c]; 01307 } 01308 } 01309 } 01310 01311 if(uip_connr == 0) { 01312 /* All connections are used already, we drop packet and hope that 01313 the remote end will retransmit the packet at a time when we 01314 have more spare connections. */ 01315 UIP_STAT(++uip_stat.tcp.syndrop); 01316 UIP_LOG("tcp: found no unused connections."); 01317 goto drop; 01318 } 01319 uip_conn = uip_connr; 01320 01321 /* Fill in the necessary fields for the new connection. */ 01322 uip_connr->rto = uip_connr->timer = UIP_RTO; 01323 uip_connr->sa = 0; 01324 uip_connr->sv = 4; 01325 uip_connr->nrtx = 0; 01326 uip_connr->lport = BUF->destport; 01327 uip_connr->rport = BUF->srcport; 01328 uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); 01329 uip_connr->tcpstateflags = UIP_SYN_RCVD; 01330 01331 uip_connr->snd_nxt[0] = iss[0]; 01332 uip_connr->snd_nxt[1] = iss[1]; 01333 uip_connr->snd_nxt[2] = iss[2]; 01334 uip_connr->snd_nxt[3] = iss[3]; 01335 uip_connr->len = 1; 01336 01337 /* rcv_nxt should be the seqno from the incoming packet + 1. */ 01338 uip_connr->rcv_nxt[3] = BUF->seqno[3]; 01339 uip_connr->rcv_nxt[2] = BUF->seqno[2]; 01340 uip_connr->rcv_nxt[1] = BUF->seqno[1]; 01341 uip_connr->rcv_nxt[0] = BUF->seqno[0]; 01342 uip_add_rcv_nxt(1); 01343 01344 /* Parse the TCP MSS option, if present. */ 01345 if((BUF->tcpoffset & 0xf0) > 0x50) { 01346 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { 01347 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; 01348 if(opt == TCP_OPT_END) { 01349 /* End of options. */ 01350 break; 01351 } else if(opt == TCP_OPT_NOOP) { 01352 ++c; 01353 /* NOP option. */ 01354 } else if(opt == TCP_OPT_MSS && 01355 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { 01356 /* An MSS option with the right option length. */ 01357 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | 01358 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; 01359 uip_connr->initialmss = uip_connr->mss = 01360 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; 01361 01362 /* And we are done processing options. */ 01363 break; 01364 } else { 01365 /* All other options have a length field, so that we easily 01366 can skip past them. */ 01367 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { 01368 /* If the length field is zero, the options are malformed 01369 and we don't process them further. */ 01370 break; 01371 } 01372 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; 01373 } 01374 } 01375 } 01376 01377 /* Our response will be a SYNACK. */ 01378 #if UIP_ACTIVE_OPEN 01379 tcp_send_synack: 01380 BUF->flags = TCP_ACK; 01381 01382 tcp_send_syn: 01383 BUF->flags |= TCP_SYN; 01384 #else /* UIP_ACTIVE_OPEN */ 01385 tcp_send_synack: 01386 BUF->flags = TCP_SYN | TCP_ACK; 01387 #endif /* UIP_ACTIVE_OPEN */ 01388 01389 /* We send out the TCP Maximum Segment Size option with our 01390 SYNACK. */ 01391 BUF->optdata[0] = TCP_OPT_MSS; 01392 BUF->optdata[1] = TCP_OPT_MSS_LEN; 01393 BUF->optdata[2] = (UIP_TCP_MSS) / 256; 01394 BUF->optdata[3] = (UIP_TCP_MSS) & 255; 01395 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; 01396 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; 01397 goto tcp_send; 01398 01399 /* This label will be jumped to if we found an active connection. */ 01400 found: 01401 uip_conn = uip_connr; 01402 uip_flags = 0; 01403 /* We do a very naive form of TCP reset processing; we just accept 01404 any RST and kill our connection. We should in fact check if the 01405 sequence number of this reset is wihtin our advertised window 01406 before we accept the reset. */ 01407 if(BUF->flags & TCP_RST) { 01408 uip_connr->tcpstateflags = UIP_CLOSED; 01409 UIP_LOG("tcp: got reset, aborting connection."); 01410 uip_flags = UIP_ABORT; 01411 UIP_APPCALL(); 01412 goto drop; 01413 } 01414 /* Calculated the length of the data, if the application has sent 01415 any data to us. */ 01416 c = (BUF->tcpoffset >> 4) << 2; 01417 /* uip_len will contain the length of the actual TCP data. This is 01418 calculated by subtracing the length of the TCP header (in 01419 c) and the length of the IP header (20 bytes). */ 01420 uip_len = uip_len - c - UIP_IPH_LEN; 01421 01422 /* First, check if the sequence number of the incoming packet is 01423 what we're expecting next. If not, we send out an ACK with the 01424 correct numbers in. */ 01425 if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && 01426 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { 01427 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && 01428 (BUF->seqno[0] != uip_connr->rcv_nxt[0] || 01429 BUF->seqno[1] != uip_connr->rcv_nxt[1] || 01430 BUF->seqno[2] != uip_connr->rcv_nxt[2] || 01431 BUF->seqno[3] != uip_connr->rcv_nxt[3])) { 01432 goto tcp_send_ack; 01433 } 01434 } 01435 01436 /* Next, check if the incoming segment acknowledges any outstanding 01437 data. If so, we update the sequence number, reset the length of 01438 the outstanding data, calculate RTT estimations, and reset the 01439 retransmission timer. */ 01440 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { 01441 uip_add32(uip_connr->snd_nxt, uip_connr->len); 01442 01443 if(BUF->ackno[0] == uip_acc32[0] && 01444 BUF->ackno[1] == uip_acc32[1] && 01445 BUF->ackno[2] == uip_acc32[2] && 01446 BUF->ackno[3] == uip_acc32[3]) { 01447 /* Update sequence number. */ 01448 uip_connr->snd_nxt[0] = uip_acc32[0]; 01449 uip_connr->snd_nxt[1] = uip_acc32[1]; 01450 uip_connr->snd_nxt[2] = uip_acc32[2]; 01451 uip_connr->snd_nxt[3] = uip_acc32[3]; 01452 01453 01454 /* Do RTT estimation, unless we have done retransmissions. */ 01455 if(uip_connr->nrtx == 0) { 01456 signed char m; 01457 m = uip_connr->rto - uip_connr->timer; 01458 /* This is taken directly from VJs original code in his paper */ 01459 m = m - (uip_connr->sa >> 3); 01460 uip_connr->sa += m; 01461 if(m < 0) { 01462 m = -m; 01463 } 01464 m = m - (uip_connr->sv >> 2); 01465 uip_connr->sv += m; 01466 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; 01467 01468 } 01469 /* Set the acknowledged flag. */ 01470 uip_flags = UIP_ACKDATA; 01471 /* Reset the retransmission timer. */ 01472 uip_connr->timer = uip_connr->rto; 01473 01474 /* Reset length of outstanding data. */ 01475 uip_connr->len = 0; 01476 } 01477 01478 } 01479 01480 /* Do different things depending on in what state the connection is. */ 01481 switch(uip_connr->tcpstateflags & UIP_TS_MASK) { 01482 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not 01483 implemented, since we force the application to close when the 01484 peer sends a FIN (hence the application goes directly from 01485 ESTABLISHED to LAST_ACK). */ 01486 case UIP_SYN_RCVD: 01487 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and 01488 we are waiting for an ACK that acknowledges the data we sent 01489 out the last time. Therefore, we want to have the UIP_ACKDATA 01490 flag set. If so, we enter the ESTABLISHED state. */ 01491 if(uip_flags & UIP_ACKDATA) { 01492 uip_connr->tcpstateflags = UIP_ESTABLISHED; 01493 uip_flags = UIP_CONNECTED; 01494 uip_connr->len = 0; 01495 if(uip_len > 0) { 01496 uip_flags |= UIP_NEWDATA; 01497 uip_add_rcv_nxt(uip_len); 01498 } 01499 uip_slen = 0; 01500 UIP_APPCALL(); 01501 goto appsend; 01502 } 01503 goto drop; 01504 #if UIP_ACTIVE_OPEN 01505 case UIP_SYN_SENT: 01506 /* In SYN_SENT, we wait for a SYNACK that is sent in response to 01507 our SYN. The rcv_nxt is set to sequence number in the SYNACK 01508 plus one, and we send an ACK. We move into the ESTABLISHED 01509 state. */ 01510 if((uip_flags & UIP_ACKDATA) && 01511 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { 01512 01513 /* Parse the TCP MSS option, if present. */ 01514 if((BUF->tcpoffset & 0xf0) > 0x50) { 01515 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { 01516 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; 01517 if(opt == TCP_OPT_END) { 01518 /* End of options. */ 01519 break; 01520 } else if(opt == TCP_OPT_NOOP) { 01521 ++c; 01522 /* NOP option. */ 01523 } else if(opt == TCP_OPT_MSS && 01524 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { 01525 /* An MSS option with the right option length. */ 01526 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | 01527 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; 01528 uip_connr->initialmss = 01529 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; 01530 01531 /* And we are done processing options. */ 01532 break; 01533 } else { 01534 /* All other options have a length field, so that we easily 01535 can skip past them. */ 01536 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { 01537 /* If the length field is zero, the options are malformed 01538 and we don't process them further. */ 01539 break; 01540 } 01541 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; 01542 } 01543 } 01544 } 01545 uip_connr->tcpstateflags = UIP_ESTABLISHED; 01546 uip_connr->rcv_nxt[0] = BUF->seqno[0]; 01547 uip_connr->rcv_nxt[1] = BUF->seqno[1]; 01548 uip_connr->rcv_nxt[2] = BUF->seqno[2]; 01549 uip_connr->rcv_nxt[3] = BUF->seqno[3]; 01550 uip_add_rcv_nxt(1); 01551 uip_flags = UIP_CONNECTED | UIP_NEWDATA; 01552 uip_connr->len = 0; 01553 uip_len = 0; 01554 uip_slen = 0; 01555 UIP_APPCALL(); 01556 goto appsend; 01557 } 01558 /* Inform the application that the connection failed */ 01559 uip_flags = UIP_ABORT; 01560 UIP_APPCALL(); 01561 /* The connection is closed after we send the RST */ 01562 uip_conn->tcpstateflags = UIP_CLOSED; 01563 goto reset; 01564 #endif /* UIP_ACTIVE_OPEN */ 01565 01566 case UIP_ESTABLISHED: 01567 /* In the ESTABLISHED state, we call upon the application to feed 01568 data into the uip_buf. If the UIP_ACKDATA flag is set, the 01569 application should put new data into the buffer, otherwise we are 01570 retransmitting an old segment, and the application should put that 01571 data into the buffer. 01572 01573 If the incoming packet is a FIN, we should close the connection on 01574 this side as well, and we send out a FIN and enter the LAST_ACK 01575 state. We require that there is no outstanding data; otherwise the 01576 sequence numbers will be screwed up. */ 01577 01578 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { 01579 if(uip_outstanding(uip_connr)) { 01580 goto drop; 01581 } 01582 uip_add_rcv_nxt(1 + uip_len); 01583 uip_flags |= UIP_CLOSE; 01584 if(uip_len > 0) { 01585 uip_flags |= UIP_NEWDATA; 01586 } 01587 UIP_APPCALL(); 01588 uip_connr->len = 1; 01589 uip_connr->tcpstateflags = UIP_LAST_ACK; 01590 uip_connr->nrtx = 0; 01591 tcp_send_finack: 01592 BUF->flags = TCP_FIN | TCP_ACK; 01593 goto tcp_send_nodata; 01594 } 01595 01596 /* Check the URG flag. If this is set, the segment carries urgent 01597 data that we must pass to the application. */ 01598 if((BUF->flags & TCP_URG) != 0) { 01599 #if UIP_URGDATA > 0 01600 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; 01601 if(uip_urglen > uip_len) { 01602 /* There is more urgent data in the next segment to come. */ 01603 uip_urglen = uip_len; 01604 } 01605 uip_add_rcv_nxt(uip_urglen); 01606 uip_len -= uip_urglen; 01607 uip_urgdata = uip_appdata; 01608 uip_appdata += uip_urglen; 01609 } else { 01610 uip_urglen = 0; 01611 #else /* UIP_URGDATA > 0 */ 01612 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); 01613 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; 01614 #endif /* UIP_URGDATA > 0 */ 01615 } 01616 01617 /* If uip_len > 0 we have TCP data in the packet, and we flag this 01618 by setting the UIP_NEWDATA flag and update the sequence number 01619 we acknowledge. If the application has stopped the dataflow 01620 using uip_stop(), we must not accept any data packets from the 01621 remote host. */ 01622 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { 01623 uip_flags |= UIP_NEWDATA; 01624 uip_add_rcv_nxt(uip_len); 01625 } 01626 01627 /* Check if the available buffer space advertised by the other end 01628 is smaller than the initial MSS for this connection. If so, we 01629 set the current MSS to the window size to ensure that the 01630 application does not send more data than the other end can 01631 handle. 01632 01633 If the remote host advertises a zero window, we set the MSS to 01634 the initial MSS so that the application will send an entire MSS 01635 of data. This data will not be acknowledged by the receiver, 01636 and the application will retransmit it. This is called the 01637 "persistent timer" and uses the retransmission mechanim. 01638 */ 01639 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; 01640 if(tmp16 > uip_connr->initialmss || 01641 tmp16 == 0) { 01642 tmp16 = uip_connr->initialmss; 01643 } 01644 uip_connr->mss = tmp16; 01645 01646 /* If this packet constitutes an ACK for outstanding data (flagged 01647 by the UIP_ACKDATA flag, we should call the application since it 01648 might want to send more data. If the incoming packet had data 01649 from the peer (as flagged by the UIP_NEWDATA flag), the 01650 application must also be notified. 01651 01652 When the application is called, the global variable uip_len 01653 contains the length of the incoming data. The application can 01654 access the incoming data through the global pointer 01655 uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN 01656 bytes into the uip_buf array. 01657 01658 If the application wishes to send any data, this data should be 01659 put into the uip_appdata and the length of the data should be 01660 put into uip_len. If the application don't have any data to 01661 send, uip_len must be set to 0. */ 01662 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { 01663 uip_slen = 0; 01664 UIP_APPCALL(); 01665 01666 appsend: 01667 01668 if(uip_flags & UIP_ABORT) { 01669 uip_slen = 0; 01670 uip_connr->tcpstateflags = UIP_CLOSED; 01671 BUF->flags = TCP_RST | TCP_ACK; 01672 goto tcp_send_nodata; 01673 } 01674 01675 if(uip_flags & UIP_CLOSE) { 01676 uip_slen = 0; 01677 uip_connr->len = 1; 01678 uip_connr->tcpstateflags = UIP_FIN_WAIT_1; 01679 uip_connr->nrtx = 0; 01680 BUF->flags = TCP_FIN | TCP_ACK; 01681 goto tcp_send_nodata; 01682 } 01683 01684 /* If uip_slen > 0, the application has data to be sent. */ 01685 if(uip_slen > 0) { 01686 01687 /* If the connection has acknowledged data, the contents of 01688 the ->len variable should be discarded. */ 01689 if((uip_flags & UIP_ACKDATA) != 0) { 01690 uip_connr->len = 0; 01691 } 01692 01693 /* If the ->len variable is non-zero the connection has 01694 already data in transit and cannot send anymore right 01695 now. */ 01696 if(uip_connr->len == 0) { 01697 01698 /* The application cannot send more than what is allowed by 01699 the mss (the minumum of the MSS and the available 01700 window). */ 01701 if(uip_slen > uip_connr->mss) { 01702 uip_slen = uip_connr->mss; 01703 } 01704 01705 /* Remember how much data we send out now so that we know 01706 when everything has been acknowledged. */ 01707 uip_connr->len = uip_slen; 01708 } else { 01709 01710 /* If the application already had unacknowledged data, we 01711 make sure that the application does not send (i.e., 01712 retransmit) out more than it previously sent out. */ 01713 uip_slen = uip_connr->len; 01714 } 01715 } 01716 uip_connr->nrtx = 0; 01717 apprexmit: 01718 uip_appdata = uip_sappdata; 01719 01720 /* If the application has data to be sent, or if the incoming 01721 packet had new data in it, we must send out a packet. */ 01722 if(uip_slen > 0 && uip_connr->len > 0) { 01723 /* Add the length of the IP and TCP headers. */ 01724 uip_len = uip_connr->len + UIP_TCPIP_HLEN; 01725 /* We always set the ACK flag in response packets. */ 01726 BUF->flags = TCP_ACK | TCP_PSH; 01727 /* Send the packet. */ 01728 goto tcp_send_noopts; 01729 } 01730 /* If there is no data to send, just send out a pure ACK if 01731 there is newdata. */ 01732 if(uip_flags & UIP_NEWDATA) { 01733 uip_len = UIP_TCPIP_HLEN; 01734 BUF->flags = TCP_ACK; 01735 goto tcp_send_noopts; 01736 } 01737 } 01738 goto drop; 01739 case UIP_LAST_ACK: 01740 /* We can close this connection if the peer has acknowledged our 01741 FIN. This is indicated by the UIP_ACKDATA flag. */ 01742 if(uip_flags & UIP_ACKDATA) { 01743 uip_connr->tcpstateflags = UIP_CLOSED; 01744 uip_flags = UIP_CLOSE; 01745 UIP_APPCALL(); 01746 } 01747 break; 01748 01749 case UIP_FIN_WAIT_1: 01750 /* The application has closed the connection, but the remote host 01751 hasn't closed its end yet. Thus we do nothing but wait for a 01752 FIN from the other side. */ 01753 if(uip_len > 0) { 01754 uip_add_rcv_nxt(uip_len); 01755 } 01756 if(BUF->flags & TCP_FIN) { 01757 if(uip_flags & UIP_ACKDATA) { 01758 uip_connr->tcpstateflags = UIP_TIME_WAIT; 01759 uip_connr->timer = 0; 01760 uip_connr->len = 0; 01761 } else { 01762 uip_connr->tcpstateflags = UIP_CLOSING; 01763 } 01764 uip_add_rcv_nxt(1); 01765 uip_flags = UIP_CLOSE; 01766 UIP_APPCALL(); 01767 goto tcp_send_ack; 01768 } else if(uip_flags & UIP_ACKDATA) { 01769 uip_connr->tcpstateflags = UIP_FIN_WAIT_2; 01770 uip_connr->len = 0; 01771 goto drop; 01772 } 01773 if(uip_len > 0) { 01774 goto tcp_send_ack; 01775 } 01776 goto drop; 01777 01778 case UIP_FIN_WAIT_2: 01779 if(uip_len > 0) { 01780 uip_add_rcv_nxt(uip_len); 01781 } 01782 if(BUF->flags & TCP_FIN) { 01783 uip_connr->tcpstateflags = UIP_TIME_WAIT; 01784 uip_connr->timer = 0; 01785 uip_add_rcv_nxt(1); 01786 uip_flags = UIP_CLOSE; 01787 UIP_APPCALL(); 01788 goto tcp_send_ack; 01789 } 01790 if(uip_len > 0) { 01791 goto tcp_send_ack; 01792 } 01793 goto drop; 01794 01795 case UIP_TIME_WAIT: 01796 goto tcp_send_ack; 01797 01798 case UIP_CLOSING: 01799 if(uip_flags & UIP_ACKDATA) { 01800 uip_connr->tcpstateflags = UIP_TIME_WAIT; 01801 uip_connr->timer = 0; 01802 } 01803 } 01804 goto drop; 01805 01806 01807 /* We jump here when we are ready to send the packet, and just want 01808 to set the appropriate TCP sequence numbers in the TCP header. */ 01809 tcp_send_ack: 01810 BUF->flags = TCP_ACK; 01811 tcp_send_nodata: 01812 uip_len = UIP_IPTCPH_LEN; 01813 tcp_send_noopts: 01814 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; 01815 tcp_send: 01816 /* We're done with the input processing. We are now ready to send a 01817 reply. Our job is to fill in all the fields of the TCP and IP 01818 headers before calculating the checksum and finally send the 01819 packet. */ 01820 BUF->ackno[0] = uip_connr->rcv_nxt[0]; 01821 BUF->ackno[1] = uip_connr->rcv_nxt[1]; 01822 BUF->ackno[2] = uip_connr->rcv_nxt[2]; 01823 BUF->ackno[3] = uip_connr->rcv_nxt[3]; 01824 01825 BUF->seqno[0] = uip_connr->snd_nxt[0]; 01826 BUF->seqno[1] = uip_connr->snd_nxt[1]; 01827 BUF->seqno[2] = uip_connr->snd_nxt[2]; 01828 BUF->seqno[3] = uip_connr->snd_nxt[3]; 01829 01830 BUF->proto = UIP_PROTO_TCP; 01831 01832 BUF->srcport = uip_connr->lport; 01833 BUF->destport = uip_connr->rport; 01834 01835 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); 01836 uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); 01837 01838 if(uip_connr->tcpstateflags & UIP_STOPPED) { 01839 /* If the connection has issued uip_stop(), we advertise a zero 01840 window so that the remote host will stop sending data. */ 01841 BUF->wnd[0] = BUF->wnd[1] = 0; 01842 } else { 01843 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); 01844 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); 01845 } 01846 01847 tcp_send_noconn: 01848 BUF->ttl = UIP_TTL; 01849 #if UIP_CONF_IPV6 01850 /* For IPv6, the IP length field does not include the IPv6 IP header 01851 length. */ 01852 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 01853 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 01854 #else /* UIP_CONF_IPV6 */ 01855 BUF->len[0] = (uip_len >> 8); 01856 BUF->len[1] = (uip_len & 0xff); 01857 #endif /* UIP_CONF_IPV6 */ 01858 01859 BUF->urgp[0] = BUF->urgp[1] = 0; 01860 01861 /* Calculate TCP checksum. */ 01862 BUF->tcpchksum = 0; 01863 BUF->tcpchksum = ~(uip_tcpchksum()); 01864 01865 #if UIP_UDP 01866 ip_send_nolen: 01867 #endif /* UIP_UDP */ 01868 01869 #if UIP_CONF_IPV6 01870 BUF->vtc = 0x60; 01871 BUF->tcflow = 0x00; 01872 BUF->flow = 0x00; 01873 #else /* UIP_CONF_IPV6 */ 01874 BUF->vhl = 0x45; 01875 BUF->tos = 0; 01876 BUF->ipoffset[0] = BUF->ipoffset[1] = 0; 01877 ++ipid; 01878 BUF->ipid[0] = ipid >> 8; 01879 BUF->ipid[1] = ipid & 0xff; 01880 /* Calculate IP checksum. */ 01881 BUF->ipchksum = 0; 01882 BUF->ipchksum = ~(uip_ipchksum()); 01883 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); 01884 #endif /* UIP_CONF_IPV6 */ 01885 01886 UIP_STAT(++uip_stat.tcp.sent); 01887 send: 01888 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, 01889 (BUF->len[0] << 8) | BUF->len[1]); 01890 01891 UIP_STAT(++uip_stat.ip.sent); 01892 /* Return and let the caller do the actual transmission. */ 01893 uip_flags = 0; 01894 return; 01895 drop: 01896 uip_len = 0; 01897 uip_flags = 0; 01898 return; 01899 } 01900 /*---------------------------------------------------------------------------*/ 01901 u16_t 01902 htons(u16_t val) 01903 { 01904 return HTONS(val); 01905 } 01906 /*---------------------------------------------------------------------------*/ 01907 void 01908 uip_send(const void *data, int len) 01909 { 01910 if(len > 0) { 01911 uip_slen = len; 01912 if(data != uip_sappdata) { 01913 memcpy(uip_sappdata, (data), uip_slen); 01914 } 01915 } 01916 } 01917 /** @} */ 01918 /** @} */
Generated on Tue Jul 12 2022 17:28:09 by 1.7.2