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
155uint16_t uip_urglen, uip_surglen;
176#if UIP_ACTIVE_OPEN || UIP_UDP
178static uint16_t lastport;
199#define TCP_OPT_NOOP 1
202#define TCP_OPT_MSS_LEN 4
216static uint8_t iss[4];
282chksum(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);
331upper_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];
439 if(conn->tcpstateflags != UIP_CLOSED &&
447 cconn = &uip_conns[c];
454 cconn->
timer > conn->timer) {
464 conn->tcpstateflags = UIP_SYN_SENT;
466 conn->snd_nxt[0] = iss[0];
467 conn->snd_nxt[1] = iss[1];
468 conn->snd_nxt[2] = iss[2];
469 conn->snd_nxt[3] = iss[3];
471 conn->rcv_nxt[0] = 0;
472 conn->rcv_nxt[1] = 0;
473 conn->rcv_nxt[2] = 0;
474 conn->rcv_nxt[3] = 0;
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),
531 if(lastport >= 32000) {
543 if(uip_udp_conns[c].
lport == 0) {
544 conn = &uip_udp_conns[c];
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)
596static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
598static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
601static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
602 0x0f, 0x07, 0x03, 0x01};
603static uint16_t uip_reasslen;
604static 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
624static uint32_t uip_id;
630uip_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");
808uip_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;
948uip_process(uint8_t flag)
950 uint8_t *last_header;
952 uint8_t *next_header;
953 struct uip_ext_hdr *ext_ptr;
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) {
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");
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;
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");
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");
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));
2353uip_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);
Default definitions of C compiler quirk work-arounds.
#define CLOCK_SECOND
A second, measured in system clock time.
void etimer_stop(struct etimer *et)
Stop a pending event timer.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define UIP_APPCALL
The name of the application function that uIP should call in response to TCP/IP events.
void uip_send(const void *data, int len)
Send data on the current connection.
#define ICMP6_TIME_EXCEEDED
time exceeded
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
struct uip_udp_conn * uip_udp_conn
The current UDP connection.
#define ICMP6_DST_UNREACH
dest unreachable
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode)
Handle an incoming ICMPv6 message.
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
uip_lladdr_t uip_lladdr
Host L2 address.
#define uip_is_addr_mcast_routable(a)
is address a routable multicast address.
#define ICMP6_DST_UNREACH_NOTNEIGHBOR
not a neighbor(obsolete)
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
#define ICMP6_TIME_EXCEED_REASSEMBLY
ttl==0 in reass
void uip_listen(uint16_t port)
Start listening to the specified port.
void uip_ds6_init(void)
Initialize data structures.
void * uip_appdata
Pointer to the application data in the packet buffer.
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
void uip_add32(uint8_t *op32, uint16_t op16)
Carry out a 32-bit addition.
uint16_t uip_ext_len
Total length of all IPv6 extension headers.
#define ICMP6_PACKET_TOO_BIG
packet too big
struct etimer uip_reass_timer
Timer for reassembly.
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
uint16_t uip_len
The length of the packet in the uip_buf buffer.
struct uip_conn * uip_conn
Pointer to the current TCP connection.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
void uip_icmp6_init()
Initialise the uIP ICMPv6 core.
#define UIP_EXT_HDR_OPT_PAD1
Destination and Hop By Hop extension headers option types.
#define ICMP6_PARAM_PROB
ip6 header bad
void uip_nd6_init()
Initialise the uIP ND core.
#define ICMP6_DST_UNREACH_NOPORT
port unreachable
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len)
#define UIP_STAT(s)
The uIP TCP/IP statistics.
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.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
void uip_init(void)
uIP initialization function.
static uint8_t ext_hdr_options_process(uint8_t *ext_buf)
Process the options in Destination and Hop By Hop extension headers.
#define ICMP6_PARAMPROB_NEXTHEADER
unrecognized next header
uint16_t uip_chksum(uint16_t *data, uint16_t len)
Calculate the Internet checksum over a buffer.
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
#define ICMP6_PARAMPROB_HEADER
erroneous header field
#define UIP_EXT_HDR_BITMAP_HBHO
Bitmaps for extension header processing.
uip_buf_t uip_aligned_buf
Packet buffer for incoming and outgoing packets.
uint16_t uip_udpchksum(void)
Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
uip_ds6_netif_t uip_ds6_if
The single interface.
#define ICMP6_PARAMPROB_OPTION
unrecognized option
uint8_t uip_acc32[4]
4-byte array used for the 32-bit sequence number calculations.
#define uip_is_addr_loopback(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
void uip_reass_over(void)
Abandon the reassembly of the current packet.
#define UIP_PROTO_HBHO
extension headers types
#define UIP_IP_BUF
Direct access to IPv6 header.
uint8_t uip_ext_bitmap
bitmap we use to record which IPv6 headers we have already seen
#define ICMP6_TIME_EXCEED_TRANSIT
ttl==0 in transit
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
uint16_t uip_ipchksum(void)
Calculate the IP header checksum of the packet header in uip_buf.
uint16_t uip_tcpchksum(void)
Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define UIP_REASS_MAXAGE
The maximum time an IP fragment should wait in the reassembly buffer before it is dropped.
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
#define UIP_RTO
The initial retransmission timeout counted in timer pulses.
#define UIP_MAXSYNRTX
The maximum number of times a SYN segment should be retransmitted before a connection request should ...
#define UIP_TIME_WAIT_TIMEOUT
How long a connection should stay in the TIME_WAIT state.
#define UIP_TCP_MSS
The TCP maximum segment size.
#define UIP_RECEIVE_WINDOW
The size of the advertised receiver's window.
#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_TCP_CONNS
The maximum number of simultaneously open TCP connections.
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
Header file for the logging system.
Routing driver header file.
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.
int(* ext_header_srh_update)(void)
Process and update SRH in-place, i.e.
Representation of a uIP TCP connection.
uint8_t rcv_nxt[4]
The sequence number that we expect to receive next.
uint8_t timer
The retransmission timer.
uint16_t mss
Current maximum segment size for the connection.
uint8_t sa
Retransmission time-out calculation state variable.
uint16_t len
Length of the data that was previously sent.
uint16_t lport
The local TCP port, in network byte order.
uint16_t rport
The local remote TCP port, in network byte order.
uip_ipaddr_t ripaddr
The IP address of the remote host.
uint8_t sv
Retransmission time-out calculation state variable.
uint8_t nrtx
The number of retransmissions for the last segment sent.
uint16_t initialmss
Initial maximum segment size for the connection.
uint8_t snd_nxt[4]
The sequence number that was last sent by us.
uint8_t tcpstateflags
TCP state and flags.
uint8_t rto
Retransmission time-out.
uint8_t(* in)(void)
Process an incoming multicast datagram and determine whether it should be delivered up the stack or n...
void(* init)(void)
Initialize the multicast engine.
The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1.
Representation of a uIP UDP connection.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
uint8_t ttl
Default time-to-live.
uint16_t rport
The remote port number in network byte order.
uint16_t lport
The local port number in network byte order.
Declarations of architecture specific functions.
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
Header file for IPv6-related data structures.
Header file for ICMPv6 message and error handing (RFC 4443)
This header file contains configuration directives for uIPv6 multicast support.
Header file for IPv6 Neighbor discovery (RFC 4861)
Header file for the uIP TCP/IP stack.
Configuration options for uIP.