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);
396 uip_listenports[c] = 0;
403#if UIP_ACTIVE_OPEN || UIP_UDP
409 uip_udp_conns[c].
lport = 0;
413#if UIP_IPV6_MULTICAST
418#if UIP_TCP && UIP_ACTIVE_OPEN
422 register struct uip_conn *conn, *cconn;
429 if(lastport >= 32000) {
436 conn = &uip_conns[c];
445 cconn = &uip_conns[c];
495 LOG_DBG(
"Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
498 LOG_ERR(
"uip_len too short compared to ext len\n");
506 memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(
uip_ext_len),
529 if(lastport >= 32000) {
541 if(uip_udp_conns[c].
lport == 0) {
542 conn = &uip_udp_conns[c];
554 memset(&conn->
ripaddr, 0,
sizeof(uip_ipaddr_t));
570 if(uip_listenports[c] == port) {
571 uip_listenports[c] = 0;
582 if(uip_listenports[c] == 0) {
583 uip_listenports[c] = port;
591#if UIP_CONF_IPV6_REASSEMBLY
592#define UIP_REASS_BUFSIZE (UIP_BUFSIZE)
594static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
596static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
599static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
600 0x0f, 0x07, 0x03, 0x01};
601static uint16_t uip_reasslen;
602static uint8_t uip_reassflags;
604#define UIP_REASS_FLAG_LASTFRAG 0x01
605#define UIP_REASS_FLAG_FIRSTFRAG 0x02
606#define UIP_REASS_FLAG_ERROR_MSG 0x04
622static uint32_t uip_id;
628uip_reass(uint8_t *prev_proto_ptr)
633 struct uip_frag_hdr *frag_buf = (
struct uip_frag_hdr *)UIP_IP_PAYLOAD(
uip_ext_len);
638 if(uip_reass_on == 0) {
639 LOG_INFO(
"Starting reassembly\n");
645 uip_id = frag_buf->id;
647 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
654 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &
UIP_IP_BUF->srcipaddr) &&
655 uip_ipaddr_cmp(&FBUF->destipaddr, &
UIP_IP_BUF->destipaddr) &&
656 frag_buf->id == uip_id) {
658 offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
660 LOG_INFO(
"len %d\n", len);
661 LOG_INFO(
"offset %d\n", offset);
663 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
669 *prev_proto_ptr = frag_buf->next;
672 LOG_INFO_6ADDR(&FBUF->srcipaddr);
674 LOG_INFO_6ADDR(&FBUF->destipaddr);
681 if(offset > UIP_REASS_BUFSIZE ||
682 offset + len > UIP_REASS_BUFSIZE) {
690 if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
691 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
693 uip_reasslen = offset + len;
694 LOG_INFO(
"last fragment reasslen %d\n", uip_reasslen);
702 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
713 memcpy((uint8_t *)FBUF + UIP_IPH_LEN +
uip_ext_len + offset,
714 (uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
717 if(offset >> 6 == (offset + len) >> 6) {
718 uip_reassbitmap[offset >> 6] |=
719 bitmap_bits[(offset >> 3) & 7] &
720 ~bitmap_bits[((offset + len) >> 3) & 7];
725 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
727 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
728 uip_reassbitmap[i] = 0xff;
730 uip_reassbitmap[(offset + len) >> 6] |=
731 ~bitmap_bits[((offset + len) >> 3) & 7];
738 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
741 for(i = 0; i < (uip_reasslen >> 6); ++i) {
742 if(uip_reassbitmap[i] != 0xff) {
748 if(uip_reassbitmap[uip_reasslen >> 6] !=
749 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
760 uipbuf_set_len_field(
UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
761 LOG_INFO(
"reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(
UIP_IP_BUF));
767 LOG_WARN(
"Already reassembling another paquet\n");
780 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
781 LOG_ERR(
"fragmentation timeout\n");
806uip_add_rcv_nxt(uint16_t n)
828 uint16_t opt_offset = 2;
829 struct uip_hbho_hdr *ext_hdr = (
struct uip_hbho_hdr *)ext_buf;
830 uint16_t ext_hdr_len = (ext_hdr->len << 3) + 8;
832 while(opt_offset + 2 <= ext_hdr_len) {
833 struct uip_ext_hdr_opt *opt_hdr = (
struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
834 uint16_t opt_len = opt_hdr->len + 2;
836 if(opt_offset + opt_len > ext_hdr_len) {
837 LOG_ERR(
"Extension header option too long: dropping packet\n");
839 (ext_buf + opt_offset) -
uip_buf);
843 switch(opt_hdr->type) {
845 LOG_DBG(
"Processing PAD1 option\n");
848 case UIP_EXT_HDR_OPT_PADN:
849 LOG_DBG(
"Processing PADN option\n");
850 opt_offset += opt_len;
852 case UIP_EXT_HDR_OPT_RPL:
861 LOG_DBG(
"Processing RPL option\n");
863 LOG_ERR(
"RPL Option Error: Dropping Packet\n");
866 opt_offset += opt_len;
868#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL
869 case UIP_EXT_HDR_OPT_MPL:
874 LOG_DBG(
"Processing MPL option\n");
875 opt_offset += opt_len + opt_len;
892 LOG_DBG(
"Unrecognized option, MSB 0x%x\n", opt_hdr->type);
893 switch(opt_hdr->type & 0xC0) {
904 (ext_buf + opt_offset) -
uip_buf);
908 opt_offset += opt_len;
917process_tcp_options(
struct uip_conn *conn)
919 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
924 for(
unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
929 uint8_t opt =
uip_buf[UIP_IPTCPH_LEN + c];
939 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
945 uint16_t tmp16 = (
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
946 uip_buf[UIP_IPTCPH_LEN + 3 + c];
958 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
963 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
996uip_process(uint8_t flag)
998 uint8_t *last_header;
1000 uint8_t *next_header;
1001 struct uip_ext_hdr *ext_ptr;
1007 if(flag == UIP_UDP_SEND_CONN) {
1015 if(flag == UIP_POLL_REQUEST) {
1017 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1018 !uip_outstanding(uip_connr)) {
1019 uip_flags = UIP_POLL;
1023 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1025 UIP_TCP_BUF->flags = 0;
1032 }
else if(flag == UIP_TIMER) {
1055 ++(uip_connr->
timer);
1065 if(uip_outstanding(uip_connr)) {
1066 if(uip_connr->
timer-- == 0) {
1078 uip_flags = UIP_TIMEDOUT;
1082 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1083 goto tcp_send_nodata;
1090 ++(uip_connr->
nrtx);
1104 goto tcp_send_synack;
1109 UIP_TCP_BUF->flags = 0;
1113 case UIP_ESTABLISHED:
1120 uip_flags = UIP_REXMIT;
1124 case UIP_FIN_WAIT_1:
1128 goto tcp_send_finack;
1131 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1136 uip_flags = UIP_POLL;
1145 if(flag == UIP_UDP_TIMER) {
1150 uip_flags = UIP_POLL;
1168 LOG_WARN(
"incomplete IPv6 header received (%d bytes)\n", (
int)
uip_len);
1176 LOG_ERR(
"invalid version\n");
1191 LOG_ERR(
"packet shorter than reported in IP header\n");
1208 LOG_WARN(
"dropping packet with length %d > %d\n",
1217 if(last_header == NULL) {
1218 LOG_ERR(
"invalid extension header chain\n");
1224 LOG_INFO(
"packet received from ");
1232 LOG_ERR(
"Dropping packet, src is mcast\n");
1239 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1249 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1273#if UIP_IPV6_MULTICAST
1275 if(UIP_MCAST6.
in() == UIP_MCAST6_ACCEPT) {
1286 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1287 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1294 if(!uip_check_mtu() || !uip_update_ttl()) {
1299 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1309 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1310 LOG_ERR(
"LL source address with off link destination, dropping\n");
1315 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1321 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1322 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1324 LOG_ERR(
"Dropping packet, not for me\n");
1330#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1336 for(next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1337 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1338 next_header = uipbuf_get_next_header(next_header,
uip_len - (next_header -
uip_buf), &protocol,
false)) {
1340 ext_ptr = (
struct uip_ext_hdr *)next_header;
1343 LOG_DBG(
"Processing hbh header\n");
1345#if UIP_CONF_IPV6_CHECKS
1355 if(!UIP_CONF_ROUTER) {
1367 case UIP_PROTO_DESTO:
1368#if UIP_CONF_IPV6_CHECKS
1370 LOG_DBG(
"Processing desto header\n");
1391 case UIP_PROTO_ROUTING:
1392#if UIP_CONF_IPV6_CHECKS
1408 LOG_DBG(
"Processing Routing header\n");
1409 if(((
struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1416 if(!uip_check_mtu() || !uip_update_ttl()) {
1421 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) ||
1422 uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) ||
1426 LOG_ERR(
"SRH next hop address is unacceptable; drop the packet\n");
1430 LOG_INFO(
"Forwarding packet to next hop ");
1437 LOG_ERR(
"Unrecognized routing type\n");
1442 case UIP_PROTO_FRAG:
1444#if UIP_CONF_IPV6_REASSEMBLY
1445 LOG_INFO(
"Processing fragmentation header\n");
1446 uip_len = uip_reass(&ext_ptr->next);
1450 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1455 LOG_INFO(
"Processing reassembled packet\n");
1457 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1462 LOG_ERR(
"fragment dropped.");
1465 case UIP_PROTO_NONE:
1473 if(next_header != NULL) {
1485 case UIP_PROTO_ICMP6:
1499 LOG_ERR(
"unrecognized header\n");
1507#if UIP_CONF_IPV6_CHECKS
1512 LOG_ERR(
"icmpv6 bad checksum\n");
1537 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1557 LOG_INFO(
"Receiving UDP packet\n");
1563#if UIP_UDP_CHECKSUMS
1569 if(UIP_UDP_BUF->udpchksum != 0 &&
uip_udpchksum() != 0xffff) {
1572 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1579 if(UIP_UDP_BUF->destport == 0) {
1580 LOG_ERR(
"udp: zero port.\n");
1604 LOG_ERR(
"udp: no matching connection found\n");
1611 LOG_DBG(
"In udp_found\n");
1617 uip_flags = UIP_NEWDATA;
1623 LOG_DBG(
"In udp_send\n");
1628 uip_len = uip_slen + UIP_IPUDPH_LEN;
1639 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1640 UIP_UDP_BUF->udpchksum = 0;
1650#if UIP_UDP_CHECKSUMS
1653 if(UIP_UDP_BUF->udpchksum == 0) {
1654 UIP_UDP_BUF->udpchksum = 0xffff;
1669 LOG_INFO(
"Receiving TCP packet\n");
1676 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1682 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1683 LOG_ERR(
"tcp: zero port\n");
1689 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1692 UIP_TCP_BUF->destport == uip_connr->
lport &&
1693 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1703 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1707 uint16_t tmp16 = UIP_TCP_BUF->destport;
1710 if(tmp16 == uip_listenports[c]) {
1719 LOG_WARN(
"In reset\n");
1721 if(UIP_TCP_BUF->flags & TCP_RST) {
1727 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1729 UIP_TCP_BUF->tcpoffset = 5 << 4;
1732 c = UIP_TCP_BUF->seqno[3];
1733 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1734 UIP_TCP_BUF->ackno[3] = c;
1736 c = UIP_TCP_BUF->seqno[2];
1737 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1738 UIP_TCP_BUF->ackno[2] = c;
1740 c = UIP_TCP_BUF->seqno[1];
1741 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1742 UIP_TCP_BUF->ackno[1] = c;
1744 c = UIP_TCP_BUF->seqno[0];
1745 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1746 UIP_TCP_BUF->ackno[0] = c;
1751 if(++UIP_TCP_BUF->ackno[3] == 0) {
1752 if(++UIP_TCP_BUF->ackno[2] == 0) {
1753 if(++UIP_TCP_BUF->ackno[1] == 0) {
1754 ++UIP_TCP_BUF->ackno[0];
1760 tmp16 = UIP_TCP_BUF->srcport;
1761 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1762 UIP_TCP_BUF->destport = tmp16;
1768 goto tcp_send_noconn;
1774 LOG_DBG(
"In found listen\n");
1783 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1784 uip_connr = &uip_conns[c];
1787 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1788 if(uip_connr == 0 ||
1790 uip_connr = &uip_conns[c];
1795 if(uip_connr == 0) {
1800 LOG_ERR(
"tcp: found no unused connections\n");
1809 uip_connr->
nrtx = 0;
1810 uip_connr->
lport = UIP_TCP_BUF->destport;
1811 uip_connr->
rport = UIP_TCP_BUF->srcport;
1815 uip_connr->
snd_nxt[0] = iss[0];
1816 uip_connr->
snd_nxt[1] = iss[1];
1817 uip_connr->
snd_nxt[2] = iss[2];
1818 uip_connr->
snd_nxt[3] = iss[3];
1822 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1823 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1824 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1825 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1828 process_tcp_options(uip_connr);
1833 UIP_TCP_BUF->flags = TCP_ACK;
1836 UIP_TCP_BUF->flags |= TCP_SYN;
1839 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1844 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1845 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1848 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1849 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1854 LOG_DBG(
"In found\n");
1861 if(UIP_TCP_BUF->flags & TCP_RST) {
1863 LOG_WARN(
"tcp: got reset, aborting connection.");
1864 uip_flags = UIP_ABORT;
1870 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1874 if(
uip_len < c + UIP_IPH_LEN) {
1875 LOG_WARN(
"Dropping TCP packet with too large data offset (%u bytes)\n",
1890 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1891 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1892 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1893 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1894 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1895 (UIP_TCP_BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1896 UIP_TCP_BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1897 UIP_TCP_BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1898 UIP_TCP_BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1900 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1901 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1902 goto tcp_send_synack;
1904 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1917 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1920 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
1921 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
1922 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
1923 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
1931 if(uip_connr->
nrtx == 0) {
1933 m = uip_connr->
rto - uip_connr->
timer;
1935 m = m - (uip_connr->
sa >> 3);
1940 m = m - (uip_connr->
sv >> 2);
1942 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1946 uip_flags = UIP_ACKDATA;
1967 if(uip_flags & UIP_ACKDATA) {
1969 uip_flags = UIP_CONNECTED;
1972 uip_flags |= UIP_NEWDATA;
1980 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1981 goto tcp_send_synack;
1990 if((uip_flags & UIP_ACKDATA) &&
1991 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1993 process_tcp_options(uip_connr);
1996 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1997 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1998 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1999 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2001 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2009 uip_flags = UIP_ABORT;
2016 case UIP_ESTABLISHED:
2028 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2029 if(uip_outstanding(uip_connr)) {
2033 uip_flags |= UIP_CLOSE;
2035 uip_flags |= UIP_NEWDATA;
2040 uip_connr->
nrtx = 0;
2042 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2043 goto tcp_send_nodata;
2048 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2049 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2058 uip_add_rcv_nxt(uip_urglen);
2077 uip_flags |= UIP_NEWDATA;
2093 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2098 uip_connr->
mss = tmp16;
2116 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2122 if(uip_flags & UIP_ABORT) {
2125 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2126 goto tcp_send_nodata;
2129 if(uip_flags & UIP_CLOSE) {
2133 uip_connr->
nrtx = 0;
2134 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2135 goto tcp_send_nodata;
2143 if((uip_flags & UIP_ACKDATA) != 0) {
2150 if(uip_connr->
len == 0) {
2155 if(uip_slen > uip_connr->
mss) {
2156 uip_slen = uip_connr->
mss;
2161 uip_connr->
len = uip_slen;
2167 uip_slen = uip_connr->
len;
2170 uip_connr->
nrtx = 0;
2176 if(uip_slen > 0 && uip_connr->
len > 0) {
2180 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2182 goto tcp_send_noopts;
2186 if(uip_flags & UIP_NEWDATA) {
2188 UIP_TCP_BUF->flags = TCP_ACK;
2189 goto tcp_send_noopts;
2196 if(uip_flags & UIP_ACKDATA) {
2198 uip_flags = UIP_CLOSE;
2203 case UIP_FIN_WAIT_1:
2210 if(UIP_TCP_BUF->flags & TCP_FIN) {
2211 if(uip_flags & UIP_ACKDATA) {
2213 uip_connr->
timer = 0;
2219 uip_flags = UIP_CLOSE;
2222 }
else if(uip_flags & UIP_ACKDATA) {
2232 case UIP_FIN_WAIT_2:
2236 if(UIP_TCP_BUF->flags & TCP_FIN) {
2238 uip_connr->
timer = 0;
2240 uip_flags = UIP_CLOSE;
2253 if(uip_flags & UIP_ACKDATA) {
2255 uip_connr->
timer = 0;
2263 UIP_TCP_BUF->flags = TCP_ACK;
2269 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2276 LOG_DBG(
"In tcp_send\n");
2278 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2279 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2280 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2281 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2283 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2284 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2285 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2286 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2288 UIP_TCP_BUF->srcport = uip_connr->
lport;
2289 UIP_TCP_BUF->destport = uip_connr->
rport;
2296 LOG_INFO(
"Sending TCP packet to ");
2298 LOG_INFO_(
" from ");
2305 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2317 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2320 UIP_TCP_BUF->tcpchksum = 0;
2330 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len, uipbuf_get_len_field(
UIP_IP_BUF));
2351uip_htonl(uint32_t val)
2353 return UIP_HTONL(val);
2361 if(uip_sappdata != NULL) {
2363 (
int)((
char *)uip_sappdata - (
char *)UIP_TCP_PAYLOAD));
2369 if(data != uip_sappdata) {
2370 if(uip_sappdata == NULL) {
2371 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2373 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.
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 in seconds that an IP fragment should wait in the reassembly buffer before it is dro...
#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.