00001 #define DEBUG_PRINTF(...)
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #include "uip.h"
00083 #include "uipopt.h"
00084 #include "uip_arch.h"
00085
00086 #if UIP_CONF_IPV6
00087 #include "uip-neighbor.h"
00088 #endif
00089
00090 #include <string.h>
00091
00092
00093
00094
00095
00096
00097
00098
00099 #if UIP_FIXEDADDR > 0
00100 const uip_ipaddr_t uip_hostaddr =
00101 {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
00102 HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
00103 const uip_ipaddr_t uip_draddr =
00104 {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
00105 HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
00106 const uip_ipaddr_t uip_netmask =
00107 {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
00108 HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
00109 #else
00110 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
00111 #endif
00112
00113 static const uip_ipaddr_t all_ones_addr =
00114 #if UIP_CONF_IPV6
00115 {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
00116 #else
00117 {0xffff,0xffff};
00118 #endif
00119 static const uip_ipaddr_t all_zeroes_addr =
00120 #if UIP_CONF_IPV6
00121 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
00122 #else
00123 {0x0000,0x0000};
00124 #endif
00125
00126
00127 #if UIP_FIXEDETHADDR
00128 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
00129 UIP_ETHADDR1,
00130 UIP_ETHADDR2,
00131 UIP_ETHADDR3,
00132 UIP_ETHADDR4,
00133 UIP_ETHADDR5}};
00134 #else
00135 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
00136 #endif
00137
00138 #ifndef UIP_CONF_EXTERNAL_BUFFER
00139 u8_t uip_buf[UIP_BUFSIZE + 2];
00140
00141 #endif
00142
00143 void *uip_appdata;
00144
00145 void *uip_sappdata;
00146
00147
00148 #if UIP_URGDATA > 0
00149 void *uip_urgdata;
00150
00151
00152 u16_t uip_urglen, uip_surglen;
00153 #endif
00154
00155 u16_t uip_len, uip_slen;
00156
00157
00158
00159
00160 u8_t uip_flags;
00161
00162
00163 struct uip_conn *uip_conn;
00164
00165
00166 struct uip_conn uip_conns[UIP_CONNS];
00167
00168
00169 u16_t uip_listenports[UIP_LISTENPORTS];
00170
00171
00172 #if UIP_UDP
00173 struct uip_udp_conn *uip_udp_conn;
00174 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00175 #endif
00176
00177 static u16_t ipid;
00178
00179
00180
00181 void uip_setipid(u16_t id) { ipid = id; }
00182
00183 static u8_t iss[4];
00184
00185
00186 #if UIP_ACTIVE_OPEN
00187 static u16_t lastport;
00188
00189 #endif
00190
00191
00192 u8_t uip_acc32[4];
00193 static u8_t c, opt;
00194 static u16_t tmp16;
00195
00196
00197 #define TCP_FIN 0x01
00198 #define TCP_SYN 0x02
00199 #define TCP_RST 0x04
00200 #define TCP_PSH 0x08
00201 #define TCP_ACK 0x10
00202 #define TCP_URG 0x20
00203 #define TCP_CTL 0x3f
00204
00205 #define TCP_OPT_END 0
00206 #define TCP_OPT_NOOP 1
00207 #define TCP_OPT_MSS 2
00208
00209 #define TCP_OPT_MSS_LEN 4
00210
00211 #define ICMP_ECHO_REPLY 0
00212 #define ICMP_ECHO 8
00213
00214 #define ICMP6_ECHO_REPLY 129
00215 #define ICMP6_ECHO 128
00216 #define ICMP6_NEIGHBOR_SOLICITATION 135
00217 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
00218
00219 #define ICMP6_FLAG_S (1 << 6)
00220
00221 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
00222 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
00223
00224
00225
00226 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00227 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
00228 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
00229 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
00230
00231
00232 #if UIP_STATISTICS == 1
00233 struct uip_stats uip_stat;
00234 #define UIP_STAT(s) s
00235 #else
00236 #define UIP_STAT(s)
00237 #endif
00238
00239 #if UIP_LOGGING == 1
00240 #include <stdio.h>
00241 void uip_log(char *msg);
00242 #define UIP_LOG(m) uip_log(m)
00243 #else
00244 #define UIP_LOG(m)
00245 #endif
00246
00247 #if ! UIP_ARCH_ADD32
00248 void
00249 uip_add32(u8_t *op32, u16_t op16)
00250 {
00251 uip_acc32[3] = op32[3] + (op16 & 0xff);
00252 uip_acc32[2] = op32[2] + (op16 >> 8);
00253 uip_acc32[1] = op32[1];
00254 uip_acc32[0] = op32[0];
00255
00256 if(uip_acc32[2] < (op16 >> 8)) {
00257 ++uip_acc32[1];
00258 if(uip_acc32[1] == 0) {
00259 ++uip_acc32[0];
00260 }
00261 }
00262
00263
00264 if(uip_acc32[3] < (op16 & 0xff)) {
00265 ++uip_acc32[2];
00266 if(uip_acc32[2] == 0) {
00267 ++uip_acc32[1];
00268 if(uip_acc32[1] == 0) {
00269 ++uip_acc32[0];
00270 }
00271 }
00272 }
00273 }
00274
00275 #endif
00276
00277 #if ! UIP_ARCH_CHKSUM
00278
00279 static u16_t
00280 chksum(u16_t sum, const u8_t *data, u16_t len)
00281 {
00282 u16_t t;
00283 const u8_t *dataptr;
00284 const u8_t *last_byte;
00285
00286 dataptr = data;
00287 last_byte = data + len - 1;
00288
00289 while(dataptr < last_byte) {
00290 t = (dataptr[0] << 8) + dataptr[1];
00291 sum += t;
00292 if(sum < t) {
00293 sum++;
00294 }
00295 dataptr += 2;
00296 }
00297
00298 if(dataptr == last_byte) {
00299 t = (dataptr[0] << 8) + 0;
00300 sum += t;
00301 if(sum < t) {
00302 sum++;
00303 }
00304 }
00305
00306
00307 return sum;
00308 }
00309
00310 u16_t
00311 uip_chksum(u16_t *data, u16_t len)
00312 {
00313 return htons(chksum(0, (u8_t *)data, len));
00314 }
00315
00316 #ifndef UIP_ARCH_IPCHKSUM
00317 u16_t
00318 uip_ipchksum(void)
00319 {
00320 u16_t sum;
00321
00322 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
00323 DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
00324 return (sum == 0) ? 0xffff : htons(sum);
00325 }
00326 #endif
00327
00328 static u16_t
00329 upper_layer_chksum(u8_t proto)
00330 {
00331 u16_t upper_layer_len;
00332 u16_t sum;
00333
00334 #if UIP_CONF_IPV6
00335 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
00336 #else
00337 upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
00338 #endif
00339
00340
00341
00342
00343 sum = upper_layer_len + proto;
00344
00345 sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
00346
00347
00348 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
00349 upper_layer_len);
00350
00351 return (sum == 0) ? 0xffff : htons(sum);
00352 }
00353
00354 #if UIP_CONF_IPV6
00355 u16_t
00356 uip_icmp6chksum(void)
00357 {
00358 return upper_layer_chksum(UIP_PROTO_ICMP6);
00359
00360 }
00361 #endif
00362
00363 u16_t
00364 uip_tcpchksum(void)
00365 {
00366 return upper_layer_chksum(UIP_PROTO_TCP);
00367 }
00368
00369 #if UIP_UDP_CHECKSUMS
00370 u16_t
00371 uip_udpchksum(void)
00372 {
00373 return upper_layer_chksum(UIP_PROTO_UDP);
00374 }
00375 #endif
00376 #endif
00377
00378 void
00379 uip_init(void)
00380 {
00381 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00382 uip_listenports[c] = 0;
00383 }
00384 for(c = 0; c < UIP_CONNS; ++c) {
00385 uip_conns[c].tcpstateflags = UIP_CLOSED;
00386 }
00387 #if UIP_ACTIVE_OPEN
00388 lastport = 1024;
00389 #endif
00390
00391 #if UIP_UDP
00392 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00393 uip_udp_conns[c].lport = 0;
00394 }
00395 #endif
00396
00397
00398
00399 #if UIP_FIXEDADDR == 0
00400
00401 #endif
00402
00403 }
00404
00405 #if UIP_ACTIVE_OPEN
00406 struct uip_conn *
00407 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
00408 {
00409 register struct uip_conn *conn, *cconn;
00410
00411
00412 again:
00413 ++lastport;
00414
00415 if(lastport >= 32000) {
00416 lastport = 4096;
00417 }
00418
00419
00420
00421 for(c = 0; c < UIP_CONNS; ++c) {
00422 conn = &uip_conns[c];
00423 if(conn->tcpstateflags != UIP_CLOSED &&
00424 conn->lport == htons(lastport)) {
00425 goto again;
00426 }
00427 }
00428
00429 conn = 0;
00430 for(c = 0; c < UIP_CONNS; ++c) {
00431 cconn = &uip_conns[c];
00432 if(cconn->tcpstateflags == UIP_CLOSED) {
00433 conn = cconn;
00434 break;
00435 }
00436 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
00437 if(conn == 0 ||
00438 cconn->timer > conn->timer) {
00439 conn = cconn;
00440 }
00441 }
00442 }
00443
00444 if(conn == 0) {
00445 return 0;
00446 }
00447
00448 conn->tcpstateflags = UIP_SYN_SENT;
00449
00450 conn->snd_nxt[0] = iss[0];
00451 conn->snd_nxt[1] = iss[1];
00452 conn->snd_nxt[2] = iss[2];
00453 conn->snd_nxt[3] = iss[3];
00454
00455 conn->initialmss = conn->mss = UIP_TCP_MSS;
00456
00457 conn->len = 1;
00458 conn->nrtx = 0;
00459 conn->timer = 1;
00460 conn->rto = UIP_RTO;
00461 conn->sa = 0;
00462 conn->sv = 16;
00463 conn->lport = htons(lastport);
00464 conn->rport = rport;
00465 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00466
00467 return conn;
00468 }
00469 #endif
00470
00471 #if UIP_UDP
00472 struct uip_udp_conn *
00473 uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
00474 {
00475 register struct uip_udp_conn *conn;
00476
00477
00478 again:
00479 ++lastport;
00480
00481 if(lastport >= 32000) {
00482 lastport = 4096;
00483 }
00484
00485 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00486 if(uip_udp_conns[c].lport == htons(lastport)) {
00487 goto again;
00488 }
00489 }
00490
00491
00492 conn = 0;
00493 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00494 if(uip_udp_conns[c].lport == 0) {
00495 conn = &uip_udp_conns[c];
00496 break;
00497 }
00498 }
00499
00500 if(conn == 0) {
00501 return 0;
00502 }
00503
00504 conn->lport = HTONS(lastport);
00505 conn->rport = rport;
00506 if(ripaddr == NULL) {
00507 memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
00508 } else {
00509 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00510 }
00511 conn->ttl = UIP_TTL;
00512
00513 return conn;
00514 }
00515 #endif
00516
00517 void
00518 uip_unlisten(u16_t port)
00519 {
00520 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00521 if(uip_listenports[c] == port) {
00522 uip_listenports[c] = 0;
00523 return;
00524 }
00525 }
00526 }
00527
00528 void
00529 uip_listen(u16_t port)
00530 {
00531 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00532 if(uip_listenports[c] == 0) {
00533 uip_listenports[c] = port;
00534 return;
00535 }
00536 }
00537 }
00538
00539
00540
00541 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
00542 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
00543 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
00544 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
00545 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
00546 0x0f, 0x07, 0x03, 0x01};
00547 static u16_t uip_reasslen;
00548 static u8_t uip_reassflags;
00549 #define UIP_REASS_FLAG_LASTFRAG 0x01
00550 static u8_t uip_reasstmr;
00551
00552 #define IP_MF 0x20
00553
00554 static u8_t
00555 uip_reass(void)
00556 {
00557 u16_t offset, len;
00558 u16_t i;
00559
00560
00561
00562
00563 if(uip_reasstmr == 0) {
00564 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
00565 uip_reasstmr = UIP_REASS_MAXAGE;
00566 uip_reassflags = 0;
00567
00568 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
00569 }
00570
00571
00572
00573
00574 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
00575 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
00576 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
00577 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
00578 BUF->ipid[0] == FBUF->ipid[0] &&
00579 BUF->ipid[1] == FBUF->ipid[1]) {
00580
00581 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
00582 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
00583
00584
00585
00586 if(offset > UIP_REASS_BUFSIZE ||
00587 offset + len > UIP_REASS_BUFSIZE) {
00588 uip_reasstmr = 0;
00589 goto nullreturn;
00590 }
00591
00592
00593
00594 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
00595 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
00596 len);
00597
00598
00599 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
00600
00601
00602
00603 uip_reassbitmap[offset / (8 * 8)] |=
00604 bitmap_bits[(offset / 8 ) & 7] &
00605 ~bitmap_bits[((offset + len) / 8 ) & 7];
00606 } else {
00607
00608
00609
00610 uip_reassbitmap[offset / (8 * 8)] |=
00611 bitmap_bits[(offset / 8 ) & 7];
00612 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
00613 uip_reassbitmap[i] = 0xff;
00614 }
00615 uip_reassbitmap[(offset + len) / (8 * 8)] |=
00616 ~bitmap_bits[((offset + len) / 8 ) & 7];
00617 }
00618
00619
00620
00621
00622
00623
00624
00625 if((BUF->ipoffset[0] & IP_MF) == 0) {
00626 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
00627 uip_reasslen = offset + len;
00628 }
00629
00630
00631
00632
00633 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
00634
00635
00636 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
00637 if(uip_reassbitmap[i] != 0xff) {
00638 goto nullreturn;
00639 }
00640 }
00641
00642
00643 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
00644 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
00645 goto nullreturn;
00646 }
00647
00648
00649
00650
00651 uip_reasstmr = 0;
00652 memcpy(BUF, FBUF, uip_reasslen);
00653
00654
00655
00656 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
00657 BUF->len[0] = uip_reasslen >> 8;
00658 BUF->len[1] = uip_reasslen & 0xff;
00659 BUF->ipchksum = 0;
00660 BUF->ipchksum = ~(uip_ipchksum());
00661
00662 return uip_reasslen;
00663 }
00664 }
00665
00666 nullreturn:
00667 return 0;
00668 }
00669 #endif
00670
00671 static void
00672 uip_add_rcv_nxt(u16_t n)
00673 {
00674 uip_add32(uip_conn->rcv_nxt, n);
00675 uip_conn->rcv_nxt[0] = uip_acc32[0];
00676 uip_conn->rcv_nxt[1] = uip_acc32[1];
00677 uip_conn->rcv_nxt[2] = uip_acc32[2];
00678 uip_conn->rcv_nxt[3] = uip_acc32[3];
00679 }
00680
00681 void
00682 uip_process(u8_t flag)
00683 {
00684 register struct uip_conn *uip_connr = uip_conn;
00685
00686 #if UIP_UDP
00687 if(flag == UIP_UDP_SEND_CONN) {
00688 goto udp_send;
00689 }
00690 #endif
00691
00692 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
00693
00694
00695
00696 if(flag == UIP_POLL_REQUEST) {
00697 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
00698 !uip_outstanding(uip_connr)) {
00699 uip_flags = UIP_POLL;
00700 UIP_APPCALL();
00701 goto appsend;
00702 }
00703 goto drop;
00704
00705
00706 } else if(flag == UIP_TIMER) {
00707 #if UIP_REASSEMBLY
00708 if(uip_reasstmr != 0) {
00709 --uip_reasstmr;
00710 }
00711 #endif
00712
00713 if(++iss[3] == 0) {
00714 if(++iss[2] == 0) {
00715 if(++iss[1] == 0) {
00716 ++iss[0];
00717 }
00718 }
00719 }
00720
00721
00722 uip_len = 0;
00723 uip_slen = 0;
00724
00725
00726
00727
00728
00729 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
00730 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
00731 ++(uip_connr->timer);
00732 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00733 uip_connr->tcpstateflags = UIP_CLOSED;
00734 }
00735 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
00736
00737
00738
00739 if(uip_outstanding(uip_connr)) {
00740 if(uip_connr->timer-- == 0) {
00741 if(uip_connr->nrtx == UIP_MAXRTX ||
00742 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
00743 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
00744 uip_connr->nrtx == UIP_MAXSYNRTX)) {
00745 uip_connr->tcpstateflags = UIP_CLOSED;
00746
00747
00748
00749
00750 uip_flags = UIP_TIMEDOUT;
00751 UIP_APPCALL();
00752
00753
00754 BUF->flags = TCP_RST | TCP_ACK;
00755 goto tcp_send_nodata;
00756 }
00757
00758
00759 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00760 4:
00761 uip_connr->nrtx);
00762 ++(uip_connr->nrtx);
00763
00764
00765
00766
00767
00768
00769
00770 UIP_STAT(++uip_stat.tcp.rexmit);
00771 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
00772 case UIP_SYN_RCVD:
00773
00774
00775 goto tcp_send_synack;
00776
00777 #if UIP_ACTIVE_OPEN
00778 case UIP_SYN_SENT:
00779
00780 BUF->flags = 0;
00781 goto tcp_send_syn;
00782 #endif
00783
00784 case UIP_ESTABLISHED:
00785
00786
00787
00788
00789 uip_flags = UIP_REXMIT;
00790 UIP_APPCALL();
00791 goto apprexmit;
00792
00793 case UIP_FIN_WAIT_1:
00794 case UIP_CLOSING:
00795 case UIP_LAST_ACK:
00796
00797 goto tcp_send_finack;
00798
00799 }
00800 }
00801 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
00802
00803
00804 uip_flags = UIP_POLL;
00805 UIP_APPCALL();
00806 goto appsend;
00807 }
00808 }
00809 goto drop;
00810 }
00811 #if UIP_UDP
00812 if(flag == UIP_UDP_TIMER) {
00813 if(uip_udp_conn->lport != 0) {
00814 uip_conn = NULL;
00815 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
00816 uip_len = uip_slen = 0;
00817 uip_flags = UIP_POLL;
00818 UIP_UDP_APPCALL();
00819 goto udp_send;
00820 } else {
00821 goto drop;
00822 }
00823 }
00824 #endif
00825
00826
00827 UIP_STAT(++uip_stat.ip.recv);
00828
00829
00830
00831 #if UIP_CONF_IPV6
00832
00833 if((BUF->vtc & 0xf0) != 0x60) {
00834 UIP_STAT(++uip_stat.ip.drop);
00835 UIP_STAT(++uip_stat.ip.vhlerr);
00836 UIP_LOG("ipv6: invalid version.");
00837 goto drop;
00838 }
00839 #else
00840
00841 if(BUF->vhl != 0x45) {
00842 UIP_STAT(++uip_stat.ip.drop);
00843 UIP_STAT(++uip_stat.ip.vhlerr);
00844 UIP_LOG("ip: invalid version or header length.");
00845 goto drop;
00846 }
00847 #endif
00848
00849
00850
00851
00852
00853
00854
00855
00856 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
00857 uip_len = (BUF->len[0] << 8) + BUF->len[1];
00858 #if UIP_CONF_IPV6
00859 uip_len += 40;
00860
00861
00862
00863
00864
00865
00866
00867
00868 #endif
00869 } else {
00870 UIP_LOG("ip: packet shorter than reported in IP header.");
00871 goto drop;
00872 }
00873
00874 #if !UIP_CONF_IPV6
00875
00876 if((BUF->ipoffset[0] & 0x3f) != 0 ||
00877 BUF->ipoffset[1] != 0) {
00878 #if UIP_REASSEMBLY
00879 uip_len = uip_reass();
00880 if(uip_len == 0) {
00881 goto drop;
00882 }
00883 #else
00884 UIP_STAT(++uip_stat.ip.drop);
00885 UIP_STAT(++uip_stat.ip.fragerr);
00886 UIP_LOG("ip: fragment dropped.");
00887 goto drop;
00888 #endif
00889 }
00890 #endif
00891
00892 if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
00893
00894
00895
00896 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
00897 if(BUF->proto == UIP_PROTO_ICMP) {
00898 UIP_LOG("ip: possible ping config packet received.");
00899 goto icmp_input;
00900 } else {
00901 UIP_LOG("ip: packet dropped since no address assigned.");
00902 goto drop;
00903 }
00904 #endif
00905
00906 } else {
00907
00908
00909 #if UIP_BROADCAST
00910 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
00911 if(BUF->proto == UIP_PROTO_UDP &&
00912 uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
00913
00914 ) {
00915 goto udp_input;
00916 }
00917 #endif
00918
00919
00920 #if !UIP_CONF_IPV6
00921 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
00922 UIP_STAT(++uip_stat.ip.drop);
00923 goto drop;
00924 }
00925 #else
00926
00927
00928
00929
00930
00931 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
00932 BUF->destipaddr[0] != HTONS(0xff02)) {
00933 UIP_STAT(++uip_stat.ip.drop);
00934 goto drop;
00935 }
00936 #endif
00937 }
00938
00939 #if !UIP_CONF_IPV6
00940 if(uip_ipchksum() != 0xffff) {
00941
00942 UIP_STAT(++uip_stat.ip.drop);
00943 UIP_STAT(++uip_stat.ip.chkerr);
00944 UIP_LOG("ip: bad checksum.");
00945 goto drop;
00946 }
00947 #endif
00948
00949 if(BUF->proto == UIP_PROTO_TCP) {
00950
00951
00952 goto tcp_input;
00953 }
00954
00955 #if UIP_UDP
00956 if(BUF->proto == UIP_PROTO_UDP) {
00957 goto udp_input;
00958 }
00959 #endif
00960
00961 #if !UIP_CONF_IPV6
00962
00963 if(BUF->proto != UIP_PROTO_ICMP) {
00964
00965 UIP_STAT(++uip_stat.ip.drop);
00966 UIP_STAT(++uip_stat.ip.protoerr);
00967 UIP_LOG("ip: neither tcp nor icmp.");
00968 goto drop;
00969 }
00970
00971 #if UIP_PINGADDRCONF
00972 icmp_input:
00973 #endif
00974 UIP_STAT(++uip_stat.icmp.recv);
00975
00976
00977
00978
00979 if(ICMPBUF->type != ICMP_ECHO) {
00980 UIP_STAT(++uip_stat.icmp.drop);
00981 UIP_STAT(++uip_stat.icmp.typeerr);
00982 UIP_LOG("icmp: not icmp echo.");
00983 goto drop;
00984 }
00985
00986
00987
00988
00989 #if UIP_PINGADDRCONF
00990 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
00991 uip_hostaddr[0] = BUF->destipaddr[0];
00992 uip_hostaddr[1] = BUF->destipaddr[1];
00993 }
00994 #endif
00995
00996 ICMPBUF->type = ICMP_ECHO_REPLY;
00997
00998 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
00999 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
01000 } else {
01001 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
01002 }
01003
01004
01005 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
01006 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
01007
01008 UIP_STAT(++uip_stat.icmp.sent);
01009 goto send;
01010
01011
01012 #else
01013
01014
01015 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
01016
01017 if(BUF->proto != UIP_PROTO_ICMP6) {
01018
01019 UIP_STAT(++uip_stat.ip.drop);
01020 UIP_STAT(++uip_stat.ip.protoerr);
01021 UIP_LOG("ip: neither tcp nor icmp6.");
01022 goto drop;
01023 }
01024
01025 UIP_STAT(++uip_stat.icmp.recv);
01026
01027
01028
01029 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
01030 if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
01031
01032 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
01033
01034 uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
01035 }
01036
01037
01038
01039 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
01040 ICMPBUF->flags = ICMP6_FLAG_S;
01041
01042 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
01043
01044 uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
01045 uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
01046 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
01047 ICMPBUF->options[1] = 1;
01048 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
01049 ICMPBUF->icmpchksum = 0;
01050 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
01051 goto send;
01052
01053 }
01054 goto drop;
01055 } else if(ICMPBUF->type == ICMP6_ECHO) {
01056
01057
01058
01059
01060 ICMPBUF->type = ICMP6_ECHO_REPLY;
01061
01062 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
01063 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
01064 ICMPBUF->icmpchksum = 0;
01065 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
01066
01067 UIP_STAT(++uip_stat.icmp.sent);
01068 goto send;
01069 } else {
01070 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
01071 UIP_STAT(++uip_stat.icmp.drop);
01072 UIP_STAT(++uip_stat.icmp.typeerr);
01073 UIP_LOG("icmp: unknown ICMP message.");
01074 goto drop;
01075 }
01076
01077
01078
01079 #endif
01080
01081 #if UIP_UDP
01082
01083 udp_input:
01084
01085
01086
01087
01088 #if UIP_UDP_CHECKSUMS
01089 uip_len = uip_len - UIP_IPUDPH_LEN;
01090 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01091 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
01092 UIP_STAT(++uip_stat.udp.drop);
01093 UIP_STAT(++uip_stat.udp.chkerr);
01094 UIP_LOG("udp: bad checksum.");
01095 goto drop;
01096 }
01097 #else
01098 uip_len = uip_len - UIP_IPUDPH_LEN;
01099 #endif
01100
01101
01102 for(uip_udp_conn = &uip_udp_conns[0];
01103 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
01104 ++uip_udp_conn) {
01105
01106
01107
01108
01109
01110
01111
01112 if(uip_udp_conn->lport != 0 &&
01113 UDPBUF->destport == uip_udp_conn->lport &&
01114 (uip_udp_conn->rport == 0 ||
01115 UDPBUF->srcport == uip_udp_conn->rport) &&
01116 (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
01117 uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
01118 uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
01119 goto udp_found;
01120 }
01121 }
01122 UIP_LOG("udp: no matching connection found");
01123 goto drop;
01124
01125 udp_found:
01126 uip_conn = NULL;
01127 uip_flags = UIP_NEWDATA;
01128 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01129 uip_slen = 0;
01130 UIP_UDP_APPCALL();
01131 udp_send:
01132 if(uip_slen == 0) {
01133 goto drop;
01134 }
01135 uip_len = uip_slen + UIP_IPUDPH_LEN;
01136
01137 #if UIP_CONF_IPV6
01138
01139
01140 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01141 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01142 #else
01143 BUF->len[0] = (uip_len >> 8);
01144 BUF->len[1] = (uip_len & 0xff);
01145 #endif
01146
01147 BUF->ttl = uip_udp_conn->ttl;
01148 BUF->proto = UIP_PROTO_UDP;
01149
01150 UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
01151 UDPBUF->udpchksum = 0;
01152
01153 BUF->srcport = uip_udp_conn->lport;
01154 BUF->destport = uip_udp_conn->rport;
01155
01156 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
01157 uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
01158
01159 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
01160
01161 #if UIP_UDP_CHECKSUMS
01162
01163 UDPBUF->udpchksum = ~(uip_udpchksum());
01164 if(UDPBUF->udpchksum == 0) {
01165 UDPBUF->udpchksum = 0xffff;
01166 }
01167 #endif
01168
01169 goto ip_send_nolen;
01170 #endif
01171
01172
01173 tcp_input:
01174 UIP_STAT(++uip_stat.tcp.recv);
01175
01176
01177
01178 if(uip_tcpchksum() != 0xffff) {
01179
01180 UIP_STAT(++uip_stat.tcp.drop);
01181 UIP_STAT(++uip_stat.tcp.chkerr);
01182 UIP_LOG("tcp: bad checksum.");
01183 goto drop;
01184 }
01185
01186
01187
01188
01189 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
01190 ++uip_connr) {
01191 if(uip_connr->tcpstateflags != UIP_CLOSED &&
01192 BUF->destport == uip_connr->lport &&
01193 BUF->srcport == uip_connr->rport &&
01194 uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
01195 goto found;
01196 }
01197 }
01198
01199
01200
01201
01202
01203 if((BUF->flags & TCP_CTL) != TCP_SYN) {
01204 goto reset;
01205 }
01206
01207 tmp16 = BUF->destport;
01208
01209 for(c = 0; c < UIP_LISTENPORTS; ++c) {
01210 if(tmp16 == uip_listenports[c])
01211 goto found_listen;
01212 }
01213
01214
01215 UIP_STAT(++uip_stat.tcp.synrst);
01216 reset:
01217
01218
01219 if(BUF->flags & TCP_RST) {
01220 goto drop;
01221 }
01222
01223 UIP_STAT(++uip_stat.tcp.rst);
01224
01225 BUF->flags = TCP_RST | TCP_ACK;
01226 uip_len = UIP_IPTCPH_LEN;
01227 BUF->tcpoffset = 5 << 4;
01228
01229
01230 c = BUF->seqno[3];
01231 BUF->seqno[3] = BUF->ackno[3];
01232 BUF->ackno[3] = c;
01233
01234 c = BUF->seqno[2];
01235 BUF->seqno[2] = BUF->ackno[2];
01236 BUF->ackno[2] = c;
01237
01238 c = BUF->seqno[1];
01239 BUF->seqno[1] = BUF->ackno[1];
01240 BUF->ackno[1] = c;
01241
01242 c = BUF->seqno[0];
01243 BUF->seqno[0] = BUF->ackno[0];
01244 BUF->ackno[0] = c;
01245
01246
01247
01248
01249 if(++BUF->ackno[3] == 0) {
01250 if(++BUF->ackno[2] == 0) {
01251 if(++BUF->ackno[1] == 0) {
01252 ++BUF->ackno[0];
01253 }
01254 }
01255 }
01256
01257
01258 tmp16 = BUF->srcport;
01259 BUF->srcport = BUF->destport;
01260 BUF->destport = tmp16;
01261
01262
01263 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
01264 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
01265
01266
01267 goto tcp_send_noconn;
01268
01269
01270
01271
01272 found_listen:
01273
01274
01275
01276
01277
01278
01279 uip_connr = 0;
01280 for(c = 0; c < UIP_CONNS; ++c) {
01281 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
01282 uip_connr = &uip_conns[c];
01283 break;
01284 }
01285 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
01286 if(uip_connr == 0 ||
01287 uip_conns[c].timer > uip_connr->timer) {
01288 uip_connr = &uip_conns[c];
01289 }
01290 }
01291 }
01292
01293 if(uip_connr == 0) {
01294
01295
01296
01297 UIP_STAT(++uip_stat.tcp.syndrop);
01298 UIP_LOG("tcp: found no unused connections.");
01299 goto drop;
01300 }
01301 uip_conn = uip_connr;
01302
01303
01304 uip_connr->rto = uip_connr->timer = UIP_RTO;
01305 uip_connr->sa = 0;
01306 uip_connr->sv = 4;
01307 uip_connr->nrtx = 0;
01308 uip_connr->lport = BUF->destport;
01309 uip_connr->rport = BUF->srcport;
01310 uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
01311 uip_connr->tcpstateflags = UIP_SYN_RCVD;
01312
01313 uip_connr->snd_nxt[0] = iss[0];
01314 uip_connr->snd_nxt[1] = iss[1];
01315 uip_connr->snd_nxt[2] = iss[2];
01316 uip_connr->snd_nxt[3] = iss[3];
01317 uip_connr->len = 1;
01318
01319
01320 uip_connr->rcv_nxt[3] = BUF->seqno[3];
01321 uip_connr->rcv_nxt[2] = BUF->seqno[2];
01322 uip_connr->rcv_nxt[1] = BUF->seqno[1];
01323 uip_connr->rcv_nxt[0] = BUF->seqno[0];
01324 uip_add_rcv_nxt(1);
01325
01326
01327 if((BUF->tcpoffset & 0xf0) > 0x50) {
01328 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01329 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
01330 if(opt == TCP_OPT_END) {
01331
01332 break;
01333 } else if(opt == TCP_OPT_NOOP) {
01334 ++c;
01335
01336 } else if(opt == TCP_OPT_MSS &&
01337 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01338
01339 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01340 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
01341 uip_connr->initialmss = uip_connr->mss =
01342 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01343
01344
01345 break;
01346 } else {
01347
01348
01349 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01350
01351
01352 break;
01353 }
01354 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01355 }
01356 }
01357 }
01358
01359
01360 #if UIP_ACTIVE_OPEN
01361 tcp_send_synack:
01362 BUF->flags = TCP_ACK;
01363
01364 tcp_send_syn:
01365 BUF->flags |= TCP_SYN;
01366 #else
01367 tcp_send_synack:
01368 BUF->flags = TCP_SYN | TCP_ACK;
01369 #endif
01370
01371
01372
01373 BUF->optdata[0] = TCP_OPT_MSS;
01374 BUF->optdata[1] = TCP_OPT_MSS_LEN;
01375 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01376 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01377 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
01378 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
01379 goto tcp_send;
01380
01381
01382 found:
01383 uip_conn = uip_connr;
01384 uip_flags = 0;
01385
01386
01387
01388
01389 if(BUF->flags & TCP_RST) {
01390 uip_connr->tcpstateflags = UIP_CLOSED;
01391 UIP_LOG("tcp: got reset, aborting connection.");
01392 uip_flags = UIP_ABORT;
01393 UIP_APPCALL();
01394 goto drop;
01395 }
01396
01397
01398 c = (BUF->tcpoffset >> 4) << 2;
01399
01400
01401
01402 uip_len = uip_len - c - UIP_IPH_LEN;
01403
01404
01405
01406
01407 if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
01408 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
01409 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
01410 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01411 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01412 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01413 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01414 goto tcp_send_ack;
01415 }
01416 }
01417
01418
01419
01420
01421
01422 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01423 uip_add32(uip_connr->snd_nxt, uip_connr->len);
01424
01425 if(BUF->ackno[0] == uip_acc32[0] &&
01426 BUF->ackno[1] == uip_acc32[1] &&
01427 BUF->ackno[2] == uip_acc32[2] &&
01428 BUF->ackno[3] == uip_acc32[3]) {
01429
01430 uip_connr->snd_nxt[0] = uip_acc32[0];
01431 uip_connr->snd_nxt[1] = uip_acc32[1];
01432 uip_connr->snd_nxt[2] = uip_acc32[2];
01433 uip_connr->snd_nxt[3] = uip_acc32[3];
01434
01435
01436
01437 if(uip_connr->nrtx == 0) {
01438 signed char m;
01439 m = uip_connr->rto - uip_connr->timer;
01440
01441 m = m - (uip_connr->sa >> 3);
01442 uip_connr->sa += m;
01443 if(m < 0) {
01444 m = -m;
01445 }
01446 m = m - (uip_connr->sv >> 2);
01447 uip_connr->sv += m;
01448 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01449
01450 }
01451
01452 uip_flags = UIP_ACKDATA;
01453
01454 uip_connr->timer = uip_connr->rto;
01455
01456
01457 uip_connr->len = 0;
01458 }
01459
01460 }
01461
01462
01463 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
01464
01465
01466
01467
01468 case UIP_SYN_RCVD:
01469
01470
01471
01472
01473 if(uip_flags & UIP_ACKDATA) {
01474 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01475 uip_flags = UIP_CONNECTED;
01476 uip_connr->len = 0;
01477 if(uip_len > 0) {
01478 uip_flags |= UIP_NEWDATA;
01479 uip_add_rcv_nxt(uip_len);
01480 }
01481 uip_slen = 0;
01482 UIP_APPCALL();
01483 goto appsend;
01484 }
01485 goto drop;
01486 #if UIP_ACTIVE_OPEN
01487 case UIP_SYN_SENT:
01488
01489
01490
01491
01492 if((uip_flags & UIP_ACKDATA) &&
01493 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
01494
01495
01496 if((BUF->tcpoffset & 0xf0) > 0x50) {
01497 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01498 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
01499 if(opt == TCP_OPT_END) {
01500
01501 break;
01502 } else if(opt == TCP_OPT_NOOP) {
01503 ++c;
01504
01505 } else if(opt == TCP_OPT_MSS &&
01506 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01507
01508 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01509 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01510 uip_connr->initialmss =
01511 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01512
01513
01514 break;
01515 } else {
01516
01517
01518 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01519
01520
01521 break;
01522 }
01523 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01524 }
01525 }
01526 }
01527 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01528 uip_connr->rcv_nxt[0] = BUF->seqno[0];
01529 uip_connr->rcv_nxt[1] = BUF->seqno[1];
01530 uip_connr->rcv_nxt[2] = BUF->seqno[2];
01531 uip_connr->rcv_nxt[3] = BUF->seqno[3];
01532 uip_add_rcv_nxt(1);
01533 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01534 uip_connr->len = 0;
01535 uip_len = 0;
01536 uip_slen = 0;
01537 UIP_APPCALL();
01538 goto appsend;
01539 }
01540
01541 uip_flags = UIP_ABORT;
01542 UIP_APPCALL();
01543
01544 uip_conn->tcpstateflags = UIP_CLOSED;
01545 goto reset;
01546 #endif
01547
01548 case UIP_ESTABLISHED:
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01561 if(uip_outstanding(uip_connr)) {
01562 goto drop;
01563 }
01564 uip_add_rcv_nxt(1 + uip_len);
01565 uip_flags |= UIP_CLOSE;
01566 if(uip_len > 0) {
01567 uip_flags |= UIP_NEWDATA;
01568 }
01569 UIP_APPCALL();
01570 uip_connr->len = 1;
01571 uip_connr->tcpstateflags = UIP_LAST_ACK;
01572 uip_connr->nrtx = 0;
01573 tcp_send_finack:
01574 BUF->flags = TCP_FIN | TCP_ACK;
01575 goto tcp_send_nodata;
01576 }
01577
01578
01579
01580 if((BUF->flags & TCP_URG) != 0) {
01581 #if UIP_URGDATA > 0
01582 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
01583 if(uip_urglen > uip_len) {
01584
01585 uip_urglen = uip_len;
01586 }
01587 uip_add_rcv_nxt(uip_urglen);
01588 uip_len -= uip_urglen;
01589 uip_urgdata = uip_appdata;
01590 uip_appdata += uip_urglen;
01591 } else {
01592 uip_urglen = 0;
01593 #else
01594 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
01595 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
01596 #endif
01597 }
01598
01599
01600
01601
01602
01603
01604 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01605 uip_flags |= UIP_NEWDATA;
01606 uip_add_rcv_nxt(uip_len);
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
01622 if(tmp16 > uip_connr->initialmss ||
01623 tmp16 == 0) {
01624 tmp16 = uip_connr->initialmss;
01625 }
01626 uip_connr->mss = tmp16;
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
01645 uip_slen = 0;
01646 UIP_APPCALL();
01647
01648 appsend:
01649
01650 if(uip_flags & UIP_ABORT) {
01651 uip_slen = 0;
01652 uip_connr->tcpstateflags = UIP_CLOSED;
01653 BUF->flags = TCP_RST | TCP_ACK;
01654 goto tcp_send_nodata;
01655 }
01656
01657 if(uip_flags & UIP_CLOSE) {
01658 uip_slen = 0;
01659 uip_connr->len = 1;
01660 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
01661 uip_connr->nrtx = 0;
01662 BUF->flags = TCP_FIN | TCP_ACK;
01663 goto tcp_send_nodata;
01664 }
01665
01666
01667 if(uip_slen > 0) {
01668
01669
01670
01671 if((uip_flags & UIP_ACKDATA) != 0) {
01672 uip_connr->len = 0;
01673 }
01674
01675
01676
01677
01678 if(uip_connr->len == 0) {
01679
01680
01681
01682
01683 if(uip_slen > uip_connr->mss) {
01684 uip_slen = uip_connr->mss;
01685 }
01686
01687
01688
01689 uip_connr->len = uip_slen;
01690 } else {
01691
01692
01693
01694
01695 uip_slen = uip_connr->len;
01696 }
01697 }
01698 uip_connr->nrtx = 0;
01699 apprexmit:
01700 uip_appdata = uip_sappdata;
01701
01702
01703
01704 if(uip_slen > 0 && uip_connr->len > 0) {
01705
01706 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
01707
01708 BUF->flags = TCP_ACK | TCP_PSH;
01709
01710 goto tcp_send_noopts;
01711 }
01712
01713
01714 if(uip_flags & UIP_NEWDATA) {
01715 uip_len = UIP_TCPIP_HLEN;
01716 BUF->flags = TCP_ACK;
01717 goto tcp_send_noopts;
01718 }
01719 }
01720 goto drop;
01721 case UIP_LAST_ACK:
01722
01723
01724 if(uip_flags & UIP_ACKDATA) {
01725 uip_connr->tcpstateflags = UIP_CLOSED;
01726 uip_flags = UIP_CLOSE;
01727 UIP_APPCALL();
01728 }
01729 break;
01730
01731 case UIP_FIN_WAIT_1:
01732
01733
01734
01735 if(uip_len > 0) {
01736 uip_add_rcv_nxt(uip_len);
01737 }
01738 if(BUF->flags & TCP_FIN) {
01739 if(uip_flags & UIP_ACKDATA) {
01740 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01741 uip_connr->timer = 0;
01742 uip_connr->len = 0;
01743 } else {
01744 uip_connr->tcpstateflags = UIP_CLOSING;
01745 }
01746 uip_add_rcv_nxt(1);
01747 uip_flags = UIP_CLOSE;
01748 UIP_APPCALL();
01749 goto tcp_send_ack;
01750 } else if(uip_flags & UIP_ACKDATA) {
01751 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
01752 uip_connr->len = 0;
01753 goto drop;
01754 }
01755 if(uip_len > 0) {
01756 goto tcp_send_ack;
01757 }
01758 goto drop;
01759
01760 case UIP_FIN_WAIT_2:
01761 if(uip_len > 0) {
01762 uip_add_rcv_nxt(uip_len);
01763 }
01764 if(BUF->flags & TCP_FIN) {
01765 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01766 uip_connr->timer = 0;
01767 uip_add_rcv_nxt(1);
01768 uip_flags = UIP_CLOSE;
01769 UIP_APPCALL();
01770 goto tcp_send_ack;
01771 }
01772 if(uip_len > 0) {
01773 goto tcp_send_ack;
01774 }
01775 goto drop;
01776
01777 case UIP_TIME_WAIT:
01778 goto tcp_send_ack;
01779
01780 case UIP_CLOSING:
01781 if(uip_flags & UIP_ACKDATA) {
01782 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01783 uip_connr->timer = 0;
01784 }
01785 }
01786 goto drop;
01787
01788
01789
01790
01791 tcp_send_ack:
01792 BUF->flags = TCP_ACK;
01793 tcp_send_nodata:
01794 uip_len = UIP_IPTCPH_LEN;
01795 tcp_send_noopts:
01796 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
01797 tcp_send:
01798
01799
01800
01801
01802 BUF->ackno[0] = uip_connr->rcv_nxt[0];
01803 BUF->ackno[1] = uip_connr->rcv_nxt[1];
01804 BUF->ackno[2] = uip_connr->rcv_nxt[2];
01805 BUF->ackno[3] = uip_connr->rcv_nxt[3];
01806
01807 BUF->seqno[0] = uip_connr->snd_nxt[0];
01808 BUF->seqno[1] = uip_connr->snd_nxt[1];
01809 BUF->seqno[2] = uip_connr->snd_nxt[2];
01810 BUF->seqno[3] = uip_connr->snd_nxt[3];
01811
01812 BUF->proto = UIP_PROTO_TCP;
01813
01814 BUF->srcport = uip_connr->lport;
01815 BUF->destport = uip_connr->rport;
01816
01817 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
01818 uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
01819
01820 if(uip_connr->tcpstateflags & UIP_STOPPED) {
01821
01822
01823 BUF->wnd[0] = BUF->wnd[1] = 0;
01824 } else {
01825 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
01826 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
01827 }
01828
01829 tcp_send_noconn:
01830 BUF->ttl = UIP_TTL;
01831 #if UIP_CONF_IPV6
01832
01833
01834 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01835 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01836 #else
01837 BUF->len[0] = (uip_len >> 8);
01838 BUF->len[1] = (uip_len & 0xff);
01839 #endif
01840
01841 BUF->urgp[0] = BUF->urgp[1] = 0;
01842
01843
01844 BUF->tcpchksum = 0;
01845 BUF->tcpchksum = ~(uip_tcpchksum());
01846
01847 ip_send_nolen:
01848
01849 #if UIP_CONF_IPV6
01850 BUF->vtc = 0x60;
01851 BUF->tcflow = 0x00;
01852 BUF->flow = 0x00;
01853 #else
01854 BUF->vhl = 0x45;
01855 BUF->tos = 0;
01856 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
01857 ++ipid;
01858 BUF->ipid[0] = ipid >> 8;
01859 BUF->ipid[1] = ipid & 0xff;
01860
01861 BUF->ipchksum = 0;
01862 BUF->ipchksum = ~(uip_ipchksum());
01863 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
01864 #endif
01865
01866 UIP_STAT(++uip_stat.tcp.sent);
01867 send:
01868 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
01869 (BUF->len[0] << 8) | BUF->len[1]);
01870
01871 UIP_STAT(++uip_stat.ip.sent);
01872
01873 uip_flags = 0;
01874 return;
01875 drop:
01876 uip_len = 0;
01877 uip_flags = 0;
01878 return;
01879 }
01880
01881 u16_t
01882 htons(u16_t val)
01883 {
01884 return HTONS(val);
01885 }
01886
01887 void
01888 uip_send(const void *data, int len)
01889 {
01890 if(len > 0) {
01891 uip_slen = len;
01892 if(data != uip_sappdata) {
01893 memcpy(uip_sappdata, (data), uip_slen);
01894 }
01895 }
01896 }
01897