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