1 #define DEBUG_PRINTF(...) 77 #include "net/uip_backlog.h" 78 #include "lib/assert.h" 79 #include "lib/random.h" 88 #include "net/uip-neighbor.h" 100 #define PRINTD(FORMAT, args...) do {} while (0) 102 #define PRINTD(FORMAT, args...) printf("%s" FORMAT, "[UIP] ", ##args) 105 static unsigned seq_to_cpu(uint8_t *p)
107 return (((
unsigned) p[0]) << 24) |
108 (((unsigned) p[1]) << 16) |
109 (((
unsigned) p[2]) << 8) |
110 (((unsigned) p[3]) << 0);
120 #if UIP_FIXEDADDR > 0 122 { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
124 { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
126 { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
133 { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
136 { { 0xff, 0xff, 0xff, 0xff } };
163 uint16_t uip_urglen, uip_surglen;
191 static uint16_t ipid;
197 static uint8_t iss[4];
200 #if UIP_ACTIVE_OPEN || UIP_UDP 201 static uint16_t lastport;
207 static uint8_t c, opt;
208 static uint16_t tmp16;
219 #define TCP_OPT_END 0 220 #define TCP_OPT_NOOP 1 221 #define TCP_OPT_MSS 2 223 #define TCP_OPT_MSS_LEN 4 225 #define ICMP_ECHO_REPLY 0 228 #define ICMP_DEST_UNREACHABLE 3 229 #define ICMP_PORT_UNREACHABLE 3 231 #define ICMP6_ECHO_REPLY 129 232 #define ICMP6_ECHO 128 233 #define ICMP6_NEIGHBOR_SOLICITATION 135 234 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136 236 #define ICMP6_FLAG_S (1 << 6) 238 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 239 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 243 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 244 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) 245 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) 246 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) 249 #if UIP_STATISTICS == 1 251 #define UIP_STAT(s) s 259 #define UIP_LOG(m) uip_log(m) 270 uip_acc32[1] = op32[1];
271 uip_acc32[0] = op32[0];
273 if(uip_acc32[2] < (op16 >> 8)) {
275 if(uip_acc32[1] == 0) {
281 if(uip_acc32[3] < (op16 & 0xff)) {
283 if(uip_acc32[2] == 0) {
285 if(uip_acc32[1] == 0) {
294 #if ! UIP_ARCH_CHKSUM 297 chksum(uint16_t sum,
const uint8_t *
data, uint16_t len)
300 const uint8_t *dataptr;
301 const uint8_t *last_byte;
304 last_byte =
data + len - 1;
306 while(dataptr < last_byte) {
307 t = (dataptr[0] << 8) + dataptr[1];
315 if(dataptr == last_byte) {
316 t = (dataptr[0] << 8) + 0;
330 return uip_htons(chksum(0, (uint8_t *)data, len));
333 #ifndef UIP_ARCH_IPCHKSUM 339 sum = chksum(0, &uip_buf[
UIP_LLH_LEN], UIP_IPH_LEN);
340 DEBUG_PRINTF(
"uip_ipchksum: sum 0x%04x\n", sum);
341 return (sum == 0) ? 0xffff :
uip_htons(sum);
346 upper_layer_chksum(uint8_t proto)
348 uint16_t upper_layer_len;
352 upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]);
354 upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
360 sum = upper_layer_len + proto;
362 sum = chksum(sum, (uint8_t *)&BUF->srcipaddr, 2 *
sizeof(
uip_ipaddr_t));
365 sum = chksum(sum, &uip_buf[UIP_IPH_LEN +
UIP_LLH_LEN],
368 return (sum == 0) ? 0xffff :
uip_htons(sum);
375 return upper_layer_chksum(UIP_PROTO_ICMP6);
383 return upper_layer_chksum(UIP_PROTO_TCP);
386 #if UIP_UDP_CHECKSUMS 390 return upper_layer_chksum(UIP_PROTO_UDP);
399 uip_listenports[c] = 0;
405 #if UIP_ACTIVE_OPEN || UIP_UDP 408 lastport = 1024 + (random_rand() & 0x7FFF);
409 }
while (lastport < 1024 || lastport >= 32000);
414 uip_udp_conns[c].
lport = 0;
420 #if UIP_FIXEDADDR == 0 430 register struct uip_conn *conn, *cconn;
436 if(lastport >= 32000) {
443 conn = &uip_conns[c];
452 cconn = &uip_conns[c];
494 struct uip_udp_conn *
497 register struct uip_udp_conn *conn;
503 if(lastport >= 32000) {
516 if(uip_udp_conns[c].
lport == 0) {
517 conn = &uip_udp_conns[c];
528 if(ripaddr == NULL) {
530 conn->
arpid = UIP_ARP_NONE;
545 if(uip_listenports[c] == port) {
546 uip_listenports[c] = 0;
556 if(uip_listenports[c] == 0) {
557 uip_listenports[c] = port;
565 #if UIP_REASSEMBLY && !UIP_CONF_IPV6 566 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) 567 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
568 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
569 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
570 0x0f, 0x07, 0x03, 0x01};
571 static uint16_t uip_reasslen;
572 static uint8_t uip_reassflags;
573 #define UIP_REASS_FLAG_LASTFRAG 0x01 574 static uint8_t uip_reasstmr;
581 uint16_t offset, len;
587 if(uip_reasstmr == 0) {
588 memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
592 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
598 if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
599 BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
600 BUF->destipaddr[0] == FBUF->destipaddr[0] &&
601 BUF->destipaddr[1] == FBUF->destipaddr[1] &&
602 BUF->ipid[0] == FBUF->ipid[0] &&
603 BUF->ipid[1] == FBUF->ipid[1]) {
605 len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
606 offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
610 if(offset > UIP_REASS_BUFSIZE ||
611 offset + len > UIP_REASS_BUFSIZE) {
618 memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
619 (
char *)BUF + (
int)((BUF->vhl & 0x0f) * 4),
623 if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
627 uip_reassbitmap[offset / (8 * 8)] |=
628 bitmap_bits[(offset / 8 ) & 7] &
629 ~bitmap_bits[((offset + len) / 8 ) & 7];
634 uip_reassbitmap[offset / (8 * 8)] |=
635 bitmap_bits[(offset / 8 ) & 7];
636 for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
637 uip_reassbitmap[i] = 0xff;
639 uip_reassbitmap[(offset + len) / (8 * 8)] |=
640 ~bitmap_bits[((offset + len) / 8 ) & 7];
649 if((BUF->ipoffset[0] & IP_MF) == 0) {
650 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
651 uip_reasslen = offset + len;
657 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
660 for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
661 if(uip_reassbitmap[i] != 0xff) {
667 if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
668 (uint8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
676 memcpy(BUF, FBUF, uip_reasslen);
680 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
681 BUF->len[0] = uip_reasslen >> 8;
682 BUF->len[1] = uip_reasslen & 0xff;
696 uip_add_rcv_nxt(uint16_t n)
708 register struct uip_conn *uip_connr =
uip_conn;
710 uint8_t
arpid = UIP_ARP_NONE;
716 if(flag == UIP_UDP_SEND_CONN) {
723 if (flag == UIP_POLL_REQUEST || flag == UIP_TIMER) {
725 if (uip_connr->
arpid == UIP_ARP_NONE) {
726 uip_connr->
arpid = uip_arp_resolve(&uip_connr->
ripaddr);
727 if (uip_connr->
arpid == UIP_ARP_NONE) {
728 uip_arp_request(&uip_connr->
ripaddr);
732 arpid = uip_connr->
arpid;
738 if(flag == UIP_POLL_REQUEST) {
739 if (uip_tx_stopped(uip_connr)) {
741 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED
742 || (uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_FIN_WAIT_1) {
744 uip_flags = UIP_POLL;
747 #if UIP_ACTIVE_OPEN && UIP_TCP 748 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
757 }
else if(flag == UIP_TIMER) {
759 if(uip_reasstmr != 0) {
783 ++(uip_connr->
timer);
785 uip_backlog_cleanup(&uip_connr->
backlog);
794 if(uip_connr->
timer-- == 0) {
799 uip_backlog_cleanup(&uip_connr->
backlog);
805 uip_flags = UIP_TIMEDOUT;
809 BUF->flags = TCP_RST | TCP_ACK;
810 goto tcp_send_nodata;
818 PRINTD(
"REXMIT: [%d] In pipe: %d \n",
819 uip_connr - uip_conns, uip_connr->
len);
831 goto tcp_send_synack;
840 case UIP_ESTABLISHED:
842 uip_backlog_rexmit(&uip_connr->
backlog);
849 goto tcp_send_finack;
852 uip_backlog_rexmit(&uip_connr->
backlog);
858 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
862 uip_flags = UIP_POLL;
871 if(flag == UIP_UDP_TIMER) {
872 if(uip_udp_conn->
lport != 0) {
876 uip_flags = UIP_POLL;
892 if((BUF->vtc & 0xf0) != 0x60) {
895 UIP_LOG(
"ipv6: invalid version.");
900 if(BUF->vhl != 0x45) {
903 UIP_LOG(
"ip: invalid version or header length.");
915 if((BUF->len[0] << 8) + BUF->len[1] <=
uip_len) {
916 uip_len = (BUF->len[0] << 8) + BUF->len[1];
929 UIP_LOG(
"ip: packet shorter than reported in IP header.");
935 if((BUF->ipoffset[0] & 0x3f) != 0 ||
936 BUF->ipoffset[1] != 0) {
945 UIP_LOG(
"ip: fragment dropped.");
951 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
955 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6 956 if(BUF->proto == UIP_PROTO_ICMP) {
957 UIP_LOG(
"ip: possible ping config packet received.");
960 UIP_LOG(
"ip: packet dropped since no address assigned.");
969 DEBUG_PRINTF(
"UDP IP checksum 0x%04x\n",
uip_ipchksum());
970 if(BUF->proto == UIP_PROTO_UDP &&
971 (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) ||
972 (BUF->destipaddr.u8[0] & 224) == 224)) {
987 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
997 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
998 BUF->destipaddr.u16[0] !=
UIP_HTONS(0xff02)) {
1010 UIP_LOG(
"ip: bad checksum.");
1016 if(BUF->proto == UIP_PROTO_TCP) {
1024 if(BUF->proto == UIP_PROTO_UDP) {
1031 if(BUF->proto != UIP_PROTO_ICMP) {
1035 UIP_LOG(
"ip: neither tcp nor icmp.");
1039 #if UIP_PINGADDRCONF 1047 if(ICMPBUF->type != ICMP_ECHO) {
1050 UIP_LOG(
"icmp: not icmp echo.");
1057 #if UIP_PINGADDRCONF 1058 if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
1059 uip_hostaddr = BUF->destipaddr;
1063 ICMPBUF->type = ICMP_ECHO_REPLY;
1065 if(ICMPBUF->icmpchksum >=
UIP_HTONS(0xffff - (ICMP_ECHO << 8))) {
1066 ICMPBUF->icmpchksum +=
UIP_HTONS(ICMP_ECHO << 8) + 1;
1068 ICMPBUF->icmpchksum +=
UIP_HTONS(ICMP_ECHO << 8);
1083 DEBUG_PRINTF(
"icmp6_input: length %d\n",
uip_len);
1085 if(BUF->proto != UIP_PROTO_ICMP6) {
1089 UIP_LOG(
"ip: neither tcp nor icmp6.");
1097 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
1098 if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
1100 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
1102 uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
1107 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1108 ICMPBUF->flags = ICMP6_FLAG_S;
1110 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1114 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1115 ICMPBUF->options[1] = 1;
1116 memcpy(&(ICMPBUF->options[2]), &uip_lladdr,
sizeof(uip_lladdr));
1117 ICMPBUF->icmpchksum = 0;
1124 }
else if(ICMPBUF->type == ICMP6_ECHO) {
1129 ICMPBUF->type = ICMP6_ECHO_REPLY;
1133 ICMPBUF->icmpchksum = 0;
1139 DEBUG_PRINTF(
"Unknown icmp6 message type %d\n", ICMPBUF->type);
1142 UIP_LOG(
"icmp: unknown ICMP message.");
1157 #if UIP_UDP_CHECKSUMS 1163 UIP_LOG(
"udp: bad checksum.");
1171 if(UDPBUF->destport == 0) {
1172 UIP_LOG(
"udp: zero port.");
1177 for(uip_udp_conn = &uip_udp_conns[0];
1187 if(uip_udp_conn->
lport != 0 &&
1188 UDPBUF->destport == uip_udp_conn->
lport &&
1189 (uip_udp_conn->
rport == 0 ||
1190 UDPBUF->srcport == uip_udp_conn->
rport) &&
1191 (uip_ipaddr_cmp(&uip_udp_conn->
ripaddr, &uip_all_zeroes_addr) ||
1192 uip_ipaddr_cmp(&uip_udp_conn->
ripaddr, &uip_broadcast_addr) ||
1193 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->
ripaddr))) {
1197 UIP_LOG(
"udp: no matching connection found");
1199 #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 1201 memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
1204 ICMPBUF->type = ICMP_DEST_UNREACHABLE;
1205 ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
1208 ICMPBUF->icmpchksum = 0;
1209 ICMPBUF->icmpchksum = ~
uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
1221 ICMPBUF->len[0] = 0;
1222 ICMPBUF->len[1] = (uint8_t)
uip_len;
1224 ICMPBUF->proto = UIP_PROTO_ICMP;
1234 uip_flags = UIP_NEWDATA;
1243 uip_len = uip_slen + UIP_IPUDPH_LEN;
1246 if (uip_udp_conn->
arpid == UIP_ARP_NONE)
1247 uip_udp_conn->
arpid = uip_arp_resolve(&uip_udp_conn->
ripaddr);
1248 arpid = uip_udp_conn->
arpid;
1253 BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
1254 BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
1257 BUF->len[1] = (
uip_len & 0xff);
1260 BUF->ttl = uip_udp_conn->
ttl;
1261 BUF->proto = UIP_PROTO_UDP;
1263 UDPBUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1264 UDPBUF->udpchksum = 0;
1266 BUF->srcport = uip_udp_conn->
lport;
1267 BUF->destport = uip_udp_conn->
rport;
1274 #if UIP_UDP_CHECKSUMS 1277 if(UDPBUF->udpchksum == 0) {
1278 UDPBUF->udpchksum = 0xffff;
1297 UIP_LOG(
"tcp: bad checksum.");
1302 if(BUF->destport == 0 || BUF->srcport == 0) {
1303 UIP_LOG(
"tcp: zero port.");
1309 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_CONNS - 1];
1312 BUF->destport == uip_connr->
lport &&
1313 BUF->srcport == uip_connr->
rport &&
1314 uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->
ripaddr)) {
1323 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1327 tmp16 = BUF->destport;
1330 if(tmp16 == uip_listenports[c]) {
1340 if(BUF->flags & TCP_RST) {
1346 BUF->flags = TCP_RST | TCP_ACK;
1348 BUF->tcpoffset = 5 << 4;
1352 BUF->seqno[3] = BUF->ackno[3];
1356 BUF->seqno[2] = BUF->ackno[2];
1360 BUF->seqno[1] = BUF->ackno[1];
1364 BUF->seqno[0] = BUF->ackno[0];
1370 if(++BUF->ackno[3] == 0) {
1371 if(++BUF->ackno[2] == 0) {
1372 if(++BUF->ackno[1] == 0) {
1379 tmp16 = BUF->srcport;
1380 BUF->srcport = BUF->destport;
1381 BUF->destport = tmp16;
1389 arpid = uip_arp_resolve(&BUF->destipaddr);
1390 if (arpid == UIP_ARP_NONE)
1395 goto tcp_send_noconn;
1410 uip_connr = &uip_conns[c];
1414 if(uip_connr == 0 ||
1416 uip_connr = &uip_conns[c];
1421 if(uip_connr == 0) {
1426 UIP_LOG(
"tcp: found no unused connections.");
1431 arpid = uip_arp_resolve(&BUF->srcipaddr);
1432 if (arpid == UIP_ARP_NONE) {
1434 uip_arp_request(&BUF->srcipaddr);
1438 uip_conn = uip_connr;
1444 uip_connr->
nrtx = 0;
1445 uip_connr->
lport = BUF->destport;
1446 uip_connr->
rport = BUF->srcport;
1451 uip_connr->
snd_nxt[0] = iss[0];
1452 uip_connr->
snd_nxt[1] = iss[1];
1453 uip_connr->
snd_nxt[2] = iss[2];
1454 uip_connr->
snd_nxt[3] = iss[3];
1458 uip_connr->
rcv_nxt[3] = BUF->seqno[3];
1459 uip_connr->
rcv_nxt[2] = BUF->seqno[2];
1460 uip_connr->
rcv_nxt[1] = BUF->seqno[1];
1461 uip_connr->
rcv_nxt[0] = BUF->seqno[0];
1465 if((BUF->tcpoffset & 0xf0) > 0x50) {
1466 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1468 if(opt == TCP_OPT_END) {
1471 }
else if(opt == TCP_OPT_NOOP) {
1474 }
else if(opt == TCP_OPT_MSS &&
1475 uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1477 tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 2 + c] << 8) |
1478 (uint16_t)uip_buf[UIP_IPTCPH_LEN +
UIP_LLH_LEN + 3 + c];
1481 if (uip_connr->
window != tmp16) {
1482 uip_connr->
window = tmp16;
1483 PRINTD(
"WIN: [%d] %d, MSS: %d\n",
1484 uip_connr - uip_conns,
1492 if(uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == 0) {
1497 c += uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c];
1505 BUF->flags = TCP_ACK;
1508 BUF->flags |= TCP_SYN;
1511 BUF->flags = TCP_SYN | TCP_ACK;
1516 BUF->optdata[0] = TCP_OPT_MSS;
1517 BUF->optdata[1] = TCP_OPT_MSS_LEN;
1520 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1522 BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1527 uip_conn = uip_connr;
1531 arpid = uip_connr->
arpid;
1532 assert(arpid != UIP_ARP_NONE);
1533 if (arpid == UIP_ARP_NONE) {
1534 uip_arp_request(&BUF->srcipaddr);
1542 if(BUF->flags & TCP_RST) {
1543 uip_backlog_cleanup(&uip_connr->
backlog);
1545 UIP_LOG(
"tcp: got reset, aborting connection.");
1546 uip_flags = UIP_ABORT;
1552 c = (BUF->tcpoffset >> 4) << 2;
1563 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1564 ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1565 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1566 ((BUF->flags & TCP_CTL) == TCP_SYN)))) {
1567 if((
uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1568 (BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1569 BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1570 BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1571 BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1580 if (BUF->flags & TCP_ACK) {
1582 int last_ack = seq_to_cpu(uip_connr->
snd_nxt);
1584 int this_ack = seq_to_cpu(BUF->ackno);
1586 PRINTD(
"ACK: [%d] (%u..%u] -> %u\n",
1587 uip_connr - uip_conns, (
unsigned)last_ack,
1588 (
unsigned)last_sent, (
unsigned)this_ack);
1589 if ((this_ack - last_ack > 0) && (last_sent - this_ack >= 0)) {
1591 uip_connr->
snd_nxt[0] = BUF->ackno[0];
1592 uip_connr->
snd_nxt[1] = BUF->ackno[1];
1593 uip_connr->
snd_nxt[2] = BUF->ackno[2];
1594 uip_connr->
snd_nxt[3] = BUF->ackno[3];
1597 uip_connr->
len -= (this_ack - last_ack);
1600 uip_flags = UIP_ACKDATA;
1605 uip_backlog_release(&uip_connr->
backlog, this_ack);
1620 if(uip_flags & UIP_ACKDATA) {
1622 uip_flags = UIP_CONNECTED;
1624 uip_flags |= UIP_NEWDATA;
1627 uip_connr - uip_conns,
uip_len);
1634 if((BUF->flags & TCP_CTL) == TCP_SYN) {
1635 goto tcp_send_synack;
1644 if((uip_flags & UIP_ACKDATA) &&
1645 (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1648 if((BUF->tcpoffset & 0xf0) > 0x50) {
1649 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
1651 if(opt == TCP_OPT_END) {
1654 }
else if(opt == TCP_OPT_NOOP) {
1657 }
else if(opt == TCP_OPT_MSS &&
1658 uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1660 tmp16 = (uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 2 + c] << 8) |
1664 if (uip_connr->
window != tmp16) {
1665 uip_connr->
window = tmp16;
1666 PRINTD(
"WIN: [%d] %d, MSS: %d\n",
1667 uip_connr - uip_conns,
1675 if(uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c] == 0) {
1680 c += uip_buf[UIP_TCPIP_HLEN +
UIP_LLH_LEN + 1 + c];
1685 uip_connr->
rcv_nxt[0] = BUF->seqno[0];
1686 uip_connr->
rcv_nxt[1] = BUF->seqno[1];
1687 uip_connr->
rcv_nxt[2] = BUF->seqno[2];
1688 uip_connr->
rcv_nxt[3] = BUF->seqno[3];
1690 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1697 uip_flags = UIP_ABORT;
1700 uip_backlog_cleanup(&uip_connr->
backlog);
1705 case UIP_ESTABLISHED:
1717 if((BUF->flags & TCP_FIN) && !(uip_connr->
tcpstateflags & UIP_RX_STOPPED)) {
1719 uip_flags |= UIP_CLOSE;
1721 uip_flags |= UIP_NEWDATA;
1723 uip_connr - uip_conns,
uip_len);
1727 uip_connr->
len += 1;
1729 uip_connr->
nrtx = 0;
1731 BUF->flags = TCP_FIN | TCP_ACK;
1732 goto tcp_send_nodata;
1737 if((BUF->flags & TCP_URG) != 0) {
1739 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1744 uip_add_rcv_nxt(uip_urglen);
1752 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1762 uip_flags |= UIP_NEWDATA;
1765 uip_connr - uip_conns,
uip_len);
1780 tmp16 = ((uint16_t)BUF->wnd[0] << 8) + (uint16_t)BUF->wnd[1];
1781 uip_connr->
window = tmp16;
1787 if (uip_connr->
window != tmp16) {
1788 uip_connr->
window = tmp16;
1789 PRINTD(
"WIN: [%d] %d, MSS: %d\n",
1790 uip_connr - uip_conns,
1810 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1816 if(uip_flags & UIP_ABORT) {
1818 uip_backlog_cleanup(&uip_connr->
backlog);
1820 BUF->flags = TCP_RST | TCP_ACK;
1821 goto tcp_send_nodata;
1824 if(uip_flags & UIP_CLOSE) {
1826 uip_connr->
len += 1;
1828 uip_connr->
nrtx = 0;
1829 BUF->flags = TCP_FIN | TCP_ACK;
1830 goto tcp_send_nodata;
1838 if((uip_flags & UIP_ACKDATA) != 0) {
1845 if(uip_connr->
len == 0) {
1850 if(uip_slen > uip_connr->
mss) {
1851 uip_slen = uip_connr->
mss;
1856 uip_connr->
len = uip_slen;
1857 uip_connr->
len += uip_slen;
1863 uip_slen = uip_connr->
len;
1868 uip_connr->
len += uip_slen;
1871 uip_connr->
nrtx = 0;
1879 uip_len = uip_slen + UIP_TCPIP_HLEN;
1881 BUF->flags = TCP_ACK | TCP_PSH;
1883 goto tcp_send_noopts;
1887 if(uip_flags & UIP_NEWDATA) {
1889 BUF->flags = TCP_ACK;
1890 goto tcp_send_noopts;
1897 if(uip_flags & UIP_ACKDATA) {
1898 uip_backlog_cleanup(&uip_connr->
backlog);
1900 uip_flags = UIP_CLOSE;
1905 case UIP_FIN_WAIT_1:
1912 if(BUF->flags & TCP_FIN) {
1913 if(uip_flags & UIP_ACKDATA) {
1915 uip_connr->
timer = 0;
1920 uip_flags = UIP_CLOSE;
1923 }
else if(uip_flags & UIP_ACKDATA) {
1933 case UIP_FIN_WAIT_2:
1937 if(BUF->flags & TCP_FIN) {
1939 uip_connr->
timer = 0;
1941 uip_flags = UIP_CLOSE;
1954 if(uip_flags & UIP_ACKDATA) {
1956 uip_connr->
timer = 0;
1964 BUF->flags = TCP_ACK;
1971 BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
1978 BUF->ackno[0] = uip_connr->
rcv_nxt[0];
1979 BUF->ackno[1] = uip_connr->
rcv_nxt[1];
1980 BUF->ackno[2] = uip_connr->
rcv_nxt[2];
1981 BUF->ackno[3] = uip_connr->
rcv_nxt[3];
1984 PRINTD(
"SEQ: [%d] %u. In pipe: %d, len: %d \n",
1985 uip_connr - uip_conns, seq_to_cpu(
uip_acc32),
1986 uip_connr->
len, uip_slen);
1994 if ((BUF->flags & (TCP_FIN | TCP_SYN | TCP_RST)) == 0)
1995 uip_backlog = &uip_connr->
backlog;
1999 BUF->proto = UIP_PROTO_TCP;
2001 BUF->srcport = uip_connr->
lport;
2002 BUF->destport = uip_connr->
rport;
2010 BUF->wnd[0] = BUF->wnd[1] = 0;
2013 BUF->wnd[0] = (rxwnd >> 8);
2014 BUF->wnd[1] = (rxwnd & 0xff);
2022 BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
2023 BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
2026 BUF->len[1] = (
uip_len & 0xff);
2029 BUF->urgp[0] = BUF->urgp[1] = 0;
2044 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
2046 BUF->ipid[0] = ipid >> 8;
2047 BUF->ipid[1] = ipid & 0xff;
2051 DEBUG_PRINTF(
"uip ip_send_nolen: chkecum 0x%04x\n",
uip_ipchksum());
2052 if (arpid == UIP_ARP_NONE)
2053 arpid = uip_arp_resolve(&BUF->destipaddr);
2054 if (arpid == UIP_ARP_NONE)
2055 uip_arp_request(&BUF->destipaddr);
2057 uip_arp_fill_mac(arpid);
2061 DEBUG_PRINTF(
"Sending packet with length %d (%d)\n",
uip_len,
2062 (BUF->len[0] << 8) | BUF->len[1]);
2082 uip_htonl(uint32_t val)
2084 return UIP_HTONL(val);
2091 #define MIN(a,b) ((a) < (b)? (a): (b)) 2093 (
int)((
char *)uip_sappdata - (
char *)&uip_buf[
UIP_LLH_LEN + UIP_TCPIP_HLEN]));
2096 if(data != uip_sappdata) {
2097 memcpy(uip_sappdata, (data), uip_slen);
2102 unsigned uip_quote()
2105 if (uip_udp_conn != NULL) {
2107 return tcpip_quote(&uip_udp_conn->
ripaddr) ?
2111 if (!tcpip_quote(&uip_conn->
ripaddr)) {
2112 uip_stop_tx(uip_conn);
2113 PRINTD(
"QUO: [%d] NOMEM\n",
2114 uip_conn - uip_conns);
2117 PRINTD(
"QUO: [%d] Win: %d, Pipe: %d\n",
2118 uip_conn - uip_conns,
2120 if (uip_conn->
len >= uip_conn->
mss * 2) {
2122 }
else if (uip_conn->
len >= uip_conn->
window) {
2125 register unsigned quote = uip_conn->
window - uip_conn->
len;
2126 return MIN(uip_conn->
mss, quote);
2130 bool uip_udp_quote()
2132 return tcpip_quote(&uip_udp_conn->
ripaddr);
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
#define UIP_RECEIVE_WINDOW
void uip_listen(uint16_t port)
void uip_process(uint8_t flag)
process the options within a hop by hop or destination option header
#define PRINTD(FORMAT, args...)
uint16_t uip_chksum(uint16_t *data, uint16_t len)
void uip_send(const void *data, int len)
struct uip_conn * uip_connect(uip_ipaddr_t *ripaddr, uint16_t port)
uint16_t uip_ipchksum(void)
#define UIP_TIME_WAIT_TIMEOUT
static void dlist_init(struct dlist_t *list)
void uip_add32(uint8_t *op32, uint16_t op16)
#define uip_ipaddr_copy(dest, src)
uint8_t data[USBNET_RX_BUF_SIZE]
uint16_t uip_icmp6chksum(void)
uint16_t uip_tcpchksum(void)
void uip_setipid(uint16_t id)
struct uip_conn * uip_conn
uint16_t uip_htons(uint16_t val)
void uip_unlisten(uint16_t port)
uint16_t uip_udpchksum(void)
struct uip_udp_conn * uip_udp_conn