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];
437 if(conn->tcpstateflags != UIP_CLOSED &&
445 cconn = &uip_conns[c];
452 cconn->
timer > conn->timer) {
462 conn->tcpstateflags = UIP_SYN_SENT;
464 conn->snd_nxt[0] = iss[0];
465 conn->snd_nxt[1] = iss[1];
466 conn->snd_nxt[2] = iss[2];
467 conn->snd_nxt[3] = iss[3];
469 conn->rcv_nxt[0] = 0;
470 conn->rcv_nxt[1] = 0;
471 conn->rcv_nxt[2] = 0;
472 conn->rcv_nxt[3] = 0;
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) {
850 LOG_DBG(
"Processing PAD1 option\n");
853 case UIP_EXT_HDR_OPT_PADN:
854 LOG_DBG(
"Processing PADN option\n");
855 opt_offset += opt_len;
857 case UIP_EXT_HDR_OPT_RPL:
866 LOG_DBG(
"Processing RPL option\n");
868 LOG_ERR(
"RPL Option Error: Dropping Packet\n");
871 opt_offset += opt_len;
873#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL
874 case UIP_EXT_HDR_OPT_MPL:
879 LOG_DBG(
"Processing MPL option\n");
880 opt_offset += opt_len + opt_len;
897 LOG_DBG(
"Unrecognized option, MSB 0x%x\n", opt_hdr->type);
898 switch(opt_hdr->type & 0xC0) {
909 (ext_buf + opt_offset) -
uip_buf);
913 opt_offset += opt_len;
922process_tcp_options(
struct uip_conn *conn)
924 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
929 for(
unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
934 uint8_t opt =
uip_buf[UIP_IPTCPH_LEN + c];
944 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
950 uint16_t tmp16 = (
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
951 uip_buf[UIP_IPTCPH_LEN + 3 + c];
952 conn->initialmss = conn->mss =
963 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
968 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
1001uip_process(uint8_t flag)
1003 uint8_t *last_header;
1005 uint8_t *next_header;
1006 struct uip_ext_hdr *ext_ptr;
1012 if(flag == UIP_UDP_SEND_CONN) {
1020 if(flag == UIP_POLL_REQUEST) {
1022 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1023 !uip_outstanding(uip_connr)) {
1024 uip_flags = UIP_POLL;
1028 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1030 UIP_TCP_BUF->flags = 0;
1037 }
else if(flag == UIP_TIMER) {
1060 ++(uip_connr->
timer);
1070 if(uip_outstanding(uip_connr)) {
1071 if(uip_connr->
timer-- == 0) {
1083 uip_flags = UIP_TIMEDOUT;
1087 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1088 goto tcp_send_nodata;
1095 ++(uip_connr->
nrtx);
1109 goto tcp_send_synack;
1114 UIP_TCP_BUF->flags = 0;
1118 case UIP_ESTABLISHED:
1125 uip_flags = UIP_REXMIT;
1129 case UIP_FIN_WAIT_1:
1133 goto tcp_send_finack;
1136 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1141 uip_flags = UIP_POLL;
1150 if(flag == UIP_UDP_TIMER) {
1155 uip_flags = UIP_POLL;
1173 LOG_WARN(
"incomplete IPv6 header received (%d bytes)\n", (
int)
uip_len);
1181 LOG_ERR(
"invalid version\n");
1196 LOG_ERR(
"packet shorter than reported in IP header\n");
1213 LOG_WARN(
"dropping packet with length %d > %d\n",
1222 if(last_header == NULL) {
1223 LOG_ERR(
"invalid extension header chain\n");
1229 LOG_INFO(
"packet received from ");
1237 LOG_ERR(
"Dropping packet, src is mcast\n");
1244 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1254 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1278#if UIP_IPV6_MULTICAST
1280 if(UIP_MCAST6.
in() == UIP_MCAST6_ACCEPT) {
1291 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1292 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1299 if(!uip_check_mtu() || !uip_update_ttl()) {
1304 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1314 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1315 LOG_ERR(
"LL source address with off link destination, dropping\n");
1320 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1326 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1327 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1329 LOG_ERR(
"Dropping packet, not for me\n");
1335#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1341 for(next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1342 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1343 next_header = uipbuf_get_next_header(next_header,
uip_len - (next_header -
uip_buf), &protocol,
false)) {
1345 ext_ptr = (
struct uip_ext_hdr *)next_header;
1348 LOG_DBG(
"Processing hbh header\n");
1350#if UIP_CONF_IPV6_CHECKS
1360 if(!UIP_CONF_ROUTER) {
1372 case UIP_PROTO_DESTO:
1373#if UIP_CONF_IPV6_CHECKS
1375 LOG_DBG(
"Processing desto header\n");
1396 case UIP_PROTO_ROUTING:
1397#if UIP_CONF_IPV6_CHECKS
1413 LOG_DBG(
"Processing Routing header\n");
1414 if(((
struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1421 if(!uip_check_mtu() || !uip_update_ttl()) {
1426 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1433 LOG_ERR(
"Unrecognized routing type\n");
1438 case UIP_PROTO_FRAG:
1440#if UIP_CONF_IPV6_REASSEMBLY
1441 LOG_INFO(
"Processing fragmentation header\n");
1442 uip_len = uip_reass(&ext_ptr->next);
1446 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1451 LOG_INFO(
"Processing reassembled packet\n");
1453 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1458 LOG_ERR(
"fragment dropped.");
1461 case UIP_PROTO_NONE:
1469 if(next_header != NULL) {
1481 case UIP_PROTO_ICMP6:
1495 LOG_ERR(
"unrecognized header\n");
1503#if UIP_CONF_IPV6_CHECKS
1508 LOG_ERR(
"icmpv6 bad checksum\n");
1533 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1553 LOG_INFO(
"Receiving UDP packet\n");
1559#if UIP_UDP_CHECKSUMS
1565 if(UIP_UDP_BUF->udpchksum != 0 &&
uip_udpchksum() != 0xffff) {
1568 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1575 if(UIP_UDP_BUF->destport == 0) {
1576 LOG_ERR(
"udp: zero port.\n");
1600 LOG_ERR(
"udp: no matching connection found\n");
1607 LOG_DBG(
"In udp_found\n");
1613 uip_flags = UIP_NEWDATA;
1619 LOG_DBG(
"In udp_send\n");
1624 uip_len = uip_slen + UIP_IPUDPH_LEN;
1635 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1636 UIP_UDP_BUF->udpchksum = 0;
1646#if UIP_UDP_CHECKSUMS
1649 if(UIP_UDP_BUF->udpchksum == 0) {
1650 UIP_UDP_BUF->udpchksum = 0xffff;
1665 LOG_INFO(
"Receiving TCP packet\n");
1672 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1678 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1679 LOG_ERR(
"tcp: zero port\n");
1685 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1688 UIP_TCP_BUF->destport == uip_connr->
lport &&
1689 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1699 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1703 uint16_t tmp16 = UIP_TCP_BUF->destport;
1706 if(tmp16 == uip_listenports[c]) {
1715 LOG_WARN(
"In reset\n");
1717 if(UIP_TCP_BUF->flags & TCP_RST) {
1723 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1725 UIP_TCP_BUF->tcpoffset = 5 << 4;
1728 c = UIP_TCP_BUF->seqno[3];
1729 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1730 UIP_TCP_BUF->ackno[3] = c;
1732 c = UIP_TCP_BUF->seqno[2];
1733 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1734 UIP_TCP_BUF->ackno[2] = c;
1736 c = UIP_TCP_BUF->seqno[1];
1737 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1738 UIP_TCP_BUF->ackno[1] = c;
1740 c = UIP_TCP_BUF->seqno[0];
1741 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1742 UIP_TCP_BUF->ackno[0] = c;
1747 if(++UIP_TCP_BUF->ackno[3] == 0) {
1748 if(++UIP_TCP_BUF->ackno[2] == 0) {
1749 if(++UIP_TCP_BUF->ackno[1] == 0) {
1750 ++UIP_TCP_BUF->ackno[0];
1756 tmp16 = UIP_TCP_BUF->srcport;
1757 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1758 UIP_TCP_BUF->destport = tmp16;
1764 goto tcp_send_noconn;
1770 LOG_DBG(
"In found listen\n");
1779 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1780 uip_connr = &uip_conns[c];
1783 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1784 if(uip_connr == 0 ||
1786 uip_connr = &uip_conns[c];
1791 if(uip_connr == 0) {
1796 LOG_ERR(
"tcp: found no unused connections\n");
1805 uip_connr->
nrtx = 0;
1806 uip_connr->
lport = UIP_TCP_BUF->destport;
1807 uip_connr->
rport = UIP_TCP_BUF->srcport;
1811 uip_connr->
snd_nxt[0] = iss[0];
1812 uip_connr->
snd_nxt[1] = iss[1];
1813 uip_connr->
snd_nxt[2] = iss[2];
1814 uip_connr->
snd_nxt[3] = iss[3];
1818 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1819 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1820 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1821 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1824 process_tcp_options(uip_connr);
1829 UIP_TCP_BUF->flags = TCP_ACK;
1832 UIP_TCP_BUF->flags |= TCP_SYN;
1835 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1840 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1841 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1844 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1845 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1850 LOG_DBG(
"In found\n");
1857 if(UIP_TCP_BUF->flags & TCP_RST) {
1859 LOG_WARN(
"tcp: got reset, aborting connection.");
1860 uip_flags = UIP_ABORT;
1866 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1870 if(
uip_len < c + UIP_IPH_LEN) {
1871 LOG_WARN(
"Dropping TCP packet with too large data offset (%u bytes)\n",
1886 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1887 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1888 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1889 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1890 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1891 (UIP_TCP_BUF->seqno[0] != uip_connr->
rcv_nxt[0] ||
1892 UIP_TCP_BUF->seqno[1] != uip_connr->
rcv_nxt[1] ||
1893 UIP_TCP_BUF->seqno[2] != uip_connr->
rcv_nxt[2] ||
1894 UIP_TCP_BUF->seqno[3] != uip_connr->
rcv_nxt[3])) {
1896 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1897 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1898 goto tcp_send_synack;
1900 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1913 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1916 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
1917 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
1918 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
1919 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
1927 if(uip_connr->
nrtx == 0) {
1929 m = uip_connr->
rto - uip_connr->
timer;
1931 m = m - (uip_connr->
sa >> 3);
1936 m = m - (uip_connr->
sv >> 2);
1938 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
1942 uip_flags = UIP_ACKDATA;
1963 if(uip_flags & UIP_ACKDATA) {
1965 uip_flags = UIP_CONNECTED;
1968 uip_flags |= UIP_NEWDATA;
1976 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
1977 goto tcp_send_synack;
1986 if((uip_flags & UIP_ACKDATA) &&
1987 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
1989 process_tcp_options(uip_connr);
1992 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1993 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1994 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1995 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1997 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2005 uip_flags = UIP_ABORT;
2012 case UIP_ESTABLISHED:
2024 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2025 if(uip_outstanding(uip_connr)) {
2029 uip_flags |= UIP_CLOSE;
2031 uip_flags |= UIP_NEWDATA;
2036 uip_connr->
nrtx = 0;
2038 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2039 goto tcp_send_nodata;
2044 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2045 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2054 uip_add_rcv_nxt(uip_urglen);
2073 uip_flags |= UIP_NEWDATA;
2089 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2094 uip_connr->
mss = tmp16;
2112 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2118 if(uip_flags & UIP_ABORT) {
2121 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2122 goto tcp_send_nodata;
2125 if(uip_flags & UIP_CLOSE) {
2129 uip_connr->
nrtx = 0;
2130 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2131 goto tcp_send_nodata;
2139 if((uip_flags & UIP_ACKDATA) != 0) {
2146 if(uip_connr->
len == 0) {
2151 if(uip_slen > uip_connr->
mss) {
2152 uip_slen = uip_connr->
mss;
2157 uip_connr->
len = uip_slen;
2163 uip_slen = uip_connr->
len;
2166 uip_connr->
nrtx = 0;
2172 if(uip_slen > 0 && uip_connr->
len > 0) {
2176 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2178 goto tcp_send_noopts;
2182 if(uip_flags & UIP_NEWDATA) {
2184 UIP_TCP_BUF->flags = TCP_ACK;
2185 goto tcp_send_noopts;
2192 if(uip_flags & UIP_ACKDATA) {
2194 uip_flags = UIP_CLOSE;
2199 case UIP_FIN_WAIT_1:
2206 if(UIP_TCP_BUF->flags & TCP_FIN) {
2207 if(uip_flags & UIP_ACKDATA) {
2209 uip_connr->
timer = 0;
2215 uip_flags = UIP_CLOSE;
2218 }
else if(uip_flags & UIP_ACKDATA) {
2228 case UIP_FIN_WAIT_2:
2232 if(UIP_TCP_BUF->flags & TCP_FIN) {
2234 uip_connr->
timer = 0;
2236 uip_flags = UIP_CLOSE;
2249 if(uip_flags & UIP_ACKDATA) {
2251 uip_connr->
timer = 0;
2259 UIP_TCP_BUF->flags = TCP_ACK;
2265 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2272 LOG_DBG(
"In tcp_send\n");
2274 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2275 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2276 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2277 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2279 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2280 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2281 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2282 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2284 UIP_TCP_BUF->srcport = uip_connr->
lport;
2285 UIP_TCP_BUF->destport = uip_connr->
rport;
2292 LOG_INFO(
"Sending TCP packet to ");
2294 LOG_INFO_(
" from ");
2301 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2313 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2316 UIP_TCP_BUF->tcpchksum = 0;
2326 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len, uipbuf_get_len_field(
UIP_IP_BUF));
2347uip_htonl(uint32_t val)
2349 return UIP_HTONL(val);
2357 if(uip_sappdata != NULL) {
2359 (
int)((
char *)uip_sappdata - (
char *)UIP_TCP_PAYLOAD));
2365 if(data != uip_sappdata) {
2366 if(uip_sappdata == NULL) {
2367 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2369 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 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.