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