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