90 #define LOG_MODULE "IPv6" 91 #define LOG_LEVEL LOG_LEVEL_IPV6 93 #if UIP_STATISTICS == 1 104 #if UIP_CONF_LL_802154 144 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) 145 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 146 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 147 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 148 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) 149 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 150 #define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 151 #define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 152 #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 153 #define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 154 #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) 155 #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) 156 #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len]) 163 #ifndef UIP_CONF_EXTERNAL_BUFFER 175 uint16_t uip_urglen, uip_surglen;
196 #if UIP_ACTIVE_OPEN || UIP_UDP 198 static uint16_t lastport;
218 #define TCP_OPT_END 0 219 #define TCP_OPT_NOOP 1 220 #define TCP_OPT_MSS 2 222 #define TCP_OPT_MSS_LEN 4 236 static uint8_t iss[4];
276 uip_acc32[1] = op32[1];
277 uip_acc32[0] = op32[0];
279 if(uip_acc32[2] < (op16 >> 8)) {
281 if(uip_acc32[1] == 0) {
287 if(uip_acc32[3] < (op16 & 0xff)) {
289 if(uip_acc32[2] == 0) {
291 if(uip_acc32[1] == 0) {
299 #if ! UIP_ARCH_CHKSUM 302 chksum(uint16_t sum,
const uint8_t *data, uint16_t len)
305 const uint8_t *dataptr;
306 const uint8_t *last_byte;
309 last_byte = data + len - 1;
311 while(dataptr < last_byte) {
312 t = (dataptr[0] << 8) + dataptr[1];
320 if(dataptr == last_byte) {
321 t = (dataptr[0] << 8) + 0;
335 return uip_htons(chksum(0, (uint8_t *)data, len));
338 #ifndef UIP_ARCH_IPCHKSUM 345 LOG_DBG(
"uip_ipchksum: sum 0x%04x\n", sum);
346 return (sum == 0) ? 0xffff :
uip_htons(sum);
351 upper_layer_chksum(uint8_t proto)
362 volatile uint16_t upper_layer_len;
367 LOG_DBG(
"Upper layer checksum len: %d from: %d\n", upper_layer_len,
372 sum = upper_layer_len + proto;
374 sum = chksum(sum, (uint8_t *)&
UIP_IP_BUF->srcipaddr, 2 *
sizeof(uip_ipaddr_t));
380 return (sum == 0) ? 0xffff :
uip_htons(sum);
386 return upper_layer_chksum(UIP_PROTO_ICMP6);
394 return upper_layer_chksum(UIP_PROTO_TCP);
398 #if UIP_UDP && UIP_UDP_CHECKSUMS 402 return upper_layer_chksum(UIP_PROTO_UDP);
418 uip_listenports[c] = 0;
425 #if UIP_ACTIVE_OPEN || UIP_UDP 431 uip_udp_conns[c].
lport = 0;
435 #if UIP_IPV6_MULTICAST 440 #if UIP_TCP && UIP_ACTIVE_OPEN 444 register struct uip_conn *conn, *cconn;
451 if(lastport >= 32000) {
458 conn = &uip_conns[c];
467 cconn = &uip_conns[c];
515 int last_uip_ext_len;
518 LOG_DBG(
"Cutting ext-header before processing (extlen: %d, uiplen: %d)\n",
521 LOG_ERR(
"ERROR: uip_len too short compared to ext len\n");
528 memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + last_uip_ext_len,
529 uip_len - UIP_IPH_LEN - last_uip_ext_len);
540 struct uip_udp_conn *
544 register struct uip_udp_conn *conn;
550 if(lastport >= 32000) {
562 if(uip_udp_conns[c].
lport == 0) {
563 conn = &uip_udp_conns[c];
574 if(ripaddr == NULL) {
575 memset(&conn->
ripaddr, 0,
sizeof(uip_ipaddr_t));
591 if(uip_listenports[c] == port) {
592 uip_listenports[c] = 0;
603 if(uip_listenports[c] == 0) {
604 uip_listenports[c] = port;
612 #if UIP_CONF_IPV6_REASSEMBLY 613 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) 615 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
617 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
620 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
621 0x0f, 0x07, 0x03, 0x01};
622 static uint16_t uip_reasslen;
623 static uint8_t uip_reassflags;
625 #define UIP_REASS_FLAG_LASTFRAG 0x01 626 #define UIP_REASS_FLAG_FIRSTFRAG 0x02 627 #define UIP_REASS_FLAG_ERROR_MSG 0x04 641 uint8_t uip_reass_on;
643 static uint32_t uip_id;
658 if(uip_reass_on == 0) {
659 LOG_INFO(
"Starting reassembly\n");
665 uip_id = UIP_FRAG_BUF->id;
667 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
674 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &
UIP_IP_BUF->srcipaddr) &&
675 uip_ipaddr_cmp(&FBUF->destipaddr, &
UIP_IP_BUF->destipaddr) &&
676 UIP_FRAG_BUF->id == uip_id) {
678 offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
680 LOG_INFO(
"len %d\n", len);
681 LOG_INFO(
"offset %d\n", offset);
683 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
692 LOG_INFO_6ADDR(&FBUF->srcipaddr);
694 LOG_INFO_6ADDR(&FBUF->destipaddr);
701 if(offset > UIP_REASS_BUFSIZE ||
702 offset + len > UIP_REASS_BUFSIZE) {
710 if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
711 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
713 uip_reasslen = offset + len;
714 LOG_INFO(
"last fragment reasslen %d\n", uip_reasslen);
722 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
733 memcpy((uint8_t *)FBUF + UIP_IPH_LEN +
uip_ext_len + offset,
734 (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
737 if(offset >> 6 == (offset + len) >> 6) {
738 uip_reassbitmap[offset >> 6] |=
739 bitmap_bits[(offset >> 3) & 7] &
740 ~bitmap_bits[((offset + len) >> 3) & 7];
745 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
747 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
748 uip_reassbitmap[i] = 0xff;
750 uip_reassbitmap[(offset + len) >> 6] |=
751 ~bitmap_bits[((offset + len) >> 3) & 7];
758 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
761 for(i = 0; i < (uip_reasslen >> 6); ++i) {
762 if(uip_reassbitmap[i] != 0xff) {
768 if(uip_reassbitmap[uip_reasslen >> 6] !=
769 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
780 UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
781 UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
782 LOG_INFO(
"reassembled packet %d (%d)\n", uip_reasslen,
789 LOG_WARN(
"Already reassembling another paquet\n");
802 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
803 LOG_ERR(
"fragmentation timeout\n");
828 uip_add_rcv_nxt(uint16_t n)
852 switch(UIP_EXT_HDR_OPT_BUF->type) {
859 LOG_DBG(
"Processing PAD1 option\n");
862 case UIP_EXT_HDR_OPT_PADN:
863 LOG_DBG(
"Processing PADN option\n");
866 case UIP_EXT_HDR_OPT_RPL:
876 LOG_ERR(
"RPL Option Error: Dropping Packet\n");
895 LOG_DBG(
"MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
896 switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
927 register struct uip_conn *uip_connr =
uip_conn;
930 if(flag == UIP_UDP_SEND_CONN) {
938 if(flag == UIP_POLL_REQUEST) {
940 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
941 !uip_outstanding(uip_connr)) {
942 uip_flags = UIP_POLL;
946 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
948 UIP_TCP_BUF->flags = 0;
955 }
else if(flag == UIP_TIMER) {
978 ++(uip_connr->
timer);
988 if(uip_outstanding(uip_connr)) {
989 if(uip_connr->
timer-- == 0) {
1001 uip_flags = UIP_TIMEDOUT;
1005 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1006 goto tcp_send_nodata;
1013 ++(uip_connr->
nrtx);
1027 goto tcp_send_synack;
1032 UIP_TCP_BUF->flags = 0;
1036 case UIP_ESTABLISHED:
1043 uip_flags = UIP_REXMIT;
1047 case UIP_FIN_WAIT_1:
1051 goto tcp_send_finack;
1054 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1059 uip_flags = UIP_POLL;
1068 if(flag == UIP_UDP_TIMER) {
1069 if(uip_udp_conn->
lport != 0) {
1073 uip_flags = UIP_POLL;
1092 LOG_ERR(
"invalid version\n");
1118 LOG_ERR(
"packet shorter than reported in IP header.");
1122 LOG_INFO(
"packet received from ");
1130 LOG_ERR(
"Dropping packet, src is mcast\n");
1137 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1151 #if UIP_CONF_IPV6_CHECKS 1161 LOG_ERR(
"Dropping packet after extension header processing\n");
1165 LOG_ERR(
"Sending error message after extension header processing\n");
1183 #if UIP_IPV6_MULTICAST 1185 if(UIP_MCAST6.
in() == UIP_MCAST6_ACCEPT) {
1196 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1197 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1220 LOG_INFO(
"Forwarding packet towards ");
1230 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1231 LOG_ERR(
"LL source address with off link destination, dropping\n");
1236 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1242 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1243 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1245 LOG_ERR(
"Dropping packet, not for me\n");
1259 #if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER 1275 case UIP_PROTO_ICMP6:
1279 LOG_DBG(
"Processing hbh header\n");
1281 #if UIP_CONF_IPV6_CHECKS 1304 case UIP_PROTO_DESTO:
1305 #if UIP_CONF_IPV6_CHECKS 1307 LOG_DBG(
"Processing desto header\n");
1333 case UIP_PROTO_ROUTING:
1334 #if UIP_CONF_IPV6_CHECKS 1350 LOG_DBG(
"Processing Routing header\n");
1351 if(UIP_ROUTING_BUF->seg_left > 0) {
1373 LOG_INFO(
"Forwarding packet to next hop ");
1382 LOG_ERR(
"unrecognized routing type");
1388 case UIP_PROTO_FRAG:
1390 #if UIP_CONF_IPV6_REASSEMBLY 1391 LOG_INFO(
"Processing fragmentation header\n");
1396 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
1402 LOG_INFO(
"Processing reassembled packet\n");
1410 LOG_ERR(
"fragment dropped.");
1413 case UIP_PROTO_NONE:
1427 LOG_ERR(
"unrecognized header");
1435 #if UIP_CONF_IPV6_CHECKS 1440 LOG_ERR(
"icmpv6 bad checksum\n");
1465 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1485 LOG_INFO(
"Receiving UDP packet\n");
1491 #if UIP_UDP_CHECKSUMS 1497 if(UIP_UDP_BUF->udpchksum != 0 &&
uip_udpchksum() != 0xffff) {
1500 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1507 if(UIP_UDP_BUF->destport == 0) {
1508 LOG_ERR(
"udp: zero port.\n");
1513 for(uip_udp_conn = &uip_udp_conns[0];
1523 if(uip_udp_conn->
lport != 0 &&
1524 UIP_UDP_BUF->destport == uip_udp_conn->
lport &&
1525 (uip_udp_conn->
rport == 0 ||
1526 UIP_UDP_BUF->srcport == uip_udp_conn->
rport) &&
1528 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_udp_conn->
ripaddr))) {
1532 LOG_ERR(
"udp: no matching connection found\n");
1539 LOG_DBG(
"In udp_found\n");
1545 uip_flags = UIP_NEWDATA;
1551 LOG_DBG(
"In udp_send\n");
1556 uip_len = uip_slen + UIP_IPUDPH_LEN;
1560 UIP_IP_BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
1561 UIP_IP_BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
1563 UIP_IP_BUF->vtc = 0x60;
1564 UIP_IP_BUF->tcflow = 0x00;
1565 UIP_IP_BUF->ttl = uip_udp_conn->
ttl;
1566 UIP_IP_BUF->proto = UIP_PROTO_UDP;
1568 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1569 UIP_UDP_BUF->udpchksum = 0;
1571 UIP_UDP_BUF->srcport = uip_udp_conn->
lport;
1572 UIP_UDP_BUF->destport = uip_udp_conn->
rport;
1579 #if UIP_UDP_CHECKSUMS 1582 if(UIP_UDP_BUF->udpchksum == 0) {
1583 UIP_UDP_BUF->udpchksum = 0xffff;
1598 LOG_INFO(
"Receiving TCP packet\n");
1605 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1611 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1612 LOG_ERR(
"tcp: zero port.");
1618 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1621 UIP_TCP_BUF->destport == uip_connr->
lport &&
1622 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1623 uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &uip_connr->
ripaddr)) {
1632 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1636 tmp16 = UIP_TCP_BUF->destport;
1639 if(tmp16 == uip_listenports[c]) {
1648 LOG_WARN(
"In reset\n");
1650 if(UIP_TCP_BUF->flags & TCP_RST) {
1656 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1658 UIP_TCP_BUF->tcpoffset = 5 << 4;
1661 c = UIP_TCP_BUF->seqno[3];
1662 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1663 UIP_TCP_BUF->ackno[3] = c;
1665 c = UIP_TCP_BUF->seqno[2];
1666 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1667 UIP_TCP_BUF->ackno[2] = c;
1669 c = UIP_TCP_BUF->seqno[1];
1670 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1671 UIP_TCP_BUF->ackno[1] = c;
1673 c = UIP_TCP_BUF->seqno[0];
1674 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1675 UIP_TCP_BUF->ackno[0] = c;
1680 if(++UIP_TCP_BUF->ackno[3] == 0) {
1681 if(++UIP_TCP_BUF->ackno[2] == 0) {
1682 if(++UIP_TCP_BUF->ackno[1] == 0) {
1683 ++UIP_TCP_BUF->ackno[0];
1689 tmp16 = UIP_TCP_BUF->srcport;
1690 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1691 UIP_TCP_BUF->destport = tmp16;
1697 goto tcp_send_noconn;
1703 LOG_DBG(
"In found listen\n");
1713 uip_connr = &uip_conns[c];
1717 if(uip_connr == 0 ||
1719 uip_connr = &uip_conns[c];
1724 if(uip_connr == 0) {
1729 LOG_ERR(
"tcp: found no unused connections.");
1732 uip_conn = uip_connr;
1738 uip_connr->
nrtx = 0;
1739 uip_connr->
lport = UIP_TCP_BUF->destport;
1740 uip_connr->
rport = UIP_TCP_BUF->srcport;
1744 uip_connr->
snd_nxt[0] = iss[0];
1745 uip_connr->
snd_nxt[1] = iss[1];
1746 uip_connr->
snd_nxt[2] = iss[2];
1747 uip_connr->
snd_nxt[3] = iss[3];
1751 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1752 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1753 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1754 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1758 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1759 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1761 if(opt == TCP_OPT_END) {
1764 }
else if(opt == TCP_OPT_NOOP) {
1767 }
else if(opt == TCP_OPT_MSS &&
1793 UIP_TCP_BUF->flags = TCP_ACK;
1796 UIP_TCP_BUF->flags |= TCP_SYN;
1799 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1804 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1805 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1808 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1809 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1814 LOG_DBG(
"In found\n");
1815 uip_conn = uip_connr;
1821 if(UIP_TCP_BUF->flags & TCP_RST) {
1823 LOG_WARN(
"tcp: got reset, aborting connection.");
1824 uip_flags = UIP_ABORT;
1830 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1841 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1842 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1843 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1844 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1845 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1846 (UIP_TCP_BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1847 UIP_TCP_BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1848 UIP_TCP_BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1849 UIP_TCP_BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1851 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1852 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1853 goto tcp_send_synack;
1855 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1868 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1871 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
1872 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
1873 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
1874 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
1882 if(uip_connr->
nrtx == 0) {
1884 m = uip_connr->
rto - uip_connr->
timer;
1886 m = m - (uip_connr->
sa >> 3);
1891 m = m - (uip_connr->
sv >> 2);
1893 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1897 uip_flags = UIP_ACKDATA;
1918 if(uip_flags & UIP_ACKDATA) {
1920 uip_flags = UIP_CONNECTED;
1923 uip_flags |= UIP_NEWDATA;
1931 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1932 goto tcp_send_synack;
1941 if((uip_flags & UIP_ACKDATA) &&
1942 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1945 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1946 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1948 if(opt == TCP_OPT_END) {
1951 }
else if(opt == TCP_OPT_NOOP) {
1954 }
else if(opt == TCP_OPT_MSS &&
1977 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1978 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1979 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1980 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1982 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1990 uip_flags = UIP_ABORT;
1997 case UIP_ESTABLISHED:
2009 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2010 if(uip_outstanding(uip_connr)) {
2014 uip_flags |= UIP_CLOSE;
2016 uip_flags |= UIP_NEWDATA;
2021 uip_connr->
nrtx = 0;
2023 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2024 goto tcp_send_nodata;
2029 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2031 uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2036 uip_add_rcv_nxt(uip_urglen);
2044 uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2054 uip_flags |= UIP_NEWDATA;
2070 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2075 uip_connr->
mss = tmp16;
2093 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2099 if(uip_flags & UIP_ABORT) {
2102 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2103 goto tcp_send_nodata;
2106 if(uip_flags & UIP_CLOSE) {
2110 uip_connr->
nrtx = 0;
2111 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2112 goto tcp_send_nodata;
2120 if((uip_flags & UIP_ACKDATA) != 0) {
2127 if(uip_connr->
len == 0) {
2132 if(uip_slen > uip_connr->
mss) {
2133 uip_slen = uip_connr->
mss;
2138 uip_connr->
len = uip_slen;
2144 uip_slen = uip_connr->
len;
2147 uip_connr->
nrtx = 0;
2153 if(uip_slen > 0 && uip_connr->
len > 0) {
2157 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2159 goto tcp_send_noopts;
2163 if(uip_flags & UIP_NEWDATA) {
2165 UIP_TCP_BUF->flags = TCP_ACK;
2166 goto tcp_send_noopts;
2173 if(uip_flags & UIP_ACKDATA) {
2175 uip_flags = UIP_CLOSE;
2180 case UIP_FIN_WAIT_1:
2187 if(UIP_TCP_BUF->flags & TCP_FIN) {
2188 if(uip_flags & UIP_ACKDATA) {
2190 uip_connr->
timer = 0;
2196 uip_flags = UIP_CLOSE;
2199 }
else if(uip_flags & UIP_ACKDATA) {
2209 case UIP_FIN_WAIT_2:
2213 if(UIP_TCP_BUF->flags & TCP_FIN) {
2215 uip_connr->
timer = 0;
2217 uip_flags = UIP_CLOSE;
2230 if(uip_flags & UIP_ACKDATA) {
2232 uip_connr->
timer = 0;
2240 UIP_TCP_BUF->flags = TCP_ACK;
2246 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2253 LOG_DBG(
"In tcp_send\n");
2255 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2256 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2257 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2258 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2260 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2261 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2262 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2263 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2265 UIP_TCP_BUF->srcport = uip_connr->
lport;
2266 UIP_TCP_BUF->destport = uip_connr->
rport;
2268 UIP_IP_BUF->vtc = 0x60;
2269 UIP_IP_BUF->tcflow = 0x00;
2273 LOG_INFO(
"Sending TCP packet to ");
2274 LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
2275 LOG_INFO_(
" from ");
2276 LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
2282 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2289 UIP_IP_BUF->proto = UIP_PROTO_TCP;
2292 UIP_IP_BUF->len[0] = ((
uip_len - UIP_IPH_LEN) >> 8);
2293 UIP_IP_BUF->len[1] = ((
uip_len - UIP_IPH_LEN) & 0xff);
2295 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2298 UIP_TCP_BUF->tcpchksum = 0;
2306 UIP_IP_BUF->flow = 0x00;
2308 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len,
2309 (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
2330 uip_htonl(uint32_t val)
2332 return UIP_HTONL(val);
2340 if(uip_sappdata != NULL) {
2342 (
int)((
char *)uip_sappdata -
2349 if(data != uip_sappdata) {
2350 if(uip_sappdata == NULL) {
2354 memcpy(uip_sappdata, (data), uip_slen);
static uint8_t ext_hdr_options_process(void)
Process the options in Destination and Hop By Hop extension headers.
#define UIP_IP_BUF
Pointer to IP header.
uip_lladdr_t uip_lladdr
Host L2 address.
void uip_init(void)
uIP initialization function.
#define UIP_RECEIVE_WINDOW
The size of the advertised receiver's window.
Header file for ICMPv6 message and error handing (RFC 4443)
void uip_listen(uint16_t port)
Start listening to the specified port.
Representation of a uIP TCP connection.
void etimer_stop(struct etimer *et)
Stop a pending event timer.
#define uip_is_addr_mcast_routable(a)
is address a routable multicast address.
#define UIP_RTO
The initial retransmission timeout counted in timer pulses.
uint16_t uip_tcpchksum(void)
Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
void uip_process(uint8_t flag)
process the options within a hop by hop or destination option header
void uip_ds6_init(void)
Initialize data structures.
#define UIP_ICMP_BUF
Pointer to ICMP header.
#define UIP_TCP_CONNS
The maximum number of simultaneously open TCP connections.
uint8_t uip_ext_bitmap
bitmap we use to record which IPv6 headers we have already seen
#define UIP_PROTO_HBHO
extension headers types
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
uip_ipaddr_t ripaddr
The IP address of the remote host.
#define ICMP6_PARAM_PROB
ip6 header bad
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
#define UIP_EXT_HDR_OPT_PAD1
Destination and Hop By Hop extension headers option types.
#define ICMP6_DST_UNREACH
dest unreachable
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
#define UIP_APPCALL
The name of the application function that uIP should call in response to TCP/IP events.
void uip_nd6_init()
Initialise the uIP ND core.
uint16_t uip_ipchksum(void)
Calculate the IP header checksum of the packet header in uip_buf.
uint8_t sa
Retransmission time-out calculation state variable.
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
uint8_t uip_acc32[4]
4-byte array used for the 32-bit sequence number calculations.
void uip_send(const void *data, int len)
Send data on the current connection.
Header file for IPv6-related data structures.
uint16_t lport
The local port number in network byte order.
uint16_t rport
The local remote TCP port, in network byte order.
Configuration options for uIP.
uint8_t rto
Retransmission time-out.
#define UIP_TIME_WAIT_TIMEOUT
How long a connection should stay in the TIME_WAIT state.
uint8_t snd_nxt[4]
The sequence number that was last sent by us.
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode)
Handle an incoming ICMPv6 message.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
#define UIP_REASS_MAXAGE
The maximum time an IP fragment should wait in the reassembly buffer before it is dropped...
This header file contains configuration directives for uIPv6 multicast support.
#define CLOCK_SECOND
A second, measured in system clock time.
#define ICMP6_PACKET_TOO_BIG
packet too big
uint8_t rcv_nxt[4]
The sequence number that we expect to receive next.
uint8_t(* in)(void)
Process an incoming multicast datagram and determine whether it should be delivered up the stack or n...
uint8_t uip_ext_len
length of the extension headers read.
The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1...
void uip_add32(uint8_t *op32, uint16_t op16)
Carry out a 32-bit addition.
uint8_t tcpstateflags
TCP state and flags.
uint8_t uip_ext_opt_offset
length of the header options read
#define UIP_LLH_LEN
The link level header length.
Declarations of architecture specific functions.
#define uip_is_addr_loopback(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
uint16_t lport
The local TCP port, in network byte order.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
Routing driver header file
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
void uip_reass_over(void)
Abandon the reassembly of the current packet.
#define UIP_STAT(s)
The uIP TCP/IP statistics.
#define ICMP6_PARAMPROB_NEXTHEADER
unrecognized next header
#define ICMP6_PARAMPROB_HEADER
erroneous header field
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
uint8_t nrtx
The number of retransmissions for the last segment sent.
uint16_t mss
Current maximum segment size for the connection.
#define UIP_EXT_HDR_BITMAP_HBHO
Bitmaps for extension header processing.
#define ICMP6_TIME_EXCEED_REASSEMBLY
ttl==0 in reass
struct etimer uip_reass_timer
Timer for reassembly.
uint16_t initialmss
Initial maximum segment size for the connection.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define ICMP6_TIME_EXCEEDED
time exceeded
Header file for the uIP TCP/IP stack.
#define ICMP6_PARAMPROB_OPTION
unrecognized option
void(* init)(void)
Initialize the multicast engine.
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_ds6_netif_t uip_ds6_if
The single interface.
int(* ext_header_srh_update)(void)
Process and update SRH in-place, i.e.
uint8_t timer
The retransmission timer.
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
#define UIP_TCP_MSS
The TCP maximum segment size.
uint8_t * uip_next_hdr
Type of the next header in IPv6 header or extension headers.
#define UIP_MAXRTX
The maximum number of times a segment should be retransmitted before the connection should be aborted...
int(* ext_header_hbh_update)(int uip_ext_opt_offset)
Process and update the routing protocol hob-by-hop extention headers of the current uIP packet...
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
#define UIP_MAXSYNRTX
The maximum number of times a SYN segment should be retransmitted before a connection request should ...
uip_buf_t uip_aligned_buf
Packet buffer for incoming and outgoing packets.
struct uip_conn * uip_conn
Pointer to the current TCP connection.
void uip_icmp6_init()
Initialise the uIP ICMPv6 core.
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
#define ICMP6_DST_UNREACH_NOTNEIGHBOR
not a neighbor(obsolete)
uint8_t sv
Retransmission time-out calculation state variable.
Default definitions of C compiler quirk work-arounds.
uint8_t ttl
Default time-to-live.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
#define ICMP6_DST_UNREACH_NOPORT
port unreachable
uint16_t len
Length of the data that was previously sent.
Header file for the logging system
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
uint16_t uip_udpchksum(void)
Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
#define ICMP6_TIME_EXCEED_TRANSIT
ttl==0 in transit
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
uint16_t uip_chksum(uint16_t *data, uint16_t len)
Calculate the Internet checksum over a buffer.
void * uip_appdata
Pointer to the application data in the packet buffer.
uint16_t rport
The remote port number in network byte order.
struct uip_udp_conn * uip_udp_conn
The current UDP connection.
Representation of a uIP UDP connection.