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