00001
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 #include "uip.h"
00067 #include "uipopt.h"
00068 #include "uip_arch.h"
00069
00070
00071
00072
00073
00074
00075 #if UIP_FIXEDADDR > 0
00076 const u16_t uip_hostaddr[2] =
00077 {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
00078 HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
00079 const u16_t uip_arp_draddr[2] =
00080 {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
00081 HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
00082 const u16_t uip_arp_netmask[2] =
00083 {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
00084 HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
00085 #else
00086 u16_t uip_hostaddr[2];
00087 u16_t uip_arp_draddr[2], uip_arp_netmask[2];
00088 #endif
00089
00090 u8_t uip_buf[UIP_BUFSIZE+2];
00091
00092 volatile u8_t *uip_appdata;
00093
00094 volatile u8_t *uip_sappdata;
00095
00096 #if UIP_URGDATA > 0
00097 volatile u8_t *uip_urgdata;
00098
00099
00100 volatile u8_t uip_urglen, uip_surglen;
00101 #endif
00102
00103 volatile u16_t uip_len, uip_slen;
00104
00105
00106
00107
00108 volatile u8_t uip_flags;
00109
00110
00111 struct uip_conn *uip_conn;
00112
00113
00114 struct uip_conn uip_conns[UIP_CONNS];
00115
00116
00117 u16_t uip_listenports[UIP_LISTENPORTS];
00118
00119
00120 #if UIP_UDP
00121 struct uip_udp_conn *uip_udp_conn;
00122 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00123 #endif
00124
00125
00126 static u16_t ipid;
00127
00128
00129
00130 static u8_t iss[4];
00131
00132
00133 #if UIP_ACTIVE_OPEN
00134 static u16_t lastport;
00135
00136 #endif
00137
00138
00139 volatile u8_t uip_acc32[4];
00140 static u8_t c, opt;
00141 static u16_t tmp16;
00142
00143
00144 #define TCP_FIN 0x01
00145 #define TCP_SYN 0x02
00146 #define TCP_RST 0x04
00147 #define TCP_PSH 0x08
00148 #define TCP_ACK 0x10
00149 #define TCP_URG 0x20
00150 #define TCP_CTL 0x3f
00151
00152 #define ICMP_ECHO_REPLY 0
00153 #define ICMP_ECHO 8
00154
00155
00156 #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00157 #define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
00158 #define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
00159 #define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
00160
00161 #if UIP_STATISTICS == 1
00162 struct uip_stats uip_stat;
00163 #define UIP_STAT(s) s
00164 #else
00165 #define UIP_STAT(s)
00166 #endif
00167
00168 #if UIP_LOGGING == 1
00169 #define uip_log(str) TxStrk_P(str);
00170
00171 #define UIP_LOG(m) uip_log(m)
00172 #else
00173 #define UIP_LOG(m)
00174 #endif
00175
00176
00177 void
00178 uip_init(void)
00179 {
00180 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00181 uip_listenports[c] = 0;
00182 }
00183 for(c = 0; c < UIP_CONNS; ++c) {
00184 uip_conns[c].tcpstateflags = CLOSED;
00185 }
00186 #if UIP_ACTIVE_OPEN
00187 lastport = 1024;
00188 #endif
00189
00190 #if UIP_UDP
00191 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00192 uip_udp_conns[c].lport = 0;
00193 }
00194 #endif
00195
00196
00197
00198 #if UIP_FIXEDADDR == 0
00199 uip_hostaddr[0] = uip_hostaddr[1] = 0;
00200 #endif
00201
00202 }
00203
00204 #if UIP_ACTIVE_OPEN
00205 struct uip_conn *
00206 uip_connect(u16_t *ripaddr, u16_t rport)
00207 {
00208 register struct uip_conn *conn, *cconn;
00209
00210
00211 again:
00212 ++lastport;
00213
00214 if(lastport >= 32000) {
00215 lastport = 4096;
00216 }
00217
00218
00219
00220 for(c = 0; c < UIP_CONNS; ++c) {
00221 conn = &uip_conns[c];
00222 if(conn->tcpstateflags != CLOSED &&
00223 conn->lport == htons(lastport)) {
00224 goto again;
00225 }
00226 }
00227
00228
00229 conn = 0;
00230 for(c = 0; c < UIP_CONNS; ++c) {
00231 cconn = &uip_conns[c];
00232 if(cconn->tcpstateflags == CLOSED) {
00233 conn = cconn;
00234 break;
00235 }
00236 if(cconn->tcpstateflags == TIME_WAIT) {
00237 if(conn == 0 ||
00238 cconn->timer > uip_conn->timer) {
00239 conn = cconn;
00240 }
00241 }
00242 }
00243
00244 if(conn == 0) {
00245 return 0;
00246 }
00247
00248 conn->tcpstateflags = SYN_SENT;
00249
00250 conn->snd_nxt[0] = iss[0];
00251 conn->snd_nxt[1] = iss[1];
00252 conn->snd_nxt[2] = iss[2];
00253 conn->snd_nxt[3] = iss[3];
00254
00255 conn->initialmss = conn->mss = UIP_TCP_MSS;
00256
00257 conn->len = 1;
00258 conn->nrtx = 0;
00259 conn->timer = 1;
00260 conn->rto = UIP_RTO;
00261 conn->sa = 0;
00262 conn->sv = 16;
00263 conn->lport = htons(lastport);
00264 conn->rport = rport;
00265 conn->ripaddr[0] = ripaddr[0];
00266 conn->ripaddr[1] = ripaddr[1];
00267
00268 return conn;
00269 }
00270 #endif
00271
00272 #if UIP_UDP
00273 struct uip_udp_conn *
00274 uip_udp_new(u16_t *ripaddr, u16_t rport)
00275 {
00276 register struct uip_udp_conn *conn;
00277
00278
00279 again:
00280 ++lastport;
00281
00282 if(lastport >= 32000) {
00283 lastport = 4096;
00284 }
00285
00286 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00287 if(uip_udp_conns[c].lport == lastport) {
00288 goto again;
00289 }
00290 }
00291
00292
00293 conn = 0;
00294 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00295 if(uip_udp_conns[c].lport == 0) {
00296 conn = &uip_udp_conns[c];
00297 break;
00298 }
00299 }
00300
00301 if(conn == 0) {
00302 return 0;
00303 }
00304
00305 conn->lport = HTONS(lastport);
00306 conn->rport = HTONS(rport);
00307 conn->ripaddr[0] = ripaddr[0];
00308 conn->ripaddr[1] = ripaddr[1];
00309
00310 return conn;
00311 }
00312 #endif
00313
00314 void
00315 uip_unlisten(u16_t port)
00316 {
00317 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00318 if(uip_listenports[c] == port) {
00319 uip_listenports[c] = 0;
00320 return;
00321 }
00322 }
00323 }
00324
00325 void
00326 uip_listen(u16_t port)
00327 {
00328 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00329 if(uip_listenports[c] == 0) {
00330 uip_listenports[c] = port;
00331 return;
00332 }
00333 }
00334 }
00335
00336
00337
00338 #if UIP_REASSEMBLY
00339 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
00340 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
00341 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
00342 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
00343 0x0f, 0x07, 0x03, 0x01};
00344 static u16_t uip_reasslen;
00345 static u8_t uip_reassflags;
00346 #define UIP_REASS_FLAG_LASTFRAG 0x01
00347 static u8_t uip_reasstmr;
00348
00349 #define IP_HLEN 20
00350 #define IP_MF 0x20
00351
00352 static u8_t
00353 uip_reass(void)
00354 {
00355 u16_t offset, len;
00356 u16_t i;
00357
00358
00359
00360
00361 if(uip_reasstmr == 0) {
00362 memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
00363 uip_reasstmr = UIP_REASS_MAXAGE;
00364 uip_reassflags = 0;
00365
00366 memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
00367 }
00368
00369
00370
00371
00372 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
00373 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
00374 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
00375 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
00376 BUF->ipid[0] == FBUF->ipid[0] &&
00377 BUF->ipid[1] == FBUF->ipid[1]) {
00378
00379 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
00380 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
00381
00382
00383
00384 if(offset > UIP_REASS_BUFSIZE ||
00385 offset + len > UIP_REASS_BUFSIZE) {
00386 uip_reasstmr = 0;
00387 goto nullreturn;
00388 }
00389
00390
00391
00392 memcpy(&uip_reassbuf[IP_HLEN + offset],
00393 (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
00394 len);
00395
00396
00397 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
00398
00399
00400
00401 uip_reassbitmap[offset / (8 * 8)] |=
00402 bitmap_bits[(offset / 8 ) & 7] &
00403 ~bitmap_bits[((offset + len) / 8 ) & 7];
00404 } else {
00405
00406
00407
00408 uip_reassbitmap[offset / (8 * 8)] |=
00409 bitmap_bits[(offset / 8 ) & 7];
00410 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
00411 uip_reassbitmap[i] = 0xff;
00412 }
00413 uip_reassbitmap[(offset + len) / (8 * 8)] |=
00414 ~bitmap_bits[((offset + len) / 8 ) & 7];
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 if((BUF->ipoffset[0] & IP_MF) == 0) {
00424 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
00425 uip_reasslen = offset + len;
00426 }
00427
00428
00429
00430
00431 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
00432
00433
00434 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
00435 if(uip_reassbitmap[i] != 0xff) {
00436 goto nullreturn;
00437 }
00438 }
00439
00440
00441 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
00442 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
00443 goto nullreturn;
00444 }
00445
00446
00447
00448
00449 uip_reasstmr = 0;
00450 memcpy(BUF, FBUF, uip_reasslen);
00451
00452
00453
00454 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
00455 BUF->len[0] = uip_reasslen >> 8;
00456 BUF->len[1] = uip_reasslen & 0xff;
00457 BUF->ipchksum = 0;
00458 BUF->ipchksum = ~(uip_ipchksum());
00459
00460 return uip_reasslen;
00461 }
00462 }
00463
00464 nullreturn:
00465 return 0;
00466 }
00467 #endif
00468
00469 static void
00470 uip_add_rcv_nxt(u16_t n)
00471 {
00472 uip_add32(uip_conn->rcv_nxt, n);
00473 uip_conn->rcv_nxt[0] = uip_acc32[0];
00474 uip_conn->rcv_nxt[1] = uip_acc32[1];
00475 uip_conn->rcv_nxt[2] = uip_acc32[2];
00476 uip_conn->rcv_nxt[3] = uip_acc32[3];
00477 }
00478
00479 void
00480 uip_process(u8_t flag)
00481 {
00482 register struct uip_conn *uip_connr = uip_conn;
00483
00484 uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
00485
00486
00487
00488 if(flag == UIP_TIMER) {
00489 #if UIP_REASSEMBLY
00490 if(uip_reasstmr != 0) {
00491 --uip_reasstmr;
00492 }
00493 #endif
00494
00495 if(++iss[3] == 0) {
00496 if(++iss[2] == 0) {
00497 if(++iss[1] == 0) {
00498 ++iss[0];
00499 }
00500 }
00501 }
00502 uip_len = 0;
00503 if(uip_connr->tcpstateflags == TIME_WAIT ||
00504 uip_connr->tcpstateflags == FIN_WAIT_2) {
00505 ++(uip_connr->timer);
00506 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00507 uip_connr->tcpstateflags = CLOSED;
00508 }
00509 } else if(uip_connr->tcpstateflags != CLOSED) {
00510
00511
00512
00513 if(uip_outstanding(uip_connr)) {
00514 if(uip_connr->timer-- == 0) {
00515 if(uip_connr->nrtx == UIP_MAXRTX ||
00516 ((uip_connr->tcpstateflags == SYN_SENT ||
00517 uip_connr->tcpstateflags == SYN_RCVD) &&
00518 uip_connr->nrtx == UIP_MAXSYNRTX)) {
00519 uip_connr->tcpstateflags = CLOSED;
00520
00521
00522
00523
00524 uip_flags = UIP_TIMEDOUT;
00525 UIP_APPCALL();
00526
00527
00528 BUF->flags = TCP_RST | TCP_ACK;
00529 goto tcp_send_nodata;
00530 }
00531
00532
00533 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00534 4:
00535 uip_connr->nrtx);
00536 ++(uip_connr->nrtx);
00537
00538
00539
00540
00541
00542
00543
00544 UIP_STAT(++uip_stat.tcp.rexmit);
00545 switch(uip_connr->tcpstateflags & TS_MASK) {
00546 case SYN_RCVD:
00547
00548
00549 goto tcp_send_synack;
00550
00551 #if UIP_ACTIVE_OPEN
00552 case SYN_SENT:
00553
00554 BUF->flags = 0;
00555 goto tcp_send_syn;
00556 #endif
00557
00558 case ESTABLISHED:
00559
00560
00561
00562
00563 uip_len = 0;
00564 uip_slen = 0;
00565 uip_flags = UIP_REXMIT;
00566 UIP_APPCALL();
00567 goto apprexmit;
00568
00569 case FIN_WAIT_1:
00570 case CLOSING:
00571 case LAST_ACK:
00572
00573 goto tcp_send_finack;
00574
00575 }
00576 }
00577 } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
00578
00579
00580 uip_len = 0;
00581 uip_slen = 0;
00582 uip_flags = UIP_POLL;
00583 UIP_APPCALL();
00584 goto appsend;
00585 }
00586 }
00587 goto drop;
00588 }
00589 #if UIP_UDP
00590 if(flag == UIP_UDP_TIMER) {
00591 if(uip_udp_conn->lport != 0) {
00592 uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
00593 uip_len = uip_slen = 0;
00594 uip_flags = UIP_POLL;
00595 UIP_UDP_APPCALL();
00596 goto udp_send;
00597 } else {
00598 goto drop;
00599 }
00600 }
00601 #endif
00602
00603
00604 UIP_STAT(++uip_stat.ip.recv);
00605
00606
00607
00608
00609
00610 if(BUF->vhl != 0x45) {
00611 UIP_STAT(++uip_stat.ip.drop);
00612 UIP_STAT(++uip_stat.ip.vhlerr);
00613 UIP_LOG("ip: invalid version or header length.");
00614 goto drop;
00615 }
00616
00617
00618
00619
00620
00621 if(BUF->len[0] != (uip_len >> 8)) {
00622 uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
00623 }
00624 if(BUF->len[1] != (uip_len & 0xff)) {
00625 uip_len = (uip_len & 0xff00) | BUF->len[1];
00626 }
00627
00628
00629 if((BUF->ipoffset[0] & 0x3f) != 0 ||
00630 BUF->ipoffset[1] != 0) {
00631 #if UIP_REASSEMBLY
00632 uip_len = uip_reass();
00633 if(uip_len == 0) {
00634 goto drop;
00635 }
00636 #else
00637 UIP_STAT(++uip_stat.ip.drop);
00638 UIP_STAT(++uip_stat.ip.fragerr);
00639 UIP_LOG("ip: fragment dropped.");
00640 goto drop;
00641 #endif
00642 }
00643
00644
00645
00646
00647 #if UIP_PINGADDRCONF
00648 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
00649 if(BUF->proto == UIP_PROTO_ICMP) {
00650 UIP_LOG("ip: possible ping config packet received.");
00651 goto icmp_input;
00652 } else {
00653 UIP_LOG("ip: packet dropped since no address assigned.");
00654 goto drop;
00655 }
00656 }
00657 #endif
00658
00659
00660 if(BUF->destipaddr[0] != uip_hostaddr[0]) {
00661 UIP_STAT(++uip_stat.ip.drop);
00662 UIP_LOG("ip: packet not for us.");
00663 goto drop;
00664 }
00665 if(BUF->destipaddr[1] != uip_hostaddr[1]) {
00666 UIP_STAT(++uip_stat.ip.drop);
00667 UIP_LOG("ip: packet not for us.");
00668 goto drop;
00669 }
00670
00671 if(uip_ipchksum() != 0xffff) {
00672
00673 UIP_STAT(++uip_stat.ip.drop);
00674 UIP_STAT(++uip_stat.ip.chkerr);
00675 UIP_LOG("ip: bad checksum.");
00676 goto drop;
00677 }
00678
00679 if(BUF->proto == UIP_PROTO_TCP)
00680
00681 goto tcp_input;
00682
00683 #if UIP_UDP
00684 if(BUF->proto == UIP_PROTO_UDP)
00685 goto udp_input;
00686 #endif
00687
00688 if(BUF->proto != UIP_PROTO_ICMP) {
00689
00690 UIP_STAT(++uip_stat.ip.drop);
00691 UIP_STAT(++uip_stat.ip.protoerr);
00692 UIP_LOG("ip: neither tcp nor icmp.");
00693 goto drop;
00694 }
00695
00696 icmp_input:
00697 UIP_STAT(++uip_stat.icmp.recv);
00698
00699
00700
00701
00702 if(ICMPBUF->type != ICMP_ECHO) {
00703 UIP_STAT(++uip_stat.icmp.drop);
00704 UIP_STAT(++uip_stat.icmp.typeerr);
00705 UIP_LOG("icmp: not icmp echo.");
00706 goto drop;
00707 }
00708
00709
00710
00711
00712 #if UIP_PINGADDRCONF
00713 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
00714 uip_hostaddr[0] = BUF->destipaddr[0];
00715 uip_hostaddr[1] = BUF->destipaddr[1];
00716 }
00717 #endif
00718
00719 ICMPBUF->type = ICMP_ECHO_REPLY;
00720
00721 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
00722 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
00723 } else {
00724 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
00725 }
00726
00727
00728 tmp16 = BUF->destipaddr[0];
00729 BUF->destipaddr[0] = BUF->srcipaddr[0];
00730 BUF->srcipaddr[0] = tmp16;
00731 tmp16 = BUF->destipaddr[1];
00732 BUF->destipaddr[1] = BUF->srcipaddr[1];
00733 BUF->srcipaddr[1] = tmp16;
00734
00735 UIP_STAT(++uip_stat.icmp.sent);
00736 goto send;
00737
00738
00739
00740
00741 #if UIP_UDP
00742
00743 udp_input:
00744
00745
00746
00747
00748 #if UIP_UDP_CHECKSUMS
00749 if(uip_udpchksum() != 0xffff) {
00750 UIP_STAT(++uip_stat.udp.drop);
00751 UIP_STAT(++uip_stat.udp.chkerr);
00752 UIP_LOG("udp: bad checksum.");
00753 goto drop;
00754 }
00755 #endif
00756
00757
00758 for(uip_udp_conn = &uip_udp_conns[0];
00759 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
00760 ++uip_udp_conn) {
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 if(uip_udp_conn->lport != 0 &&
00773 UDPBUF->destport == uip_udp_conn->lport ) {
00774 goto udp_found;
00775 }
00776 }
00777 goto drop;
00778
00779 udp_found:
00780 uip_len = uip_len - 28;
00781 uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
00782 uip_flags = UIP_NEWDATA;
00783 uip_slen = 0;
00784 UIP_UDP_APPCALL();
00785 udp_send:
00786 if(uip_slen == 0) {
00787 goto drop;
00788 }
00789 uip_len = uip_slen + 28;
00790
00791 BUF->len[0] = (uip_len >> 8);
00792 BUF->len[1] = (uip_len & 0xff);
00793
00794 BUF->proto = UIP_PROTO_UDP;
00795
00796 UDPBUF->udplen = HTONS(uip_slen + 8);
00797 UDPBUF->udpchksum = 0;
00798 #if UIP_UDP_CHECKSUMS
00799
00800 UDPBUF->udpchksum = ~(uip_udpchksum());
00801 if(UDPBUF->udpchksum == 0) {
00802 UDPBUF->udpchksum = 0xffff;
00803 }
00804 #endif
00805
00806
00807
00808
00809
00810
00811 BUF->destport = BUF->srcport;
00812 BUF->srcport = uip_udp_conn->lport;
00813
00814 BUF->destipaddr[0] = BUF->srcipaddr[0];
00815 BUF->destipaddr[1] = BUF->srcipaddr[1];
00816 BUF->srcipaddr[0] = uip_hostaddr[0];
00817 BUF->srcipaddr[1] = uip_hostaddr[1];
00818
00819 uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
00820 goto ip_send_nolen;
00821 #endif
00822
00823
00824 tcp_input:
00825 UIP_STAT(++uip_stat.tcp.recv);
00826
00827
00828
00829 if(uip_tcpchksum() != 0xffff) {
00830
00831 UIP_STAT(++uip_stat.tcp.drop);
00832 UIP_STAT(++uip_stat.tcp.chkerr);
00833 UIP_LOG("tcp: bad checksum.");
00834 goto drop;
00835 }
00836
00837
00838
00839 for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
00840 if(uip_connr->tcpstateflags != CLOSED &&
00841 BUF->destport == uip_connr->lport &&
00842 BUF->srcport == uip_connr->rport &&
00843 BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
00844 BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
00845 goto found;
00846 }
00847 }
00848
00849
00850
00851
00852
00853 if((BUF->flags & TCP_CTL) != TCP_SYN)
00854 goto reset;
00855
00856 tmp16 = BUF->destport;
00857
00858 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00859 if(tmp16 == uip_listenports[c])
00860 goto found_listen;
00861 }
00862
00863
00864 UIP_STAT(++uip_stat.tcp.synrst);
00865 reset:
00866
00867
00868 if(BUF->flags & TCP_RST)
00869 goto drop;
00870
00871 UIP_STAT(++uip_stat.tcp.rst);
00872
00873 BUF->flags = TCP_RST | TCP_ACK;
00874 uip_len = 40;
00875 BUF->tcpoffset = 5 << 4;
00876
00877
00878 c = BUF->seqno[3];
00879 BUF->seqno[3] = BUF->ackno[3];
00880 BUF->ackno[3] = c;
00881
00882 c = BUF->seqno[2];
00883 BUF->seqno[2] = BUF->ackno[2];
00884 BUF->ackno[2] = c;
00885
00886 c = BUF->seqno[1];
00887 BUF->seqno[1] = BUF->ackno[1];
00888 BUF->ackno[1] = c;
00889
00890 c = BUF->seqno[0];
00891 BUF->seqno[0] = BUF->ackno[0];
00892 BUF->ackno[0] = c;
00893
00894
00895
00896
00897 if(++BUF->ackno[3] == 0) {
00898 if(++BUF->ackno[2] == 0) {
00899 if(++BUF->ackno[1] == 0) {
00900 ++BUF->ackno[0];
00901 }
00902 }
00903 }
00904
00905
00906 tmp16 = BUF->srcport;
00907 BUF->srcport = BUF->destport;
00908 BUF->destport = tmp16;
00909
00910
00911 tmp16 = BUF->destipaddr[0];
00912 BUF->destipaddr[0] = BUF->srcipaddr[0];
00913 BUF->srcipaddr[0] = tmp16;
00914 tmp16 = BUF->destipaddr[1];
00915 BUF->destipaddr[1] = BUF->srcipaddr[1];
00916 BUF->srcipaddr[1] = tmp16;
00917
00918
00919
00920 goto tcp_send_noconn;
00921
00922
00923
00924
00925 found_listen:
00926
00927
00928
00929
00930
00931
00932 uip_connr = 0;
00933 for(c = 0; c < UIP_CONNS; ++c) {
00934 if(uip_conns[c].tcpstateflags == CLOSED) {
00935 uip_connr = &uip_conns[c];
00936 break;
00937 }
00938 if(uip_conns[c].tcpstateflags == TIME_WAIT) {
00939 if(uip_connr == 0 ||
00940 uip_conns[c].timer > uip_connr->timer) {
00941 uip_connr = &uip_conns[c];
00942 }
00943 }
00944 }
00945
00946 if(uip_connr == 0) {
00947
00948
00949
00950 UIP_STAT(++uip_stat.tcp.syndrop);
00951 UIP_LOG("tcp: found no unused connections.");
00952 goto drop;
00953 }
00954 uip_conn = uip_connr;
00955
00956
00957 uip_connr->rto = uip_connr->timer = UIP_RTO;
00958 uip_connr->sa = 0;
00959 uip_connr->sv = 4;
00960 uip_connr->nrtx = 0;
00961 uip_connr->lport = BUF->destport;
00962 uip_connr->rport = BUF->srcport;
00963 uip_connr->ripaddr[0] = BUF->srcipaddr[0];
00964 uip_connr->ripaddr[1] = BUF->srcipaddr[1];
00965 uip_connr->tcpstateflags = SYN_RCVD;
00966
00967 uip_connr->snd_nxt[0] = iss[0];
00968 uip_connr->snd_nxt[1] = iss[1];
00969 uip_connr->snd_nxt[2] = iss[2];
00970 uip_connr->snd_nxt[3] = iss[3];
00971 uip_connr->len = 1;
00972
00973
00974 uip_connr->rcv_nxt[3] = BUF->seqno[3];
00975 uip_connr->rcv_nxt[2] = BUF->seqno[2];
00976 uip_connr->rcv_nxt[1] = BUF->seqno[1];
00977 uip_connr->rcv_nxt[0] = BUF->seqno[0];
00978 uip_add_rcv_nxt(1);
00979
00980
00981 if((BUF->tcpoffset & 0xf0) > 0x50) {
00982 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
00983 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
00984 if(opt == 0x00) {
00985
00986 break;
00987 } else if(opt == 0x01) {
00988 ++c;
00989
00990 } else if(opt == 0x02 &&
00991 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
00992
00993 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
00994 (u16_t)uip_buf[40 + UIP_LLH_LEN + 3 + c];
00995 uip_connr->initialmss = uip_connr->mss =
00996 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
00997
00998
00999 break;
01000 } else {
01001
01002
01003 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01004
01005
01006 break;
01007 }
01008 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01009 }
01010 }
01011 }
01012
01013
01014 #if UIP_ACTIVE_OPEN
01015 tcp_send_synack:
01016 BUF->flags = TCP_ACK;
01017
01018 tcp_send_syn:
01019 BUF->flags |= TCP_SYN;
01020 #else
01021 tcp_send_synack:
01022 BUF->flags = TCP_SYN | TCP_ACK;
01023 #endif
01024
01025
01026
01027 BUF->optdata[0] = 2;
01028 BUF->optdata[1] = 4;
01029 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01030 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01031 uip_len = 44;
01032 BUF->tcpoffset = 6 << 4;
01033 goto tcp_send;
01034
01035
01036 found:
01037 uip_conn = uip_connr;
01038 uip_flags = 0;
01039
01040
01041
01042
01043
01044 if(BUF->flags & TCP_RST) {
01045 uip_connr->tcpstateflags = CLOSED;
01046 UIP_LOG("tcp: got reset, aborting connection.");
01047 uip_flags = UIP_ABORT;
01048 UIP_APPCALL();
01049 goto drop;
01050 }
01051
01052
01053 c = (BUF->tcpoffset >> 4) << 2;
01054
01055
01056
01057 uip_len = uip_len - c - 20;
01058
01059
01060
01061
01062 if(uip_len > 0 &&
01063 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01064 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01065 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01066 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01067 goto tcp_send_ack;
01068 }
01069
01070
01071
01072
01073
01074 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01075 uip_add32(uip_connr->snd_nxt, uip_connr->len);
01076 if(BUF->ackno[0] == uip_acc32[0] &&
01077 BUF->ackno[1] == uip_acc32[1] &&
01078 BUF->ackno[2] == uip_acc32[2] &&
01079 BUF->ackno[3] == uip_acc32[3]) {
01080
01081 uip_connr->snd_nxt[0] = uip_acc32[0];
01082 uip_connr->snd_nxt[1] = uip_acc32[1];
01083 uip_connr->snd_nxt[2] = uip_acc32[2];
01084 uip_connr->snd_nxt[3] = uip_acc32[3];
01085
01086
01087
01088 if(uip_connr->nrtx == 0) {
01089 signed char m;
01090 m = uip_connr->rto - uip_connr->timer;
01091
01092 m = m - (uip_connr->sa >> 3);
01093 uip_connr->sa += m;
01094 if(m < 0) {
01095 m = -m;
01096 }
01097 m = m - (uip_connr->sv >> 2);
01098 uip_connr->sv += m;
01099 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01100
01101 }
01102
01103 uip_flags = UIP_ACKDATA;
01104
01105 uip_connr->timer = uip_connr->rto;
01106 }
01107
01108 }
01109
01110
01111 switch(uip_connr->tcpstateflags & TS_MASK) {
01112
01113
01114
01115
01116 case SYN_RCVD:
01117
01118
01119
01120
01121 if(uip_flags & UIP_ACKDATA) {
01122 uip_connr->tcpstateflags = ESTABLISHED;
01123 uip_flags = UIP_CONNECTED;
01124 uip_connr->len = 0;
01125 if(uip_len > 0) {
01126 uip_flags |= UIP_NEWDATA;
01127 uip_add_rcv_nxt(uip_len);
01128 }
01129 uip_slen = 0;
01130 UIP_APPCALL();
01131 goto appsend;
01132 }
01133 goto drop;
01134 #if UIP_ACTIVE_OPEN
01135 case SYN_SENT:
01136
01137
01138
01139
01140 if((uip_flags & UIP_ACKDATA) &&
01141 BUF->flags == (TCP_SYN | TCP_ACK)) {
01142
01143
01144 if((BUF->tcpoffset & 0xf0) > 0x50) {
01145 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01146 opt = uip_buf[40 + UIP_LLH_LEN + c];
01147 if(opt == 0x00) {
01148
01149 break;
01150 } else if(opt == 0x01) {
01151 ++c;
01152
01153 } else if(opt == 0x02 &&
01154 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
01155
01156 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01157 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01158 uip_connr->initialmss =
01159 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01160
01161
01162 break;
01163 } else {
01164
01165
01166 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01167
01168
01169 break;
01170 }
01171 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01172 }
01173 }
01174 }
01175 uip_connr->tcpstateflags = ESTABLISHED;
01176 uip_connr->rcv_nxt[0] = BUF->seqno[0];
01177 uip_connr->rcv_nxt[1] = BUF->seqno[1];
01178 uip_connr->rcv_nxt[2] = BUF->seqno[2];
01179 uip_connr->rcv_nxt[3] = BUF->seqno[3];
01180 uip_add_rcv_nxt(1);
01181 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01182 uip_connr->len = 0;
01183 uip_len = 0;
01184 uip_slen = 0;
01185 UIP_APPCALL();
01186 goto appsend;
01187 }
01188 goto reset;
01189 #endif
01190
01191 case ESTABLISHED:
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203 if(BUF->flags & TCP_FIN) {
01204 if(uip_outstanding(uip_connr)) {
01205 goto drop;
01206 }
01207 uip_add_rcv_nxt(1 + uip_len);
01208 uip_flags = UIP_CLOSE;
01209 if(uip_len > 0) {
01210 uip_flags |= UIP_NEWDATA;
01211 }
01212 UIP_APPCALL();
01213 uip_connr->len = 1;
01214 uip_connr->tcpstateflags = LAST_ACK;
01215 uip_connr->nrtx = 0;
01216 tcp_send_finack:
01217 BUF->flags = TCP_FIN | TCP_ACK;
01218 goto tcp_send_nodata;
01219 }
01220
01221
01222
01223 if(BUF->flags & TCP_URG) {
01224 #if UIP_URGDATA > 0
01225 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
01226 if(uip_urglen > uip_len) {
01227
01228 uip_urglen = uip_len;
01229 }
01230 uip_add_rcv_nxt(uip_urglen);
01231 uip_len -= uip_urglen;
01232 uip_urgdata = uip_appdata;
01233 uip_appdata += uip_urglen;
01234 } else {
01235 uip_urglen = 0;
01236 #endif
01237 uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
01238 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
01239 }
01240
01241
01242
01243
01244
01245
01246
01247 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01248 uip_flags |= UIP_NEWDATA;
01249 uip_add_rcv_nxt(uip_len);
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
01265 if(tmp16 > uip_connr->initialmss ||
01266 tmp16 == 0) {
01267 tmp16 = uip_connr->initialmss;
01268 }
01269 uip_connr->mss = tmp16;
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
01288 uip_slen = 0;
01289 UIP_APPCALL();
01290
01291 appsend:
01292
01293 if(uip_flags & UIP_ABORT) {
01294 uip_slen = 0;
01295 uip_connr->tcpstateflags = CLOSED;
01296 BUF->flags = TCP_RST | TCP_ACK;
01297 goto tcp_send_nodata;
01298 }
01299
01300 if(uip_flags & UIP_CLOSE) {
01301 uip_slen = 0;
01302 uip_connr->len = 1;
01303 uip_connr->tcpstateflags = FIN_WAIT_1;
01304 uip_connr->nrtx = 0;
01305 BUF->flags = TCP_FIN | TCP_ACK;
01306 goto tcp_send_nodata;
01307 }
01308
01309
01310 if(uip_slen > 0) {
01311
01312
01313
01314 if((uip_flags & UIP_ACKDATA) != 0) {
01315 uip_connr->len = 0;
01316 }
01317
01318
01319
01320
01321 if(uip_connr->len == 0) {
01322
01323
01324
01325
01326 if(uip_slen > uip_connr->mss) {
01327 uip_slen = uip_connr->mss;
01328 }
01329
01330
01331
01332 uip_connr->len = uip_slen;
01333 } else {
01334
01335
01336
01337
01338 uip_slen = uip_connr->len;
01339 }
01340 } else {
01341 uip_connr->len = 0;
01342 }
01343 uip_connr->nrtx = 0;
01344 apprexmit:
01345 uip_appdata = uip_sappdata;
01346
01347
01348
01349 if(uip_slen > 0 && uip_connr->len > 0) {
01350
01351 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
01352
01353 BUF->flags = TCP_ACK | TCP_PSH;
01354
01355 goto tcp_send_noopts;
01356 }
01357
01358
01359 if(uip_flags & UIP_NEWDATA) {
01360 uip_len = UIP_TCPIP_HLEN;
01361 BUF->flags = TCP_ACK;
01362 goto tcp_send_noopts;
01363 }
01364 }
01365 goto drop;
01366 case LAST_ACK:
01367
01368
01369 if(uip_flags & UIP_ACKDATA) {
01370 uip_connr->tcpstateflags = CLOSED;
01371 uip_flags = UIP_CLOSE;
01372 UIP_APPCALL();
01373 }
01374 break;
01375
01376 case FIN_WAIT_1:
01377
01378
01379
01380 if(uip_len > 0) {
01381 uip_add_rcv_nxt(uip_len);
01382 }
01383 if(BUF->flags & TCP_FIN) {
01384 if(uip_flags & UIP_ACKDATA) {
01385 uip_connr->tcpstateflags = TIME_WAIT;
01386 uip_connr->timer = 0;
01387 uip_connr->len = 0;
01388 } else {
01389 uip_connr->tcpstateflags = CLOSING;
01390 }
01391 uip_add_rcv_nxt(1);
01392 uip_flags = UIP_CLOSE;
01393 UIP_APPCALL();
01394 goto tcp_send_ack;
01395 } else if(uip_flags & UIP_ACKDATA) {
01396 uip_connr->tcpstateflags = FIN_WAIT_2;
01397 uip_connr->len = 0;
01398 goto drop;
01399 }
01400 if(uip_len > 0) {
01401 goto tcp_send_ack;
01402 }
01403 goto drop;
01404
01405 case FIN_WAIT_2:
01406 if(uip_len > 0) {
01407 uip_add_rcv_nxt(uip_len);
01408 }
01409 if(BUF->flags & TCP_FIN) {
01410 uip_connr->tcpstateflags = TIME_WAIT;
01411 uip_connr->timer = 0;
01412 uip_add_rcv_nxt(1);
01413 uip_flags = UIP_CLOSE;
01414 UIP_APPCALL();
01415 goto tcp_send_ack;
01416 }
01417 if(uip_len > 0) {
01418 goto tcp_send_ack;
01419 }
01420 goto drop;
01421
01422 case TIME_WAIT:
01423 goto tcp_send_ack;
01424
01425 case CLOSING:
01426 if(uip_flags & UIP_ACKDATA) {
01427 uip_connr->tcpstateflags = TIME_WAIT;
01428 uip_connr->timer = 0;
01429 }
01430 }
01431 goto drop;
01432
01433
01434
01435
01436 tcp_send_ack:
01437 BUF->flags = TCP_ACK;
01438 tcp_send_nodata:
01439 uip_len = 40;
01440 tcp_send_noopts:
01441 BUF->tcpoffset = 5 << 4;
01442 tcp_send:
01443
01444
01445
01446
01447 BUF->ackno[0] = uip_connr->rcv_nxt[0];
01448 BUF->ackno[1] = uip_connr->rcv_nxt[1];
01449 BUF->ackno[2] = uip_connr->rcv_nxt[2];
01450 BUF->ackno[3] = uip_connr->rcv_nxt[3];
01451
01452 BUF->seqno[0] = uip_connr->snd_nxt[0];
01453 BUF->seqno[1] = uip_connr->snd_nxt[1];
01454 BUF->seqno[2] = uip_connr->snd_nxt[2];
01455 BUF->seqno[3] = uip_connr->snd_nxt[3];
01456
01457 BUF->proto = UIP_PROTO_TCP;
01458
01459 BUF->srcport = uip_connr->lport;
01460 BUF->destport = uip_connr->rport;
01461
01462 BUF->srcipaddr[0] = uip_hostaddr[0];
01463 BUF->srcipaddr[1] = uip_hostaddr[1];
01464 BUF->destipaddr[0] = uip_connr->ripaddr[0];
01465 BUF->destipaddr[1] = uip_connr->ripaddr[1];
01466
01467
01468 if(uip_connr->tcpstateflags & UIP_STOPPED) {
01469
01470
01471 BUF->wnd[0] = BUF->wnd[1] = 0;
01472 } else {
01473 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
01474 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
01475 }
01476
01477 tcp_send_noconn:
01478
01479 BUF->len[0] = (uip_len >> 8);
01480 BUF->len[1] = (uip_len & 0xff);
01481
01482
01483 BUF->tcpchksum = 0;
01484 BUF->tcpchksum = ~(uip_tcpchksum());
01485
01486 ip_send_nolen:
01487
01488 BUF->vhl = 0x45;
01489 BUF->tos = 0;
01490 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
01491 BUF->ttl = UIP_TTL;
01492 ++ipid;
01493 BUF->ipid[0] = ipid >> 8;
01494 BUF->ipid[1] = ipid & 0xff;
01495
01496
01497 BUF->ipchksum = 0;
01498 BUF->ipchksum = ~(uip_ipchksum());
01499
01500 UIP_STAT(++uip_stat.tcp.sent);
01501 send:
01502 UIP_STAT(++uip_stat.ip.sent);
01503
01504 return;
01505 drop:
01506 uip_len = 0;
01507 return;
01508 }
01509
01510 u16_t
01511 htons(u16_t val)
01512 {
01513 return HTONS(val);
01514 }
01515