Contiki 2.6
|
00001 /** 00002 * \addtogroup uip6 00003 * @{ 00004 */ 00005 00006 /** 00007 * \file 00008 * The uIP TCP/IPv6 stack code. 00009 * 00010 * \author Adam Dunkels <adam@sics.se> 00011 * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code) 00012 * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code) 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: uip6.c,v 1.25 2011/01/04 22:11:37 joxe 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-icmp6.h" 00077 #include "net/uip-nd6.h" 00078 #include "net/uip-ds6.h" 00079 00080 #include <string.h> 00081 00082 /*---------------------------------------------------------------------------*/ 00083 /* For Debug, logging, statistics */ 00084 /*---------------------------------------------------------------------------*/ 00085 00086 #define DEBUG DEBUG_NONE 00087 #include "net/uip-debug.h" 00088 00089 #if UIP_CONF_IPV6_RPL 00090 #include "rpl/rpl.h" 00091 #endif /* UIP_CONF_IPV6_RPL */ 00092 00093 #if UIP_LOGGING == 1 00094 #include <stdio.h> 00095 void uip_log(char *msg); 00096 #define UIP_LOG(m) uip_log(m) 00097 #else 00098 #define UIP_LOG(m) 00099 #endif /* UIP_LOGGING == 1 */ 00100 00101 #if UIP_STATISTICS == 1 00102 struct uip_stats uip_stat; 00103 #endif /* UIP_STATISTICS == 1 */ 00104 00105 00106 /*---------------------------------------------------------------------------*/ 00107 /** @{ \name Layer 2 variables */ 00108 /*---------------------------------------------------------------------------*/ 00109 /** Host L2 address */ 00110 #if UIP_CONF_LL_802154 00111 uip_lladdr_t uip_lladdr; 00112 #else /*UIP_CONF_LL_802154*/ 00113 uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}}; 00114 #endif /*UIP_CONF_LL_802154*/ 00115 /** @} */ 00116 00117 /*---------------------------------------------------------------------------*/ 00118 /** @{ \name Layer 3 variables */ 00119 /*---------------------------------------------------------------------------*/ 00120 /** 00121 * \brief Type of the next header in IPv6 header or extension headers 00122 * 00123 * Can be the next header field in the IPv6 header or in an extension header. 00124 * When doing fragment reassembly, we must change the value of the next header 00125 * field in the header before the fragmentation header, hence we need a pointer 00126 * to this field. 00127 */ 00128 uint8_t *uip_next_hdr; 00129 /** \brief bitmap we use to record which IPv6 headers we have already seen */ 00130 uint8_t uip_ext_bitmap = 0; 00131 /** 00132 * \brief length of the extension headers read. updated each time we process 00133 * a header 00134 */ 00135 uint8_t uip_ext_len = 0; 00136 /** \brief length of the header options read */ 00137 uint8_t uip_ext_opt_offset = 0; 00138 /** @} */ 00139 00140 /*---------------------------------------------------------------------------*/ 00141 /* Buffers */ 00142 /*---------------------------------------------------------------------------*/ 00143 /** \name Buffer defines 00144 * @{ 00145 */ 00146 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) 00147 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00148 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00149 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 00150 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 00151 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00152 #define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00153 #define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00154 #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00155 #define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00156 #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) 00157 #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) 00158 #if UIP_CONF_IPV6_RPL 00159 #define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) 00160 #endif /* UIP_CONF_IPV6_RPL */ 00161 #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len]) 00162 /** @} */ 00163 /** \name Buffer variables 00164 * @{ 00165 */ 00166 /** Packet buffer for incoming and outgoing packets */ 00167 #ifndef UIP_CONF_EXTERNAL_BUFFER 00168 uip_buf_t uip_aligned_buf; 00169 #endif /* UIP_CONF_EXTERNAL_BUFFER */ 00170 00171 /* The uip_appdata pointer points to application data. */ 00172 void *uip_appdata; 00173 /* The uip_appdata pointer points to the application data which is to be sent*/ 00174 void *uip_sappdata; 00175 00176 #if UIP_URGDATA > 0 00177 /* The uip_urgdata pointer points to urgent data (out-of-band data), if present */ 00178 void *uip_urgdata; 00179 uint16_t uip_urglen, uip_surglen; 00180 #endif /* UIP_URGDATA > 0 */ 00181 00182 /* The uip_len is either 8 or 16 bits, depending on the maximum packet size.*/ 00183 uint16_t uip_len, uip_slen; 00184 /** @} */ 00185 00186 /*---------------------------------------------------------------------------*/ 00187 /** @{ \name General variables */ 00188 /*---------------------------------------------------------------------------*/ 00189 00190 /* The uip_flags variable is used for communication between the TCP/IP stack 00191 and the application program. */ 00192 uint8_t uip_flags; 00193 00194 /* uip_conn always points to the current connection (set to NULL for UDP). */ 00195 struct uip_conn *uip_conn; 00196 00197 /* Temporary variables. */ 00198 #if (UIP_TCP || UIP_UDP) 00199 static uint8_t c; 00200 #endif 00201 00202 #if UIP_ACTIVE_OPEN || UIP_UDP 00203 /* Keeps track of the last port used for a new connection. */ 00204 static uint16_t lastport; 00205 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */ 00206 /** @} */ 00207 00208 /*---------------------------------------------------------------------------*/ 00209 /* TCP */ 00210 /*---------------------------------------------------------------------------*/ 00211 /** \name TCP defines 00212 *@{ 00213 */ 00214 /* Structures and definitions. */ 00215 #define TCP_FIN 0x01 00216 #define TCP_SYN 0x02 00217 #define TCP_RST 0x04 00218 #define TCP_PSH 0x08 00219 #define TCP_ACK 0x10 00220 #define TCP_URG 0x20 00221 #define TCP_CTL 0x3f 00222 00223 #define TCP_OPT_END 0 /* End of TCP options list */ 00224 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ 00225 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ 00226 00227 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ 00228 /** @} */ 00229 /** \name TCP variables 00230 *@{ 00231 */ 00232 #if UIP_TCP 00233 /* The uip_conns array holds all TCP connections. */ 00234 struct uip_conn uip_conns[UIP_CONNS]; 00235 00236 /* The uip_listenports list all currently listning ports. */ 00237 uint16_t uip_listenports[UIP_LISTENPORTS]; 00238 00239 /* The iss variable is used for the TCP initial sequence number. */ 00240 static uint8_t iss[4]; 00241 00242 /* Temporary variables. */ 00243 uint8_t uip_acc32[4]; 00244 static uint8_t opt; 00245 static uint16_t tmp16; 00246 #endif /* UIP_TCP */ 00247 /** @} */ 00248 00249 /*---------------------------------------------------------------------------*/ 00250 /** @{ \name UDP variables */ 00251 /*---------------------------------------------------------------------------*/ 00252 #if UIP_UDP 00253 struct uip_udp_conn *uip_udp_conn; 00254 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; 00255 #endif /* UIP_UDP */ 00256 /** @} */ 00257 00258 /*---------------------------------------------------------------------------*/ 00259 /** @{ \name ICMPv6 variables */ 00260 /*---------------------------------------------------------------------------*/ 00261 #if UIP_CONF_ICMP6 00262 /** single possible icmpv6 "connection" */ 00263 struct uip_icmp6_conn uip_icmp6_conns; 00264 #endif /*UIP_CONF_ICMP6*/ 00265 00266 /*---------------------------------------------------------------------------*/ 00267 /* Functions */ 00268 /*---------------------------------------------------------------------------*/ 00269 #if (!UIP_ARCH_ADD32 && UIP_TCP) 00270 void 00271 uip_add32(uint8_t *op32, uint16_t op16) 00272 { 00273 uip_acc32[3] = op32[3] + (op16 & 0xff); 00274 uip_acc32[2] = op32[2] + (op16 >> 8); 00275 uip_acc32[1] = op32[1]; 00276 uip_acc32[0] = op32[0]; 00277 00278 if(uip_acc32[2] < (op16 >> 8)) { 00279 ++uip_acc32[1]; 00280 if(uip_acc32[1] == 0) { 00281 ++uip_acc32[0]; 00282 } 00283 } 00284 00285 00286 if(uip_acc32[3] < (op16 & 0xff)) { 00287 ++uip_acc32[2]; 00288 if(uip_acc32[2] == 0) { 00289 ++uip_acc32[1]; 00290 if(uip_acc32[1] == 0) { 00291 ++uip_acc32[0]; 00292 } 00293 } 00294 } 00295 } 00296 00297 #endif /* UIP_ARCH_ADD32 && UIP_TCP */ 00298 00299 #if ! UIP_ARCH_CHKSUM 00300 /*---------------------------------------------------------------------------*/ 00301 static uint16_t 00302 chksum(uint16_t sum, const uint8_t *data, uint16_t len) 00303 { 00304 uint16_t t; 00305 const uint8_t *dataptr; 00306 const uint8_t *last_byte; 00307 00308 dataptr = data; 00309 last_byte = data + len - 1; 00310 00311 while(dataptr < last_byte) { /* At least two more bytes */ 00312 t = (dataptr[0] << 8) + dataptr[1]; 00313 sum += t; 00314 if(sum < t) { 00315 sum++; /* carry */ 00316 } 00317 dataptr += 2; 00318 } 00319 00320 if(dataptr == last_byte) { 00321 t = (dataptr[0] << 8) + 0; 00322 sum += t; 00323 if(sum < t) { 00324 sum++; /* carry */ 00325 } 00326 } 00327 00328 /* Return sum in host byte order. */ 00329 return sum; 00330 } 00331 /*---------------------------------------------------------------------------*/ 00332 uint16_t 00333 uip_chksum(uint16_t *data, uint16_t len) 00334 { 00335 return uip_htons(chksum(0, (uint8_t *)data, len)); 00336 } 00337 /*---------------------------------------------------------------------------*/ 00338 #ifndef UIP_ARCH_IPCHKSUM 00339 uint16_t 00340 uip_ipchksum(void) 00341 { 00342 uint16_t sum; 00343 00344 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); 00345 PRINTF("uip_ipchksum: sum 0x%04x\n", sum); 00346 return (sum == 0) ? 0xffff : uip_htons(sum); 00347 } 00348 #endif 00349 /*---------------------------------------------------------------------------*/ 00350 static uint16_t 00351 upper_layer_chksum(uint8_t proto) 00352 { 00353 /* gcc 4.4.0 - 4.6.1 (maybe 4.3...) with -Os on 8 bit CPUS incorrectly compiles: 00354 * int bar (int); 00355 * int foo (unsigned char a, unsigned char b) { 00356 * int len = (a << 8) + b; //len becomes 0xff00&<random>+b 00357 * return len + bar (len); 00358 * } 00359 * upper_layer_len triggers this bug unless it is declared volatile. 00360 * See https://sourceforge.net/apps/mantisbt/contiki/view.php?id=3 00361 */ 00362 volatile uint16_t upper_layer_len; 00363 uint16_t sum; 00364 00365 upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len); 00366 00367 PRINTF("Upper layer checksum len: %d from: %d\n", upper_layer_len, 00368 UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len); 00369 00370 /* First sum pseudoheader. */ 00371 /* IP protocol and length fields. This addition cannot carry. */ 00372 sum = upper_layer_len + proto; 00373 /* Sum IP source and destination addresses. */ 00374 sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t)); 00375 00376 /* Sum TCP header and data. */ 00377 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len], 00378 upper_layer_len); 00379 00380 return (sum == 0) ? 0xffff : uip_htons(sum); 00381 } 00382 /*---------------------------------------------------------------------------*/ 00383 uint16_t 00384 uip_icmp6chksum(void) 00385 { 00386 return upper_layer_chksum(UIP_PROTO_ICMP6); 00387 00388 } 00389 /*---------------------------------------------------------------------------*/ 00390 #if UIP_TCP 00391 uint16_t 00392 uip_tcpchksum(void) 00393 { 00394 return upper_layer_chksum(UIP_PROTO_TCP); 00395 } 00396 #endif /* UIP_TCP */ 00397 /*---------------------------------------------------------------------------*/ 00398 #if UIP_UDP && UIP_UDP_CHECKSUMS 00399 uint16_t 00400 uip_udpchksum(void) 00401 { 00402 return upper_layer_chksum(UIP_PROTO_UDP); 00403 } 00404 #endif /* UIP_UDP && UIP_UDP_CHECKSUMS */ 00405 #endif /* UIP_ARCH_CHKSUM */ 00406 /*---------------------------------------------------------------------------*/ 00407 void 00408 uip_init(void) 00409 { 00410 00411 uip_ds6_init(); 00412 00413 #if UIP_TCP 00414 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00415 uip_listenports[c] = 0; 00416 } 00417 for(c = 0; c < UIP_CONNS; ++c) { 00418 uip_conns[c].tcpstateflags = UIP_CLOSED; 00419 } 00420 #endif /* UIP_TCP */ 00421 00422 #if UIP_ACTIVE_OPEN || UIP_UDP 00423 lastport = 1024; 00424 #endif /* UIP_ACTIVE_OPEN || UIP_UDP */ 00425 00426 #if UIP_UDP 00427 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00428 uip_udp_conns[c].lport = 0; 00429 } 00430 #endif /* UIP_UDP */ 00431 } 00432 /*---------------------------------------------------------------------------*/ 00433 #if UIP_TCP && UIP_ACTIVE_OPEN 00434 struct uip_conn * 00435 uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) 00436 { 00437 register struct uip_conn *conn, *cconn; 00438 00439 /* Find an unused local port. */ 00440 again: 00441 ++lastport; 00442 00443 if(lastport >= 32000) { 00444 lastport = 4096; 00445 } 00446 00447 /* Check if this port is already in use, and if so try to find 00448 another one. */ 00449 for(c = 0; c < UIP_CONNS; ++c) { 00450 conn = &uip_conns[c]; 00451 if(conn->tcpstateflags != UIP_CLOSED && 00452 conn->lport == uip_htons(lastport)) { 00453 goto again; 00454 } 00455 } 00456 00457 conn = 0; 00458 for(c = 0; c < UIP_CONNS; ++c) { 00459 cconn = &uip_conns[c]; 00460 if(cconn->tcpstateflags == UIP_CLOSED) { 00461 conn = cconn; 00462 break; 00463 } 00464 if(cconn->tcpstateflags == UIP_TIME_WAIT) { 00465 if(conn == 0 || 00466 cconn->timer > conn->timer) { 00467 conn = cconn; 00468 } 00469 } 00470 } 00471 00472 if(conn == 0) { 00473 return 0; 00474 } 00475 00476 conn->tcpstateflags = UIP_SYN_SENT; 00477 00478 conn->snd_nxt[0] = iss[0]; 00479 conn->snd_nxt[1] = iss[1]; 00480 conn->snd_nxt[2] = iss[2]; 00481 conn->snd_nxt[3] = iss[3]; 00482 00483 conn->rcv_nxt[0] = 0; 00484 conn->rcv_nxt[1] = 0; 00485 conn->rcv_nxt[2] = 0; 00486 conn->rcv_nxt[3] = 0; 00487 00488 conn->initialmss = conn->mss = UIP_TCP_MSS; 00489 00490 conn->len = 1; /* TCP length of the SYN is one. */ 00491 conn->nrtx = 0; 00492 conn->timer = 1; /* Send the SYN next time around. */ 00493 conn->rto = UIP_RTO; 00494 conn->sa = 0; 00495 conn->sv = 16; /* Initial value of the RTT variance. */ 00496 conn->lport = uip_htons(lastport); 00497 conn->rport = rport; 00498 uip_ipaddr_copy(&conn->ripaddr, ripaddr); 00499 00500 return conn; 00501 } 00502 #endif /* UIP_TCP && UIP_ACTIVE_OPEN */ 00503 /*---------------------------------------------------------------------------*/ 00504 void 00505 remove_ext_hdr(void) 00506 { 00507 /* Remove ext header before TCP/UDP processing. */ 00508 if(uip_ext_len > 0) { 00509 PRINTF("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n", 00510 uip_ext_len, uip_len); 00511 if(uip_len - UIP_IPH_LEN - uip_ext_len < 0) { 00512 PRINTF("ERROR: uip_len too short compared to ext len\n"); 00513 uip_ext_len = 0; 00514 uip_len = 0; 00515 return; 00516 } 00517 memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, 00518 uip_len - UIP_IPH_LEN - uip_ext_len); 00519 00520 uip_len -= uip_ext_len; 00521 00522 /* Update the IP length. */ 00523 UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8; 00524 UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff; 00525 uip_ext_len = 0; 00526 } 00527 } 00528 /*---------------------------------------------------------------------------*/ 00529 #if UIP_UDP 00530 struct uip_udp_conn * 00531 uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) 00532 { 00533 register struct uip_udp_conn *conn; 00534 00535 /* Find an unused local port. */ 00536 again: 00537 ++lastport; 00538 00539 if(lastport >= 32000) { 00540 lastport = 4096; 00541 } 00542 00543 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00544 if(uip_udp_conns[c].lport == uip_htons(lastport)) { 00545 goto again; 00546 } 00547 } 00548 00549 conn = 0; 00550 for(c = 0; c < UIP_UDP_CONNS; ++c) { 00551 if(uip_udp_conns[c].lport == 0) { 00552 conn = &uip_udp_conns[c]; 00553 break; 00554 } 00555 } 00556 00557 if(conn == 0) { 00558 return 0; 00559 } 00560 00561 conn->lport = UIP_HTONS(lastport); 00562 conn->rport = rport; 00563 if(ripaddr == NULL) { 00564 memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t)); 00565 } else { 00566 uip_ipaddr_copy(&conn->ripaddr, ripaddr); 00567 } 00568 conn->ttl = uip_ds6_if.cur_hop_limit; 00569 00570 return conn; 00571 } 00572 #endif /* UIP_UDP */ 00573 /*---------------------------------------------------------------------------*/ 00574 #if UIP_TCP 00575 void 00576 uip_unlisten(uint16_t port) 00577 { 00578 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00579 if(uip_listenports[c] == port) { 00580 uip_listenports[c] = 0; 00581 return; 00582 } 00583 } 00584 } 00585 /*---------------------------------------------------------------------------*/ 00586 void 00587 uip_listen(uint16_t port) 00588 { 00589 for(c = 0; c < UIP_LISTENPORTS; ++c) { 00590 if(uip_listenports[c] == 0) { 00591 uip_listenports[c] = port; 00592 return; 00593 } 00594 } 00595 } 00596 #endif 00597 /*---------------------------------------------------------------------------*/ 00598 00599 #if UIP_CONF_IPV6_REASSEMBLY 00600 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) 00601 00602 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE]; 00603 00604 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; 00605 /*the first byte of an IP fragment is aligned on an 8-byte boundary */ 00606 00607 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, 00608 0x0f, 0x07, 0x03, 0x01}; 00609 static uint16_t uip_reasslen; 00610 static uint8_t uip_reassflags; 00611 00612 #define UIP_REASS_FLAG_LASTFRAG 0x01 00613 #define UIP_REASS_FLAG_FIRSTFRAG 0x02 00614 #define UIP_REASS_FLAG_ERROR_MSG 0x04 00615 00616 00617 /* 00618 * See RFC 2460 for a description of fragmentation in IPv6 00619 * A typical Ipv6 fragment 00620 * +------------------+--------+--------------+ 00621 * | Unfragmentable |Fragment| first | 00622 * | Part | Header | fragment | 00623 * +------------------+--------+--------------+ 00624 */ 00625 00626 00627 struct etimer uip_reass_timer; /* timer for reassembly */ 00628 uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */ 00629 00630 static uint32_t uip_id; /* For every packet that is to be fragmented, the source 00631 node generates an Identification value that is present 00632 in all the fragments */ 00633 #define IP_MF 0x0001 00634 00635 static uint16_t 00636 uip_reass(void) 00637 { 00638 uint16_t offset=0; 00639 uint16_t len; 00640 uint16_t i; 00641 00642 /* If ip_reasstmr is zero, no packet is present in the buffer */ 00643 /* We first write the unfragmentable part of IP header into the reassembly 00644 buffer. The reset the other reassembly variables. */ 00645 if(uip_reass_on == 0) { 00646 PRINTF("Starting reassembly\n"); 00647 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN); 00648 /* temporary in case we do not receive the fragment with offset 0 first */ 00649 etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND); 00650 uip_reass_on = 1; 00651 uip_reassflags = 0; 00652 uip_id = UIP_FRAG_BUF->id; 00653 /* Clear the bitmap. */ 00654 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); 00655 } 00656 /* 00657 * Check if the incoming fragment matches the one currently present 00658 * in the reasembly buffer. If so, we proceed with copying the fragment 00659 * into the buffer. 00660 */ 00661 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) && 00662 uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) && 00663 UIP_FRAG_BUF->id == uip_id) { 00664 len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN; 00665 offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8); 00666 /* in byte, originaly in multiple of 8 bytes*/ 00667 PRINTF("len %d\n", len); 00668 PRINTF("offset %d\n", offset); 00669 if(offset == 0){ 00670 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG; 00671 /* 00672 * The Next Header field of the last header of the Unfragmentable 00673 * Part is obtained from the Next Header field of the first 00674 * fragment's Fragment header. 00675 */ 00676 *uip_next_hdr = UIP_FRAG_BUF->next; 00677 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN); 00678 PRINTF("src "); 00679 PRINT6ADDR(&FBUF->srcipaddr); 00680 PRINTF("dest "); 00681 PRINT6ADDR(&FBUF->destipaddr); 00682 PRINTF("next %d\n", UIP_IP_BUF->proto); 00683 00684 } 00685 00686 /* If the offset or the offset + fragment length overflows the 00687 reassembly buffer, we discard the entire packet. */ 00688 if(offset > UIP_REASS_BUFSIZE || 00689 offset + len > UIP_REASS_BUFSIZE) { 00690 uip_reass_on = 0; 00691 etimer_stop(&uip_reass_timer); 00692 return 0; 00693 } 00694 00695 /* If this fragment has the More Fragments flag set to zero, it is the 00696 last fragment*/ 00697 if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) { 00698 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; 00699 /*calculate the size of the entire packet*/ 00700 uip_reasslen = offset + len; 00701 PRINTF("LAST FRAGMENT reasslen %d\n", uip_reasslen); 00702 } else { 00703 /* If len is not a multiple of 8 octets and the M flag of that fragment 00704 is 1, then that fragment must be discarded and an ICMP Parameter 00705 Problem, Code 0, message should be sent to the source of the fragment, 00706 pointing to the Payload Length field of the fragment packet. */ 00707 if(len % 8 != 0){ 00708 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4); 00709 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG; 00710 /* not clear if we should interrupt reassembly, but it seems so from 00711 the conformance tests */ 00712 uip_reass_on = 0; 00713 etimer_stop(&uip_reass_timer); 00714 return uip_len; 00715 } 00716 } 00717 00718 /* Copy the fragment into the reassembly buffer, at the right 00719 offset. */ 00720 memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset, 00721 (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len); 00722 00723 /* Update the bitmap. */ 00724 if(offset >> 6 == (offset + len) >> 6) { 00725 uip_reassbitmap[offset >> 6] |= 00726 bitmap_bits[(offset >> 3) & 7] & 00727 ~bitmap_bits[((offset + len) >> 3) & 7]; 00728 } else { 00729 /* If the two endpoints are in different bytes, we update the 00730 bytes in the endpoints and fill the stuff inbetween with 00731 0xff. */ 00732 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7]; 00733 00734 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) { 00735 uip_reassbitmap[i] = 0xff; 00736 } 00737 uip_reassbitmap[(offset + len) >> 6] |= 00738 ~bitmap_bits[((offset + len) >> 3) & 7]; 00739 } 00740 00741 /* Finally, we check if we have a full packet in the buffer. We do 00742 this by checking if we have the last fragment and if all bits 00743 in the bitmap are set. */ 00744 00745 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { 00746 /* Check all bytes up to and including all but the last byte in 00747 the bitmap. */ 00748 for(i = 0; i < (uip_reasslen >> 6); ++i) { 00749 if(uip_reassbitmap[i] != 0xff) { 00750 return 0; 00751 } 00752 } 00753 /* Check the last byte in the bitmap. It should contain just the 00754 right amount of bits. */ 00755 if(uip_reassbitmap[uip_reasslen >> 6] != 00756 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) { 00757 return 0; 00758 } 00759 00760 /* If we have come this far, we have a full packet in the 00761 buffer, so we copy it to uip_buf. We also reset the timer. */ 00762 uip_reass_on = 0; 00763 etimer_stop(&uip_reass_timer); 00764 00765 uip_reasslen += UIP_IPH_LEN + uip_ext_len; 00766 memcpy(UIP_IP_BUF, FBUF, uip_reasslen); 00767 UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8); 00768 UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff); 00769 PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen, 00770 (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); 00771 00772 return uip_reasslen; 00773 00774 } 00775 } else { 00776 PRINTF("Already reassembling another paquet\n"); 00777 } 00778 return 0; 00779 } 00780 00781 void 00782 uip_reass_over(void) 00783 { 00784 /* to late, we abandon the reassembly of the packet */ 00785 00786 uip_reass_on = 0; 00787 etimer_stop(&uip_reass_timer); 00788 00789 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){ 00790 PRINTF("FRAG INTERRUPTED TOO LATE\n"); 00791 /* If the first fragment has been received, an ICMP Time Exceeded 00792 -- Fragment Reassembly Time Exceeded message should be sent to the 00793 source of that fragment. */ 00794 /** \note 00795 * We don't have a complete packet to put in the error message. 00796 * We could include the first fragment but since its not mandated by 00797 * any RFC, we decided not to include it as it reduces the size of 00798 * the packet. 00799 */ 00800 uip_len = 0; 00801 uip_ext_len = 0; 00802 memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src 00803 and dest address*/ 00804 uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0); 00805 00806 UIP_STAT(++uip_stat.ip.sent); 00807 uip_flags = 0; 00808 } 00809 } 00810 00811 #endif /* UIP_CONF_IPV6_REASSEMBLY */ 00812 00813 /*---------------------------------------------------------------------------*/ 00814 #if UIP_TCP 00815 static void 00816 uip_add_rcv_nxt(uint16_t n) 00817 { 00818 uip_add32(uip_conn->rcv_nxt, n); 00819 uip_conn->rcv_nxt[0] = uip_acc32[0]; 00820 uip_conn->rcv_nxt[1] = uip_acc32[1]; 00821 uip_conn->rcv_nxt[2] = uip_acc32[2]; 00822 uip_conn->rcv_nxt[3] = uip_acc32[3]; 00823 } 00824 #endif 00825 /*---------------------------------------------------------------------------*/ 00826 00827 /** 00828 * \brief Process the options in Destination and Hop By Hop extension headers 00829 */ 00830 static uint8_t 00831 ext_hdr_options_process(void) 00832 { 00833 /* 00834 * Length field in the extension header: length of the header in units of 00835 * 8 bytes, excluding the first 8 bytes 00836 * length field in an option : the length of data in the option 00837 */ 00838 uip_ext_opt_offset = 2; 00839 while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) { 00840 switch(UIP_EXT_HDR_OPT_BUF->type) { 00841 /* 00842 * for now we do not support any options except padding ones 00843 * PAD1 does not make sense as the header must be 8bytes aligned, 00844 * hence we can only have 00845 */ 00846 case UIP_EXT_HDR_OPT_PAD1: 00847 PRINTF("Processing PAD1 option\n"); 00848 uip_ext_opt_offset += 1; 00849 break; 00850 case UIP_EXT_HDR_OPT_PADN: 00851 PRINTF("Processing PADN option\n"); 00852 uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; 00853 break; 00854 #if UIP_CONF_IPV6_RPL 00855 case UIP_EXT_HDR_OPT_RPL: 00856 PRINTF("Processing RPL option\n"); 00857 if(rpl_verify_header(uip_ext_opt_offset)) { 00858 PRINTF("RPL Option Error : Dropping Packet"); 00859 return 1; 00860 } 00861 uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2; 00862 return 0; 00863 #endif /* UIP_CONF_IPV6_RPL */ 00864 default: 00865 /* 00866 * check the two highest order bits of the option 00867 * - 00 skip over this option and continue processing the header. 00868 * - 01 discard the packet. 00869 * - 10 discard the packet and, regardless of whether or not the 00870 * packet's Destination Address was a multicast address, send an 00871 * ICMP Parameter Problem, Code 2, message to the packet's 00872 * Source Address, pointing to the unrecognized Option Type. 00873 * - 11 discard the packet and, only if the packet's Destination 00874 * Address was not a multicast address, send an ICMP Parameter 00875 * Problem, Code 2, message to the packet's Source Address, 00876 * pointing to the unrecognized Option Type. 00877 */ 00878 PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type); 00879 switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) { 00880 case 0: 00881 break; 00882 case 0x40: 00883 return 1; 00884 case 0xC0: 00885 if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { 00886 return 1; 00887 } 00888 case 0x80: 00889 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, 00890 (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); 00891 return 2; 00892 } 00893 /* in the cases were we did not discard, update ext_opt* */ 00894 uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2; 00895 break; 00896 } 00897 } 00898 return 0; 00899 } 00900 00901 00902 /*---------------------------------------------------------------------------*/ 00903 void 00904 uip_process(uint8_t flag) 00905 { 00906 #if UIP_TCP 00907 register struct uip_conn *uip_connr = uip_conn; 00908 #endif /* UIP_TCP */ 00909 #if UIP_UDP 00910 if(flag == UIP_UDP_SEND_CONN) { 00911 goto udp_send; 00912 } 00913 #endif /* UIP_UDP */ 00914 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; 00915 00916 /* Check if we were invoked because of a poll request for a 00917 particular connection. */ 00918 if(flag == UIP_POLL_REQUEST) { 00919 #if UIP_TCP 00920 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && 00921 !uip_outstanding(uip_connr)) { 00922 uip_flags = UIP_POLL; 00923 UIP_APPCALL(); 00924 goto appsend; 00925 #if UIP_ACTIVE_OPEN 00926 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) { 00927 /* In the SYN_SENT state, we retransmit out SYN. */ 00928 UIP_TCP_BUF->flags = 0; 00929 goto tcp_send_syn; 00930 #endif /* UIP_ACTIVE_OPEN */ 00931 } 00932 goto drop; 00933 #endif /* UIP_TCP */ 00934 /* Check if we were invoked because of the perodic timer fireing. */ 00935 } else if(flag == UIP_TIMER) { 00936 /* Reset the length variables. */ 00937 #if UIP_TCP 00938 uip_len = 0; 00939 uip_slen = 0; 00940 00941 /* Increase the initial sequence number. */ 00942 if(++iss[3] == 0) { 00943 if(++iss[2] == 0) { 00944 if(++iss[1] == 0) { 00945 ++iss[0]; 00946 } 00947 } 00948 } 00949 00950 /* 00951 * Check if the connection is in a state in which we simply wait 00952 * for the connection to time out. If so, we increase the 00953 * connection's timer and remove the connection if it times 00954 * out. 00955 */ 00956 if(uip_connr->tcpstateflags == UIP_TIME_WAIT || 00957 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { 00958 ++(uip_connr->timer); 00959 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { 00960 uip_connr->tcpstateflags = UIP_CLOSED; 00961 } 00962 } else if(uip_connr->tcpstateflags != UIP_CLOSED) { 00963 /* 00964 * If the connection has outstanding data, we increase the 00965 * connection's timer and see if it has reached the RTO value 00966 * in which case we retransmit. 00967 */ 00968 if(uip_outstanding(uip_connr)) { 00969 if(uip_connr->timer-- == 0) { 00970 if(uip_connr->nrtx == UIP_MAXRTX || 00971 ((uip_connr->tcpstateflags == UIP_SYN_SENT || 00972 uip_connr->tcpstateflags == UIP_SYN_RCVD) && 00973 uip_connr->nrtx == UIP_MAXSYNRTX)) { 00974 uip_connr->tcpstateflags = UIP_CLOSED; 00975 00976 /* 00977 * We call UIP_APPCALL() with uip_flags set to 00978 * UIP_TIMEDOUT to inform the application that the 00979 * connection has timed out. 00980 */ 00981 uip_flags = UIP_TIMEDOUT; 00982 UIP_APPCALL(); 00983 00984 /* We also send a reset packet to the remote host. */ 00985 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; 00986 goto tcp_send_nodata; 00987 } 00988 00989 /* Exponential backoff. */ 00990 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? 00991 4: 00992 uip_connr->nrtx); 00993 ++(uip_connr->nrtx); 00994 00995 /* 00996 * Ok, so we need to retransmit. We do this differently 00997 * depending on which state we are in. In ESTABLISHED, we 00998 * call upon the application so that it may prepare the 00999 * data for the retransmit. In SYN_RCVD, we resend the 01000 * SYNACK that we sent earlier and in LAST_ACK we have to 01001 * retransmit our FINACK. 01002 */ 01003 UIP_STAT(++uip_stat.tcp.rexmit); 01004 switch(uip_connr->tcpstateflags & UIP_TS_MASK) { 01005 case UIP_SYN_RCVD: 01006 /* In the SYN_RCVD state, we should retransmit our SYNACK. */ 01007 goto tcp_send_synack; 01008 01009 #if UIP_ACTIVE_OPEN 01010 case UIP_SYN_SENT: 01011 /* In the SYN_SENT state, we retransmit out SYN. */ 01012 UIP_TCP_BUF->flags = 0; 01013 goto tcp_send_syn; 01014 #endif /* UIP_ACTIVE_OPEN */ 01015 01016 case UIP_ESTABLISHED: 01017 /* 01018 * In the ESTABLISHED state, we call upon the application 01019 * to do the actual retransmit after which we jump into 01020 * the code for sending out the packet (the apprexmit 01021 * label). 01022 */ 01023 uip_flags = UIP_REXMIT; 01024 UIP_APPCALL(); 01025 goto apprexmit; 01026 01027 case UIP_FIN_WAIT_1: 01028 case UIP_CLOSING: 01029 case UIP_LAST_ACK: 01030 /* In all these states we should retransmit a FINACK. */ 01031 goto tcp_send_finack; 01032 } 01033 } 01034 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { 01035 /* 01036 * If there was no need for a retransmission, we poll the 01037 * application for new data. 01038 */ 01039 uip_flags = UIP_POLL; 01040 UIP_APPCALL(); 01041 goto appsend; 01042 } 01043 } 01044 goto drop; 01045 #endif /* UIP_TCP */ 01046 } 01047 #if UIP_UDP 01048 if(flag == UIP_UDP_TIMER) { 01049 if(uip_udp_conn->lport != 0) { 01050 uip_conn = NULL; 01051 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; 01052 uip_len = uip_slen = 0; 01053 uip_flags = UIP_POLL; 01054 UIP_UDP_APPCALL(); 01055 goto udp_send; 01056 } else { 01057 goto drop; 01058 } 01059 } 01060 #endif /* UIP_UDP */ 01061 01062 01063 /* This is where the input processing starts. */ 01064 UIP_STAT(++uip_stat.ip.recv); 01065 01066 /* Start of IP input header processing code. */ 01067 01068 /* Check validity of the IP header. */ 01069 if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ 01070 UIP_STAT(++uip_stat.ip.drop); 01071 UIP_STAT(++uip_stat.ip.vhlerr); 01072 UIP_LOG("ipv6: invalid version."); 01073 goto drop; 01074 } 01075 /* 01076 * Check the size of the packet. If the size reported to us in 01077 * uip_len is smaller the size reported in the IP header, we assume 01078 * that the packet has been corrupted in transit. If the size of 01079 * uip_len is larger than the size reported in the IP packet header, 01080 * the packet has been padded and we set uip_len to the correct 01081 * value.. 01082 */ 01083 01084 if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) { 01085 uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN; 01086 /* 01087 * The length reported in the IPv6 header is the 01088 * length of the payload that follows the 01089 * header. However, uIP uses the uip_len variable 01090 * for holding the size of the entire packet, 01091 * including the IP header. For IPv4 this is not a 01092 * problem as the length field in the IPv4 header 01093 * contains the length of the entire packet. But 01094 * for IPv6 we need to add the size of the IPv6 01095 * header (40 bytes). 01096 */ 01097 } else { 01098 UIP_LOG("ip: packet shorter than reported in IP header."); 01099 goto drop; 01100 } 01101 01102 PRINTF("IPv6 packet received from "); 01103 PRINT6ADDR(&UIP_IP_BUF->srcipaddr); 01104 PRINTF(" to "); 01105 PRINT6ADDR(&UIP_IP_BUF->destipaddr); 01106 PRINTF("\n"); 01107 01108 if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){ 01109 UIP_STAT(++uip_stat.ip.drop); 01110 PRINTF("Dropping packet, src is mcast\n"); 01111 goto drop; 01112 } 01113 01114 #if UIP_CONF_ROUTER 01115 /* 01116 * Next header field processing. In IPv6, we can have extension headers, 01117 * if present, the Hop-by-Hop Option must be processed before forwarding 01118 * the packet. 01119 */ 01120 uip_next_hdr = &UIP_IP_BUF->proto; 01121 uip_ext_len = 0; 01122 uip_ext_bitmap = 0; 01123 if(*uip_next_hdr == UIP_PROTO_HBHO) { 01124 #if UIP_CONF_IPV6_CHECKS 01125 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; 01126 #endif /*UIP_CONF_IPV6_CHECKS*/ 01127 switch(ext_hdr_options_process()) { 01128 case 0: 01129 /*continue*/ 01130 uip_next_hdr = &UIP_EXT_BUF->next; 01131 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; 01132 break; 01133 case 1: 01134 /*silently discard*/ 01135 goto drop; 01136 case 2: 01137 /* send icmp error message (created in ext_hdr_options_process) 01138 * and discard*/ 01139 goto send; 01140 } 01141 } 01142 01143 01144 /* TBD Some Parameter problem messages */ 01145 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && 01146 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { 01147 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && 01148 !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && 01149 !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && 01150 !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) && 01151 !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) { 01152 01153 01154 /* Check MTU */ 01155 if(uip_len > UIP_LINK_MTU) { 01156 uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU); 01157 UIP_STAT(++uip_stat.ip.drop); 01158 goto send; 01159 } 01160 /* Check Hop Limit */ 01161 if(UIP_IP_BUF->ttl <= 1) { 01162 uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, 01163 ICMP6_TIME_EXCEED_TRANSIT, 0); 01164 UIP_STAT(++uip_stat.ip.drop); 01165 goto send; 01166 } 01167 01168 #if UIP_CONF_IPV6_RPL 01169 rpl_update_header_empty(); 01170 #endif /* UIP_CONF_IPV6_RPL */ 01171 01172 UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; 01173 PRINTF("Forwarding packet to "); 01174 PRINT6ADDR(&UIP_IP_BUF->destipaddr); 01175 PRINTF("\n"); 01176 UIP_STAT(++uip_stat.ip.forwarded); 01177 goto send; 01178 } else { 01179 if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) && 01180 (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) && 01181 (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) && 01182 (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) && 01183 (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) { 01184 PRINTF("LL source address with off link destination, dropping\n"); 01185 uip_icmp6_error_output(ICMP6_DST_UNREACH, 01186 ICMP6_DST_UNREACH_NOTNEIGHBOR, 0); 01187 goto send; 01188 } 01189 PRINTF("Dropping packet, not for me and link local or multicast\n"); 01190 UIP_STAT(++uip_stat.ip.drop); 01191 goto drop; 01192 } 01193 } 01194 #else /* UIP_CONF_ROUTER */ 01195 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && 01196 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) && 01197 !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { 01198 PRINTF("Dropping packet, not for me\n"); 01199 UIP_STAT(++uip_stat.ip.drop); 01200 goto drop; 01201 } 01202 01203 /* 01204 * Next header field processing. In IPv6, we can have extension headers, 01205 * they are processed here 01206 */ 01207 uip_next_hdr = &UIP_IP_BUF->proto; 01208 uip_ext_len = 0; 01209 uip_ext_bitmap = 0; 01210 #endif /* UIP_CONF_ROUTER */ 01211 01212 while(1) { 01213 switch(*uip_next_hdr){ 01214 #if UIP_TCP 01215 case UIP_PROTO_TCP: 01216 /* TCP, for both IPv4 and IPv6 */ 01217 goto tcp_input; 01218 #endif /* UIP_TCP */ 01219 #if UIP_UDP 01220 case UIP_PROTO_UDP: 01221 /* UDP, for both IPv4 and IPv6 */ 01222 goto udp_input; 01223 #endif /* UIP_UDP */ 01224 case UIP_PROTO_ICMP6: 01225 /* ICMPv6 */ 01226 goto icmp6_input; 01227 case UIP_PROTO_HBHO: 01228 PRINTF("Processing hbh header\n"); 01229 /* Hop by hop option header */ 01230 #if UIP_CONF_IPV6_CHECKS 01231 /* Hop by hop option header. If we saw one HBH already, drop */ 01232 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) { 01233 goto bad_hdr; 01234 } else { 01235 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; 01236 } 01237 #endif /*UIP_CONF_IPV6_CHECKS*/ 01238 switch(ext_hdr_options_process()) { 01239 case 0: 01240 /*continue*/ 01241 uip_next_hdr = &UIP_EXT_BUF->next; 01242 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; 01243 break; 01244 case 1: 01245 /*silently discard*/ 01246 goto drop; 01247 case 2: 01248 /* send icmp error message (created in ext_hdr_options_process) 01249 * and discard*/ 01250 goto send; 01251 } 01252 break; 01253 case UIP_PROTO_DESTO: 01254 #if UIP_CONF_IPV6_CHECKS 01255 /* Destination option header. if we saw two already, drop */ 01256 PRINTF("Processing desto header\n"); 01257 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) { 01258 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) { 01259 goto bad_hdr; 01260 } else{ 01261 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2; 01262 } 01263 } else { 01264 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1; 01265 } 01266 #endif /*UIP_CONF_IPV6_CHECKS*/ 01267 switch(ext_hdr_options_process()) { 01268 case 0: 01269 /*continue*/ 01270 uip_next_hdr = &UIP_EXT_BUF->next; 01271 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; 01272 break; 01273 case 1: 01274 /*silently discard*/ 01275 goto drop; 01276 case 2: 01277 /* send icmp error message (created in ext_hdr_options_process) 01278 * and discard*/ 01279 goto send; 01280 } 01281 break; 01282 case UIP_PROTO_ROUTING: 01283 #if UIP_CONF_IPV6_CHECKS 01284 /* Routing header. If we saw one already, drop */ 01285 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) { 01286 goto bad_hdr; 01287 } else { 01288 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; 01289 } 01290 #endif /*UIP_CONF_IPV6_CHECKS*/ 01291 /* 01292 * Routing Header length field is in units of 8 bytes, excluding 01293 * As per RFC2460 section 4.4, if routing type is unrecognized: 01294 * if segments left = 0, ignore the header 01295 * if segments left > 0, discard packet and send icmp error pointing 01296 * to the routing type 01297 */ 01298 01299 PRINTF("Processing Routing header\n"); 01300 if(UIP_ROUTING_BUF->seg_left > 0) { 01301 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2); 01302 UIP_STAT(++uip_stat.ip.drop); 01303 UIP_LOG("ip6: unrecognized routing type"); 01304 goto send; 01305 } 01306 uip_next_hdr = &UIP_EXT_BUF->next; 01307 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; 01308 break; 01309 case UIP_PROTO_FRAG: 01310 /* Fragmentation header:call the reassembly function, then leave */ 01311 #if UIP_CONF_IPV6_REASSEMBLY 01312 PRINTF("Processing frag header\n"); 01313 uip_len = uip_reass(); 01314 if(uip_len == 0) { 01315 goto drop; 01316 } 01317 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ 01318 /* we are not done with reassembly, this is an error message */ 01319 goto send; 01320 } 01321 /*packet is reassembled, reset the next hdr to the beginning 01322 of the IP header and restart the parsing of the reassembled pkt*/ 01323 PRINTF("Processing reassembled packet\n"); 01324 uip_ext_len = 0; 01325 uip_ext_bitmap = 0; 01326 uip_next_hdr = &UIP_IP_BUF->proto; 01327 break; 01328 #else /* UIP_CONF_IPV6_REASSEMBLY */ 01329 UIP_STAT(++uip_stat.ip.drop); 01330 UIP_STAT(++uip_stat.ip.fragerr); 01331 UIP_LOG("ip: fragment dropped."); 01332 goto drop; 01333 #endif /* UIP_CONF_IPV6_REASSEMBLY */ 01334 case UIP_PROTO_NONE: 01335 goto drop; 01336 default: 01337 goto bad_hdr; 01338 } 01339 } 01340 bad_hdr: 01341 /* 01342 * RFC 2460 send error message parameterr problem, code unrecognized 01343 * next header, pointing to the next header field 01344 */ 01345 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(uip_next_hdr - (uint8_t *)UIP_IP_BUF)); 01346 UIP_STAT(++uip_stat.ip.drop); 01347 UIP_STAT(++uip_stat.ip.protoerr); 01348 UIP_LOG("ip6: unrecognized header"); 01349 goto send; 01350 /* End of headers processing */ 01351 01352 icmp6_input: 01353 /* This is IPv6 ICMPv6 processing code. */ 01354 PRINTF("icmp6_input: length %d type: %d \n", uip_len, UIP_ICMP_BUF->type); 01355 01356 #if UIP_CONF_IPV6_CHECKS 01357 /* Compute and check the ICMP header checksum */ 01358 if(uip_icmp6chksum() != 0xffff) { 01359 UIP_STAT(++uip_stat.icmp.drop); 01360 UIP_STAT(++uip_stat.icmp.chkerr); 01361 UIP_LOG("icmpv6: bad checksum."); 01362 PRINTF("icmpv6: bad checksum."); 01363 goto drop; 01364 } 01365 #endif /*UIP_CONF_IPV6_CHECKS*/ 01366 01367 UIP_STAT(++uip_stat.icmp.recv); 01368 /* 01369 * Here we process incoming ICMPv6 packets 01370 * For echo request, we send echo reply 01371 * For ND pkts, we call the appropriate function in uip-nd6.c 01372 * We do not treat Error messages for now 01373 * If no pkt is to be sent as an answer to the incoming one, we 01374 * "goto drop". Else we just break; then at the after the "switch" 01375 * we "goto send" 01376 */ 01377 #if UIP_CONF_ICMP6 01378 UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type); 01379 #endif /*UIP_CONF_ICMP6*/ 01380 01381 switch(UIP_ICMP_BUF->type) { 01382 case ICMP6_NS: 01383 uip_nd6_ns_input(); 01384 break; 01385 case ICMP6_NA: 01386 uip_nd6_na_input(); 01387 break; 01388 case ICMP6_RS: 01389 #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA 01390 uip_nd6_rs_input(); 01391 #else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ 01392 UIP_STAT(++uip_stat.icmp.drop); 01393 uip_len = 0; 01394 #endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ 01395 break; 01396 case ICMP6_RA: 01397 #if UIP_CONF_ROUTER 01398 UIP_STAT(++uip_stat.icmp.drop); 01399 uip_len = 0; 01400 #else /* UIP_CONF_ROUTER */ 01401 uip_nd6_ra_input(); 01402 #endif /* UIP_CONF_ROUTER */ 01403 break; 01404 #if UIP_CONF_IPV6_RPL 01405 case ICMP6_RPL: 01406 uip_rpl_input(); 01407 break; 01408 #endif /* UIP_CONF_IPV6_RPL */ 01409 case ICMP6_ECHO_REQUEST: 01410 uip_icmp6_echo_request_input(); 01411 break; 01412 case ICMP6_ECHO_REPLY: 01413 /** \note We don't implement any application callback for now */ 01414 PRINTF("Received an icmp6 echo reply\n"); 01415 UIP_STAT(++uip_stat.icmp.recv); 01416 uip_len = 0; 01417 break; 01418 default: 01419 PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type); 01420 UIP_STAT(++uip_stat.icmp.drop); 01421 UIP_STAT(++uip_stat.icmp.typeerr); 01422 UIP_LOG("icmp6: unknown ICMP message."); 01423 uip_len = 0; 01424 break; 01425 } 01426 01427 if(uip_len > 0) { 01428 goto send; 01429 } else { 01430 goto drop; 01431 } 01432 /* End of IPv6 ICMP processing. */ 01433 01434 01435 #if UIP_UDP 01436 /* UDP input processing. */ 01437 udp_input: 01438 01439 remove_ext_hdr(); 01440 01441 PRINTF("Receiving UDP packet\n"); 01442 UIP_STAT(++uip_stat.udp.recv); 01443 01444 /* UDP processing is really just a hack. We don't do anything to the 01445 UDP/IP headers, but let the UDP application do all the hard 01446 work. If the application sets uip_slen, it has a packet to 01447 send. */ 01448 #if UIP_UDP_CHECKSUMS 01449 uip_len = uip_len - UIP_IPUDPH_LEN; 01450 uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; 01451 if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { 01452 UIP_STAT(++uip_stat.udp.drop); 01453 UIP_STAT(++uip_stat.udp.chkerr); 01454 PRINTF("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum, 01455 uip_udpchksum()); 01456 goto drop; 01457 } 01458 #else /* UIP_UDP_CHECKSUMS */ 01459 uip_len = uip_len - UIP_IPUDPH_LEN; 01460 #endif /* UIP_UDP_CHECKSUMS */ 01461 01462 /* Make sure that the UDP destination port number is not zero. */ 01463 if(UIP_UDP_BUF->destport == 0) { 01464 PRINTF("udp: zero port.\n"); 01465 goto drop; 01466 } 01467 01468 /* Demultiplex this UDP packet between the UDP "connections". */ 01469 for(uip_udp_conn = &uip_udp_conns[0]; 01470 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; 01471 ++uip_udp_conn) { 01472 /* If the local UDP port is non-zero, the connection is considered 01473 to be used. If so, the local port number is checked against the 01474 destination port number in the received packet. If the two port 01475 numbers match, the remote port number is checked if the 01476 connection is bound to a remote port. Finally, if the 01477 connection is bound to a remote IP address, the source IP 01478 address of the packet is checked. */ 01479 if(uip_udp_conn->lport != 0 && 01480 UIP_UDP_BUF->destport == uip_udp_conn->lport && 01481 (uip_udp_conn->rport == 0 || 01482 UIP_UDP_BUF->srcport == uip_udp_conn->rport) && 01483 (uip_is_addr_unspecified(&uip_udp_conn->ripaddr) || 01484 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) { 01485 goto udp_found; 01486 } 01487 } 01488 PRINTF("udp: no matching connection found\n"); 01489 01490 #if UIP_UDP_SEND_UNREACH_NOPORT 01491 uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); 01492 UIP_STAT(++uip_stat.ip.drop); 01493 goto send; 01494 #else 01495 goto drop; 01496 #endif 01497 01498 udp_found: 01499 PRINTF("In udp_found\n"); 01500 01501 uip_conn = NULL; 01502 uip_flags = UIP_NEWDATA; 01503 uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; 01504 uip_slen = 0; 01505 UIP_UDP_APPCALL(); 01506 01507 udp_send: 01508 PRINTF("In udp_send\n"); 01509 01510 if(uip_slen == 0) { 01511 goto drop; 01512 } 01513 uip_len = uip_slen + UIP_IPUDPH_LEN; 01514 01515 /* For IPv6, the IP length field does not include the IPv6 IP header 01516 length. */ 01517 UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 01518 UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 01519 01520 UIP_IP_BUF->ttl = uip_udp_conn->ttl; 01521 UIP_IP_BUF->proto = UIP_PROTO_UDP; 01522 01523 UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN); 01524 UIP_UDP_BUF->udpchksum = 0; 01525 01526 UIP_UDP_BUF->srcport = uip_udp_conn->lport; 01527 UIP_UDP_BUF->destport = uip_udp_conn->rport; 01528 01529 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr); 01530 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); 01531 01532 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; 01533 01534 #if UIP_UDP_CHECKSUMS 01535 /* Calculate UDP checksum. */ 01536 UIP_UDP_BUF->udpchksum = ~(uip_udpchksum()); 01537 if(UIP_UDP_BUF->udpchksum == 0) { 01538 UIP_UDP_BUF->udpchksum = 0xffff; 01539 } 01540 #endif /* UIP_UDP_CHECKSUMS */ 01541 UIP_STAT(++uip_stat.udp.sent); 01542 goto ip_send_nolen; 01543 #endif /* UIP_UDP */ 01544 01545 #if UIP_TCP 01546 /* TCP input processing. */ 01547 tcp_input: 01548 01549 remove_ext_hdr(); 01550 01551 UIP_STAT(++uip_stat.tcp.recv); 01552 PRINTF("Receiving TCP packet\n"); 01553 /* Start of TCP input header processing code. */ 01554 01555 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP 01556 checksum. */ 01557 UIP_STAT(++uip_stat.tcp.drop); 01558 UIP_STAT(++uip_stat.tcp.chkerr); 01559 PRINTF("tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum, 01560 uip_tcpchksum()); 01561 goto drop; 01562 } 01563 01564 /* Make sure that the TCP port number is not zero. */ 01565 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) { 01566 PRINTF("tcp: zero port."); 01567 goto drop; 01568 } 01569 01570 /* Demultiplex this segment. */ 01571 /* First check any active connections. */ 01572 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; 01573 ++uip_connr) { 01574 if(uip_connr->tcpstateflags != UIP_CLOSED && 01575 UIP_TCP_BUF->destport == uip_connr->lport && 01576 UIP_TCP_BUF->srcport == uip_connr->rport && 01577 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) { 01578 goto found; 01579 } 01580 } 01581 01582 /* If we didn't find and active connection that expected the packet, 01583 either this packet is an old duplicate, or this is a SYN packet 01584 destined for a connection in LISTEN. If the SYN flag isn't set, 01585 it is an old packet and we send a RST. */ 01586 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) { 01587 goto reset; 01588 } 01589 01590 tmp16 = UIP_TCP_BUF->destport; 01591 /* Next, check listening connections. */ 01592 for(c = 0; c < UIP_LISTENPORTS; ++c) { 01593 if(tmp16 == uip_listenports[c]) { 01594 goto found_listen; 01595 } 01596 } 01597 01598 /* No matching connection found, so we send a RST packet. */ 01599 UIP_STAT(++uip_stat.tcp.synrst); 01600 01601 reset: 01602 PRINTF("In reset\n"); 01603 /* We do not send resets in response to resets. */ 01604 if(UIP_TCP_BUF->flags & TCP_RST) { 01605 goto drop; 01606 } 01607 01608 UIP_STAT(++uip_stat.tcp.rst); 01609 01610 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; 01611 uip_len = UIP_IPTCPH_LEN; 01612 UIP_TCP_BUF->tcpoffset = 5 << 4; 01613 01614 /* Flip the seqno and ackno fields in the TCP header. */ 01615 c = UIP_TCP_BUF->seqno[3]; 01616 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3]; 01617 UIP_TCP_BUF->ackno[3] = c; 01618 01619 c = UIP_TCP_BUF->seqno[2]; 01620 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2]; 01621 UIP_TCP_BUF->ackno[2] = c; 01622 01623 c = UIP_TCP_BUF->seqno[1]; 01624 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1]; 01625 UIP_TCP_BUF->ackno[1] = c; 01626 01627 c = UIP_TCP_BUF->seqno[0]; 01628 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0]; 01629 UIP_TCP_BUF->ackno[0] = c; 01630 01631 /* We also have to increase the sequence number we are 01632 acknowledging. If the least significant byte overflowed, we need 01633 to propagate the carry to the other bytes as well. */ 01634 if(++UIP_TCP_BUF->ackno[3] == 0) { 01635 if(++UIP_TCP_BUF->ackno[2] == 0) { 01636 if(++UIP_TCP_BUF->ackno[1] == 0) { 01637 ++UIP_TCP_BUF->ackno[0]; 01638 } 01639 } 01640 } 01641 01642 /* Swap port numbers. */ 01643 tmp16 = UIP_TCP_BUF->srcport; 01644 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport; 01645 UIP_TCP_BUF->destport = tmp16; 01646 01647 /* Swap IP addresses. */ 01648 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); 01649 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); 01650 /* And send out the RST packet! */ 01651 goto tcp_send_noconn; 01652 01653 /* This label will be jumped to if we matched the incoming packet 01654 with a connection in LISTEN. In that case, we should create a new 01655 connection and send a SYNACK in return. */ 01656 found_listen: 01657 PRINTF("In found listen\n"); 01658 /* First we check if there are any connections avaliable. Unused 01659 connections are kept in the same table as used connections, but 01660 unused ones have the tcpstate set to CLOSED. Also, connections in 01661 TIME_WAIT are kept track of and we'll use the oldest one if no 01662 CLOSED connections are found. Thanks to Eddie C. Dost for a very 01663 nice algorithm for the TIME_WAIT search. */ 01664 uip_connr = 0; 01665 for(c = 0; c < UIP_CONNS; ++c) { 01666 if(uip_conns[c].tcpstateflags == UIP_CLOSED) { 01667 uip_connr = &uip_conns[c]; 01668 break; 01669 } 01670 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { 01671 if(uip_connr == 0 || 01672 uip_conns[c].timer > uip_connr->timer) { 01673 uip_connr = &uip_conns[c]; 01674 } 01675 } 01676 } 01677 01678 if(uip_connr == 0) { 01679 /* All connections are used already, we drop packet and hope that 01680 the remote end will retransmit the packet at a time when we 01681 have more spare connections. */ 01682 UIP_STAT(++uip_stat.tcp.syndrop); 01683 UIP_LOG("tcp: found no unused connections."); 01684 goto drop; 01685 } 01686 uip_conn = uip_connr; 01687 01688 /* Fill in the necessary fields for the new connection. */ 01689 uip_connr->rto = uip_connr->timer = UIP_RTO; 01690 uip_connr->sa = 0; 01691 uip_connr->sv = 4; 01692 uip_connr->nrtx = 0; 01693 uip_connr->lport = UIP_TCP_BUF->destport; 01694 uip_connr->rport = UIP_TCP_BUF->srcport; 01695 uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr); 01696 uip_connr->tcpstateflags = UIP_SYN_RCVD; 01697 01698 uip_connr->snd_nxt[0] = iss[0]; 01699 uip_connr->snd_nxt[1] = iss[1]; 01700 uip_connr->snd_nxt[2] = iss[2]; 01701 uip_connr->snd_nxt[3] = iss[3]; 01702 uip_connr->len = 1; 01703 01704 /* rcv_nxt should be the seqno from the incoming packet + 1. */ 01705 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; 01706 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; 01707 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; 01708 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; 01709 uip_add_rcv_nxt(1); 01710 01711 /* Parse the TCP MSS option, if present. */ 01712 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { 01713 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { 01714 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; 01715 if(opt == TCP_OPT_END) { 01716 /* End of options. */ 01717 break; 01718 } else if(opt == TCP_OPT_NOOP) { 01719 ++c; 01720 /* NOP option. */ 01721 } else if(opt == TCP_OPT_MSS && 01722 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { 01723 /* An MSS option with the right option length. */ 01724 tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | 01725 (uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; 01726 uip_connr->initialmss = uip_connr->mss = 01727 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; 01728 01729 /* And we are done processing options. */ 01730 break; 01731 } else { 01732 /* All other options have a length field, so that we easily 01733 can skip past them. */ 01734 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { 01735 /* If the length field is zero, the options are malformed 01736 and we don't process them further. */ 01737 break; 01738 } 01739 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; 01740 } 01741 } 01742 } 01743 01744 /* Our response will be a SYNACK. */ 01745 #if UIP_ACTIVE_OPEN 01746 tcp_send_synack: 01747 UIP_TCP_BUF->flags = TCP_ACK; 01748 01749 tcp_send_syn: 01750 UIP_TCP_BUF->flags |= TCP_SYN; 01751 #else /* UIP_ACTIVE_OPEN */ 01752 tcp_send_synack: 01753 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK; 01754 #endif /* UIP_ACTIVE_OPEN */ 01755 01756 /* We send out the TCP Maximum Segment Size option with our 01757 SYNACK. */ 01758 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS; 01759 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN; 01760 UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256; 01761 UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255; 01762 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; 01763 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; 01764 goto tcp_send; 01765 01766 /* This label will be jumped to if we found an active connection. */ 01767 found: 01768 PRINTF("In found\n"); 01769 uip_conn = uip_connr; 01770 uip_flags = 0; 01771 /* We do a very naive form of TCP reset processing; we just accept 01772 any RST and kill our connection. We should in fact check if the 01773 sequence number of this reset is wihtin our advertised window 01774 before we accept the reset. */ 01775 if(UIP_TCP_BUF->flags & TCP_RST) { 01776 uip_connr->tcpstateflags = UIP_CLOSED; 01777 UIP_LOG("tcp: got reset, aborting connection."); 01778 uip_flags = UIP_ABORT; 01779 UIP_APPCALL(); 01780 goto drop; 01781 } 01782 /* Calculate the length of the data, if the application has sent 01783 any data to us. */ 01784 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2; 01785 /* uip_len will contain the length of the actual TCP data. This is 01786 calculated by subtracing the length of the TCP header (in 01787 c) and the length of the IP header (20 bytes). */ 01788 uip_len = uip_len - c - UIP_IPH_LEN; 01789 01790 /* First, check if the sequence number of the incoming packet is 01791 what we're expecting next. If not, we send out an ACK with the 01792 correct numbers in, unless we are in the SYN_RCVD state and 01793 receive a SYN, in which case we should retransmit our SYNACK 01794 (which is done futher down). */ 01795 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && 01796 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || 01797 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) && 01798 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) { 01799 if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && 01800 (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] || 01801 UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] || 01802 UIP_TCP_BUF->seqno[2] != uip_connr->rcv_nxt[2] || 01803 UIP_TCP_BUF->seqno[3] != uip_connr->rcv_nxt[3])) { 01804 01805 if(UIP_TCP_BUF->flags & TCP_SYN) { 01806 goto tcp_send_synack; 01807 } 01808 goto tcp_send_ack; 01809 } 01810 } 01811 01812 /* Next, check if the incoming segment acknowledges any outstanding 01813 data. If so, we update the sequence number, reset the length of 01814 the outstanding data, calculate RTT estimations, and reset the 01815 retransmission timer. */ 01816 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { 01817 uip_add32(uip_connr->snd_nxt, uip_connr->len); 01818 01819 if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] && 01820 UIP_TCP_BUF->ackno[1] == uip_acc32[1] && 01821 UIP_TCP_BUF->ackno[2] == uip_acc32[2] && 01822 UIP_TCP_BUF->ackno[3] == uip_acc32[3]) { 01823 /* Update sequence number. */ 01824 uip_connr->snd_nxt[0] = uip_acc32[0]; 01825 uip_connr->snd_nxt[1] = uip_acc32[1]; 01826 uip_connr->snd_nxt[2] = uip_acc32[2]; 01827 uip_connr->snd_nxt[3] = uip_acc32[3]; 01828 01829 /* Do RTT estimation, unless we have done retransmissions. */ 01830 if(uip_connr->nrtx == 0) { 01831 signed char m; 01832 m = uip_connr->rto - uip_connr->timer; 01833 /* This is taken directly from VJs original code in his paper */ 01834 m = m - (uip_connr->sa >> 3); 01835 uip_connr->sa += m; 01836 if(m < 0) { 01837 m = -m; 01838 } 01839 m = m - (uip_connr->sv >> 2); 01840 uip_connr->sv += m; 01841 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; 01842 01843 } 01844 /* Set the acknowledged flag. */ 01845 uip_flags = UIP_ACKDATA; 01846 /* Reset the retransmission timer. */ 01847 uip_connr->timer = uip_connr->rto; 01848 01849 /* Reset length of outstanding data. */ 01850 uip_connr->len = 0; 01851 } 01852 01853 } 01854 01855 /* Do different things depending on in what state the connection is. */ 01856 switch(uip_connr->tcpstateflags & UIP_TS_MASK) { 01857 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not 01858 implemented, since we force the application to close when the 01859 peer sends a FIN (hence the application goes directly from 01860 ESTABLISHED to LAST_ACK). */ 01861 case UIP_SYN_RCVD: 01862 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and 01863 we are waiting for an ACK that acknowledges the data we sent 01864 out the last time. Therefore, we want to have the UIP_ACKDATA 01865 flag set. If so, we enter the ESTABLISHED state. */ 01866 if(uip_flags & UIP_ACKDATA) { 01867 uip_connr->tcpstateflags = UIP_ESTABLISHED; 01868 uip_flags = UIP_CONNECTED; 01869 uip_connr->len = 0; 01870 if(uip_len > 0) { 01871 uip_flags |= UIP_NEWDATA; 01872 uip_add_rcv_nxt(uip_len); 01873 } 01874 uip_slen = 0; 01875 UIP_APPCALL(); 01876 goto appsend; 01877 } 01878 /* We need to retransmit the SYNACK */ 01879 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) { 01880 goto tcp_send_synack; 01881 } 01882 goto drop; 01883 #if UIP_ACTIVE_OPEN 01884 case UIP_SYN_SENT: 01885 /* In SYN_SENT, we wait for a SYNACK that is sent in response to 01886 our SYN. The rcv_nxt is set to sequence number in the SYNACK 01887 plus one, and we send an ACK. We move into the ESTABLISHED 01888 state. */ 01889 if((uip_flags & UIP_ACKDATA) && 01890 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { 01891 01892 /* Parse the TCP MSS option, if present. */ 01893 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { 01894 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { 01895 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; 01896 if(opt == TCP_OPT_END) { 01897 /* End of options. */ 01898 break; 01899 } else if(opt == TCP_OPT_NOOP) { 01900 ++c; 01901 /* NOP option. */ 01902 } else if(opt == TCP_OPT_MSS && 01903 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { 01904 /* An MSS option with the right option length. */ 01905 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | 01906 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; 01907 uip_connr->initialmss = 01908 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; 01909 01910 /* And we are done processing options. */ 01911 break; 01912 } else { 01913 /* All other options have a length field, so that we easily 01914 can skip past them. */ 01915 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { 01916 /* If the length field is zero, the options are malformed 01917 and we don't process them further. */ 01918 break; 01919 } 01920 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; 01921 } 01922 } 01923 } 01924 uip_connr->tcpstateflags = UIP_ESTABLISHED; 01925 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; 01926 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; 01927 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; 01928 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; 01929 uip_add_rcv_nxt(1); 01930 uip_flags = UIP_CONNECTED | UIP_NEWDATA; 01931 uip_connr->len = 0; 01932 uip_len = 0; 01933 uip_slen = 0; 01934 UIP_APPCALL(); 01935 goto appsend; 01936 } 01937 /* Inform the application that the connection failed */ 01938 uip_flags = UIP_ABORT; 01939 UIP_APPCALL(); 01940 /* The connection is closed after we send the RST */ 01941 uip_conn->tcpstateflags = UIP_CLOSED; 01942 goto reset; 01943 #endif /* UIP_ACTIVE_OPEN */ 01944 01945 case UIP_ESTABLISHED: 01946 /* In the ESTABLISHED state, we call upon the application to feed 01947 data into the uip_buf. If the UIP_ACKDATA flag is set, the 01948 application should put new data into the buffer, otherwise we are 01949 retransmitting an old segment, and the application should put that 01950 data into the buffer. 01951 01952 If the incoming packet is a FIN, we should close the connection on 01953 this side as well, and we send out a FIN and enter the LAST_ACK 01954 state. We require that there is no outstanding data; otherwise the 01955 sequence numbers will be screwed up. */ 01956 01957 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { 01958 if(uip_outstanding(uip_connr)) { 01959 goto drop; 01960 } 01961 uip_add_rcv_nxt(1 + uip_len); 01962 uip_flags |= UIP_CLOSE; 01963 if(uip_len > 0) { 01964 uip_flags |= UIP_NEWDATA; 01965 } 01966 UIP_APPCALL(); 01967 uip_connr->len = 1; 01968 uip_connr->tcpstateflags = UIP_LAST_ACK; 01969 uip_connr->nrtx = 0; 01970 tcp_send_finack: 01971 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; 01972 goto tcp_send_nodata; 01973 } 01974 01975 /* Check the URG flag. If this is set, the segment carries urgent 01976 data that we must pass to the application. */ 01977 if((UIP_TCP_BUF->flags & TCP_URG) != 0) { 01978 #if UIP_URGDATA > 0 01979 uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; 01980 if(uip_urglen > uip_len) { 01981 /* There is more urgent data in the next segment to come. */ 01982 uip_urglen = uip_len; 01983 } 01984 uip_add_rcv_nxt(uip_urglen); 01985 uip_len -= uip_urglen; 01986 uip_urgdata = uip_appdata; 01987 uip_appdata += uip_urglen; 01988 } else { 01989 uip_urglen = 0; 01990 #else /* UIP_URGDATA > 0 */ 01991 uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]); 01992 uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; 01993 #endif /* UIP_URGDATA > 0 */ 01994 } 01995 01996 /* If uip_len > 0 we have TCP data in the packet, and we flag this 01997 by setting the UIP_NEWDATA flag and update the sequence number 01998 we acknowledge. If the application has stopped the dataflow 01999 using uip_stop(), we must not accept any data packets from the 02000 remote host. */ 02001 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { 02002 uip_flags |= UIP_NEWDATA; 02003 uip_add_rcv_nxt(uip_len); 02004 } 02005 02006 /* Check if the available buffer space advertised by the other end 02007 is smaller than the initial MSS for this connection. If so, we 02008 set the current MSS to the window size to ensure that the 02009 application does not send more data than the other end can 02010 handle. 02011 02012 If the remote host advertises a zero window, we set the MSS to 02013 the initial MSS so that the application will send an entire MSS 02014 of data. This data will not be acknowledged by the receiver, 02015 and the application will retransmit it. This is called the 02016 "persistent timer" and uses the retransmission mechanim. 02017 */ 02018 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1]; 02019 if(tmp16 > uip_connr->initialmss || 02020 tmp16 == 0) { 02021 tmp16 = uip_connr->initialmss; 02022 } 02023 uip_connr->mss = tmp16; 02024 02025 /* If this packet constitutes an ACK for outstanding data (flagged 02026 by the UIP_ACKDATA flag, we should call the application since it 02027 might want to send more data. If the incoming packet had data 02028 from the peer (as flagged by the UIP_NEWDATA flag), the 02029 application must also be notified. 02030 02031 When the application is called, the global variable uip_len 02032 contains the length of the incoming data. The application can 02033 access the incoming data through the global pointer 02034 uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN 02035 bytes into the uip_buf array. 02036 02037 If the application wishes to send any data, this data should be 02038 put into the uip_appdata and the length of the data should be 02039 put into uip_len. If the application don't have any data to 02040 send, uip_len must be set to 0. */ 02041 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { 02042 uip_slen = 0; 02043 UIP_APPCALL(); 02044 02045 appsend: 02046 02047 if(uip_flags & UIP_ABORT) { 02048 uip_slen = 0; 02049 uip_connr->tcpstateflags = UIP_CLOSED; 02050 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; 02051 goto tcp_send_nodata; 02052 } 02053 02054 if(uip_flags & UIP_CLOSE) { 02055 uip_slen = 0; 02056 uip_connr->len = 1; 02057 uip_connr->tcpstateflags = UIP_FIN_WAIT_1; 02058 uip_connr->nrtx = 0; 02059 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; 02060 goto tcp_send_nodata; 02061 } 02062 02063 /* If uip_slen > 0, the application has data to be sent. */ 02064 if(uip_slen > 0) { 02065 02066 /* If the connection has acknowledged data, the contents of 02067 the ->len variable should be discarded. */ 02068 if((uip_flags & UIP_ACKDATA) != 0) { 02069 uip_connr->len = 0; 02070 } 02071 02072 /* If the ->len variable is non-zero the connection has 02073 already data in transit and cannot send anymore right 02074 now. */ 02075 if(uip_connr->len == 0) { 02076 02077 /* The application cannot send more than what is allowed by 02078 the mss (the minumum of the MSS and the available 02079 window). */ 02080 if(uip_slen > uip_connr->mss) { 02081 uip_slen = uip_connr->mss; 02082 } 02083 02084 /* Remember how much data we send out now so that we know 02085 when everything has been acknowledged. */ 02086 uip_connr->len = uip_slen; 02087 } else { 02088 02089 /* If the application already had unacknowledged data, we 02090 make sure that the application does not send (i.e., 02091 retransmit) out more than it previously sent out. */ 02092 uip_slen = uip_connr->len; 02093 } 02094 } 02095 uip_connr->nrtx = 0; 02096 apprexmit: 02097 uip_appdata = uip_sappdata; 02098 02099 /* If the application has data to be sent, or if the incoming 02100 packet had new data in it, we must send out a packet. */ 02101 if(uip_slen > 0 && uip_connr->len > 0) { 02102 /* Add the length of the IP and TCP headers. */ 02103 uip_len = uip_connr->len + UIP_TCPIP_HLEN; 02104 /* We always set the ACK flag in response packets. */ 02105 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH; 02106 /* Send the packet. */ 02107 goto tcp_send_noopts; 02108 } 02109 /* If there is no data to send, just send out a pure ACK if 02110 there is newdata. */ 02111 if(uip_flags & UIP_NEWDATA) { 02112 uip_len = UIP_TCPIP_HLEN; 02113 UIP_TCP_BUF->flags = TCP_ACK; 02114 goto tcp_send_noopts; 02115 } 02116 } 02117 goto drop; 02118 case UIP_LAST_ACK: 02119 /* We can close this connection if the peer has acknowledged our 02120 FIN. This is indicated by the UIP_ACKDATA flag. */ 02121 if(uip_flags & UIP_ACKDATA) { 02122 uip_connr->tcpstateflags = UIP_CLOSED; 02123 uip_flags = UIP_CLOSE; 02124 UIP_APPCALL(); 02125 } 02126 break; 02127 02128 case UIP_FIN_WAIT_1: 02129 /* The application has closed the connection, but the remote host 02130 hasn't closed its end yet. Thus we do nothing but wait for a 02131 FIN from the other side. */ 02132 if(uip_len > 0) { 02133 uip_add_rcv_nxt(uip_len); 02134 } 02135 if(UIP_TCP_BUF->flags & TCP_FIN) { 02136 if(uip_flags & UIP_ACKDATA) { 02137 uip_connr->tcpstateflags = UIP_TIME_WAIT; 02138 uip_connr->timer = 0; 02139 uip_connr->len = 0; 02140 } else { 02141 uip_connr->tcpstateflags = UIP_CLOSING; 02142 } 02143 uip_add_rcv_nxt(1); 02144 uip_flags = UIP_CLOSE; 02145 UIP_APPCALL(); 02146 goto tcp_send_ack; 02147 } else if(uip_flags & UIP_ACKDATA) { 02148 uip_connr->tcpstateflags = UIP_FIN_WAIT_2; 02149 uip_connr->len = 0; 02150 goto drop; 02151 } 02152 if(uip_len > 0) { 02153 goto tcp_send_ack; 02154 } 02155 goto drop; 02156 02157 case UIP_FIN_WAIT_2: 02158 if(uip_len > 0) { 02159 uip_add_rcv_nxt(uip_len); 02160 } 02161 if(UIP_TCP_BUF->flags & TCP_FIN) { 02162 uip_connr->tcpstateflags = UIP_TIME_WAIT; 02163 uip_connr->timer = 0; 02164 uip_add_rcv_nxt(1); 02165 uip_flags = UIP_CLOSE; 02166 UIP_APPCALL(); 02167 goto tcp_send_ack; 02168 } 02169 if(uip_len > 0) { 02170 goto tcp_send_ack; 02171 } 02172 goto drop; 02173 02174 case UIP_TIME_WAIT: 02175 goto tcp_send_ack; 02176 02177 case UIP_CLOSING: 02178 if(uip_flags & UIP_ACKDATA) { 02179 uip_connr->tcpstateflags = UIP_TIME_WAIT; 02180 uip_connr->timer = 0; 02181 } 02182 } 02183 goto drop; 02184 02185 /* We jump here when we are ready to send the packet, and just want 02186 to set the appropriate TCP sequence numbers in the TCP header. */ 02187 tcp_send_ack: 02188 UIP_TCP_BUF->flags = TCP_ACK; 02189 02190 tcp_send_nodata: 02191 uip_len = UIP_IPTCPH_LEN; 02192 02193 tcp_send_noopts: 02194 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; 02195 02196 /* We're done with the input processing. We are now ready to send a 02197 reply. Our job is to fill in all the fields of the TCP and IP 02198 headers before calculating the checksum and finally send the 02199 packet. */ 02200 tcp_send: 02201 PRINTF("In tcp_send\n"); 02202 02203 UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0]; 02204 UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1]; 02205 UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2]; 02206 UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3]; 02207 02208 UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0]; 02209 UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1]; 02210 UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2]; 02211 UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3]; 02212 02213 UIP_IP_BUF->proto = UIP_PROTO_TCP; 02214 02215 UIP_TCP_BUF->srcport = uip_connr->lport; 02216 UIP_TCP_BUF->destport = uip_connr->rport; 02217 02218 02219 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr); 02220 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr); 02221 PRINTF("Sending TCP packet to"); 02222 PRINT6ADDR(&UIP_IP_BUF->destipaddr); 02223 PRINTF("from"); 02224 PRINT6ADDR(&UIP_IP_BUF->srcipaddr); 02225 PRINTF("\n"); 02226 02227 if(uip_connr->tcpstateflags & UIP_STOPPED) { 02228 /* If the connection has issued uip_stop(), we advertise a zero 02229 window so that the remote host will stop sending data. */ 02230 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0; 02231 } else { 02232 UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); 02233 UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); 02234 } 02235 02236 tcp_send_noconn: 02237 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; 02238 UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 02239 UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 02240 02241 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0; 02242 02243 /* Calculate TCP checksum. */ 02244 UIP_TCP_BUF->tcpchksum = 0; 02245 UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum()); 02246 UIP_STAT(++uip_stat.tcp.sent); 02247 02248 #endif /* UIP_TCP */ 02249 #if UIP_UDP 02250 ip_send_nolen: 02251 #endif 02252 UIP_IP_BUF->vtc = 0x60; 02253 UIP_IP_BUF->tcflow = 0x00; 02254 UIP_IP_BUF->flow = 0x00; 02255 send: 02256 PRINTF("Sending packet with length %d (%d)\n", uip_len, 02257 (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); 02258 02259 UIP_STAT(++uip_stat.ip.sent); 02260 /* Return and let the caller do the actual transmission. */ 02261 uip_flags = 0; 02262 return; 02263 02264 drop: 02265 uip_len = 0; 02266 uip_ext_len = 0; 02267 uip_ext_bitmap = 0; 02268 uip_flags = 0; 02269 return; 02270 } 02271 /*---------------------------------------------------------------------------*/ 02272 uint16_t 02273 uip_htons(uint16_t val) 02274 { 02275 return UIP_HTONS(val); 02276 } 02277 02278 uint32_t 02279 uip_htonl(uint32_t val) 02280 { 02281 return UIP_HTONL(val); 02282 } 02283 /*---------------------------------------------------------------------------*/ 02284 void 02285 uip_send(const void *data, int len) 02286 { 02287 int copylen; 02288 #define MIN(a,b) ((a) < (b)? (a): (b)) 02289 copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - 02290 (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); 02291 if(copylen > 0) { 02292 uip_slen = copylen; 02293 if(data != uip_sappdata) { 02294 memcpy(uip_sappdata, (data), uip_slen); 02295 } 02296 } 02297 } 02298 /*---------------------------------------------------------------------------*/ 02299 /** @} */