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;
924process_tcp_options(
struct uip_conn *conn)
926 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
931 for(
unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
936 uint8_t opt =
uip_buf[UIP_IPTCPH_LEN + c];
946 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
952 uint16_t tmp16 = (
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
953 uip_buf[UIP_IPTCPH_LEN + 3 + c];
954 conn->initialmss = conn->mss =
965 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
970 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
1003uip_process(uint8_t flag)
1005 uint8_t *last_header;
1007 uint8_t *next_header;
1008 struct uip_ext_hdr *ext_ptr;
1014 if(flag == UIP_UDP_SEND_CONN) {
1022 if(flag == UIP_POLL_REQUEST) {
1024 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1025 !uip_outstanding(uip_connr)) {
1026 uip_flags = UIP_POLL;
1030 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1032 UIP_TCP_BUF->flags = 0;
1039 }
else if(flag == UIP_TIMER) {
1062 ++(uip_connr->
timer);
1072 if(uip_outstanding(uip_connr)) {
1073 if(uip_connr->
timer-- == 0) {
1085 uip_flags = UIP_TIMEDOUT;
1089 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1090 goto tcp_send_nodata;
1097 ++(uip_connr->
nrtx);
1111 goto tcp_send_synack;
1116 UIP_TCP_BUF->flags = 0;
1120 case UIP_ESTABLISHED:
1127 uip_flags = UIP_REXMIT;
1131 case UIP_FIN_WAIT_1:
1135 goto tcp_send_finack;
1138 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1143 uip_flags = UIP_POLL;
1152 if(flag == UIP_UDP_TIMER) {
1157 uip_flags = UIP_POLL;
1175 LOG_WARN(
"incomplete IPv6 header received (%d bytes)\n", (
int)
uip_len);
1183 LOG_ERR(
"invalid version\n");
1198 LOG_ERR(
"packet shorter than reported in IP header\n");
1215 LOG_WARN(
"dropping packet with length %d > %d\n",
1224 if(last_header == NULL) {
1225 LOG_ERR(
"invalid extension header chain\n");
1231 LOG_INFO(
"packet received from ");
1239 LOG_ERR(
"Dropping packet, src is mcast\n");
1246 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1256 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1280#if UIP_IPV6_MULTICAST
1282 if(UIP_MCAST6.
in() == UIP_MCAST6_ACCEPT) {
1293 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1294 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1301 if(!uip_check_mtu() || !uip_update_ttl()) {
1306 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1316 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1317 LOG_ERR(
"LL source address with off link destination, dropping\n");
1322 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1328 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1329 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1331 LOG_ERR(
"Dropping packet, not for me\n");
1337#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1343 for(next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1344 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1345 next_header = uipbuf_get_next_header(next_header,
uip_len - (next_header -
uip_buf), &protocol,
false)) {
1347 ext_ptr = (
struct uip_ext_hdr *)next_header;
1350 LOG_DBG(
"Processing hbh header\n");
1352#if UIP_CONF_IPV6_CHECKS
1370 case UIP_PROTO_DESTO:
1371#if UIP_CONF_IPV6_CHECKS
1373 LOG_DBG(
"Processing desto header\n");
1394 case UIP_PROTO_ROUTING:
1395#if UIP_CONF_IPV6_CHECKS
1411 LOG_DBG(
"Processing Routing header\n");
1412 if(((
struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1419 if(!uip_check_mtu() || !uip_update_ttl()) {
1424 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1431 LOG_ERR(
"Unrecognized routing type\n");
1436 case UIP_PROTO_FRAG:
1438#if UIP_CONF_IPV6_REASSEMBLY
1439 LOG_INFO(
"Processing fragmentation header\n");
1440 uip_len = uip_reass(&ext_ptr->next);
1444 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1449 LOG_INFO(
"Processing reassembled packet\n");
1451 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1456 LOG_ERR(
"fragment dropped.");
1459 case UIP_PROTO_NONE:
1467 if(next_header != NULL) {
1479 case UIP_PROTO_ICMP6:
1493 LOG_ERR(
"unrecognized header\n");
1501#if UIP_CONF_IPV6_CHECKS
1506 LOG_ERR(
"icmpv6 bad checksum\n");
1531 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1551 LOG_INFO(
"Receiving UDP packet\n");
1557#if UIP_UDP_CHECKSUMS
1563 if(UIP_UDP_BUF->udpchksum != 0 &&
uip_udpchksum() != 0xffff) {
1566 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1573 if(UIP_UDP_BUF->destport == 0) {
1574 LOG_ERR(
"udp: zero port.\n");
1598 LOG_ERR(
"udp: no matching connection found\n");
1605 LOG_DBG(
"In udp_found\n");
1611 uip_flags = UIP_NEWDATA;
1617 LOG_DBG(
"In udp_send\n");
1622 uip_len = uip_slen + UIP_IPUDPH_LEN;
1633 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1634 UIP_UDP_BUF->udpchksum = 0;
1644#if UIP_UDP_CHECKSUMS
1647 if(UIP_UDP_BUF->udpchksum == 0) {
1648 UIP_UDP_BUF->udpchksum = 0xffff;
1663 LOG_INFO(
"Receiving TCP packet\n");
1670 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1676 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1677 LOG_ERR(
"tcp: zero port\n");
1683 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1686 UIP_TCP_BUF->destport == uip_connr->
lport &&
1687 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1697 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1701 uint16_t tmp16 = UIP_TCP_BUF->destport;
1704 if(tmp16 == uip_listenports[c]) {
1713 LOG_WARN(
"In reset\n");
1715 if(UIP_TCP_BUF->flags & TCP_RST) {
1721 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1723 UIP_TCP_BUF->tcpoffset = 5 << 4;
1726 c = UIP_TCP_BUF->seqno[3];
1727 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1728 UIP_TCP_BUF->ackno[3] = c;
1730 c = UIP_TCP_BUF->seqno[2];
1731 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1732 UIP_TCP_BUF->ackno[2] = c;
1734 c = UIP_TCP_BUF->seqno[1];
1735 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1736 UIP_TCP_BUF->ackno[1] = c;
1738 c = UIP_TCP_BUF->seqno[0];
1739 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1740 UIP_TCP_BUF->ackno[0] = c;
1745 if(++UIP_TCP_BUF->ackno[3] == 0) {
1746 if(++UIP_TCP_BUF->ackno[2] == 0) {
1747 if(++UIP_TCP_BUF->ackno[1] == 0) {
1748 ++UIP_TCP_BUF->ackno[0];
1754 tmp16 = UIP_TCP_BUF->srcport;
1755 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1756 UIP_TCP_BUF->destport = tmp16;
1762 goto tcp_send_noconn;
1768 LOG_DBG(
"In found listen\n");
1777 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1778 uip_connr = &uip_conns[c];
1781 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1782 if(uip_connr == 0 ||
1784 uip_connr = &uip_conns[c];
1789 if(uip_connr == 0) {
1794 LOG_ERR(
"tcp: found no unused connections\n");
1803 uip_connr->
nrtx = 0;
1804 uip_connr->
lport = UIP_TCP_BUF->destport;
1805 uip_connr->
rport = UIP_TCP_BUF->srcport;
1809 uip_connr->
snd_nxt[0] = iss[0];
1810 uip_connr->
snd_nxt[1] = iss[1];
1811 uip_connr->
snd_nxt[2] = iss[2];
1812 uip_connr->
snd_nxt[3] = iss[3];
1816 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1817 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1818 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1819 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1822 process_tcp_options(uip_connr);
1827 UIP_TCP_BUF->flags = TCP_ACK;
1830 UIP_TCP_BUF->flags |= TCP_SYN;
1833 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1838 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1839 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1842 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1843 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1848 LOG_DBG(
"In found\n");
1855 if(UIP_TCP_BUF->flags & TCP_RST) {
1857 LOG_WARN(
"tcp: got reset, aborting connection.");
1858 uip_flags = UIP_ABORT;
1864 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1868 if(
uip_len < c + UIP_IPH_LEN) {
1869 LOG_WARN(
"Dropping TCP packet with too large data offset (%u bytes)\n",
1884 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1885 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1886 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1887 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1888 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1889 (UIP_TCP_BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1890 UIP_TCP_BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1891 UIP_TCP_BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1892 UIP_TCP_BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1894 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1895 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1896 goto tcp_send_synack;
1898 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1911 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1914 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
1915 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
1916 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
1917 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
1925 if(uip_connr->
nrtx == 0) {
1927 m = uip_connr->
rto - uip_connr->
timer;
1929 m = m - (uip_connr->
sa >> 3);
1934 m = m - (uip_connr->
sv >> 2);
1936 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1940 uip_flags = UIP_ACKDATA;
1961 if(uip_flags & UIP_ACKDATA) {
1963 uip_flags = UIP_CONNECTED;
1966 uip_flags |= UIP_NEWDATA;
1974 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1975 goto tcp_send_synack;
1984 if((uip_flags & UIP_ACKDATA) &&
1985 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1987 process_tcp_options(uip_connr);
1990 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1991 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1992 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1993 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1995 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2003 uip_flags = UIP_ABORT;
2010 case UIP_ESTABLISHED:
2022 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2023 if(uip_outstanding(uip_connr)) {
2027 uip_flags |= UIP_CLOSE;
2029 uip_flags |= UIP_NEWDATA;
2034 uip_connr->
nrtx = 0;
2036 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2037 goto tcp_send_nodata;
2042 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2043 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2052 uip_add_rcv_nxt(uip_urglen);
2071 uip_flags |= UIP_NEWDATA;
2087 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2092 uip_connr->
mss = tmp16;
2110 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2116 if(uip_flags & UIP_ABORT) {
2119 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2120 goto tcp_send_nodata;
2123 if(uip_flags & UIP_CLOSE) {
2127 uip_connr->
nrtx = 0;
2128 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2129 goto tcp_send_nodata;
2137 if((uip_flags & UIP_ACKDATA) != 0) {
2144 if(uip_connr->
len == 0) {
2149 if(uip_slen > uip_connr->
mss) {
2150 uip_slen = uip_connr->
mss;
2155 uip_connr->
len = uip_slen;
2161 uip_slen = uip_connr->
len;
2164 uip_connr->
nrtx = 0;
2170 if(uip_slen > 0 && uip_connr->
len > 0) {
2174 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2176 goto tcp_send_noopts;
2180 if(uip_flags & UIP_NEWDATA) {
2182 UIP_TCP_BUF->flags = TCP_ACK;
2183 goto tcp_send_noopts;
2190 if(uip_flags & UIP_ACKDATA) {
2192 uip_flags = UIP_CLOSE;
2197 case UIP_FIN_WAIT_1:
2204 if(UIP_TCP_BUF->flags & TCP_FIN) {
2205 if(uip_flags & UIP_ACKDATA) {
2207 uip_connr->
timer = 0;
2213 uip_flags = UIP_CLOSE;
2216 }
else if(uip_flags & UIP_ACKDATA) {
2226 case UIP_FIN_WAIT_2:
2230 if(UIP_TCP_BUF->flags & TCP_FIN) {
2232 uip_connr->
timer = 0;
2234 uip_flags = UIP_CLOSE;
2247 if(uip_flags & UIP_ACKDATA) {
2249 uip_connr->
timer = 0;
2257 UIP_TCP_BUF->flags = TCP_ACK;
2263 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2270 LOG_DBG(
"In tcp_send\n");
2272 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2273 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2274 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2275 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2277 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2278 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2279 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2280 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2282 UIP_TCP_BUF->srcport = uip_connr->
lport;
2283 UIP_TCP_BUF->destport = uip_connr->
rport;
2290 LOG_INFO(
"Sending TCP packet to ");
2292 LOG_INFO_(
" from ");
2299 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2311 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2314 UIP_TCP_BUF->tcpchksum = 0;
2324 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len, uipbuf_get_len_field(
UIP_IP_BUF));
2345uip_htonl(uint32_t val)
2347 return UIP_HTONL(val);
2355 if(uip_sappdata != NULL) {
2357 (
int)((
char *)uip_sappdata - (
char *)UIP_TCP_PAYLOAD));
2363 if(data != uip_sappdata) {
2364 if(uip_sappdata == NULL) {
2365 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2367 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.