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];
280static inline uint32_t
281seq_to_uint32(uint8_t *seq)
283 return ((uint32_t)seq[0] << 24) | ((uint32_t)seq[1] << 16) |
284 ((uint32_t)seq[2] << 8) | seq[3];
295seg_in_window(uint8_t *seq, uint16_t seg_len, uint8_t *rcv_nxt,
298 int32_t start_diff = (int32_t)(seq_to_uint32(seq) - seq_to_uint32(rcv_nxt));
302 return start_diff == 0;
304 return start_diff >= 0 && start_diff < (int32_t)window;
312 if(start_diff >= 0 && start_diff < (int32_t)window) {
315 int32_t end_diff = start_diff + (int32_t)(seg_len - 1);
316 return end_diff >= 0 && end_diff < (int32_t)window;
323chksum(uint16_t sum,
const uint8_t *data, uint16_t len)
326 const uint8_t *dataptr;
327 const uint8_t *last_byte;
330 last_byte = data + len - 1;
332 while(dataptr < last_byte) {
333 t = (dataptr[0] << 8) + dataptr[1];
341 if(dataptr == last_byte) {
342 t = (dataptr[0] << 8) + 0;
356 return uip_htons(chksum(0, (uint8_t *)data, len));
359#ifndef UIP_ARCH_IPCHKSUM
365 sum = chksum(0,
uip_buf, UIP_IPH_LEN);
366 LOG_DBG(
"uip_ipchksum: sum 0x%04x\n", sum);
367 return (sum == 0) ? 0xffff :
uip_htons(sum);
372upper_layer_chksum(uint8_t proto)
383 volatile uint16_t upper_layer_len;
388 LOG_DBG(
"Upper layer checksum len: %d from: %d\n", upper_layer_len,
393 sum = upper_layer_len + proto;
395 sum = chksum(sum, (uint8_t *)&
UIP_IP_BUF->srcipaddr, 2 *
sizeof(uip_ipaddr_t));
398 sum = chksum(sum, UIP_IP_PAYLOAD(
uip_ext_len), upper_layer_len);
400 return (sum == 0) ? 0xffff :
uip_htons(sum);
406 return upper_layer_chksum(UIP_PROTO_ICMP6);
414 return upper_layer_chksum(UIP_PROTO_TCP);
418#if UIP_UDP && UIP_UDP_CHECKSUMS
422 return upper_layer_chksum(UIP_PROTO_UDP);
437 uip_listenports[c] = 0;
440 uip_conns[c].tcpstateflags = UIP_CLOSED;
444#if UIP_ACTIVE_OPEN || UIP_UDP
450 uip_udp_conns[c].lport = 0;
454#if UIP_IPV6_MULTICAST
459#if UIP_TCP && UIP_ACTIVE_OPEN
463 register struct uip_conn *conn, *cconn;
470 if(lastport >= 32000) {
477 conn = &uip_conns[c];
486 cconn = &uip_conns[c];
536 LOG_DBG(
"Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
539 LOG_ERR(
"uip_len too short compared to ext len\n");
547 memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(
uip_ext_len),
570 if(lastport >= 32000) {
582 if(uip_udp_conns[c].
lport == 0) {
583 conn = &uip_udp_conns[c];
595 memset(&conn->
ripaddr, 0,
sizeof(uip_ipaddr_t));
611 if(uip_listenports[c] == port) {
612 uip_listenports[c] = 0;
623 if(uip_listenports[c] == 0) {
624 uip_listenports[c] = port;
632#if UIP_CONF_IPV6_REASSEMBLY
633#define UIP_REASS_BUFSIZE (UIP_BUFSIZE)
635static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
642static uint8_t uip_reassbitmap[(UIP_REASS_BUFSIZE + (8 * 8) - 1) / (8 * 8)];
645static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
646 0x0f, 0x07, 0x03, 0x01};
647static uint16_t uip_reasslen;
648static uint8_t uip_reassflags;
650#define UIP_REASS_FLAG_LASTFRAG 0x01
651#define UIP_REASS_FLAG_FIRSTFRAG 0x02
652#define UIP_REASS_FLAG_ERROR_MSG 0x04
668static uint32_t uip_id;
674uip_reass(uint8_t *prev_proto_ptr)
679 struct uip_frag_hdr *frag_buf = (
struct uip_frag_hdr *)UIP_IP_PAYLOAD(
uip_ext_len);
684 if(uip_reass_on == 0) {
685 LOG_INFO(
"Starting reassembly\n");
691 uip_id = frag_buf->id;
693 memset(uip_reassbitmap, 0,
sizeof(uip_reassbitmap));
700 if(uip_ipaddr_cmp(&FBUF->srcipaddr, &
UIP_IP_BUF->srcipaddr) &&
701 uip_ipaddr_cmp(&FBUF->destipaddr, &
UIP_IP_BUF->destipaddr) &&
702 frag_buf->id == uip_id) {
704 offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
706 LOG_INFO(
"len %d\n", len);
707 LOG_INFO(
"offset %d\n", offset);
709 uip_reassflags |= UIP_REASS_FLAG_FIRSTFRAG;
715 *prev_proto_ptr = frag_buf->next;
718 LOG_INFO_6ADDR(&FBUF->srcipaddr);
720 LOG_INFO_6ADDR(&FBUF->destipaddr);
732 if(offset > UIP_REASS_BUFSIZE ||
733 UIP_IPH_LEN +
uip_ext_len + offset + len > UIP_REASS_BUFSIZE) {
741 if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
742 uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
744 uip_reasslen = offset + len;
745 LOG_INFO(
"last fragment reasslen %d\n", uip_reasslen);
753 uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
764 memcpy((uint8_t *)FBUF + UIP_IPH_LEN +
uip_ext_len + offset,
765 (uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
768 if(offset >> 6 == (offset + len) >> 6) {
769 uip_reassbitmap[offset >> 6] |=
770 bitmap_bits[(offset >> 3) & 7] &
771 ~bitmap_bits[((offset + len) >> 3) & 7];
776 uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7];
778 for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) {
779 uip_reassbitmap[i] = 0xff;
781 uip_reassbitmap[(offset + len) >> 6] |=
782 ~bitmap_bits[((offset + len) >> 3) & 7];
789 if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
792 for(i = 0; i < (uip_reasslen >> 6); ++i) {
793 if(uip_reassbitmap[i] != 0xff) {
799 if(uip_reassbitmap[uip_reasslen >> 6] !=
800 (uint8_t)~bitmap_bits[(uip_reasslen >> 3) & 7]) {
811 uipbuf_set_len_field(
UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
812 LOG_INFO(
"reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(
UIP_IP_BUF));
818 LOG_WARN(
"Already reassembling another paquet\n");
831 if(uip_reassflags & UIP_REASS_FLAG_FIRSTFRAG){
832 LOG_ERR(
"fragmentation timeout\n");
857uip_add_rcv_nxt(uint16_t n)
879 uint16_t opt_offset = 2;
880 struct uip_hbho_hdr *ext_hdr = (
struct uip_hbho_hdr *)ext_buf;
881 uint16_t ext_hdr_len = (ext_hdr->len << 3) + 8;
883 while(opt_offset + 2 <= ext_hdr_len) {
884 struct uip_ext_hdr_opt *opt_hdr = (
struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
885 uint16_t opt_len = opt_hdr->len + 2;
887 if(opt_offset + opt_len > ext_hdr_len) {
888 LOG_ERR(
"Extension header option too long: dropping packet\n");
890 (ext_buf + opt_offset) -
uip_buf);
894 switch(opt_hdr->type) {
896 LOG_DBG(
"Processing PAD1 option\n");
899 case UIP_EXT_HDR_OPT_PADN:
900 LOG_DBG(
"Processing PADN option\n");
901 opt_offset += opt_len;
903 case UIP_EXT_HDR_OPT_RPL:
912 LOG_DBG(
"Processing RPL option\n");
913 if(!NETSTACK_ROUTING.ext_header_hbh_update(ext_buf, opt_offset)) {
914 LOG_ERR(
"RPL Option Error: Dropping Packet\n");
917 opt_offset += opt_len;
919#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_MPL
920 case UIP_EXT_HDR_OPT_MPL:
925 LOG_DBG(
"Processing MPL option\n");
926 opt_offset += opt_len;
943 LOG_DBG(
"Unrecognized option, MSB 0x%x\n", opt_hdr->type);
944 switch(opt_hdr->type & 0xC0) {
955 (ext_buf + opt_offset) -
uip_buf);
959 opt_offset += opt_len;
968process_tcp_options(
struct uip_conn *conn)
970 if((UIP_TCP_BUF->tcpoffset & 0xf0) <= 0x50) {
975 for(
unsigned c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
980 uint8_t opt =
uip_buf[UIP_IPTCPH_LEN + c];
990 uip_buf[UIP_IPTCPH_LEN + 1 + c] != TCP_OPT_MSS_LEN) {
996 uint16_t tmp16 = (
uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
997 uip_buf[UIP_IPTCPH_LEN + 3 + c];
1009 if(
uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
1014 c +=
uip_buf[UIP_IPTCPH_LEN + 1 + c];
1047uip_process(uint8_t flag)
1049 uint8_t *last_header;
1051 uint8_t *next_header;
1052 struct uip_ext_hdr *ext_ptr;
1058 if(flag == UIP_UDP_SEND_CONN) {
1066 if(flag == UIP_POLL_REQUEST) {
1068 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
1069 !uip_outstanding(uip_connr)) {
1070 uip_flags = UIP_POLL;
1074 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1076 UIP_TCP_BUF->flags = 0;
1083 }
else if(flag == UIP_TIMER) {
1106 ++(uip_connr->
timer);
1116 if(uip_outstanding(uip_connr)) {
1117 if(uip_connr->
timer-- == 0) {
1129 uip_flags = UIP_TIMEDOUT;
1133 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1134 goto tcp_send_nodata;
1141 ++(uip_connr->
nrtx);
1155 goto tcp_send_synack;
1160 UIP_TCP_BUF->flags = 0;
1164 case UIP_ESTABLISHED:
1171 uip_flags = UIP_REXMIT;
1175 case UIP_FIN_WAIT_1:
1179 goto tcp_send_finack;
1182 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
1187 uip_flags = UIP_POLL;
1196 if(flag == UIP_UDP_TIMER) {
1201 uip_flags = UIP_POLL;
1219 LOG_WARN(
"incomplete IPv6 header received (%d bytes)\n", (
int)
uip_len);
1227 LOG_ERR(
"invalid version\n");
1242 LOG_ERR(
"packet shorter than reported in IP header\n");
1259 LOG_WARN(
"dropping packet with length %d > %d\n",
1268 if(last_header == NULL) {
1269 LOG_ERR(
"invalid extension header chain\n");
1275 LOG_INFO(
"packet received from ");
1283 LOG_ERR(
"Dropping packet, src is mcast\n");
1290 uip_ds6_nbr_refresh_reachable_state(&
UIP_IP_BUF->srcipaddr);
1300 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1324#if UIP_IPV6_MULTICAST
1326 if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) {
1337 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1338 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr)) {
1345 if(!uip_check_mtu() || !uip_update_ttl()) {
1350 LOG_INFO(
"Forwarding packet to next hop, dest: ");
1360 (!uip_ds6_is_addr_onlink((&
UIP_IP_BUF->destipaddr)))) {
1361 LOG_ERR(
"LL source address with off link destination, dropping\n");
1366 LOG_ERR(
"Dropping packet, not for me and link local or multicast\n");
1372 if(!uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) &&
1373 !uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) &&
1375 LOG_ERR(
"Dropping packet, not for me\n");
1381#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
1387 for(next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1388 next_header != NULL && uip_is_proto_ext_hdr(protocol);
1389 next_header = uipbuf_get_next_header(next_header,
uip_len - (next_header -
uip_buf), &protocol,
false)) {
1391 ext_ptr = (
struct uip_ext_hdr *)next_header;
1394 LOG_DBG(
"Processing hbh header\n");
1396#if UIP_CONF_IPV6_CHECKS
1406 if(!UIP_CONF_ROUTER) {
1418 case UIP_PROTO_DESTO:
1419#if UIP_CONF_IPV6_CHECKS
1421 LOG_DBG(
"Processing desto header\n");
1442 case UIP_PROTO_ROUTING:
1443#if UIP_CONF_IPV6_CHECKS
1459 LOG_DBG(
"Processing Routing header\n");
1460 if(((
struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
1462 if(NETSTACK_ROUTING.ext_header_srh_update()) {
1467 if(!uip_check_mtu() || !uip_update_ttl()) {
1472 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr) ||
1473 uip_ds6_is_my_maddr(&
UIP_IP_BUF->destipaddr) ||
1477 LOG_ERR(
"SRH next hop address is unacceptable; drop the packet\n");
1481 LOG_INFO(
"Forwarding packet to next hop ");
1488 LOG_ERR(
"Unrecognized routing type\n");
1493 case UIP_PROTO_FRAG:
1495#if UIP_CONF_IPV6_REASSEMBLY
1496 LOG_INFO(
"Processing fragmentation header\n");
1497 uip_len = uip_reass(&ext_ptr->next);
1501 if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
1506 LOG_INFO(
"Processing reassembled packet\n");
1508 next_header = uipbuf_get_next_header(
uip_buf,
uip_len, &protocol,
true);
1513 LOG_ERR(
"fragment dropped.");
1516 case UIP_PROTO_NONE:
1524 if(next_header != NULL) {
1536 case UIP_PROTO_ICMP6:
1550 LOG_ERR(
"unrecognized header\n");
1558#if UIP_CONF_IPV6_CHECKS
1563 LOG_ERR(
"icmpv6 bad checksum\n");
1588 LOG_ERR(
"Unknown ICMPv6 message type/code %d\n",
UIP_ICMP_BUF->type);
1608 LOG_INFO(
"Receiving UDP packet\n");
1614#if UIP_UDP_CHECKSUMS
1620 if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
1623 LOG_ERR(
"udp: bad checksum 0x%04x 0x%04x\n", UIP_UDP_BUF->udpchksum,
1630 if(UIP_UDP_BUF->destport == 0) {
1631 LOG_ERR(
"udp: zero port.\n");
1655 LOG_ERR(
"udp: no matching connection found\n");
1662 LOG_DBG(
"In udp_found\n");
1668 uip_flags = UIP_NEWDATA;
1674 LOG_DBG(
"In udp_send\n");
1679 uip_len = uip_slen + UIP_IPUDPH_LEN;
1690 UIP_UDP_BUF->udplen =
UIP_HTONS(uip_slen + UIP_UDPH_LEN);
1691 UIP_UDP_BUF->udpchksum = 0;
1701#if UIP_UDP_CHECKSUMS
1704 if(UIP_UDP_BUF->udpchksum == 0) {
1705 UIP_UDP_BUF->udpchksum = 0xffff;
1720 LOG_INFO(
"Receiving TCP packet\n");
1727 LOG_ERR(
"tcp: bad checksum 0x%04x 0x%04x\n", UIP_TCP_BUF->tcpchksum,
1733 if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
1734 LOG_ERR(
"tcp: zero port\n");
1740 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[
UIP_TCP_CONNS - 1];
1743 UIP_TCP_BUF->destport == uip_connr->
lport &&
1744 UIP_TCP_BUF->srcport == uip_connr->
rport &&
1754 if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) {
1758 uint16_t tmp16 = UIP_TCP_BUF->destport;
1761 if(tmp16 == uip_listenports[c]) {
1770 LOG_WARN(
"In reset\n");
1772 if(UIP_TCP_BUF->flags & TCP_RST) {
1778 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
1780 UIP_TCP_BUF->tcpoffset = 5 << 4;
1783 c = UIP_TCP_BUF->seqno[3];
1784 UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3];
1785 UIP_TCP_BUF->ackno[3] = c;
1787 c = UIP_TCP_BUF->seqno[2];
1788 UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2];
1789 UIP_TCP_BUF->ackno[2] = c;
1791 c = UIP_TCP_BUF->seqno[1];
1792 UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1];
1793 UIP_TCP_BUF->ackno[1] = c;
1795 c = UIP_TCP_BUF->seqno[0];
1796 UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0];
1797 UIP_TCP_BUF->ackno[0] = c;
1802 if(++UIP_TCP_BUF->ackno[3] == 0) {
1803 if(++UIP_TCP_BUF->ackno[2] == 0) {
1804 if(++UIP_TCP_BUF->ackno[1] == 0) {
1805 ++UIP_TCP_BUF->ackno[0];
1811 tmp16 = UIP_TCP_BUF->srcport;
1812 UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport;
1813 UIP_TCP_BUF->destport = tmp16;
1819 goto tcp_send_noconn;
1825 LOG_DBG(
"In found listen\n");
1834 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1835 uip_connr = &uip_conns[c];
1838 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1839 if(uip_connr == 0 ||
1841 uip_connr = &uip_conns[c];
1846 if(uip_connr == 0) {
1851 LOG_ERR(
"tcp: found no unused connections\n");
1860 uip_connr->
nrtx = 0;
1861 uip_connr->
lport = UIP_TCP_BUF->destport;
1862 uip_connr->
rport = UIP_TCP_BUF->srcport;
1866 uip_connr->
snd_nxt[0] = iss[0];
1867 uip_connr->
snd_nxt[1] = iss[1];
1868 uip_connr->
snd_nxt[2] = iss[2];
1869 uip_connr->
snd_nxt[3] = iss[3];
1873 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
1874 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
1875 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
1876 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
1879 process_tcp_options(uip_connr);
1884 UIP_TCP_BUF->flags = TCP_ACK;
1887 UIP_TCP_BUF->flags |= TCP_SYN;
1890 UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK;
1895 UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS;
1896 UIP_TCP_BUF->optdata[1] = TCP_OPT_MSS_LEN;
1899 uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1900 UIP_TCP_BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
1905 LOG_DBG(
"In found\n");
1912 if(UIP_TCP_BUF->flags & TCP_RST) {
1914 LOG_WARN(
"tcp: got reset, aborting connection.");
1915 uip_flags = UIP_ABORT;
1921 c = (UIP_TCP_BUF->tcpoffset >> 4) << 2;
1925 if(
uip_len < c + UIP_IPH_LEN) {
1926 LOG_WARN(
"Dropping TCP packet with too large data offset (%u bytes)\n",
1942 if(!((((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
1943 ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
1944 (((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
1945 ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) {
1946 if((
uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0))) {
1949 uint16_t eff_seg_len =
uip_len;
1950 if(UIP_TCP_BUF->flags & TCP_FIN) {
1955 if(!seg_in_window(UIP_TCP_BUF->seqno, eff_seg_len,
1958 if((UIP_TCP_BUF->flags & TCP_SYN)) {
1959 if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
1960 goto tcp_send_synack;
1962 }
else if((uip_connr->
tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
1972 uint32_t seg_seq = seq_to_uint32(UIP_TCP_BUF->seqno);
1973 uint32_t expected_seq = seq_to_uint32(uip_connr->
rcv_nxt);
1974 int32_t seq_diff = (int32_t)(seg_seq - expected_seq);
1978 uint32_t overlap = (uint32_t)(-seq_diff);
1984 LOG_DBG(
"TCP: trimming %lu bytes of overlap from segment\n",
1985 (
unsigned long)overlap);
1991 UIP_TCP_BUF->seqno[0] = (expected_seq >> 24) & 0xff;
1992 UIP_TCP_BUF->seqno[1] = (expected_seq >> 16) & 0xff;
1993 UIP_TCP_BUF->seqno[2] = (expected_seq >> 8) & 0xff;
1994 UIP_TCP_BUF->seqno[3] = expected_seq & 0xff;
1995 }
else if(seq_diff > 0) {
1997 LOG_DBG(
"TCP: out-of-order segment (gap of %lu bytes), sending ACK\n",
1998 (
unsigned long)(uint32_t)seq_diff);
2009 if((UIP_TCP_BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
2012 if(UIP_TCP_BUF->ackno[0] ==
uip_acc32[0] &&
2013 UIP_TCP_BUF->ackno[1] ==
uip_acc32[1] &&
2014 UIP_TCP_BUF->ackno[2] ==
uip_acc32[2] &&
2015 UIP_TCP_BUF->ackno[3] ==
uip_acc32[3]) {
2023 if(uip_connr->
nrtx == 0) {
2025 m = uip_connr->
rto - uip_connr->
timer;
2027 m = m - (uip_connr->
sa >> 3);
2032 m = m - (uip_connr->
sv >> 2);
2034 uip_connr->
rto = (uip_connr->
sa >> 3) + uip_connr->
sv;
2038 uip_flags = UIP_ACKDATA;
2059 if(uip_flags & UIP_ACKDATA) {
2061 uip_flags = UIP_CONNECTED;
2064 uip_flags |= UIP_NEWDATA;
2072 if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) {
2073 goto tcp_send_synack;
2082 if((uip_flags & UIP_ACKDATA) &&
2083 (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
2085 process_tcp_options(uip_connr);
2088 uip_connr->
rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
2089 uip_connr->
rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
2090 uip_connr->
rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
2091 uip_connr->
rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
2093 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2101 uip_flags = UIP_ABORT;
2108 case UIP_ESTABLISHED:
2120 if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->
tcpstateflags & UIP_STOPPED)) {
2121 if(uip_outstanding(uip_connr)) {
2125 uip_flags |= UIP_CLOSE;
2127 uip_flags |= UIP_NEWDATA;
2132 uip_connr->
nrtx = 0;
2134 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2135 goto tcp_send_nodata;
2140 if((UIP_TCP_BUF->flags & TCP_URG) != 0) {
2141 tmp16 = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1];
2150 uip_add_rcv_nxt(uip_urglen);
2169 uip_flags |= UIP_NEWDATA;
2185 tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1];
2190 uip_connr->
mss = tmp16;
2208 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2214 if(uip_flags & UIP_ABORT) {
2217 UIP_TCP_BUF->flags = TCP_RST | TCP_ACK;
2218 goto tcp_send_nodata;
2221 if(uip_flags & UIP_CLOSE) {
2225 uip_connr->
nrtx = 0;
2226 UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK;
2227 goto tcp_send_nodata;
2235 if((uip_flags & UIP_ACKDATA) != 0) {
2242 if(uip_connr->
len == 0) {
2247 if(uip_slen > uip_connr->
mss) {
2248 uip_slen = uip_connr->
mss;
2253 uip_connr->
len = uip_slen;
2259 uip_slen = uip_connr->
len;
2262 uip_connr->
nrtx = 0;
2268 if(uip_slen > 0 && uip_connr->
len > 0) {
2272 UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
2274 goto tcp_send_noopts;
2278 if(uip_flags & UIP_NEWDATA) {
2280 UIP_TCP_BUF->flags = TCP_ACK;
2281 goto tcp_send_noopts;
2288 if(uip_flags & UIP_ACKDATA) {
2290 uip_flags = UIP_CLOSE;
2295 case UIP_FIN_WAIT_1:
2302 if(UIP_TCP_BUF->flags & TCP_FIN) {
2303 if(uip_flags & UIP_ACKDATA) {
2305 uip_connr->
timer = 0;
2311 uip_flags = UIP_CLOSE;
2314 }
else if(uip_flags & UIP_ACKDATA) {
2324 case UIP_FIN_WAIT_2:
2328 if(UIP_TCP_BUF->flags & TCP_FIN) {
2330 uip_connr->
timer = 0;
2332 uip_flags = UIP_CLOSE;
2345 if(uip_flags & UIP_ACKDATA) {
2347 uip_connr->
timer = 0;
2355 UIP_TCP_BUF->flags = TCP_ACK;
2361 UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
2368 LOG_DBG(
"In tcp_send\n");
2370 UIP_TCP_BUF->ackno[0] = uip_connr->
rcv_nxt[0];
2371 UIP_TCP_BUF->ackno[1] = uip_connr->
rcv_nxt[1];
2372 UIP_TCP_BUF->ackno[2] = uip_connr->
rcv_nxt[2];
2373 UIP_TCP_BUF->ackno[3] = uip_connr->
rcv_nxt[3];
2375 UIP_TCP_BUF->seqno[0] = uip_connr->
snd_nxt[0];
2376 UIP_TCP_BUF->seqno[1] = uip_connr->
snd_nxt[1];
2377 UIP_TCP_BUF->seqno[2] = uip_connr->
snd_nxt[2];
2378 UIP_TCP_BUF->seqno[3] = uip_connr->
snd_nxt[3];
2380 UIP_TCP_BUF->srcport = uip_connr->
lport;
2381 UIP_TCP_BUF->destport = uip_connr->
rport;
2388 LOG_INFO(
"Sending TCP packet to ");
2390 LOG_INFO_(
" from ");
2397 UIP_TCP_BUF->wnd[0] = UIP_TCP_BUF->wnd[1] = 0;
2409 UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
2412 UIP_TCP_BUF->tcpchksum = 0;
2422 LOG_INFO(
"Sending packet with length %d (%d)\n",
uip_len, uipbuf_get_len_field(
UIP_IP_BUF));
2443uip_htonl(uint32_t val)
2445 return UIP_HTONL(val);
2453 if(uip_sappdata != NULL) {
2455 (
int)((
char *)uip_sappdata - (
char *)UIP_TCP_PAYLOAD));
2461 if(data != uip_sappdata) {
2462 if(uip_sappdata == NULL) {
2463 memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
2465 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.
#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.
#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"
#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
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.
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
#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.
uint8_t uip_acc32[4]
4-byte array used for the 32-bit sequence number calculations.
#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.
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
uip_buf_t uip_aligned_buf
Packet buffer for incoming and outgoing packets.
uint16_t uip_ext_len
The length of the extension headers.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
#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.
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.
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.