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_arp.h"
00077 #include "net/uip_arch.h"
00078
00079 #if !UIP_CONF_IPV6
00080
00081
00082
00083
00084
00085 #if UIP_CONF_IPV6
00086 #include "net/uip-neighbor.h"
00087 #endif
00088
00089 #include <string.h>
00090
00091
00092
00093
00094
00095
00096
00097
00098 #if UIP_FIXEDADDR > 0
00099 const uip_ipaddr_t uip_hostaddr =
00100 { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
00101 const uip_ipaddr_t uip_draddr =
00102 { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
00103 const uip_ipaddr_t uip_netmask =
00104 { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
00105 #else
00106 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
00107 #endif
00108
00109 const uip_ipaddr_t uip_broadcast_addr =
00110 #if UIP_CONF_IPV6
00111 { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
00113 #else
00114 { { 0xff, 0xff, 0xff, 0xff } };
00115 #endif
00116 const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, } };
00117
00118 #if UIP_FIXEDETHADDR
00119 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
00120 UIP_ETHADDR1,
00121 UIP_ETHADDR2,
00122 UIP_ETHADDR3,
00123 UIP_ETHADDR4,
00124 UIP_ETHADDR5}};
00125 #else
00126 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
00127 #endif
00128
00129
00130 uip_buf_t uip_aligned_buf;
00131
00132 void *uip_appdata;
00133
00134 void *uip_sappdata;
00135
00136
00137 #if UIP_URGDATA > 0
00138 void *uip_urgdata;
00139
00140
00141 u16_t uip_urglen, uip_surglen;
00142 #endif
00143
00144 u16_t uip_len, uip_slen;
00145
00146
00147
00148
00149 u8_t uip_flags;
00150
00151
00152 struct uip_conn *uip_conn;
00153
00154
00155 struct uip_conn uip_conns[UIP_CONNS];
00156
00157
00158 u16_t uip_listenports[UIP_LISTENPORTS];
00159
00160
00161 #if UIP_UDP
00162 struct uip_udp_conn *uip_udp_conn;
00163 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00164 #endif
00165
00166 static u16_t ipid;
00167
00168
00169
00170 void uip_setipid(u16_t id) { ipid = id; }
00171
00172 static u8_t iss[4];
00173
00174
00175 #if UIP_ACTIVE_OPEN || UIP_UDP
00176 static u16_t lastport;
00177
00178 #endif
00179
00180
00181 u8_t uip_acc32[4];
00182 static u8_t c, opt;
00183 static u16_t tmp16;
00184
00185
00186 #define TCP_FIN 0x01
00187 #define TCP_SYN 0x02
00188 #define TCP_RST 0x04
00189 #define TCP_PSH 0x08
00190 #define TCP_ACK 0x10
00191 #define TCP_URG 0x20
00192 #define TCP_CTL 0x3f
00193
00194 #define TCP_OPT_END 0
00195 #define TCP_OPT_NOOP 1
00196 #define TCP_OPT_MSS 2
00197
00198 #define TCP_OPT_MSS_LEN 4
00199
00200 #define ICMP_ECHO_REPLY 0
00201 #define ICMP_ECHO 8
00202
00203 #define ICMP_DEST_UNREACHABLE 3
00204 #define ICMP_PORT_UNREACHABLE 3
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 uip_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 : uip_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, 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 : uip_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 || UIP_UDP
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 == uip_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 = uip_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(const 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 == uip_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 = UIP_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 #if UIP_ACTIVE_OPEN
00695 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
00696
00697 BUF->flags = 0;
00698 goto tcp_send_syn;
00699 #endif
00700 }
00701 goto drop;
00702
00703
00704 } else if(flag == UIP_TIMER) {
00705 #if UIP_REASSEMBLY
00706 if(uip_reasstmr != 0) {
00707 --uip_reasstmr;
00708 }
00709 #endif
00710
00711 if(++iss[3] == 0) {
00712 if(++iss[2] == 0) {
00713 if(++iss[1] == 0) {
00714 ++iss[0];
00715 }
00716 }
00717 }
00718
00719
00720 uip_len = 0;
00721 uip_slen = 0;
00722
00723
00724
00725
00726
00727 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
00728 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
00729 ++(uip_connr->timer);
00730 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00731 uip_connr->tcpstateflags = UIP_CLOSED;
00732 }
00733 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
00734
00735
00736
00737
00738 if(uip_outstanding(uip_connr)) {
00739 if(uip_connr->timer-- == 0) {
00740 if(uip_connr->nrtx == UIP_MAXRTX ||
00741 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
00742 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
00743 uip_connr->nrtx == UIP_MAXSYNRTX)) {
00744 uip_connr->tcpstateflags = UIP_CLOSED;
00745
00746
00747
00748
00749 uip_flags = UIP_TIMEDOUT;
00750 UIP_APPCALL();
00751
00752
00753 BUF->flags = TCP_RST | TCP_ACK;
00754 goto tcp_send_nodata;
00755 }
00756
00757
00758 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00759 4:
00760 uip_connr->nrtx);
00761 ++(uip_connr->nrtx);
00762
00763
00764
00765
00766
00767
00768
00769 UIP_STAT(++uip_stat.tcp.rexmit);
00770 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
00771 case UIP_SYN_RCVD:
00772
00773
00774 goto tcp_send_synack;
00775
00776 #if UIP_ACTIVE_OPEN
00777 case UIP_SYN_SENT:
00778
00779 BUF->flags = 0;
00780 goto tcp_send_syn;
00781 #endif
00782
00783 case UIP_ESTABLISHED:
00784
00785
00786
00787
00788 uip_flags = UIP_REXMIT;
00789 UIP_APPCALL();
00790 goto apprexmit;
00791
00792 case UIP_FIN_WAIT_1:
00793 case UIP_CLOSING:
00794 case UIP_LAST_ACK:
00795
00796 goto tcp_send_finack;
00797
00798 }
00799 }
00800 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
00801
00802
00803 uip_flags = UIP_POLL;
00804 UIP_APPCALL();
00805 goto appsend;
00806 }
00807 }
00808 goto drop;
00809 }
00810 #if UIP_UDP
00811 if(flag == UIP_UDP_TIMER) {
00812 if(uip_udp_conn->lport != 0) {
00813 uip_conn = NULL;
00814 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
00815 uip_len = uip_slen = 0;
00816 uip_flags = UIP_POLL;
00817 UIP_UDP_APPCALL();
00818 goto udp_send;
00819 } else {
00820 goto drop;
00821 }
00822 }
00823 #endif
00824
00825
00826 UIP_STAT(++uip_stat.ip.recv);
00827
00828
00829
00830 #if UIP_CONF_IPV6
00831
00832 if((BUF->vtc & 0xf0) != 0x60) {
00833 UIP_STAT(++uip_stat.ip.drop);
00834 UIP_STAT(++uip_stat.ip.vhlerr);
00835 UIP_LOG("ipv6: invalid version.");
00836 goto drop;
00837 }
00838 #else
00839
00840 if(BUF->vhl != 0x45) {
00841 UIP_STAT(++uip_stat.ip.drop);
00842 UIP_STAT(++uip_stat.ip.vhlerr);
00843 UIP_LOG("ip: invalid version or header length.");
00844 goto drop;
00845 }
00846 #endif
00847
00848
00849
00850
00851
00852
00853
00854
00855 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
00856 uip_len = (BUF->len[0] << 8) + BUF->len[1];
00857 #if UIP_CONF_IPV6
00858 uip_len += 40;
00859
00860
00861
00862
00863
00864
00865
00866
00867 #endif
00868 } else {
00869 UIP_LOG("ip: packet shorter than reported in IP header.");
00870 goto drop;
00871 }
00872
00873 #if !UIP_CONF_IPV6
00874
00875 if((BUF->ipoffset[0] & 0x3f) != 0 ||
00876 BUF->ipoffset[1] != 0) {
00877 #if UIP_REASSEMBLY
00878 uip_len = uip_reass();
00879 if(uip_len == 0) {
00880 goto drop;
00881 }
00882 #else
00883 UIP_STAT(++uip_stat.ip.drop);
00884 UIP_STAT(++uip_stat.ip.fragerr);
00885 UIP_LOG("ip: fragment dropped.");
00886 goto drop;
00887 #endif
00888 }
00889 #endif
00890
00891 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
00892
00893
00894
00895 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
00896 if(BUF->proto == UIP_PROTO_ICMP) {
00897 UIP_LOG("ip: possible ping config packet received.");
00898 goto icmp_input;
00899 } else {
00900 UIP_LOG("ip: packet dropped since no address assigned.");
00901 goto drop;
00902 }
00903 #endif
00904
00905 } else {
00906
00907
00908 #if UIP_BROADCAST
00909 DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
00910 if(BUF->proto == UIP_PROTO_UDP &&
00911 (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) ||
00912 (BUF->destipaddr.u8[0] & 224) == 224)) {
00913
00914
00915
00916
00917
00918
00919
00920
00921 goto udp_input;
00922 }
00923 #endif
00924
00925
00926 #if !UIP_CONF_IPV6
00927 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
00928 UIP_STAT(++uip_stat.ip.drop);
00929 goto drop;
00930 }
00931 #else
00932
00933
00934
00935
00936
00937 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
00938 BUF->destipaddr.u16[0] != UIP_HTONS(0xff02)) {
00939 UIP_STAT(++uip_stat.ip.drop);
00940 goto drop;
00941 }
00942 #endif
00943 }
00944
00945 #if !UIP_CONF_IPV6
00946 if(uip_ipchksum() != 0xffff) {
00947
00948 UIP_STAT(++uip_stat.ip.drop);
00949 UIP_STAT(++uip_stat.ip.chkerr);
00950 UIP_LOG("ip: bad checksum.");
00951 goto drop;
00952 }
00953 #endif
00954
00955 if(BUF->proto == UIP_PROTO_TCP) {
00956
00957
00958 goto tcp_input;
00959 }
00960
00961 #if UIP_UDP
00962 if(BUF->proto == UIP_PROTO_UDP) {
00963 goto udp_input;
00964 }
00965 #endif
00966
00967 #if !UIP_CONF_IPV6
00968
00969 if(BUF->proto != UIP_PROTO_ICMP) {
00970
00971 UIP_STAT(++uip_stat.ip.drop);
00972 UIP_STAT(++uip_stat.ip.protoerr);
00973 UIP_LOG("ip: neither tcp nor icmp.");
00974 goto drop;
00975 }
00976
00977 #if UIP_PINGADDRCONF
00978 icmp_input:
00979 #endif
00980 UIP_STAT(++uip_stat.icmp.recv);
00981
00982
00983
00984
00985 if(ICMPBUF->type != ICMP_ECHO) {
00986 UIP_STAT(++uip_stat.icmp.drop);
00987 UIP_STAT(++uip_stat.icmp.typeerr);
00988 UIP_LOG("icmp: not icmp echo.");
00989 goto drop;
00990 }
00991
00992
00993
00994
00995 #if UIP_PINGADDRCONF
00996 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
00997 uip_hostaddr = BUF->destipaddr;
00998 }
00999 #endif
01000
01001 ICMPBUF->type = ICMP_ECHO_REPLY;
01002
01003 if(ICMPBUF->icmpchksum >= UIP_HTONS(0xffff - (ICMP_ECHO << 8))) {
01004 ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8) + 1;
01005 } else {
01006 ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8);
01007 }
01008
01009
01010 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
01011 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01012
01013 UIP_STAT(++uip_stat.icmp.sent);
01014 BUF->ttl = UIP_TTL;
01015 goto ip_send_nolen;
01016
01017
01018 #else
01019
01020
01021 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
01022
01023 if(BUF->proto != UIP_PROTO_ICMP6) {
01024
01025 UIP_STAT(++uip_stat.ip.drop);
01026 UIP_STAT(++uip_stat.ip.protoerr);
01027 UIP_LOG("ip: neither tcp nor icmp6.");
01028 goto drop;
01029 }
01030
01031 UIP_STAT(++uip_stat.icmp.recv);
01032
01033
01034
01035 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
01036 if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
01037
01038 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
01039
01040 uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
01041 }
01042
01043
01044
01045 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
01046 ICMPBUF->flags = ICMP6_FLAG_S;
01047
01048 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
01049
01050 uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr);
01051 uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr);
01052 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
01053 ICMPBUF->options[1] = 1;
01054 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
01055 ICMPBUF->icmpchksum = 0;
01056 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
01057
01058 goto send;
01059
01060 }
01061 goto drop;
01062 } else if(ICMPBUF->type == ICMP6_ECHO) {
01063
01064
01065
01066
01067 ICMPBUF->type = ICMP6_ECHO_REPLY;
01068
01069 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
01070 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01071 ICMPBUF->icmpchksum = 0;
01072 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
01073
01074 UIP_STAT(++uip_stat.icmp.sent);
01075 goto send;
01076 } else {
01077 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
01078 UIP_STAT(++uip_stat.icmp.drop);
01079 UIP_STAT(++uip_stat.icmp.typeerr);
01080 UIP_LOG("icmp: unknown ICMP message.");
01081 goto drop;
01082 }
01083
01084
01085
01086 #endif
01087
01088 #if UIP_UDP
01089
01090 udp_input:
01091
01092
01093
01094
01095 #if UIP_UDP_CHECKSUMS
01096 uip_len = uip_len - UIP_IPUDPH_LEN;
01097 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01098 if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
01099 UIP_STAT(++uip_stat.udp.drop);
01100 UIP_STAT(++uip_stat.udp.chkerr);
01101 UIP_LOG("udp: bad checksum.");
01102 goto drop;
01103 }
01104 #else
01105 uip_len = uip_len - UIP_IPUDPH_LEN;
01106 #endif
01107
01108
01109 if(UDPBUF->destport == 0) {
01110 UIP_LOG("udp: zero port.");
01111 goto drop;
01112 }
01113
01114
01115 for(uip_udp_conn = &uip_udp_conns[0];
01116 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
01117 ++uip_udp_conn) {
01118
01119
01120
01121
01122
01123
01124
01125 if(uip_udp_conn->lport != 0 &&
01126 UDPBUF->destport == uip_udp_conn->lport &&
01127 (uip_udp_conn->rport == 0 ||
01128 UDPBUF->srcport == uip_udp_conn->rport) &&
01129 (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) ||
01130 uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) ||
01131 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
01132 goto udp_found;
01133 }
01134 }
01135 UIP_LOG("udp: no matching connection found");
01136 #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6
01137
01138 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
01139
01140
01141 ICMPBUF->type = ICMP_DEST_UNREACHABLE;
01142 ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
01143
01144
01145 ICMPBUF->icmpchksum = 0;
01146 ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
01147
01148
01149
01150 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
01151
01152
01153 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01154
01155
01156
01157 uip_len = 36 + UIP_IPH_LEN;
01158 ICMPBUF->len[0] = 0;
01159 ICMPBUF->len[1] = (u8_t)uip_len;
01160 ICMPBUF->ttl = UIP_TTL;
01161 ICMPBUF->proto = UIP_PROTO_ICMP;
01162
01163 goto ip_send_nolen;
01164 #else
01165 goto drop;
01166 #endif
01167
01168 udp_found:
01169 uip_conn = NULL;
01170 uip_flags = UIP_NEWDATA;
01171 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01172 uip_slen = 0;
01173 UIP_UDP_APPCALL();
01174
01175 udp_send:
01176 if(uip_slen == 0) {
01177 goto drop;
01178 }
01179 uip_len = uip_slen + UIP_IPUDPH_LEN;
01180
01181 #if UIP_CONF_IPV6
01182
01183
01184 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01185 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01186 #else
01187 BUF->len[0] = (uip_len >> 8);
01188 BUF->len[1] = (uip_len & 0xff);
01189 #endif
01190
01191 BUF->ttl = uip_udp_conn->ttl;
01192 BUF->proto = UIP_PROTO_UDP;
01193
01194 UDPBUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
01195 UDPBUF->udpchksum = 0;
01196
01197 BUF->srcport = uip_udp_conn->lport;
01198 BUF->destport = uip_udp_conn->rport;
01199
01200 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01201 uip_ipaddr_copy(&BUF->destipaddr, &uip_udp_conn->ripaddr);
01202
01203 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
01204
01205 #if UIP_UDP_CHECKSUMS
01206
01207 UDPBUF->udpchksum = ~(uip_udpchksum());
01208 if(UDPBUF->udpchksum == 0) {
01209 UDPBUF->udpchksum = 0xffff;
01210 }
01211 #endif
01212
01213 goto ip_send_nolen;
01214 #endif
01215
01216
01217 tcp_input:
01218 UIP_STAT(++uip_stat.tcp.recv);
01219
01220
01221
01222 if(uip_tcpchksum() != 0xffff) {
01223
01224 UIP_STAT(++uip_stat.tcp.drop);
01225 UIP_STAT(++uip_stat.tcp.chkerr);
01226 UIP_LOG("tcp: bad checksum.");
01227 goto drop;
01228 }
01229
01230
01231 if(BUF->destport == 0 || BUF->srcport == 0) {
01232 UIP_LOG("tcp: zero port.");
01233 goto drop;
01234 }
01235
01236
01237
01238 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
01239 ++uip_connr) {
01240 if(uip_connr->tcpstateflags != UIP_CLOSED &&
01241 BUF->destport == uip_connr->lport &&
01242 BUF->srcport == uip_connr->rport &&
01243 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) {
01244 goto found;
01245 }
01246 }
01247
01248
01249
01250
01251
01252 if((BUF->flags & TCP_CTL) != TCP_SYN) {
01253 goto reset;
01254 }
01255
01256 tmp16 = BUF->destport;
01257
01258 for(c = 0; c < UIP_LISTENPORTS; ++c) {
01259 if(tmp16 == uip_listenports[c]) {
01260 goto found_listen;
01261 }
01262 }
01263
01264
01265 UIP_STAT(++uip_stat.tcp.synrst);
01266
01267 reset:
01268
01269 if(BUF->flags & TCP_RST) {
01270 goto drop;
01271 }
01272
01273 UIP_STAT(++uip_stat.tcp.rst);
01274
01275 BUF->flags = TCP_RST | TCP_ACK;
01276 uip_len = UIP_IPTCPH_LEN;
01277 BUF->tcpoffset = 5 << 4;
01278
01279
01280 c = BUF->seqno[3];
01281 BUF->seqno[3] = BUF->ackno[3];
01282 BUF->ackno[3] = c;
01283
01284 c = BUF->seqno[2];
01285 BUF->seqno[2] = BUF->ackno[2];
01286 BUF->ackno[2] = c;
01287
01288 c = BUF->seqno[1];
01289 BUF->seqno[1] = BUF->ackno[1];
01290 BUF->ackno[1] = c;
01291
01292 c = BUF->seqno[0];
01293 BUF->seqno[0] = BUF->ackno[0];
01294 BUF->ackno[0] = c;
01295
01296
01297
01298
01299 if(++BUF->ackno[3] == 0) {
01300 if(++BUF->ackno[2] == 0) {
01301 if(++BUF->ackno[1] == 0) {
01302 ++BUF->ackno[0];
01303 }
01304 }
01305 }
01306
01307
01308 tmp16 = BUF->srcport;
01309 BUF->srcport = BUF->destport;
01310 BUF->destport = tmp16;
01311
01312
01313 uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
01314 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01315
01316
01317 goto tcp_send_noconn;
01318
01319
01320
01321
01322 found_listen:
01323
01324
01325
01326
01327
01328
01329 uip_connr = 0;
01330 for(c = 0; c < UIP_CONNS; ++c) {
01331 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
01332 uip_connr = &uip_conns[c];
01333 break;
01334 }
01335 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
01336 if(uip_connr == 0 ||
01337 uip_conns[c].timer > uip_connr->timer) {
01338 uip_connr = &uip_conns[c];
01339 }
01340 }
01341 }
01342
01343 if(uip_connr == 0) {
01344
01345
01346
01347 UIP_STAT(++uip_stat.tcp.syndrop);
01348 UIP_LOG("tcp: found no unused connections.");
01349 goto drop;
01350 }
01351 uip_conn = uip_connr;
01352
01353
01354 uip_connr->rto = uip_connr->timer = UIP_RTO;
01355 uip_connr->sa = 0;
01356 uip_connr->sv = 4;
01357 uip_connr->nrtx = 0;
01358 uip_connr->lport = BUF->destport;
01359 uip_connr->rport = BUF->srcport;
01360 uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr);
01361 uip_connr->tcpstateflags = UIP_SYN_RCVD;
01362
01363 uip_connr->snd_nxt[0] = iss[0];
01364 uip_connr->snd_nxt[1] = iss[1];
01365 uip_connr->snd_nxt[2] = iss[2];
01366 uip_connr->snd_nxt[3] = iss[3];
01367 uip_connr->len = 1;
01368
01369
01370 uip_connr->rcv_nxt[3] = BUF->seqno[3];
01371 uip_connr->rcv_nxt[2] = BUF->seqno[2];
01372 uip_connr->rcv_nxt[1] = BUF->seqno[1];
01373 uip_connr->rcv_nxt[0] = BUF->seqno[0];
01374 uip_add_rcv_nxt(1);
01375
01376
01377 if((BUF->tcpoffset & 0xf0) > 0x50) {
01378 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01379 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
01380 if(opt == TCP_OPT_END) {
01381
01382 break;
01383 } else if(opt == TCP_OPT_NOOP) {
01384 ++c;
01385
01386 } else if(opt == TCP_OPT_MSS &&
01387 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01388
01389 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01390 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
01391 uip_connr->initialmss = uip_connr->mss =
01392 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01393
01394
01395 break;
01396 } else {
01397
01398
01399 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01400
01401
01402 break;
01403 }
01404 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01405 }
01406 }
01407 }
01408
01409
01410 #if UIP_ACTIVE_OPEN
01411 tcp_send_synack:
01412 BUF->flags = TCP_ACK;
01413
01414 tcp_send_syn:
01415 BUF->flags |= TCP_SYN;
01416 #else
01417 tcp_send_synack:
01418 BUF->flags = TCP_SYN | TCP_ACK;
01419 #endif
01420
01421
01422
01423 BUF->optdata[0] = TCP_OPT_MSS;
01424 BUF->optdata[1] = TCP_OPT_MSS_LEN;
01425 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01426 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01427 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
01428 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
01429 goto tcp_send;
01430
01431
01432 found:
01433 uip_conn = uip_connr;
01434 uip_flags = 0;
01435
01436
01437
01438
01439 if(BUF->flags & TCP_RST) {
01440 uip_connr->tcpstateflags = UIP_CLOSED;
01441 UIP_LOG("tcp: got reset, aborting connection.");
01442 uip_flags = UIP_ABORT;
01443 UIP_APPCALL();
01444 goto drop;
01445 }
01446
01447
01448 c = (BUF->tcpoffset >> 4) << 2;
01449
01450
01451
01452 uip_len = uip_len - c - UIP_IPH_LEN;
01453
01454
01455
01456
01457
01458
01459 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
01460 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
01461 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
01462 ((BUF->flags & TCP_CTL) == TCP_SYN)))) {
01463 if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
01464 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01465 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01466 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01467 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01468 goto tcp_send_ack;
01469 }
01470 }
01471
01472
01473
01474
01475
01476 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01477 uip_add32(uip_connr->snd_nxt, uip_connr->len);
01478
01479 if(BUF->ackno[0] == uip_acc32[0] &&
01480 BUF->ackno[1] == uip_acc32[1] &&
01481 BUF->ackno[2] == uip_acc32[2] &&
01482 BUF->ackno[3] == uip_acc32[3]) {
01483
01484 uip_connr->snd_nxt[0] = uip_acc32[0];
01485 uip_connr->snd_nxt[1] = uip_acc32[1];
01486 uip_connr->snd_nxt[2] = uip_acc32[2];
01487 uip_connr->snd_nxt[3] = uip_acc32[3];
01488
01489
01490 if(uip_connr->nrtx == 0) {
01491 signed char m;
01492 m = uip_connr->rto - uip_connr->timer;
01493
01494 m = m - (uip_connr->sa >> 3);
01495 uip_connr->sa += m;
01496 if(m < 0) {
01497 m = -m;
01498 }
01499 m = m - (uip_connr->sv >> 2);
01500 uip_connr->sv += m;
01501 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01502
01503 }
01504
01505 uip_flags = UIP_ACKDATA;
01506
01507 uip_connr->timer = uip_connr->rto;
01508
01509
01510 uip_connr->len = 0;
01511 }
01512
01513 }
01514
01515
01516 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
01517
01518
01519
01520
01521 case UIP_SYN_RCVD:
01522
01523
01524
01525
01526 if(uip_flags & UIP_ACKDATA) {
01527 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01528 uip_flags = UIP_CONNECTED;
01529 uip_connr->len = 0;
01530 if(uip_len > 0) {
01531 uip_flags |= UIP_NEWDATA;
01532 uip_add_rcv_nxt(uip_len);
01533 }
01534 uip_slen = 0;
01535 UIP_APPCALL();
01536 goto appsend;
01537 }
01538
01539 if((BUF->flags & TCP_CTL) == TCP_SYN) {
01540 goto tcp_send_synack;
01541 }
01542 goto drop;
01543 #if UIP_ACTIVE_OPEN
01544 case UIP_SYN_SENT:
01545
01546
01547
01548
01549 if((uip_flags & UIP_ACKDATA) &&
01550 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
01551
01552
01553 if((BUF->tcpoffset & 0xf0) > 0x50) {
01554 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
01555 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
01556 if(opt == TCP_OPT_END) {
01557
01558 break;
01559 } else if(opt == TCP_OPT_NOOP) {
01560 ++c;
01561
01562 } else if(opt == TCP_OPT_MSS &&
01563 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01564
01565 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01566 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01567 uip_connr->initialmss =
01568 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01569
01570
01571 break;
01572 } else {
01573
01574
01575 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01576
01577
01578 break;
01579 }
01580 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01581 }
01582 }
01583 }
01584 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01585 uip_connr->rcv_nxt[0] = BUF->seqno[0];
01586 uip_connr->rcv_nxt[1] = BUF->seqno[1];
01587 uip_connr->rcv_nxt[2] = BUF->seqno[2];
01588 uip_connr->rcv_nxt[3] = BUF->seqno[3];
01589 uip_add_rcv_nxt(1);
01590 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01591 uip_connr->len = 0;
01592 uip_len = 0;
01593 uip_slen = 0;
01594 UIP_APPCALL();
01595 goto appsend;
01596 }
01597
01598 uip_flags = UIP_ABORT;
01599 UIP_APPCALL();
01600
01601 uip_conn->tcpstateflags = UIP_CLOSED;
01602 goto reset;
01603 #endif
01604
01605 case UIP_ESTABLISHED:
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617 if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01618 if(uip_outstanding(uip_connr)) {
01619 goto drop;
01620 }
01621 uip_add_rcv_nxt(1 + uip_len);
01622 uip_flags |= UIP_CLOSE;
01623 if(uip_len > 0) {
01624 uip_flags |= UIP_NEWDATA;
01625 }
01626 UIP_APPCALL();
01627 uip_connr->len = 1;
01628 uip_connr->tcpstateflags = UIP_LAST_ACK;
01629 uip_connr->nrtx = 0;
01630 tcp_send_finack:
01631 BUF->flags = TCP_FIN | TCP_ACK;
01632 goto tcp_send_nodata;
01633 }
01634
01635
01636
01637 if((BUF->flags & TCP_URG) != 0) {
01638 #if UIP_URGDATA > 0
01639 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
01640 if(uip_urglen > uip_len) {
01641
01642 uip_urglen = uip_len;
01643 }
01644 uip_add_rcv_nxt(uip_urglen);
01645 uip_len -= uip_urglen;
01646 uip_urgdata = uip_appdata;
01647 uip_appdata += uip_urglen;
01648 } else {
01649 uip_urglen = 0;
01650 #else
01651 uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
01652 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
01653 #endif
01654 }
01655
01656
01657
01658
01659
01660
01661 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01662 uip_flags |= UIP_NEWDATA;
01663 uip_add_rcv_nxt(uip_len);
01664 }
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
01679 if(tmp16 > uip_connr->initialmss ||
01680 tmp16 == 0) {
01681 tmp16 = uip_connr->initialmss;
01682 }
01683 uip_connr->mss = tmp16;
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
01702 uip_slen = 0;
01703 UIP_APPCALL();
01704
01705 appsend:
01706
01707 if(uip_flags & UIP_ABORT) {
01708 uip_slen = 0;
01709 uip_connr->tcpstateflags = UIP_CLOSED;
01710 BUF->flags = TCP_RST | TCP_ACK;
01711 goto tcp_send_nodata;
01712 }
01713
01714 if(uip_flags & UIP_CLOSE) {
01715 uip_slen = 0;
01716 uip_connr->len = 1;
01717 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
01718 uip_connr->nrtx = 0;
01719 BUF->flags = TCP_FIN | TCP_ACK;
01720 goto tcp_send_nodata;
01721 }
01722
01723
01724 if(uip_slen > 0) {
01725
01726
01727
01728 if((uip_flags & UIP_ACKDATA) != 0) {
01729 uip_connr->len = 0;
01730 }
01731
01732
01733
01734
01735 if(uip_connr->len == 0) {
01736
01737
01738
01739
01740 if(uip_slen > uip_connr->mss) {
01741 uip_slen = uip_connr->mss;
01742 }
01743
01744
01745
01746 uip_connr->len = uip_slen;
01747 } else {
01748
01749
01750
01751
01752 uip_slen = uip_connr->len;
01753 }
01754 }
01755 uip_connr->nrtx = 0;
01756 apprexmit:
01757 uip_appdata = uip_sappdata;
01758
01759
01760
01761 if(uip_slen > 0 && uip_connr->len > 0) {
01762
01763 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
01764
01765 BUF->flags = TCP_ACK | TCP_PSH;
01766
01767 goto tcp_send_noopts;
01768 }
01769
01770
01771 if(uip_flags & UIP_NEWDATA) {
01772 uip_len = UIP_TCPIP_HLEN;
01773 BUF->flags = TCP_ACK;
01774 goto tcp_send_noopts;
01775 }
01776 }
01777 goto drop;
01778 case UIP_LAST_ACK:
01779
01780
01781 if(uip_flags & UIP_ACKDATA) {
01782 uip_connr->tcpstateflags = UIP_CLOSED;
01783 uip_flags = UIP_CLOSE;
01784 UIP_APPCALL();
01785 }
01786 break;
01787
01788 case UIP_FIN_WAIT_1:
01789
01790
01791
01792 if(uip_len > 0) {
01793 uip_add_rcv_nxt(uip_len);
01794 }
01795 if(BUF->flags & TCP_FIN) {
01796 if(uip_flags & UIP_ACKDATA) {
01797 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01798 uip_connr->timer = 0;
01799 uip_connr->len = 0;
01800 } else {
01801 uip_connr->tcpstateflags = UIP_CLOSING;
01802 }
01803 uip_add_rcv_nxt(1);
01804 uip_flags = UIP_CLOSE;
01805 UIP_APPCALL();
01806 goto tcp_send_ack;
01807 } else if(uip_flags & UIP_ACKDATA) {
01808 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
01809 uip_connr->len = 0;
01810 goto drop;
01811 }
01812 if(uip_len > 0) {
01813 goto tcp_send_ack;
01814 }
01815 goto drop;
01816
01817 case UIP_FIN_WAIT_2:
01818 if(uip_len > 0) {
01819 uip_add_rcv_nxt(uip_len);
01820 }
01821 if(BUF->flags & TCP_FIN) {
01822 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01823 uip_connr->timer = 0;
01824 uip_add_rcv_nxt(1);
01825 uip_flags = UIP_CLOSE;
01826 UIP_APPCALL();
01827 goto tcp_send_ack;
01828 }
01829 if(uip_len > 0) {
01830 goto tcp_send_ack;
01831 }
01832 goto drop;
01833
01834 case UIP_TIME_WAIT:
01835 goto tcp_send_ack;
01836
01837 case UIP_CLOSING:
01838 if(uip_flags & UIP_ACKDATA) {
01839 uip_connr->tcpstateflags = UIP_TIME_WAIT;
01840 uip_connr->timer = 0;
01841 }
01842 }
01843 goto drop;
01844
01845
01846
01847 tcp_send_ack:
01848 BUF->flags = TCP_ACK;
01849
01850 tcp_send_nodata:
01851 uip_len = UIP_IPTCPH_LEN;
01852
01853 tcp_send_noopts:
01854 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
01855
01856
01857
01858
01859
01860 tcp_send:
01861 BUF->ackno[0] = uip_connr->rcv_nxt[0];
01862 BUF->ackno[1] = uip_connr->rcv_nxt[1];
01863 BUF->ackno[2] = uip_connr->rcv_nxt[2];
01864 BUF->ackno[3] = uip_connr->rcv_nxt[3];
01865
01866 BUF->seqno[0] = uip_connr->snd_nxt[0];
01867 BUF->seqno[1] = uip_connr->snd_nxt[1];
01868 BUF->seqno[2] = uip_connr->snd_nxt[2];
01869 BUF->seqno[3] = uip_connr->snd_nxt[3];
01870
01871 BUF->proto = UIP_PROTO_TCP;
01872
01873 BUF->srcport = uip_connr->lport;
01874 BUF->destport = uip_connr->rport;
01875
01876 uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
01877 uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr);
01878
01879 if(uip_connr->tcpstateflags & UIP_STOPPED) {
01880
01881
01882 BUF->wnd[0] = BUF->wnd[1] = 0;
01883 } else {
01884 BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
01885 BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
01886 }
01887
01888 tcp_send_noconn:
01889 BUF->ttl = UIP_TTL;
01890 #if UIP_CONF_IPV6
01891
01892
01893 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01894 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01895 #else
01896 BUF->len[0] = (uip_len >> 8);
01897 BUF->len[1] = (uip_len & 0xff);
01898 #endif
01899
01900 BUF->urgp[0] = BUF->urgp[1] = 0;
01901
01902
01903 BUF->tcpchksum = 0;
01904 BUF->tcpchksum = ~(uip_tcpchksum());
01905
01906 ip_send_nolen:
01907 #if UIP_CONF_IPV6
01908 BUF->vtc = 0x60;
01909 BUF->tcflow = 0x00;
01910 BUF->flow = 0x00;
01911 #else
01912 BUF->vhl = 0x45;
01913 BUF->tos = 0;
01914 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
01915 ++ipid;
01916 BUF->ipid[0] = ipid >> 8;
01917 BUF->ipid[1] = ipid & 0xff;
01918
01919 BUF->ipchksum = 0;
01920 BUF->ipchksum = ~(uip_ipchksum());
01921 DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
01922 #endif
01923 UIP_STAT(++uip_stat.tcp.sent);
01924 #if UIP_CONF_IPV6
01925 send:
01926 #endif
01927 DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
01928 (BUF->len[0] << 8) | BUF->len[1]);
01929
01930 UIP_STAT(++uip_stat.ip.sent);
01931
01932 uip_flags = 0;
01933 return;
01934
01935 drop:
01936 uip_len = 0;
01937 uip_flags = 0;
01938 return;
01939 }
01940
01941 u16_t
01942 uip_htons(u16_t val)
01943 {
01944 return UIP_HTONS(val);
01945 }
01946
01947 u32_t
01948 uip_htonl(u32_t val)
01949 {
01950 return UIP_HTONL(val);
01951 }
01952
01953 void
01954 uip_send(const void *data, int len)
01955 {
01956 int copylen;
01957 #define MIN(a,b) ((a) < (b)? (a): (b))
01958 copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
01959 (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
01960 if(copylen > 0) {
01961 uip_slen = copylen;
01962 if(data != uip_sappdata) {
01963 memcpy(uip_sappdata, (data), uip_slen);
01964 }
01965 }
01966 }
01967
01968
01969 #endif