55 #include "ip64-addr.h"
56 #include "ip64-addrmap.h"
57 #include "ip64-conf.h"
58 #include "ip64-special-ports.h"
59 #include "ip64-eth-interface.h"
60 #include "ip64-slip-interface.h"
62 #include "ip64-ipv4-dhcp.h"
63 #include "contiki-net.h"
74 #define PRINTF(...) printf(__VA_ARGS__)
84 uint8_t nxthdr, hoplim;
85 uip_ip6addr_t srcipaddr, destipaddr;
100 #define EPHEMERAL_PORTRANGE 1024
102 #define IPV6_HDRLEN 40
103 #define IPV4_HDRLEN 20
105 #define IP_PROTO_ICMPV4 1
106 #define IP_PROTO_TCP 6
107 #define IP_PROTO_UDP 17
108 #define IP_PROTO_ICMPV6 58
110 #define ICMP_ECHO_REPLY 0
112 #define ICMP6_ECHO_REPLY 129
113 #define ICMP6_ECHO 128
146 #define BUFSIZE UIP_BUFSIZE
149 uint8_t *ip64_packet_buffer = ip64_packet_buffer_aligned.u8;
151 uint16_t ip64_packet_buffer_maxlen = BUFSIZE;
157 static uint16_t ipid;
158 static uint8_t ip64_hostaddr_configured = 0;
160 static uip_ip6addr_t ipv6_local_address;
161 static uint8_t ipv6_local_address_configured = 0;
166 #define SYN_LIFETIME (CLOCK_SECOND * 20)
167 #define RST_LIFETIME (CLOCK_SECOND * 30)
168 #define DEFAULT_LIFETIME (CLOCK_SECOND * 60 * 5)
182 uip_ipaddr(&ipv4_broadcast_addr, 255,255,255,255);
183 ip64_hostaddr_configured = 0;
185 PRINTF(
"ip64_init\n");
186 IP64_ETH_DRIVER.init();
188 ip64_ipv4_dhcp_init();
193 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
194 state = uip_ds6_if.addr_list[i].state;
195 PRINTF(
"i %d used %d\n", i, uip_ds6_if.addr_list[i].isused);
196 if(uip_ds6_if.addr_list[i].isused &&
198 ip64_set_ipv6_address(&uip_ds6_if.addr_list[i].ipaddr);
208 ip64_hostaddr_configured = 1;
209 ip64_addr_copy4(&ip64_hostaddr, hostaddr);
215 ip64_addr_copy4(&ip64_netmask, netmask);
221 ip64_addr_copy4(&ip64_draddr, draddr);
225 ip64_get_hostaddr(
void)
227 return &ip64_hostaddr;
231 ip64_get_netmask(
void)
233 return &ip64_netmask;
237 ip64_get_draddr(
void)
245 ip64_set_hostaddr(addr);
246 ip64_set_netmask(netmask);
248 PRINTF(
"ip64_set_ipv4_address: configuring address %d.%d.%d.%d/%d.%d.%d.%d\n",
249 ip64_hostaddr.u8[0], ip64_hostaddr.u8[1],
250 ip64_hostaddr.u8[2], ip64_hostaddr.u8[3],
251 ip64_netmask.u8[0], ip64_netmask.u8[1],
252 ip64_netmask.u8[2], ip64_netmask.u8[3]);
256 ip64_set_ipv6_address(
const uip_ip6addr_t *addr)
258 ip64_addr_copy6(&ipv6_local_address, (
const uip_ip6addr_t *)addr);
259 ipv6_local_address_configured = 1;
261 PRINTF(
"ip64_set_ipv6_address: configuring address ");
262 uip_debug_ipaddr_print(addr);
268 chksum(uint16_t sum,
const uint8_t *data, uint16_t len)
271 const uint8_t *dataptr;
272 const uint8_t *last_byte;
275 last_byte = data + len - 1;
277 while(dataptr < last_byte) {
278 t = (dataptr[0] << 8) + dataptr[1];
286 if(dataptr == last_byte) {
287 t = (dataptr[0] << 8) + 0;
299 ipv4_checksum(
struct ipv4_hdr *hdr)
303 sum = chksum(0, (uint8_t *)hdr, IPV4_HDRLEN);
304 return (sum == 0) ? 0xffff :
uip_htons(sum);
308 ipv4_transport_checksum(
const uint8_t *packet, uint16_t len, uint8_t proto)
310 uint16_t transport_layer_len;
312 struct ipv4_hdr *v4hdr = (
struct ipv4_hdr *)packet;
314 transport_layer_len = len - IPV4_HDRLEN;
318 if(proto != IP_PROTO_ICMPV4) {
320 sum = transport_layer_len + proto;
322 sum = chksum(sum, (uint8_t *)&v4hdr->srcipaddr, 2 *
sizeof(
uip_ip4addr_t));
329 sum = chksum(sum, &packet[IPV4_HDRLEN], transport_layer_len);
331 return (sum == 0) ? 0xffff :
uip_htons(sum);
335 ipv6_transport_checksum(
const uint8_t *packet, uint16_t len, uint8_t proto)
337 uint16_t transport_layer_len;
339 struct ipv6_hdr *v6hdr = (
struct ipv6_hdr *)packet;
341 transport_layer_len = len - IPV6_HDRLEN;
346 sum = transport_layer_len + proto;
348 sum = chksum(sum, (uint8_t *)&v6hdr->srcipaddr,
sizeof(uip_ip6addr_t));
349 sum = chksum(sum, (uint8_t *)&v6hdr->destipaddr,
sizeof(uip_ip6addr_t));
352 sum = chksum(sum, &packet[IPV6_HDRLEN], transport_layer_len);
354 return (sum == 0) ? 0xffff :
uip_htons(sum);
358 ip64_6to4(
const uint8_t *ipv6packet,
const uint16_t ipv6packet_len,
359 uint8_t *resultpacket)
361 struct ipv4_hdr *v4hdr;
362 struct ipv6_hdr *v6hdr;
363 struct udp_hdr *udphdr;
364 struct tcp_hdr *tcphdr;
365 struct icmpv4_hdr *icmpv4hdr;
366 struct icmpv6_hdr *icmpv6hdr;
367 uint16_t ipv6len, ipv4len;
368 struct ip64_addrmap_entry *m;
370 v6hdr = (
struct ipv6_hdr *)ipv6packet;
371 v4hdr = (
struct ipv4_hdr *)resultpacket;
373 if((v6hdr->len[0] << 8) + v6hdr->len[1] <= ipv6packet_len) {
374 ipv6len = (v6hdr->len[0] << 8) + v6hdr->len[1] + IPV6_HDRLEN;
376 PRINTF(
"ip64_6to4: packet smaller than reported in IPv6 header, dropping\n");
382 memcpy(&resultpacket[IPV4_HDRLEN],
383 &ipv6packet[IPV6_HDRLEN],
384 ipv6len - IPV6_HDRLEN);
386 udphdr = (
struct udp_hdr *)&resultpacket[IPV4_HDRLEN];
387 tcphdr = (
struct tcp_hdr *)&resultpacket[IPV4_HDRLEN];
388 icmpv4hdr = (
struct icmpv4_hdr *)&resultpacket[IPV4_HDRLEN];
389 icmpv6hdr = (
struct icmpv6_hdr *)&ipv6packet[IPV6_HDRLEN];
399 v4hdr->ipoffset[0] = v4hdr->ipoffset[1] = 0;
404 ipv4len = ipv6len - IPV6_HDRLEN + IPV4_HDRLEN;
405 v4hdr->len[0] = ipv4len >> 8;
406 v4hdr->len[1] = ipv4len & 0xff;
411 v4hdr->ipid[0] = ipid >> 8;
412 v4hdr->ipid[1] = ipid & 0xff;
419 switch(v6hdr->nxthdr) {
421 PRINTF(
"ip64_6to4: TCP header\n");
422 v4hdr->proto = IP_PROTO_TCP;
427 if(ipv6_transport_checksum(ipv6packet, ipv6len,
428 IP_PROTO_TCP) != 0xffff) {
429 PRINTF(
"Bad TCP checksum, dropping packet\n");
435 PRINTF(
"ip64_6to4: UDP header\n");
436 v4hdr->proto = IP_PROTO_UDP;
440 if(ipv6_transport_checksum(ipv6packet, ipv6len,
441 IP_PROTO_UDP) != 0xffff) {
442 PRINTF(
"Bad UDP checksum, dropping packet\n");
446 case IP_PROTO_ICMPV6:
447 PRINTF(
"ip64_6to4: ICMPv6 header\n");
448 v4hdr->proto = IP_PROTO_ICMPV4;
451 icmpv4hdr->type = ICMP_ECHO_REPLY;
453 PRINTF(
"ip64_6to4: ICMPv6 mapping for type %d not implemented.\n",
463 PRINTF(
"ip64_6to4: Could not convert IPv6 next hop %d to an IPv4 protocol number.\n",
471 v4hdr->ttl = v6hdr->hoplim;
477 if(ip64_addr_6to4(&v6hdr->destipaddr,
478 &v4hdr->destipaddr) == 0) {
480 PRINTF(
"ip64_6to4: Could not convert IPv6 destination address.\n");
481 uip_debug_ipaddr_print(&v6hdr->destipaddr);
490 if(!ip64_hostaddr_configured &&
492 PRINTF(
"ip64_6to4: no IPv4 address configured.\n");
495 ip64_addr_copy4(&v4hdr->srcipaddr, &ip64_hostaddr);
511 if((v4hdr->proto == IP_PROTO_UDP || v4hdr->proto == IP_PROTO_TCP)) {
513 if(ip64_special_ports_outgoing_is_special(uip_ntohs(udphdr->srcport))) {
515 if(ip64_special_ports_translate_outgoing(uip_ntohs(udphdr->srcport),
520 }
else if(uip_ntohs(udphdr->srcport) >= EPHEMERAL_PORTRANGE) {
521 m = ip64_addrmap_lookup(&v6hdr->srcipaddr,
522 uip_ntohs(udphdr->srcport),
524 uip_ntohs(udphdr->destport),
527 PRINTF(
"Lookup failed\n");
528 m = ip64_addrmap_create(&v6hdr->srcipaddr,
529 uip_ntohs(udphdr->srcport),
531 uip_ntohs(udphdr->destport),
534 PRINTF(
"Could not create new map\n");
537 PRINTF(
"Could create new local port %d\n", m->mapped_port);
540 PRINTF(
"Lookup: found local port %d (%d)\n", m->mapped_port,
556 if(v4hdr->proto == IP_PROTO_TCP) {
557 if((tcphdr->flags & TCP_SYN)) {
558 ip64_addrmap_set_lifetime(m, SYN_LIFETIME);
559 }
else if((tcphdr->flags & TCP_RST)) {
560 ip64_addrmap_set_lifetime(m, RST_LIFETIME);
562 ip64_addrmap_set_lifetime(m, DEFAULT_LIFETIME);
568 if((tcphdr->flags & TCP_FIN) ||
569 (tcphdr->flags & TCP_RST)) {
570 ip64_addrmap_set_recycleble(m);
573 ip64_addrmap_set_lifetime(m, DEFAULT_LIFETIME);
578 ip64_addrmap_set_recycleble(m);
584 udphdr->srcport =
uip_htons(m->mapped_port);
591 v4hdr->ipchksum = ~(ipv4_checksum(v4hdr));
598 switch(v4hdr->proto) {
600 tcphdr->tcpchksum = 0;
601 tcphdr->tcpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len,
605 udphdr->udpchksum = 0;
606 udphdr->udpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len,
608 if(udphdr->udpchksum == 0) {
609 udphdr->udpchksum = 0xffff;
612 case IP_PROTO_ICMPV4:
613 icmpv4hdr->icmpchksum = 0;
614 icmpv4hdr->icmpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len,
619 PRINTF(
"ip64_6to4: transport protocol %d not implemented\n", v4hdr->proto);
624 PRINTF(
"ip64_6to4: ipv4len %d\n", ipv4len);
629 ip64_4to6(
const uint8_t *ipv4packet,
const uint16_t ipv4packet_len,
630 uint8_t *resultpacket)
632 struct ipv4_hdr *v4hdr;
633 struct ipv6_hdr *v6hdr;
634 struct udp_hdr *udphdr;
635 struct tcp_hdr *tcphdr;
636 struct icmpv4_hdr *icmpv4hdr;
637 struct icmpv6_hdr *icmpv6hdr;
638 uint16_t ipv4len, ipv6len, ipv6_packet_len;
639 struct ip64_addrmap_entry *m;
641 v6hdr = (
struct ipv6_hdr *)resultpacket;
642 v4hdr = (
struct ipv4_hdr *)ipv4packet;
644 if((v4hdr->len[0] << 8) + v4hdr->len[1] <= ipv4packet_len) {
645 ipv4len = (v4hdr->len[0] << 8) + v4hdr->len[1];
647 PRINTF(
"ip64_4to6: packet smaller than reported in IPv4 header, dropping\n");
651 if(ipv4len <= IPV4_HDRLEN) {
657 if(ipv4len - IPV4_HDRLEN + IPV6_HDRLEN > BUFSIZE) {
658 PRINTF(
"ip64_4to6: packet too big to fit in buffer, dropping\n");
662 memcpy(&resultpacket[IPV6_HDRLEN],
663 &ipv4packet[IPV4_HDRLEN],
664 ipv4len - IPV4_HDRLEN);
666 udphdr = (
struct udp_hdr *)&resultpacket[IPV6_HDRLEN];
667 tcphdr = (
struct tcp_hdr *)&resultpacket[IPV6_HDRLEN];
668 icmpv4hdr = (
struct icmpv4_hdr *)&ipv4packet[IPV4_HDRLEN];
669 icmpv6hdr = (
struct icmpv6_hdr *)&resultpacket[IPV6_HDRLEN];
671 ipv6len = ipv4len - IPV4_HDRLEN + IPV6_HDRLEN;
672 ipv6_packet_len = ipv6len - IPV6_HDRLEN;
681 v6hdr->len[0] = ipv6_packet_len >> 8;
682 v6hdr->len[1] = ipv6_packet_len & 0xff;
685 v6hdr->hoplim = v4hdr->ttl;
699 if(ip64_addr_4to6(&v4hdr->srcipaddr, &v6hdr->srcipaddr) == 0) {
700 PRINTF(
"ip64_packet_4to6: failed to convert source IP address\n");
706 switch(v4hdr->proto) {
708 v6hdr->nxthdr = IP_PROTO_UDP;
712 v6hdr->nxthdr = IP_PROTO_TCP;
715 case IP_PROTO_ICMPV4:
718 if(icmpv4hdr->type == ICMP_ECHO) {
719 PRINTF(
"ip64_4to6: translating ICMPv4 ECHO packet\n");
720 v6hdr->nxthdr = IP_PROTO_ICMPV6;
721 icmpv6hdr->type = ICMP6_ECHO;
722 ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address);
724 PRINTF(
"ip64_packet_4to6: ICMPv4 packet type %d not supported\n",
734 PRINTF(
"ip64_packet_4to6: protocol type %d not supported\n",
743 ((v4hdr->destipaddr.u16[0] & (~ip64_netmask.u16[0])) ==
744 (ipv4_broadcast_addr.u16[0] & (~ip64_netmask.u16[0]))) &&
745 ((v4hdr->destipaddr.u16[1] & (~ip64_netmask.u16[1])) ==
746 (ipv4_broadcast_addr.u16[1] & (~ip64_netmask.u16[1]))))) {
750 if(!ip64_hostaddr_configured) {
751 PRINTF(
"ip64_packet_4to6: no local IPv4 address configured, dropping incoming packet.\n");
756 PRINTF(
"ip64_packet_4to6: the IPv4 destination address %d.%d.%d.%d did not match our IPv4 address %d.%d.%d.%d\n",
775 if((v4hdr->proto == IP_PROTO_TCP || v4hdr->proto == IP_PROTO_UDP)) {
776 if(
uip_htons(tcphdr->destport) < EPHEMERAL_PORTRANGE) {
778 PRINTF(
"Port is in the non-ephemeral port range %d (%d)\n",
779 tcphdr->destport,
uip_htons(tcphdr->destport));
780 ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address);
781 }
else if(ip64_special_ports_incoming_is_special(
uip_htons(tcphdr->destport))) {
782 uip_ip6addr_t newip6addr;
784 PRINTF(
"ip64 port %d (%d) is special, treating it differently\n",
785 tcphdr->destport,
uip_htons(tcphdr->destport));
786 if(ip64_special_ports_translate_incoming(
uip_htons(tcphdr->destport),
787 &newip6addr, &newport)) {
788 ip64_addr_copy6(&v6hdr->destipaddr, &newip6addr);
790 PRINTF(
"New port %d (%d)\n",
791 tcphdr->destport,
uip_htons(tcphdr->destport));
793 ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address);
794 PRINTF(
"No new port\n");
801 m = ip64_addrmap_lookup_port(uip_ntohs(udphdr->destport),
804 PRINTF(
"Inbound lookup failed\n");
807 PRINTF(
"Inbound lookup did not fail\n");
809 ip64_addr_copy6(&v6hdr->destipaddr, &m->ip6addr);
810 udphdr->destport =
uip_htons(m->ip6port);
818 switch(v6hdr->nxthdr) {
820 tcphdr->tcpchksum = 0;
821 tcphdr->tcpchksum = ~(ipv6_transport_checksum(resultpacket,
826 udphdr->udpchksum = 0;
827 udphdr->udpchksum = ~(ipv6_transport_checksum(resultpacket,
830 if(udphdr->udpchksum == 0) {
831 udphdr->udpchksum = 0xffff;
835 case IP_PROTO_ICMPV6:
836 icmpv6hdr->icmpchksum = 0;
837 icmpv6hdr->icmpchksum = ~(ipv6_transport_checksum(resultpacket,
842 PRINTF(
"ip64_4to6: transport protocol %d not implemented\n", v4hdr->proto);
847 PRINTF(
"ip64_4to6: ipv6len %d\n", ipv6len);
852 ip64_hostaddr_is_configured(
void)
854 return ip64_hostaddr_configured;
860 IP64_CONF_UIP_FALLBACK_INTERFACE.init();
864 interface_output(
void)
866 PRINTF(
"ip64: interface_output len %d\n",
uip_len);
867 IP64_CONF_UIP_FALLBACK_INTERFACE.output();
870 const struct uip_fallback_interface ip64_uip_fallback_interface = {
871 interface_init, interface_output
uip_len
The length of the packet in the uip_buf buffer.
#define uip_ipaddr_maskcmp(addr1, addr2, mask)
Compare two IP addresses with netmasks.
#define ICMP6_ECHO_REPLY
Echo reply.
#define NULL
The null pointer.
#define uip_ip4addr_cmp(addr1, addr2)
Compare two IP addresses.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Representation of an IP address.
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
#define uip_ipaddr_to_quad(a)
Convert an IP address to four bytes separated by commas.
#define uip_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
A set of debugging macros.
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
Construct an IP address from four bytes.