00001
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-icmp6.h"
00077 #include "net/uip-nd6.h"
00078 #include "net/uip-ds6.h"
00079
00080 #include <string.h>
00081
00082
00083
00084
00085
00086 #define DEBUG 0
00087 #if DEBUG
00088 #include <stdio.h>
00089 #define PRINTF(...) printf(__VA_ARGS__)
00090 #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
00091 #define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5])
00092 #else
00093 #define PRINTF(...)
00094 #define PRINT6ADDR(addr)
00095 #endif
00096
00097 #if UIP_CONF_IPV6_RPL
00098 void uip_rpl_input(void);
00099 #endif
00100
00101 #if UIP_LOGGING == 1
00102 #include <stdio.h>
00103 void uip_log(char *msg);
00104 #define UIP_LOG(m) uip_log(m)
00105 #else
00106 #define UIP_LOG(m)
00107 #endif
00108
00109 #if UIP_STATISTICS == 1
00110 struct uip_stats uip_stat;
00111 #endif
00112
00113
00114
00115
00116
00117
00118 #if UIP_CONF_LL_802154
00119 uip_lladdr_t uip_lladdr;
00120 #else
00121 uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
00122 #endif
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 u8_t *uip_next_hdr;
00137
00138 u8_t uip_ext_bitmap = 0;
00139
00140
00141
00142
00143 u8_t uip_ext_len = 0;
00144
00145 u8_t uip_ext_opt_offset = 0;
00146
00147
00148
00149
00150
00151
00152
00153
00154 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
00155 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00156 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00157 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00158 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00159 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00160 #define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00161 #define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00162 #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00163 #define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00164 #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
00165 #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
00166 #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
00167
00168
00169
00170
00171
00172 #ifndef UIP_CONF_EXTERNAL_BUFFER
00173 uip_buf_t uip_aligned_buf;
00174 #endif
00175
00176
00177 void *uip_appdata;
00178
00179 void *uip_sappdata;
00180
00181 #if UIP_URGDATA > 0
00182
00183 void *uip_urgdata;
00184 u16_t uip_urglen, uip_surglen;
00185 #endif
00186
00187
00188 u16_t uip_len, uip_slen;
00189
00190
00191
00192
00193
00194
00195
00196
00197 u8_t uip_flags;
00198
00199
00200 struct uip_conn *uip_conn;
00201
00202
00203 #if (UIP_TCP || UIP_UDP)
00204 static u8_t c;
00205 #endif
00206
00207 #if UIP_ACTIVE_OPEN || UIP_UDP
00208
00209 static u16_t lastport;
00210 #endif
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 #define TCP_FIN 0x01
00221 #define TCP_SYN 0x02
00222 #define TCP_RST 0x04
00223 #define TCP_PSH 0x08
00224 #define TCP_ACK 0x10
00225 #define TCP_URG 0x20
00226 #define TCP_CTL 0x3f
00227
00228 #define TCP_OPT_END 0
00229 #define TCP_OPT_NOOP 1
00230 #define TCP_OPT_MSS 2
00231
00232 #define TCP_OPT_MSS_LEN 4
00233
00234
00235
00236
00237 #if UIP_TCP
00238
00239 struct uip_conn uip_conns[UIP_CONNS];
00240
00241
00242 u16_t uip_listenports[UIP_LISTENPORTS];
00243
00244
00245 static u8_t iss[4];
00246
00247
00248 u8_t uip_acc32[4];
00249 static u8_t opt;
00250 static u16_t tmp16;
00251 #endif
00252
00253
00254
00255
00256
00257 #if UIP_UDP
00258 struct uip_udp_conn *uip_udp_conn;
00259 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
00260 #endif
00261
00262
00263
00264
00265
00266 #if UIP_CONF_ICMP6
00267
00268 struct uip_icmp6_conn uip_icmp6_conns;
00269 #endif
00270
00271
00272
00273
00274
00275 #if (!UIP_ARCH_ADD32 && UIP_TCP)
00276 void
00277 uip_add32(u8_t *op32, u16_t op16)
00278 {
00279 uip_acc32[3] = op32[3] + (op16 & 0xff);
00280 uip_acc32[2] = op32[2] + (op16 >> 8);
00281 uip_acc32[1] = op32[1];
00282 uip_acc32[0] = op32[0];
00283
00284 if(uip_acc32[2] < (op16 >> 8)) {
00285 ++uip_acc32[1];
00286 if(uip_acc32[1] == 0) {
00287 ++uip_acc32[0];
00288 }
00289 }
00290
00291
00292 if(uip_acc32[3] < (op16 & 0xff)) {
00293 ++uip_acc32[2];
00294 if(uip_acc32[2] == 0) {
00295 ++uip_acc32[1];
00296 if(uip_acc32[1] == 0) {
00297 ++uip_acc32[0];
00298 }
00299 }
00300 }
00301 }
00302
00303 #endif
00304
00305 #if ! UIP_ARCH_CHKSUM
00306
00307 static u16_t
00308 chksum(u16_t sum, const u8_t *data, u16_t len)
00309 {
00310 u16_t t;
00311 const u8_t *dataptr;
00312 const u8_t *last_byte;
00313
00314 dataptr = data;
00315 last_byte = data + len - 1;
00316
00317 while(dataptr < last_byte) {
00318 t = (dataptr[0] << 8) + dataptr[1];
00319 sum += t;
00320 if(sum < t) {
00321 sum++;
00322 }
00323 dataptr += 2;
00324 }
00325
00326 if(dataptr == last_byte) {
00327 t = (dataptr[0] << 8) + 0;
00328 sum += t;
00329 if(sum < t) {
00330 sum++;
00331 }
00332 }
00333
00334
00335 return sum;
00336 }
00337
00338 u16_t
00339 uip_chksum(u16_t *data, u16_t len)
00340 {
00341 return uip_htons(chksum(0, (u8_t *)data, len));
00342 }
00343
00344 #ifndef UIP_ARCH_IPCHKSUM
00345 u16_t
00346 uip_ipchksum(void)
00347 {
00348 u16_t sum;
00349
00350 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
00351 PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
00352 return (sum == 0) ? 0xffff : uip_htons(sum);
00353 }
00354 #endif
00355
00356 static u16_t
00357 upper_layer_chksum(u8_t proto)
00358 {
00359 u16_t upper_layer_len;
00360 u16_t sum;
00361
00362 upper_layer_len = (((u16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len) ;
00363
00364
00365
00366 sum = upper_layer_len + proto;
00367
00368 sum = chksum(sum, (u8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
00369
00370
00371 sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len],
00372 upper_layer_len);
00373
00374 return (sum == 0) ? 0xffff : uip_htons(sum);
00375 }
00376
00377 u16_t
00378 uip_icmp6chksum(void)
00379 {
00380 return upper_layer_chksum(UIP_PROTO_ICMP6);
00381
00382 }
00383
00384 #if UIP_TCP
00385 u16_t
00386 uip_tcpchksum(void)
00387 {
00388 return upper_layer_chksum(UIP_PROTO_TCP);
00389 }
00390 #endif
00391
00392 #if UIP_UDP && UIP_UDP_CHECKSUMS
00393 u16_t
00394 uip_udpchksum(void)
00395 {
00396 return upper_layer_chksum(UIP_PROTO_UDP);
00397 }
00398 #endif
00399 #endif
00400
00401 void
00402 uip_init(void)
00403 {
00404
00405 uip_ds6_init();
00406
00407 #if UIP_TCP
00408 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00409 uip_listenports[c] = 0;
00410 }
00411 for(c = 0; c < UIP_CONNS; ++c) {
00412 uip_conns[c].tcpstateflags = UIP_CLOSED;
00413 }
00414 #endif
00415
00416 #if UIP_ACTIVE_OPEN || UIP_UDP
00417 lastport = 1024;
00418 #endif
00419
00420 #if UIP_UDP
00421 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00422 uip_udp_conns[c].lport = 0;
00423 }
00424 #endif
00425 }
00426
00427
00428 #if UIP_TCP && UIP_ACTIVE_OPEN
00429 struct uip_conn *
00430 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
00431 {
00432 register struct uip_conn *conn, *cconn;
00433
00434
00435 again:
00436 ++lastport;
00437
00438 if(lastport >= 32000) {
00439 lastport = 4096;
00440 }
00441
00442
00443
00444 for(c = 0; c < UIP_CONNS; ++c) {
00445 conn = &uip_conns[c];
00446 if(conn->tcpstateflags != UIP_CLOSED &&
00447 conn->lport == uip_htons(lastport)) {
00448 goto again;
00449 }
00450 }
00451
00452 conn = 0;
00453 for(c = 0; c < UIP_CONNS; ++c) {
00454 cconn = &uip_conns[c];
00455 if(cconn->tcpstateflags == UIP_CLOSED) {
00456 conn = cconn;
00457 break;
00458 }
00459 if(cconn->tcpstateflags == UIP_TIME_WAIT) {
00460 if(conn == 0 ||
00461 cconn->timer > conn->timer) {
00462 conn = cconn;
00463 }
00464 }
00465 }
00466
00467 if(conn == 0) {
00468 return 0;
00469 }
00470
00471 conn->tcpstateflags = UIP_SYN_SENT;
00472
00473 conn->snd_nxt[0] = iss[0];
00474 conn->snd_nxt[1] = iss[1];
00475 conn->snd_nxt[2] = iss[2];
00476 conn->snd_nxt[3] = iss[3];
00477
00478 conn->initialmss = conn->mss = UIP_TCP_MSS;
00479
00480 conn->len = 1;
00481 conn->nrtx = 0;
00482 conn->timer = 1;
00483 conn->rto = UIP_RTO;
00484 conn->sa = 0;
00485 conn->sv = 16;
00486 conn->lport = uip_htons(lastport);
00487 conn->rport = rport;
00488 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00489
00490 return conn;
00491 }
00492 #endif
00493
00494
00495
00496 #if UIP_UDP
00497 struct uip_udp_conn *
00498 uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport)
00499 {
00500 register struct uip_udp_conn *conn;
00501
00502
00503 again:
00504 ++lastport;
00505
00506 if(lastport >= 32000) {
00507 lastport = 4096;
00508 }
00509
00510 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00511 if(uip_udp_conns[c].lport == uip_htons(lastport)) {
00512 goto again;
00513 }
00514 }
00515
00516
00517 conn = 0;
00518 for(c = 0; c < UIP_UDP_CONNS; ++c) {
00519 if(uip_udp_conns[c].lport == 0) {
00520 conn = &uip_udp_conns[c];
00521 break;
00522 }
00523 }
00524
00525 if(conn == 0) {
00526 return 0;
00527 }
00528
00529 conn->lport = UIP_HTONS(lastport);
00530 conn->rport = rport;
00531 if(ripaddr == NULL) {
00532 memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
00533 } else {
00534 uip_ipaddr_copy(&conn->ripaddr, ripaddr);
00535 }
00536 conn->ttl = uip_ds6_if.cur_hop_limit;
00537
00538 return conn;
00539 }
00540 #endif
00541
00542
00543
00544 #if UIP_TCP
00545 void
00546 uip_unlisten(u16_t port)
00547 {
00548 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00549 if(uip_listenports[c] == port) {
00550 uip_listenports[c] = 0;
00551 return;
00552 }
00553 }
00554 }
00555
00556
00557
00558 void
00559 uip_listen(u16_t port)
00560 {
00561 for(c = 0; c < UIP_LISTENPORTS; ++c) {
00562 if(uip_listenports[c] == 0) {
00563 uip_listenports[c] = port;
00564 return;
00565 }
00566 }
00567 }
00568 #endif
00569
00570
00571
00572 #if UIP_CONF_IPV6_REASSEMBLY
00573 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
00574
00575 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
00576
00577 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
00578
00579
00580 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
00581 0x0f, 0x07, 0x03, 0x01};
00582 static u16_t uip_reasslen;
00583 static u8_t uip_reassflags;
00584
00585 #define UIP_REASS_FLAG_LASTFRAG 0x01
00586 #define UIP_REASS_FLAG_FIRSTFRAG 0x02
00587 #define UIP_REASS_FLAG_ERROR_MSG 0x04
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 struct etimer uip_reass_timer;
00601 u8_t uip_reass_on;
00602
00603 static u32_t uip_id;
00604
00605
00606 #define IP_MF 0x0001
00607
00608 static u16_t
00609 uip_reass(void)
00610 {
00611 u16_t offset=0;
00612 u16_t len;
00613 u16_t i;
00614
00615
00616
00617
00618 if(uip_reass_on == 0) {
00619 PRINTF("Starting reassembly\n");
00620 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
00621
00622 etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND);
00623 uip_reass_on = 1;
00624 uip_reassflags = 0;
00625 uip_id = UIP_FRAG_BUF->id;
00626
00627 memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
00628 }
00629
00630
00631
00632
00633
00634 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
00635 uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
00636 UIP_FRAG_BUF->id == uip_id) {
00637 len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
00638 offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
00639
00640 PRINTF("len %d\n", len);
00641 PRINTF("offset %d\n", offset);
00642 if(offset == 0){
00643 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
00644
00645
00646
00647
00648
00649 *uip_next_hdr = UIP_FRAG_BUF->next;
00650 memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
00651 PRINTF("src ");
00652 PRINT6ADDR(&FBUF->srcipaddr);
00653 PRINTF("dest ");
00654 PRINT6ADDR(&FBUF->destipaddr);
00655 PRINTF("next %d\n", UIP_IP_BUF->proto);
00656
00657 }
00658
00659
00660
00661 if(offset > UIP_REASS_BUFSIZE ||
00662 offset + len > UIP_REASS_BUFSIZE) {
00663 uip_reass_on = 0;
00664 etimer_stop(&uip_reass_timer);
00665 return 0;
00666 }
00667
00668
00669
00670 if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
00671 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
00672
00673 uip_reasslen = offset + len;
00674 PRINTF("LAST FRAGMENT reasslen %d\n", uip_reasslen);
00675 } else {
00676
00677
00678
00679
00680 if(len % 8 != 0){
00681 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4);
00682 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
00683
00684
00685 uip_reass_on = 0;
00686 etimer_stop(&uip_reass_timer);
00687 return uip_len;
00688 }
00689 }
00690
00691
00692
00693 memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
00694 (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
00695
00696
00697 if(offset >> 6 == (offset + len) >> 6) {
00698 uip_reassbitmap[offset >> 6] |=
00699 bitmap_bits[(offset >> 3) & 7] &
00700 ~bitmap_bits[((offset + len) >> 3) & 7];
00701 } else {
00702
00703
00704
00705 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
00706
00707 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
00708 uip_reassbitmap[i] = 0xff;
00709 }
00710 uip_reassbitmap[(offset + len) >> 6] |=
00711 ~bitmap_bits[((offset + len) >> 3) & 7];
00712 }
00713
00714
00715
00716
00717
00718 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
00719
00720
00721 for(i = 0; i < (uip_reasslen >> 6); ++i) {
00722 if(uip_reassbitmap[i] != 0xff) {
00723 return 0;
00724 }
00725 }
00726
00727
00728 if(uip_reassbitmap[uip_reasslen >> 6] !=
00729 (u8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
00730 return 0;
00731 }
00732
00733
00734
00735 uip_reass_on = 0;
00736 etimer_stop(&uip_reass_timer);
00737
00738 uip_reasslen += UIP_IPH_LEN + uip_ext_len;
00739 memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
00740 UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
00741 UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
00742 PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen,
00743 (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
00744
00745 return uip_reasslen;
00746
00747 }
00748 } else {
00749 PRINTF("Already reassembling another paquet\n");
00750 }
00751 return 0;
00752 }
00753
00754 void
00755 uip_reass_over(void)
00756 {
00757
00758
00759 uip_reass_on = 0;
00760 etimer_stop(&uip_reass_timer);
00761
00762 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
00763 PRINTF("FRAG INTERRUPTED TOO LATE\n");
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 uip_len = 0;
00774 uip_ext_len = 0;
00775 memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN);
00776
00777 uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0);
00778
00779 UIP_STAT(++uip_stat.ip.sent);
00780 uip_flags = 0;
00781 }
00782 }
00783
00784 #endif
00785
00786
00787 #if UIP_TCP
00788 static void
00789 uip_add_rcv_nxt(u16_t n)
00790 {
00791 uip_add32(uip_conn->rcv_nxt, n);
00792 uip_conn->rcv_nxt[0] = uip_acc32[0];
00793 uip_conn->rcv_nxt[1] = uip_acc32[1];
00794 uip_conn->rcv_nxt[2] = uip_acc32[2];
00795 uip_conn->rcv_nxt[3] = uip_acc32[3];
00796 }
00797 #endif
00798
00799
00800
00801
00802
00803 static u8_t
00804 ext_hdr_options_process() {
00805
00806
00807
00808
00809
00810 uip_ext_opt_offset = 2;
00811 while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
00812 switch (UIP_EXT_HDR_OPT_BUF->type) {
00813
00814
00815
00816
00817
00818 case UIP_EXT_HDR_OPT_PAD1:
00819 PRINTF("Processing PAD1 option\n");
00820 uip_ext_opt_offset += 1;
00821 break;
00822 case UIP_EXT_HDR_OPT_PADN:
00823 PRINTF("Processing PADN option\n");
00824 uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
00825 break;
00826 default:
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
00841 switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
00842 case 0:
00843 break;
00844 case 0x40:
00845 return 1;
00846 case 0xC0:
00847 if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
00848 return 1;
00849 }
00850 case 0x80:
00851 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
00852 (u32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
00853 return 2;
00854 }
00855
00856 uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2;
00857 break;
00858 }
00859 }
00860 return 0;
00861 }
00862
00863
00864
00865 void
00866 uip_process(u8_t flag)
00867 {
00868 #if UIP_TCP
00869 register struct uip_conn *uip_connr = uip_conn;
00870 #endif
00871 #if UIP_UDP
00872 if(flag == UIP_UDP_SEND_CONN) {
00873 goto udp_send;
00874 }
00875 #endif
00876 uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
00877
00878
00879
00880 if(flag == UIP_POLL_REQUEST) {
00881 #if UIP_TCP
00882 if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
00883 !uip_outstanding(uip_connr)) {
00884 uip_flags = UIP_POLL;
00885 UIP_APPCALL();
00886 goto appsend;
00887 #if UIP_ACTIVE_OPEN
00888 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
00889
00890 UIP_TCP_BUF->flags = 0;
00891 goto tcp_send_syn;
00892 #endif
00893 }
00894 goto drop;
00895 #endif
00896
00897 } else if(flag == UIP_TIMER) {
00898
00899 #if UIP_TCP
00900 uip_len = 0;
00901 uip_slen = 0;
00902
00903
00904 if(++iss[3] == 0) {
00905 if(++iss[2] == 0) {
00906 if(++iss[1] == 0) {
00907 ++iss[0];
00908 }
00909 }
00910 }
00911
00912
00913
00914
00915
00916
00917
00918 if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
00919 uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
00920 ++(uip_connr->timer);
00921 if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
00922 uip_connr->tcpstateflags = UIP_CLOSED;
00923 }
00924 } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
00925
00926
00927
00928
00929
00930 if(uip_outstanding(uip_connr)) {
00931 if(uip_connr->timer-- == 0) {
00932 if(uip_connr->nrtx == UIP_MAXRTX ||
00933 ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
00934 uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
00935 uip_connr->nrtx == UIP_MAXSYNRTX)) {
00936 uip_connr->tcpstateflags = UIP_CLOSED;
00937
00938
00939
00940
00941
00942
00943 uip_flags = UIP_TIMEDOUT;
00944 UIP_APPCALL();
00945
00946
00947 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
00948 goto tcp_send_nodata;
00949 }
00950
00951
00952 uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
00953 4:
00954 uip_connr->nrtx);
00955 ++(uip_connr->nrtx);
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 UIP_STAT(++uip_stat.tcp.rexmit);
00966 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
00967 case UIP_SYN_RCVD:
00968
00969 goto tcp_send_synack;
00970
00971 #if UIP_ACTIVE_OPEN
00972 case UIP_SYN_SENT:
00973
00974 UIP_TCP_BUF->flags = 0;
00975 goto tcp_send_syn;
00976 #endif
00977
00978 case UIP_ESTABLISHED:
00979
00980
00981
00982
00983
00984
00985 uip_flags = UIP_REXMIT;
00986 UIP_APPCALL();
00987 goto apprexmit;
00988
00989 case UIP_FIN_WAIT_1:
00990 case UIP_CLOSING:
00991 case UIP_LAST_ACK:
00992
00993 goto tcp_send_finack;
00994 }
00995 }
00996 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
00997
00998
00999
01000
01001 uip_flags = UIP_POLL;
01002 UIP_APPCALL();
01003 goto appsend;
01004 }
01005 }
01006 goto drop;
01007 #endif
01008 }
01009 #if UIP_UDP
01010 if(flag == UIP_UDP_TIMER) {
01011 if(uip_udp_conn->lport != 0) {
01012 uip_conn = NULL;
01013 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01014 uip_len = uip_slen = 0;
01015 uip_flags = UIP_POLL;
01016 UIP_UDP_APPCALL();
01017 goto udp_send;
01018 } else {
01019 goto drop;
01020 }
01021 }
01022 #endif
01023
01024
01025
01026 UIP_STAT(++uip_stat.ip.recv);
01027
01028
01029
01030
01031 if((UIP_IP_BUF->vtc & 0xf0) != 0x60) {
01032 UIP_STAT(++uip_stat.ip.drop);
01033 UIP_STAT(++uip_stat.ip.vhlerr);
01034 UIP_LOG("ipv6: invalid version.");
01035 goto drop;
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
01047 uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN;
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 } else {
01060 UIP_LOG("ip: packet shorter than reported in IP header.");
01061 goto drop;
01062 }
01063
01064 PRINTF("IPv6 packet received from ");
01065 PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
01066 PRINTF(" to ");
01067 PRINT6ADDR(&UIP_IP_BUF->destipaddr);
01068 PRINTF("\n");
01069
01070 if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){
01071 UIP_STAT(++uip_stat.ip.drop);
01072 PRINTF("Dropping packet, src is mcast\n");
01073 goto drop;
01074 }
01075
01076 #if UIP_CONF_ROUTER
01077
01078 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
01079 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
01080 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) &&
01081 !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) &&
01082 !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) &&
01083 !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
01084 !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
01085
01086
01087
01088 if(uip_len > UIP_LINK_MTU) {
01089 uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
01090 UIP_STAT(++uip_stat.ip.drop);
01091 goto send;
01092 }
01093
01094 if(UIP_IP_BUF->ttl <= 1) {
01095 uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
01096 ICMP6_TIME_EXCEED_TRANSIT, 0);
01097 UIP_STAT(++uip_stat.ip.drop);
01098 goto send;
01099 }
01100 UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
01101 PRINTF("Forwarding packet to ");
01102 PRINT6ADDR(&UIP_IP_BUF->destipaddr);
01103 PRINTF("\n");
01104 UIP_STAT(++uip_stat.ip.forwarded);
01105 goto send;
01106 } else {
01107 if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) &&
01108 (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) &&
01109 (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) &&
01110 (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) &&
01111 (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) {
01112 PRINTF("LL source address with off link destination, dropping\n");
01113 uip_icmp6_error_output(ICMP6_DST_UNREACH,
01114 ICMP6_DST_UNREACH_NOTNEIGHBOR, 0);
01115 goto send;
01116 }
01117 PRINTF("Dropping packet, not for me and link local or multicast\n");
01118 UIP_STAT(++uip_stat.ip.drop);
01119 goto drop;
01120 }
01121 }
01122 #else
01123 if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
01124 !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr) &&
01125 !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
01126 PRINTF("Dropping packet, not for me\n");
01127 UIP_STAT(++uip_stat.ip.drop);
01128 goto drop;
01129 }
01130 #endif
01131
01132
01133
01134
01135
01136 uip_next_hdr = &UIP_IP_BUF->proto;
01137 uip_ext_len = 0;
01138 uip_ext_bitmap = 0;
01139 while(1) {
01140 switch(*uip_next_hdr){
01141 #if UIP_TCP
01142 case UIP_PROTO_TCP:
01143
01144 goto tcp_input;
01145 #endif
01146 #if UIP_UDP
01147 case UIP_PROTO_UDP:
01148
01149 goto udp_input;
01150 #endif
01151 case UIP_PROTO_ICMP6:
01152
01153 goto icmp6_input;
01154 case UIP_PROTO_HBHO:
01155 PRINTF("Processing hbh header\n");
01156
01157 #if UIP_CONF_IPV6_CHECKS
01158
01159 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) {
01160 goto bad_hdr;
01161 } else {
01162 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
01163 }
01164 #endif
01165 switch(ext_hdr_options_process()) {
01166 case 0:
01167
01168 uip_next_hdr = &UIP_EXT_BUF->next;
01169 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01170 break;
01171 case 1:
01172
01173 goto drop;
01174 case 2:
01175
01176
01177 goto send;
01178 }
01179 break;
01180 case UIP_PROTO_DESTO:
01181 #if UIP_CONF_IPV6_CHECKS
01182
01183 PRINTF("Processing desto header\n");
01184 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
01185 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
01186 goto bad_hdr;
01187 } else{
01188 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
01189 }
01190 } else {
01191 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
01192 }
01193 #endif
01194 switch(ext_hdr_options_process()) {
01195 case 0:
01196
01197 uip_next_hdr = &UIP_EXT_BUF->next;
01198 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01199 break;
01200 case 1:
01201
01202 goto drop;
01203 case 2:
01204
01205
01206 goto send;
01207 }
01208 break;
01209 case UIP_PROTO_ROUTING:
01210 #if UIP_CONF_IPV6_CHECKS
01211
01212 if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
01213 goto bad_hdr;
01214 } else {
01215 uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
01216 }
01217 #endif
01218
01219
01220
01221
01222
01223
01224
01225
01226 PRINTF("Processing Routing header\n");
01227 if(UIP_ROUTING_BUF->seg_left > 0) {
01228 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2);
01229 UIP_STAT(++uip_stat.ip.drop);
01230 UIP_LOG("ip6: unrecognized routing type");
01231 goto send;
01232 }
01233 uip_next_hdr = &UIP_EXT_BUF->next;
01234 uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
01235 break;
01236 case UIP_PROTO_FRAG:
01237
01238 #if UIP_CONF_IPV6_REASSEMBLY
01239 PRINTF("Processing frag header\n");
01240 uip_len = uip_reass();
01241 if(uip_len == 0) {
01242 goto drop;
01243 }
01244 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
01245
01246 goto send;
01247 }
01248
01249
01250 PRINTF("Processing reassembled packet\n");
01251 uip_ext_len = 0;
01252 uip_ext_bitmap = 0;
01253 uip_next_hdr = &UIP_IP_BUF->proto;
01254 break;
01255 #else
01256 UIP_STAT(++uip_stat.ip.drop);
01257 UIP_STAT(++uip_stat.ip.fragerr);
01258 UIP_LOG("ip: fragment dropped.");
01259 goto drop;
01260 #endif
01261 case UIP_PROTO_NONE:
01262 goto drop;
01263 default:
01264 goto bad_hdr;
01265 }
01266 }
01267 bad_hdr:
01268
01269
01270
01271
01272 uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (u32_t)(uip_next_hdr - (uint8_t *)UIP_IP_BUF));
01273 UIP_STAT(++uip_stat.ip.drop);
01274 UIP_STAT(++uip_stat.ip.protoerr);
01275 UIP_LOG("ip6: unrecognized header");
01276 goto send;
01277
01278
01279 icmp6_input:
01280
01281 PRINTF("icmp6_input: length %d\n", uip_len);
01282
01283 #if UIP_CONF_IPV6_CHECKS
01284
01285 if(uip_icmp6chksum() != 0xffff) {
01286 UIP_STAT(++uip_stat.icmp.drop);
01287 UIP_STAT(++uip_stat.icmp.chkerr);
01288 UIP_LOG("icmpv6: bad checksum.");
01289 goto drop;
01290 }
01291 #endif
01292
01293 UIP_STAT(++uip_stat.icmp.recv);
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 #if UIP_CONF_ICMP6
01304 UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
01305 #endif
01306
01307 switch(UIP_ICMP_BUF->type) {
01308 case ICMP6_NS:
01309 uip_nd6_ns_input();
01310 break;
01311 case ICMP6_NA:
01312 uip_nd6_na_input();
01313 break;
01314 case ICMP6_RS:
01315 #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
01316 uip_nd6_rs_input();
01317 #else
01318 UIP_STAT(++uip_stat.icmp.drop);
01319 uip_len = 0;
01320 #endif
01321 break;
01322 case ICMP6_RA:
01323 #if UIP_CONF_ROUTER
01324 UIP_STAT(++uip_stat.icmp.drop);
01325 uip_len = 0;
01326 #else
01327 uip_nd6_ra_input();
01328 #endif
01329 break;
01330 #if UIP_CONF_IPV6_RPL
01331 case ICMP6_RPL:
01332 uip_rpl_input();
01333 break;
01334 #endif
01335 case ICMP6_ECHO_REQUEST:
01336 uip_icmp6_echo_request_input();
01337 break;
01338 case ICMP6_ECHO_REPLY:
01339
01340 PRINTF("Received an icmp6 echo reply\n");
01341 UIP_STAT(++uip_stat.icmp.recv);
01342 uip_len = 0;
01343 break;
01344 default:
01345 PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
01346 UIP_STAT(++uip_stat.icmp.drop);
01347 UIP_STAT(++uip_stat.icmp.typeerr);
01348 UIP_LOG("icmp6: unknown ICMP message.");
01349 uip_len = 0;
01350 break;
01351 }
01352
01353 if(uip_len > 0) {
01354 goto send;
01355 } else {
01356 goto drop;
01357 }
01358
01359
01360
01361 #if UIP_UDP
01362
01363 udp_input:
01364 PRINTF("Receiving UDP packet\n");
01365 UIP_STAT(++uip_stat.udp.recv);
01366
01367
01368
01369
01370
01371 #if UIP_UDP_CHECKSUMS
01372 uip_len = uip_len - UIP_IPUDPH_LEN;
01373 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01374 if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
01375 UIP_STAT(++uip_stat.udp.drop);
01376 UIP_STAT(++uip_stat.udp.chkerr);
01377 PRINTF("udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
01378 uip_udpchksum());
01379 goto drop;
01380 }
01381 #else
01382 uip_len = uip_len - UIP_IPUDPH_LEN;
01383 #endif
01384
01385
01386 if(UIP_UDP_BUF->destport == 0) {
01387 PRINTF("udp: zero port.\n");
01388 goto drop;
01389 }
01390
01391
01392 for(uip_udp_conn = &uip_udp_conns[0];
01393 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
01394 ++uip_udp_conn) {
01395
01396
01397
01398
01399
01400
01401
01402 if(uip_udp_conn->lport != 0 &&
01403 UIP_UDP_BUF->destport == uip_udp_conn->lport &&
01404 (uip_udp_conn->rport == 0 ||
01405 UIP_UDP_BUF->srcport == uip_udp_conn->rport) &&
01406 (uip_is_addr_unspecified(&uip_udp_conn->ripaddr) ||
01407 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
01408 goto udp_found;
01409 }
01410 }
01411 PRINTF("udp: no matching connection found\n");
01412
01413 #if UIP_UDP_SEND_UNREACH_NOPORT
01414 uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
01415 UIP_STAT(++uip_stat.ip.drop);
01416 goto send;
01417 #else
01418 goto drop;
01419 #endif
01420
01421 udp_found:
01422 PRINTF("In udp_found\n");
01423
01424 uip_conn = NULL;
01425 uip_flags = UIP_NEWDATA;
01426 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
01427 uip_slen = 0;
01428 UIP_UDP_APPCALL();
01429
01430 udp_send:
01431 PRINTF("In udp_send\n");
01432
01433 if(uip_slen == 0) {
01434 goto drop;
01435 }
01436 uip_len = uip_slen + UIP_IPUDPH_LEN;
01437
01438
01439
01440 UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
01441 UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
01442
01443 UIP_IP_BUF->ttl = uip_udp_conn->ttl;
01444 UIP_IP_BUF->proto = UIP_PROTO_UDP;
01445
01446 UIP_UDP_BUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
01447 UIP_UDP_BUF->udpchksum = 0;
01448
01449 UIP_UDP_BUF->srcport = uip_udp_conn->lport;
01450 UIP_UDP_BUF->destport = uip_udp_conn->rport;
01451
01452 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr);
01453 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
01454
01455 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
01456
01457 #if UIP_UDP_CHECKSUMS
01458
01459 UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
01460 if(UIP_UDP_BUF->udpchksum == 0) {
01461 UIP_UDP_BUF->udpchksum = 0xffff;
01462 }
01463 #endif
01464 UIP_STAT(++uip_stat.udp.sent);
01465 goto ip_send_nolen;
01466 #endif
01467
01468 #if UIP_TCP
01469
01470 tcp_input:
01471
01472 UIP_STAT(++uip_stat.tcp.recv);
01473 PRINTF("Receiving TCP packet\n");
01474
01475
01476 if(uip_tcpchksum() != 0xffff) {
01477
01478 UIP_STAT(++uip_stat.tcp.drop);
01479 UIP_STAT(++uip_stat.tcp.chkerr);
01480 UIP_LOG("tcp: bad checksum.");
01481 goto drop;
01482 }
01483
01484
01485 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
01486 UIP_LOG("tcp: zero port.");
01487 goto drop;
01488 }
01489
01490
01491
01492 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
01493 ++uip_connr) {
01494 if(uip_connr->tcpstateflags != UIP_CLOSED &&
01495 UIP_TCP_BUF->destport == uip_connr->lport &&
01496 UIP_TCP_BUF->srcport == uip_connr->rport &&
01497 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->ripaddr)) {
01498 goto found;
01499 }
01500 }
01501
01502
01503
01504
01505
01506 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
01507 goto reset;
01508 }
01509
01510 tmp16 = UIP_TCP_BUF->destport;
01511
01512 for(c = 0; c < UIP_LISTENPORTS; ++c) {
01513 if(tmp16 == uip_listenports[c]) {
01514 goto found_listen;
01515 }
01516 }
01517
01518
01519 UIP_STAT(++uip_stat.tcp.synrst);
01520
01521 reset:
01522 PRINTF("In reset\n");
01523
01524 if(UIP_TCP_BUF->flags & TCP_RST) {
01525 goto drop;
01526 }
01527
01528 UIP_STAT(++uip_stat.tcp.rst);
01529
01530 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
01531 uip_len = UIP_IPTCPH_LEN;
01532 UIP_TCP_BUF->tcpoffset = 5 << 4;
01533
01534
01535 c = UIP_TCP_BUF->seqno[3];
01536 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
01537 UIP_TCP_BUF->ackno[3] = c;
01538
01539 c = UIP_TCP_BUF->seqno[2];
01540 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
01541 UIP_TCP_BUF->ackno[2] = c;
01542
01543 c = UIP_TCP_BUF->seqno[1];
01544 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
01545 UIP_TCP_BUF->ackno[1] = c;
01546
01547 c = UIP_TCP_BUF->seqno[0];
01548 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
01549 UIP_TCP_BUF->ackno[0] = c;
01550
01551
01552
01553
01554 if(++UIP_TCP_BUF->ackno[3] == 0) {
01555 if(++UIP_TCP_BUF->ackno[2] == 0) {
01556 if(++UIP_TCP_BUF->ackno[1] == 0) {
01557 ++UIP_TCP_BUF->ackno[0];
01558 }
01559 }
01560 }
01561
01562
01563 tmp16 = UIP_TCP_BUF->srcport;
01564 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
01565 UIP_TCP_BUF->destport = tmp16;
01566
01567
01568 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
01569 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
01570
01571 goto tcp_send_noconn;
01572
01573
01574
01575
01576 found_listen:
01577 PRINTF("In found listen\n");
01578
01579
01580
01581
01582
01583
01584 uip_connr = 0;
01585 for(c = 0; c < UIP_CONNS; ++c) {
01586 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
01587 uip_connr = &uip_conns[c];
01588 break;
01589 }
01590 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
01591 if(uip_connr == 0 ||
01592 uip_conns[c].timer > uip_connr->timer) {
01593 uip_connr = &uip_conns[c];
01594 }
01595 }
01596 }
01597
01598 if(uip_connr == 0) {
01599
01600
01601
01602 UIP_STAT(++uip_stat.tcp.syndrop);
01603 UIP_LOG("tcp: found no unused connections.");
01604 goto drop;
01605 }
01606 uip_conn = uip_connr;
01607
01608
01609 uip_connr->rto = uip_connr->timer = UIP_RTO;
01610 uip_connr->sa = 0;
01611 uip_connr->sv = 4;
01612 uip_connr->nrtx = 0;
01613 uip_connr->lport = UIP_TCP_BUF->destport;
01614 uip_connr->rport = UIP_TCP_BUF->srcport;
01615 uip_ipaddr_copy(&uip_connr->ripaddr, &UIP_IP_BUF->srcipaddr);
01616 uip_connr->tcpstateflags = UIP_SYN_RCVD;
01617
01618 uip_connr->snd_nxt[0] = iss[0];
01619 uip_connr->snd_nxt[1] = iss[1];
01620 uip_connr->snd_nxt[2] = iss[2];
01621 uip_connr->snd_nxt[3] = iss[3];
01622 uip_connr->len = 1;
01623
01624
01625 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
01626 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
01627 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
01628 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
01629 uip_add_rcv_nxt(1);
01630
01631
01632 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
01633 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
01634 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
01635 if(opt == TCP_OPT_END) {
01636
01637 break;
01638 } else if(opt == TCP_OPT_NOOP) {
01639 ++c;
01640
01641 } else if(opt == TCP_OPT_MSS &&
01642 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01643
01644 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01645 (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
01646 uip_connr->initialmss = uip_connr->mss =
01647 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01648
01649
01650 break;
01651 } else {
01652
01653
01654 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01655
01656
01657 break;
01658 }
01659 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01660 }
01661 }
01662 }
01663
01664
01665 #if UIP_ACTIVE_OPEN
01666 tcp_send_synack:
01667 UIP_TCP_BUF->flags = TCP_ACK;
01668
01669 tcp_send_syn:
01670 UIP_TCP_BUF->flags |= TCP_SYN;
01671 #else
01672 tcp_send_synack:
01673 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
01674 #endif
01675
01676
01677
01678 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
01679 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
01680 UIP_TCP_BUF->optdata[2] = (UIP_TCP_MSS) / 256;
01681 UIP_TCP_BUF->optdata[3] = (UIP_TCP_MSS) & 255;
01682 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
01683 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
01684 goto tcp_send;
01685
01686
01687 found:
01688 PRINTF("In found\n");
01689 uip_conn = uip_connr;
01690 uip_flags = 0;
01691
01692
01693
01694
01695 if(UIP_TCP_BUF->flags & TCP_RST) {
01696 uip_connr->tcpstateflags = UIP_CLOSED;
01697 UIP_LOG("tcp: got reset, aborting connection.");
01698 uip_flags = UIP_ABORT;
01699 UIP_APPCALL();
01700 goto drop;
01701 }
01702
01703
01704 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
01705
01706
01707
01708 uip_len = uip_len - c - UIP_IPH_LEN;
01709
01710
01711
01712
01713
01714
01715 if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
01716 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
01717 (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
01718 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
01719 if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
01720 (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
01721 UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
01722 UIP_TCP_BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
01723 UIP_TCP_BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
01724
01725 if(UIP_TCP_BUF->flags & TCP_SYN) {
01726 goto tcp_send_synack;
01727 }
01728 goto tcp_send_ack;
01729 }
01730 }
01731
01732
01733
01734
01735
01736 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
01737 uip_add32(uip_connr->snd_nxt, uip_connr->len);
01738
01739 if(UIP_TCP_BUF->ackno[0] == uip_acc32[0] &&
01740 UIP_TCP_BUF->ackno[1] == uip_acc32[1] &&
01741 UIP_TCP_BUF->ackno[2] == uip_acc32[2] &&
01742 UIP_TCP_BUF->ackno[3] == uip_acc32[3]) {
01743
01744 uip_connr->snd_nxt[0] = uip_acc32[0];
01745 uip_connr->snd_nxt[1] = uip_acc32[1];
01746 uip_connr->snd_nxt[2] = uip_acc32[2];
01747 uip_connr->snd_nxt[3] = uip_acc32[3];
01748
01749
01750 if(uip_connr->nrtx == 0) {
01751 signed char m;
01752 m = uip_connr->rto - uip_connr->timer;
01753
01754 m = m - (uip_connr->sa >> 3);
01755 uip_connr->sa += m;
01756 if(m < 0) {
01757 m = -m;
01758 }
01759 m = m - (uip_connr->sv >> 2);
01760 uip_connr->sv += m;
01761 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
01762
01763 }
01764
01765 uip_flags = UIP_ACKDATA;
01766
01767 uip_connr->timer = uip_connr->rto;
01768
01769
01770 uip_connr->len = 0;
01771 }
01772
01773 }
01774
01775
01776 switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
01777
01778
01779
01780
01781 case UIP_SYN_RCVD:
01782
01783
01784
01785
01786 if(uip_flags & UIP_ACKDATA) {
01787 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01788 uip_flags = UIP_CONNECTED;
01789 uip_connr->len = 0;
01790 if(uip_len > 0) {
01791 uip_flags |= UIP_NEWDATA;
01792 uip_add_rcv_nxt(uip_len);
01793 }
01794 uip_slen = 0;
01795 UIP_APPCALL();
01796 goto appsend;
01797 }
01798
01799 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
01800 goto tcp_send_synack;
01801 }
01802 goto drop;
01803 #if UIP_ACTIVE_OPEN
01804 case UIP_SYN_SENT:
01805
01806
01807
01808
01809 if((uip_flags & UIP_ACKDATA) &&
01810 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
01811
01812
01813 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
01814 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
01815 opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
01816 if(opt == TCP_OPT_END) {
01817
01818 break;
01819 } else if(opt == TCP_OPT_NOOP) {
01820 ++c;
01821
01822 } else if(opt == TCP_OPT_MSS &&
01823 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
01824
01825 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
01826 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
01827 uip_connr->initialmss =
01828 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
01829
01830
01831 break;
01832 } else {
01833
01834
01835 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
01836
01837
01838 break;
01839 }
01840 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
01841 }
01842 }
01843 }
01844 uip_connr->tcpstateflags = UIP_ESTABLISHED;
01845 uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
01846 uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
01847 uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
01848 uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
01849 uip_add_rcv_nxt(1);
01850 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
01851 uip_connr->len = 0;
01852 uip_len = 0;
01853 uip_slen = 0;
01854 UIP_APPCALL();
01855 goto appsend;
01856 }
01857
01858 uip_flags = UIP_ABORT;
01859 UIP_APPCALL();
01860
01861 uip_conn->tcpstateflags = UIP_CLOSED;
01862 goto reset;
01863 #endif
01864
01865 case UIP_ESTABLISHED:
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01878 if(uip_outstanding(uip_connr)) {
01879 goto drop;
01880 }
01881 uip_add_rcv_nxt(1 + uip_len);
01882 uip_flags |= UIP_CLOSE;
01883 if(uip_len > 0) {
01884 uip_flags |= UIP_NEWDATA;
01885 }
01886 UIP_APPCALL();
01887 uip_connr->len = 1;
01888 uip_connr->tcpstateflags = UIP_LAST_ACK;
01889 uip_connr->nrtx = 0;
01890 tcp_send_finack:
01891 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
01892 goto tcp_send_nodata;
01893 }
01894
01895
01896
01897 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
01898 #if UIP_URGDATA > 0
01899 uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
01900 if(uip_urglen > uip_len) {
01901
01902 uip_urglen = uip_len;
01903 }
01904 uip_add_rcv_nxt(uip_urglen);
01905 uip_len -= uip_urglen;
01906 uip_urgdata = uip_appdata;
01907 uip_appdata += uip_urglen;
01908 } else {
01909 uip_urglen = 0;
01910 #else
01911 uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]);
01912 uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
01913 #endif
01914 }
01915
01916
01917
01918
01919
01920
01921 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
01922 uip_flags |= UIP_NEWDATA;
01923 uip_add_rcv_nxt(uip_len);
01924 }
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938 tmp16 = ((u16_t)UIP_TCP_BUF->wnd[0] << 8) + (u16_t)UIP_TCP_BUF->wnd[1];
01939 if(tmp16 > uip_connr->initialmss ||
01940 tmp16 == 0) {
01941 tmp16 = uip_connr->initialmss;
01942 }
01943 uip_connr->mss = tmp16;
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
01962 uip_slen = 0;
01963 UIP_APPCALL();
01964
01965 appsend:
01966
01967 if(uip_flags & UIP_ABORT) {
01968 uip_slen = 0;
01969 uip_connr->tcpstateflags = UIP_CLOSED;
01970 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
01971 goto tcp_send_nodata;
01972 }
01973
01974 if(uip_flags & UIP_CLOSE) {
01975 uip_slen = 0;
01976 uip_connr->len = 1;
01977 uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
01978 uip_connr->nrtx = 0;
01979 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
01980 goto tcp_send_nodata;
01981 }
01982
01983
01984 if(uip_slen > 0) {
01985
01986
01987
01988 if((uip_flags & UIP_ACKDATA) != 0) {
01989 uip_connr->len = 0;
01990 }
01991
01992
01993
01994
01995 if(uip_connr->len == 0) {
01996
01997
01998
01999
02000 if(uip_slen > uip_connr->mss) {
02001 uip_slen = uip_connr->mss;
02002 }
02003
02004
02005
02006 uip_connr->len = uip_slen;
02007 } else {
02008
02009
02010
02011
02012 uip_slen = uip_connr->len;
02013 }
02014 }
02015 uip_connr->nrtx = 0;
02016 apprexmit:
02017 uip_appdata = uip_sappdata;
02018
02019
02020
02021 if(uip_slen > 0 && uip_connr->len > 0) {
02022
02023 uip_len = uip_connr->len + UIP_TCPIP_HLEN;
02024
02025 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
02026
02027 goto tcp_send_noopts;
02028 }
02029
02030
02031 if(uip_flags & UIP_NEWDATA) {
02032 uip_len = UIP_TCPIP_HLEN;
02033 UIP_TCP_BUF->flags = TCP_ACK;
02034 goto tcp_send_noopts;
02035 }
02036 }
02037 goto drop;
02038 case UIP_LAST_ACK:
02039
02040
02041 if(uip_flags & UIP_ACKDATA) {
02042 uip_connr->tcpstateflags = UIP_CLOSED;
02043 uip_flags = UIP_CLOSE;
02044 UIP_APPCALL();
02045 }
02046 break;
02047
02048 case UIP_FIN_WAIT_1:
02049
02050
02051
02052 if(uip_len > 0) {
02053 uip_add_rcv_nxt(uip_len);
02054 }
02055 if(UIP_TCP_BUF->flags & TCP_FIN) {
02056 if(uip_flags & UIP_ACKDATA) {
02057 uip_connr->tcpstateflags = UIP_TIME_WAIT;
02058 uip_connr->timer = 0;
02059 uip_connr->len = 0;
02060 } else {
02061 uip_connr->tcpstateflags = UIP_CLOSING;
02062 }
02063 uip_add_rcv_nxt(1);
02064 uip_flags = UIP_CLOSE;
02065 UIP_APPCALL();
02066 goto tcp_send_ack;
02067 } else if(uip_flags & UIP_ACKDATA) {
02068 uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
02069 uip_connr->len = 0;
02070 goto drop;
02071 }
02072 if(uip_len > 0) {
02073 goto tcp_send_ack;
02074 }
02075 goto drop;
02076
02077 case UIP_FIN_WAIT_2:
02078 if(uip_len > 0) {
02079 uip_add_rcv_nxt(uip_len);
02080 }
02081 if(UIP_TCP_BUF->flags & TCP_FIN) {
02082 uip_connr->tcpstateflags = UIP_TIME_WAIT;
02083 uip_connr->timer = 0;
02084 uip_add_rcv_nxt(1);
02085 uip_flags = UIP_CLOSE;
02086 UIP_APPCALL();
02087 goto tcp_send_ack;
02088 }
02089 if(uip_len > 0) {
02090 goto tcp_send_ack;
02091 }
02092 goto drop;
02093
02094 case UIP_TIME_WAIT:
02095 goto tcp_send_ack;
02096
02097 case UIP_CLOSING:
02098 if(uip_flags & UIP_ACKDATA) {
02099 uip_connr->tcpstateflags = UIP_TIME_WAIT;
02100 uip_connr->timer = 0;
02101 }
02102 }
02103 goto drop;
02104
02105
02106
02107 tcp_send_ack:
02108 UIP_TCP_BUF->flags = TCP_ACK;
02109
02110 tcp_send_nodata:
02111 uip_len = UIP_IPTCPH_LEN;
02112
02113 tcp_send_noopts:
02114 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
02115
02116
02117
02118
02119
02120 tcp_send:
02121 PRINTF("In tcp_send\n");
02122
02123 UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0];
02124 UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1];
02125 UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2];
02126 UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3];
02127
02128 UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0];
02129 UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1];
02130 UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2];
02131 UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3];
02132
02133 UIP_IP_BUF->proto = UIP_PROTO_TCP;
02134
02135 UIP_TCP_BUF->srcport = uip_connr->lport;
02136 UIP_TCP_BUF->destport = uip_connr->rport;
02137
02138
02139 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
02140 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr);
02141 PRINTF("Sending TCP packet to");
02142 PRINT6ADDR(&UIP_IP_BUF->destipaddr);
02143 PRINTF("from");
02144 PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
02145 PRINTF("\n");
02146
02147 if(uip_connr->tcpstateflags & UIP_STOPPED) {
02148
02149
02150 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
02151 } else {
02152 UIP_TCP_BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
02153 UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
02154 }
02155
02156 tcp_send_noconn:
02157 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
02158 UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
02159 UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
02160
02161 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
02162
02163
02164 UIP_TCP_BUF->tcpchksum = 0;
02165 UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
02166 UIP_STAT(++uip_stat.tcp.sent);
02167
02168 #endif
02169 #if UIP_UDP
02170 ip_send_nolen:
02171 #endif
02172 UIP_IP_BUF->vtc = 0x60;
02173 UIP_IP_BUF->tcflow = 0x00;
02174 UIP_IP_BUF->flow = 0x00;
02175 send:
02176 PRINTF("Sending packet with length %d (%d)\n", uip_len,
02177 (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
02178
02179 UIP_STAT(++uip_stat.ip.sent);
02180
02181 uip_flags = 0;
02182 return;
02183
02184 drop:
02185 uip_len = 0;
02186 uip_ext_len = 0;
02187 uip_ext_bitmap = 0;
02188 uip_flags = 0;
02189 return;
02190 }
02191
02192 u16_t
02193 uip_htons(u16_t val)
02194 {
02195 return UIP_HTONS(val);
02196 }
02197
02198 u32_t
02199 uip_htonl(u32_t val)
02200 {
02201 return UIP_HTONL(val);
02202 }
02203
02204 void
02205 uip_send(const void *data, int len)
02206 {
02207 int copylen;
02208 #define MIN(a,b) ((a) < (b)? (a): (b))
02209 copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
02210 (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
02211 if(copylen > 0) {
02212 uip_slen = copylen;
02213 if(data != uip_sappdata) {
02214 memcpy(uip_sappdata, (data), uip_slen);
02215 }
02216 }
02217 }
02218
02219
02220