90 #define LOG_MODULE "IPv6" 91 #define LOG_LEVEL LOG_LEVEL_IPV6 93 #if UIP_STATISTICS == 1 104 #if UIP_CONF_LL_802154 135 #define FBUF ((struct uip_ip_hdr *)&uip_reassbuf[0]) 143 #ifndef UIP_CONF_EXTERNAL_BUFFER 155 uint16_t uip_urglen, uip_surglen;
176 #if UIP_ACTIVE_OPEN || UIP_UDP 178 static uint16_t lastport;
198 #define TCP_OPT_END 0 199 #define TCP_OPT_NOOP 1 200 #define TCP_OPT_MSS 2 202 #define TCP_OPT_MSS_LEN 4 216 static uint8_t iss[4];
256 uip_acc32[1] = op32[1];
257 uip_acc32[0] = op32[0];
259 if(uip_acc32[2] < (op16 >> 8)) {
261 if(uip_acc32[1] == 0) {
267 if(uip_acc32[3] < (op16 & 0xff)) {
269 if(uip_acc32[2] == 0) {
271 if(uip_acc32[1] == 0) {
279 #if ! UIP_ARCH_CHKSUM 282 chksum(uint16_t sum,
const uint8_t *data, uint16_t len)
285 const uint8_t *dataptr;
286 const uint8_t *last_byte;
289 last_byte = data + len - 1;
291 while(dataptr < last_byte) {
292 t = (dataptr[0] << 8) + dataptr[1];
300 if(dataptr == last_byte) {
301 t = (dataptr[0] << 8) + 0;
315 return uip_htons(chksum(0, (uint8_t *)data, len));
318 #ifndef UIP_ARCH_IPCHKSUM 324 sum = chksum(0,
uip_buf, UIP_IPH_LEN);
325 LOG_DBG(
"uip_ipchksum: sum 0x%04x\n", sum);
326 return (sum == 0) ? 0xffff :
uip_htons(sum);
331 upper_layer_chksum(uint8_t proto)
342 volatile uint16_t upper_layer_len;
347 LOG_DBG(
"Upper layer checksum len: %d from: %d\n", upper_layer_len,
352 sum = upper_layer_len + proto;
354 sum = chksum(sum, (uint8_t *)&
UIP_IP_BUF->srcipaddr, 2 *
sizeof(uip_ipaddr_t));
357 sum = chksum(sum, UIP_IP_PAYLOAD(
uip_ext_len), upper_layer_len);
359 return (sum == 0) ? 0xffff :
uip_htons(sum);
365 return upper_layer_chksum(UIP_PROTO_ICMP6);
373 return upper_layer_chksum(UIP_PROTO_TCP);
377 #if UIP_UDP && UIP_UDP_CHECKSUMS 381 return upper_layer_chksum(UIP_PROTO_UDP);
398 uip_listenports[c] = 0;
405 #if UIP_ACTIVE_OPEN || UIP_UDP 411 uip_udp_conns[c].
lport = 0;
415 #if UIP_IPV6_MULTICAST 420 #if UIP_TCP && UIP_ACTIVE_OPEN 424 register struct uip_conn *conn, *cconn;
431 if(lastport >= 32000) {
438 conn = &uip_conns[c];
447 cconn = &uip_conns[c];
497 LOG_DBG(
"Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
500 LOG_ERR(
"uip_len too short compared to ext len\n");
508 memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(
uip_ext_len),
521 struct uip_udp_conn *
525 register struct uip_udp_conn *conn;
531 if(lastport >= 32000) {
543 if(uip_udp_conns[c].
lport == 0) {
544 conn = &uip_udp_conns[c];
555 if(ripaddr == NULL) {
556 memset(&conn->
ripaddr, 0,
sizeof(uip_ipaddr_t));
572 if(uip_listenports[c] == port) {
573 uip_listenports[c] = 0;
584 if(uip_listenports[c] == 0) {
585 uip_listenports[c] = port;
593 #if UIP_CONF_IPV6_REASSEMBLY 594 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE) 596 static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
598 static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
601 static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
602 0x0f, 0x07, 0x03, 0x01};
603 static uint16_t uip_reasslen;
604 static uint8_t uip_reassflags;
606 #define UIP_REASS_FLAG_LASTFRAG 0x01 607 #define UIP_REASS_FLAG_FIRSTFRAG 0x02 608 #define UIP_REASS_FLAG_ERROR_MSG 0x04 622 uint8_t uip_reass_on;
624 static uint32_t uip_id;
630 uip_reass(uint8_t *prev_proto_ptr)
635 struct uip_frag_hdr *frag_buf = (
struct uip_frag_hdr *)UIP_IP_PAYLOAD(
uip_ext_len);
640 if(uip_reass_on == 0) {
641 LOG_INFO(
"Starting reassembly\n");
647 uip_id = frag_buf->id;
649 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
656 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &
UIP_IP_BUF->srcipaddr) &&
657 uip_ipaddr_cmp(&FBUF->destipaddr, &
UIP_IP_BUF->destipaddr) &&
658 frag_buf->id == uip_id) {
660 offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
662 LOG_INFO(
"len %d\n", len);
663 LOG_INFO(
"offset %d\n", offset);
665 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
671 *prev_proto_ptr = frag_buf->next;
674 LOG_INFO_6ADDR(&FBUF->srcipaddr);
676 LOG_INFO_6ADDR(&FBUF->destipaddr);
683 if(offset > UIP_REASS_BUFSIZE ||
684 offset + len > UIP_REASS_BUFSIZE) {
692 if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
693 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
695 uip_reasslen = offset + len;
696 LOG_INFO(
"last fragment reasslen %d\n", uip_reasslen);
704 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
715 memcpy((uint8_t *)FBUF + UIP_IPH_LEN +
uip_ext_len + offset,
716 (uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
719 if(offset >> 6 == (offset + len) >> 6) {
720 uip_reassbitmap[offset >> 6] |=
721 bitmap_bits[(offset >> 3) & 7] &
722 ~bitmap_bits[((offset + len) >> 3) & 7];
727 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
729 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
730 uip_reassbitmap[i] = 0xff;
732 uip_reassbitmap[(offset + len) >> 6] |=
733 ~bitmap_bits[((offset + len) >> 3) & 7];
740 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
743 for(i = 0; i < (uip_reasslen >> 6); ++i) {
744 if(uip_reassbitmap[i] != 0xff) {
750 if(uip_reassbitmap[uip_reasslen >> 6] !=
751 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
762 uipbuf_set_len_field(
UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
763 LOG_INFO(
"reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(
UIP_IP_BUF));
769 LOG_WARN(
"Already reassembling another paquet\n");
782 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
783 LOG_ERR(
"fragmentation timeout\n");
808 uip_add_rcv_nxt(uint16_t n)
830 uint16_t opt_offset = 2;
831 struct uip_hbho_hdr *ext_hdr = (
struct uip_hbho_hdr *)ext_buf;
832 uint16_t ext_hdr_len = (ext_hdr->len << 3) + 8;
834 while(opt_offset + 2 <= ext_hdr_len) {
835 struct uip_ext_hdr_opt *opt_hdr = (
struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
836 uint16_t opt_len = opt_hdr->len + 2;
838 if(opt_offset + opt_len > ext_hdr_len) {
839 LOG_ERR(
"Extension header option too long: dropping packet\n");
841 (ext_buf + opt_offset) -
uip_buf);
845 switch(opt_hdr->type) {
852 LOG_DBG(
"Processing PAD1 option\n");
855 case UIP_EXT_HDR_OPT_PADN:
856 LOG_DBG(
"Processing PADN option\n");
857 opt_offset += opt_len;
859 case UIP_EXT_HDR_OPT_RPL:
868 LOG_DBG(
"Processing RPL option\n");
870 LOG_ERR(
"RPL Option Error: Dropping Packet\n");
873 opt_offset += opt_len;
875 #if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL 876 case UIP_EXT_HDR_OPT_MPL:
881 LOG_DBG(
"Processing MPL option\n");
882 opt_offset += opt_len + opt_len;
899 LOG_DBG(
"Unrecognized option, MSB 0x%x\n", opt_hdr->type);
900 switch(opt_hdr->type & 0xC0) {
911 (ext_buf + opt_offset) -
uip_buf);
915 opt_offset += opt_len;
950 uint8_t *last_header;
952 uint8_t *next_header;
953 struct uip_ext_hdr *ext_ptr;
958 register struct uip_conn *uip_connr =
uip_conn;
961 if(flag == UIP_UDP_SEND_CONN) {
969 if(flag == UIP_POLL_REQUEST) {
971 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
972 !uip_outstanding(uip_connr)) {
973 uip_flags = UIP_POLL;
977 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
979 UIP_TCP_BUF->flags = 0;
986 }
else if(flag == UIP_TIMER) {
1009 ++(uip_connr->
timer);
1019 if(uip_outstanding(uip_connr)) {
1020 if(uip_connr->
timer-- == 0) {
1032 uip_flags = UIP_TIMEDOUT;
1036 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1037 goto tcp_send_nodata;
1044 ++(uip_connr->
nrtx);
1058 goto tcp_send_synack;
1063 UIP_TCP_BUF->flags = 0;
1067 case UIP_ESTABLISHED:
1074 uip_flags = UIP_REXMIT;
1078 case UIP_FIN_WAIT_1:
1082 goto tcp_send_finack;
1085 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1090 uip_flags = UIP_POLL;
1099 if(flag == UIP_UDP_TIMER) {
1100 if(uip_udp_conn->
lport != 0) {
1104 uip_flags = UIP_POLL;
1122 LOG_WARN(
"incomplete IPv6 header received (%d bytes)\n", (
int)
uip_len);
1130 LOG_ERR(
"invalid version\n");
1145 LOG_ERR(
"packet shorter than reported in IP header\n");
1162 LOG_WARN(
"dropping packet with length %d > %d\n",
1171 if(last_header == NULL) {
1172 LOG_ERR(
"invalid extension header chain\n");
1178 LOG_INFO(
"packet received from ");
1186 LOG_ERR(
"Dropping packet, src is mcast\n");
1193 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1203 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1227 #if UIP_IPV6_MULTICAST 1229 if(UIP_MCAST6.
in() == UIP_MCAST6_ACCEPT) {
1240 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1241 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1248 if(!uip_check_mtu() || !uip_update_ttl()) {
1253 LOG_INFO(
"Forwarding packet to next hop ");
1263 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1264 LOG_ERR(
"LL source address with off link destination, dropping\n");
1269 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1275 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1276 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1278 LOG_ERR(
"Dropping packet, not for me\n");
1284 #if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER 1290 for(next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1291 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1292 next_header = uipbuf_get_next_header(next_header,
uip_len - (next_header -
uip_buf), &protocol,
false)) {
1294 ext_ptr = (
struct uip_ext_hdr *)next_header;
1297 LOG_DBG(
"Processing hbh header\n");
1299 #if UIP_CONF_IPV6_CHECKS 1317 case UIP_PROTO_DESTO:
1318 #if UIP_CONF_IPV6_CHECKS 1320 LOG_DBG(
"Processing desto header\n");
1341 case UIP_PROTO_ROUTING:
1342 #if UIP_CONF_IPV6_CHECKS 1358 LOG_DBG(
"Processing Routing header\n");
1359 if(((
struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1366 if(!uip_check_mtu() || !uip_update_ttl()) {
1371 LOG_INFO(
"Forwarding packet to next hop ");
1378 LOG_ERR(
"Unrecognized routing type\n");
1383 case UIP_PROTO_FRAG:
1385 #if UIP_CONF_IPV6_REASSEMBLY 1386 LOG_INFO(
"Processing fragmentation header\n");
1387 uip_len = uip_reass(&ext_ptr->next);
1391 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1396 LOG_INFO(
"Processing reassembled packet\n");
1398 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1403 LOG_ERR(
"fragment dropped.");
1406 case UIP_PROTO_NONE:
1414 if(next_header != NULL) {
1426 case UIP_PROTO_ICMP6:
1440 LOG_ERR(
"unrecognized header\n");
1448 #if UIP_CONF_IPV6_CHECKS 1453 LOG_ERR(
"icmpv6 bad checksum\n");
1478 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1498 LOG_INFO(
"Receiving UDP packet\n");
1504 #if UIP_UDP_CHECKSUMS 1510 if(UIP_UDP_BUF->udpchksum != 0 &&
uip_udpchksum() != 0xffff) {
1513 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1520 if(UIP_UDP_BUF->destport == 0) {
1521 LOG_ERR(
"udp: zero port.\n");
1526 for(uip_udp_conn = &uip_udp_conns[0];
1536 if(uip_udp_conn->
lport != 0 &&
1537 UIP_UDP_BUF->destport == uip_udp_conn->
lport &&
1538 (uip_udp_conn->
rport == 0 ||
1539 UIP_UDP_BUF->srcport == uip_udp_conn->
rport) &&
1545 LOG_ERR(
"udp: no matching connection found\n");
1552 LOG_DBG(
"In udp_found\n");
1558 uip_flags = UIP_NEWDATA;
1564 LOG_DBG(
"In udp_send\n");
1569 uip_len = uip_slen + UIP_IPUDPH_LEN;
1580 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1581 UIP_UDP_BUF->udpchksum = 0;
1583 UIP_UDP_BUF->srcport = uip_udp_conn->
lport;
1584 UIP_UDP_BUF->destport = uip_udp_conn->
rport;
1591 #if UIP_UDP_CHECKSUMS 1594 if(UIP_UDP_BUF->udpchksum == 0) {
1595 UIP_UDP_BUF->udpchksum = 0xffff;
1610 LOG_INFO(
"Receiving TCP packet\n");
1617 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1623 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1624 LOG_ERR(
"tcp: zero port\n");
1630 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1633 UIP_TCP_BUF->destport == uip_connr->
lport &&
1634 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1644 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1648 tmp16 = UIP_TCP_BUF->destport;
1651 if(tmp16 == uip_listenports[c]) {
1660 LOG_WARN(
"In reset\n");
1662 if(UIP_TCP_BUF->flags & TCP_RST) {
1668 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1670 UIP_TCP_BUF->tcpoffset = 5 << 4;
1673 c = UIP_TCP_BUF->seqno[3];
1674 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1675 UIP_TCP_BUF->ackno[3] = c;
1677 c = UIP_TCP_BUF->seqno[2];
1678 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1679 UIP_TCP_BUF->ackno[2] = c;
1681 c = UIP_TCP_BUF->seqno[1];
1682 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1683 UIP_TCP_BUF->ackno[1] = c;
1685 c = UIP_TCP_BUF->seqno[0];
1686 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1687 UIP_TCP_BUF->ackno[0] = c;
1692 if(++UIP_TCP_BUF->ackno[3] == 0) {
1693 if(++UIP_TCP_BUF->ackno[2] == 0) {
1694 if(++UIP_TCP_BUF->ackno[1] == 0) {
1695 ++UIP_TCP_BUF->ackno[0];
1701 tmp16 = UIP_TCP_BUF->srcport;
1702 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1703 UIP_TCP_BUF->destport = tmp16;
1709 goto tcp_send_noconn;
1715 LOG_DBG(
"In found listen\n");
1724 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1725 uip_connr = &uip_conns[c];
1728 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1729 if(uip_connr == 0 ||
1731 uip_connr = &uip_conns[c];
1736 if(uip_connr == 0) {
1741 LOG_ERR(
"tcp: found no unused connections\n");
1744 uip_conn = uip_connr;
1750 uip_connr->
nrtx = 0;
1751 uip_connr->
lport = UIP_TCP_BUF->destport;
1752 uip_connr->
rport = UIP_TCP_BUF->srcport;
1756 uip_connr->
snd_nxt[0] = iss[0];
1757 uip_connr->
snd_nxt[1] = iss[1];
1758 uip_connr->
snd_nxt[2] = iss[2];
1759 uip_connr->
snd_nxt[3] = iss[3];
1763 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1764 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1765 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1766 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1770 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1771 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1772 opt =
uip_buf[UIP_IPTCPH_LEN + c];
1773 if(opt == TCP_OPT_END) {
1776 }
else if(opt == TCP_OPT_NOOP) {
1779 }
else if(opt == TCP_OPT_MSS &&
1780 uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1782 tmp16 = ((uint16_t)
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
1783 (uint16_t)
uip_buf[UIP_IPTCPH_LEN + 3 + c];
1792 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
1797 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
1805 UIP_TCP_BUF->flags = TCP_ACK;
1808 UIP_TCP_BUF->flags |= TCP_SYN;
1811 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1816 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1817 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1820 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1821 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1826 LOG_DBG(
"In found\n");
1827 uip_conn = uip_connr;
1833 if(UIP_TCP_BUF->flags & TCP_RST) {
1835 LOG_WARN(
"tcp: got reset, aborting connection.");
1836 uip_flags = UIP_ABORT;
1842 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1846 if(
uip_len < c + UIP_IPH_LEN) {
1847 LOG_WARN(
"Dropping TCP packet with too large data offset (%u bytes)\n",
1862 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1863 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1864 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1865 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1866 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1867 (UIP_TCP_BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1868 UIP_TCP_BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1869 UIP_TCP_BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1870 UIP_TCP_BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1872 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1873 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1874 goto tcp_send_synack;
1876 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1889 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1892 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
1893 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
1894 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
1895 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
1903 if(uip_connr->
nrtx == 0) {
1905 m = uip_connr->
rto - uip_connr->
timer;
1907 m = m - (uip_connr->
sa >> 3);
1912 m = m - (uip_connr->
sv >> 2);
1914 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1918 uip_flags = UIP_ACKDATA;
1939 if(uip_flags & UIP_ACKDATA) {
1941 uip_flags = UIP_CONNECTED;
1944 uip_flags |= UIP_NEWDATA;
1952 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1953 goto tcp_send_synack;
1962 if((uip_flags & UIP_ACKDATA) &&
1963 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1966 if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
1967 for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
1968 opt =
uip_buf[UIP_IPTCPH_LEN + c];
1969 if(opt == TCP_OPT_END) {
1972 }
else if(opt == TCP_OPT_NOOP) {
1975 }
else if(opt == TCP_OPT_MSS &&
1976 uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
1978 tmp16 = (
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
1979 uip_buf[UIP_IPTCPH_LEN + 3 + c];
1988 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
1993 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
1998 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1999 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
2000 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
2001 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2003 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2011 uip_flags = UIP_ABORT;
2018 case UIP_ESTABLISHED:
2030 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2031 if(uip_outstanding(uip_connr)) {
2035 uip_flags |= UIP_CLOSE;
2037 uip_flags |= UIP_NEWDATA;
2042 uip_connr->
nrtx = 0;
2044 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2045 goto tcp_send_nodata;
2050 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2051 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2060 uip_add_rcv_nxt(uip_urglen);
2079 uip_flags |= UIP_NEWDATA;
2095 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2100 uip_connr->
mss = tmp16;
2118 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2124 if(uip_flags & UIP_ABORT) {
2127 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2128 goto tcp_send_nodata;
2131 if(uip_flags & UIP_CLOSE) {
2135 uip_connr->
nrtx = 0;
2136 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2137 goto tcp_send_nodata;
2145 if((uip_flags & UIP_ACKDATA) != 0) {
2152 if(uip_connr->
len == 0) {
2157 if(uip_slen > uip_connr->
mss) {
2158 uip_slen = uip_connr->
mss;
2163 uip_connr->
len = uip_slen;
2169 uip_slen = uip_connr->
len;
2172 uip_connr->
nrtx = 0;
2178 if(uip_slen > 0 && uip_connr->
len > 0) {
2182 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2184 goto tcp_send_noopts;
2188 if(uip_flags & UIP_NEWDATA) {
2190 UIP_TCP_BUF->flags = TCP_ACK;
2191 goto tcp_send_noopts;
2198 if(uip_flags & UIP_ACKDATA) {
2200 uip_flags = UIP_CLOSE;
2205 case UIP_FIN_WAIT_1:
2212 if(UIP_TCP_BUF->flags & TCP_FIN) {
2213 if(uip_flags & UIP_ACKDATA) {
2215 uip_connr->
timer = 0;
2221 uip_flags = UIP_CLOSE;
2224 }
else if(uip_flags & UIP_ACKDATA) {
2234 case UIP_FIN_WAIT_2:
2238 if(UIP_TCP_BUF->flags & TCP_FIN) {
2240 uip_connr->
timer = 0;
2242 uip_flags = UIP_CLOSE;
2255 if(uip_flags & UIP_ACKDATA) {
2257 uip_connr->
timer = 0;
2265 UIP_TCP_BUF->flags = TCP_ACK;
2271 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2278 LOG_DBG(
"In tcp_send\n");
2280 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2281 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2282 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2283 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2285 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2286 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2287 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2288 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2290 UIP_TCP_BUF->srcport = uip_connr->
lport;
2291 UIP_TCP_BUF->destport = uip_connr->
rport;
2298 LOG_INFO(
"Sending TCP packet to ");
2300 LOG_INFO_(
" from ");
2307 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2319 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2322 UIP_TCP_BUF->tcpchksum = 0;
2332 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len, uipbuf_get_len_field(
UIP_IP_BUF));
2353 uip_htonl(uint32_t val)
2355 return UIP_HTONL(val);
2363 if(uip_sappdata != NULL) {
2365 (
int)((
char *)uip_sappdata - (
char *)UIP_TCP_PAYLOAD));
2371 if(data != uip_sappdata) {
2372 if(uip_sappdata == NULL) {
2373 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2375 memcpy(uip_sappdata, (data), uip_slen);
#define UIP_IP_BUF
Direct access to IPv6 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
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
#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"
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
#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...
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.
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.
static uint8_t ext_hdr_options_process(uint8_t *ext_buf)
Process the options in Destination and Hop By Hop extension headers.
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.
int(* ext_header_hbh_update)(uint8_t *ext_buf, int opt_offset)
Process and update the routing protocol hob-by-hop extention headers of the current uIP packet...
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.
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len) ...
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.
#define UIP_MAXRTX
The maximum number of times a segment should be retransmitted before the connection should be aborted...
#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.
uint16_t uip_ext_len
Total length of all IPv6 extension headers.
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.