Contiki-NG
Loading...
Searching...
No Matches
NAT64 gateway

Files

file  module-macros.h
 Module macros for the NAT64 service.
 
file  nat64-6lowpan.h
 6LoWPAN compression context for the NAT64 prefix.
 
file  nat64-dns64.c
 NAT64 DNS64 translation – rewrites DNS queries (AAAA->A) and responses (A->AAAA with NAT64 prefix) inline.
 
file  nat64-dns64.h
 NAT64 DNS64 translation (RFC 6147).
 
file  nat64-platform.h
 NAT64 platform interface — socket-based.
 
file  nat64-tcp.c
 NAT64 TCP splice proxy.
 
file  nat64-tcp.h
 NAT64 TCP splice proxy.
 
file  nat64.c
 NAT64 core — dispatches IPv6 packets to protocol-specific handlers (UDP via kernel sockets, TCP via splice proxy, ICMPv6 Echo via unprivileged ICMP sockets) and synthesizes ICMPv6 Destination Unreachable errors back to the IoT node when forwarding fails.
 
file  nat64.h
 NAT64 gateway core API.
 
file  nat64-sock.c
 NAT64 socket-based IPv4 forwarding for the native platform.
 

Data Structures

struct  nat64_session
 A NAT64 session binding an IoT node's IPv6 flow to an IPv4 socket. More...
 

Macros

#define BUILD_WITH_NAT64   1
 Defined when the NAT64 module is built into the image.
 
#define NAT64_6LOWPAN_PREFIX_BYTES
 Upper 64 bits of the NAT64 prefix as 8 bytes.
 

Enumerations

enum  nat64_session_proto
 Transport protocol tracked by a NAT64 session. More...
 
enum  nat64_tcp_state { NAT64_TCP_CONNECTING , NAT64_TCP_ESTABLISHED , NAT64_TCP_CLOSING }
 TCP connection state within the NAT64 splice proxy. More...
 

Functions

void nat64_dns64_6to4 (uint8_t *data, uint16_t len)
 Rewrite an outgoing DNS query from AAAA to A.
 
uint16_t nat64_dns64_4to6 (const uint8_t *ipv4data, uint16_t ipv4len, uint8_t *ipv6data, uint16_t ipv6len, uint16_t ipv6bufsiz)
 Rewrite an incoming DNS response from A to AAAA.
 
bool nat64_platform_init (void)
 Initialize the platform layer.
 
bool nat64_is_enabled (void)
 Check whether the NAT64 gateway has been enabled at runtime.
 
int nat64_platform_udp_send (const uip_ip4addr_t *dst, uint16_t dstport, const uip_ip6addr_t *ip6_src, uint16_t srcport, const uint8_t *payload, uint16_t len)
 Forward a UDP payload to an IPv4 server.
 
struct nat64_sessionnat64_platform_tcp_connect (const uip_ip4addr_t *dst, uint16_t dstport, const uip_ip6addr_t *ip6_src, uint16_t srcport, uint32_t peer_isn)
 Initiate a TCP connection to an IPv4 server.
 
int nat64_platform_tcp_send (struct nat64_session *s, const uint8_t *data, uint16_t len)
 Send data on an established TCP session.
 
void nat64_platform_tcp_close (struct nat64_session *s)
 Half-close a TCP session (send FIN).
 
void nat64_platform_tcp_destroy (struct nat64_session *s)
 Fully tear down a TCP session.
 
void nat64_platform_tcp_abort (struct nat64_session *s)
 Abort a TCP session by sending RST upstream.
 
int nat64_platform_icmp_send (const uip_ip4addr_t *dst, const uip_ip6addr_t *ip6_src, uint16_t identifier, const uint8_t *icmp_pkt, uint16_t icmp_len)
 Forward an ICMPv4 Echo Request to an IPv4 destination.
 
static void nat64_tcp_send_pending (struct tcp_seqstate *ts)
 Inject the next paced chunk from a session's receive buffer.
 
static void nat64_tcp_ack_confirmed (struct tcp_seqstate *ts)
 Promote the in-flight segment to acknowledged and queue what's next.
 
static void inject_tcp (const struct nat64_session *s, struct tcp_seqstate *ts, uint8_t flags, const uint8_t *payload, uint16_t payload_len)
 Fabricate and inject an IPv6+TCP segment toward the IoT node.
 
int nat64_tcp_output (const uint8_t *pkt, uint16_t len)
 Process an outgoing IPv6+TCP packet from an IoT node.
 
void nat64_tcp_flush_acks (void)
 Flush deferred TCP ACKs.
 
void nat64_tcp_init (void)
 Initialize the TCP splice proxy.
 
void nat64_tcp_set_isn_secret (const uint8_t key[16])
 Set the 128-bit secret key for TCP ISN generation.
 
bool nat64_tcp_has_pending_data (const struct nat64_session *s)
 Check whether a session has buffered data awaiting delivery.
 
bool nat64_tcp_peer_fin_received (const struct nat64_session *s)
 Check whether the IoT node has already half-closed the session.
 
void nat64_tcp_free_seqstate (const struct nat64_session *s)
 Free any TCP sequence state associated with a session.
 
static bool ipv4_dst_is_forbidden (const uip_ip4addr_t *addr)
 Reject IPv4 destinations that must not be reached via NAT64.
 
bool nat64_is_ip64_addr (const uip_ip6addr_t *addr)
 Check whether an IPv6 address embeds an IPv4 address via the NAT64 prefix.
 
static int handle_udp_output (const uint8_t *pkt, const struct v6hdr *ip6, const uip_ip4addr_t *dst4, uint16_t payload_len)
 Forward an outbound IPv6/UDP datagram to its IPv4 destination.
 
static int handle_icmp6_output (const uint8_t *pkt, const struct v6hdr *ip6, const uip_ip4addr_t *dst4, uint16_t payload_len)
 Translate an outbound ICMPv6 Echo Request to ICMPv4 and send it.
 
int nat64_output (const uint8_t *ipv6_pkt, uint16_t len)
 Process an outgoing IPv6 packet destined for an IPv4 host.
 
void nat64_activate (void)
 Initialize the NAT64 gateway.
 
static uint8_t errno_to_icmp6_code (int err)
 Map a Linux errno to an ICMPv6 Destination Unreachable code.
 
static void expire_session (struct nat64_session *s)
 Reap an expired session, notifying its peer if applicable.
 

Platform-to-core callbacks

Called by the platform layer (e.g., the select loop in nat64-sock.c) when data arrives on an IPv4 socket or a TCP connection changes state.

Each callback fabricates the corresponding IPv6 packet and injects it into the uIP stack via tcpip_input().

void nat64_tcp_established (struct nat64_session *s)
 Notify that a TCP connection to an IPv4 server completed.
 
void nat64_tcp_data_in (struct nat64_session *s, const uint8_t *data, uint16_t len)
 Forward TCP data from an IPv4 server to the IoT node.
 
void nat64_tcp_closed (struct nat64_session *s)
 Notify that an IPv4 server closed a TCP connection.
 
void nat64_udp_input (struct nat64_session *s, const uint8_t *payload, uint16_t len)
 Inject a UDP response from an IPv4 server.
 
void nat64_icmp_input (struct nat64_session *s, const uint8_t *icmp_pkt, uint16_t len)
 Inject an ICMPv4 Echo Reply received from an IPv4 host.
 

ICMPv6 Destination Unreachable synthesis

The gateway synthesizes ICMPv6 errors toward the IoT node when a packet cannot be delivered (forbidden destination, connection refused, host unreachable, session table exhaustion, ...).

The errors are queued and drained by nat64_flush_icmp6() from the platform layer's select loop, to avoid re-entrancy with tcpip_input() from output paths.

void nat64_queue_icmp6_unreach (const uint8_t *invoking_pkt, uint16_t invoking_len, uint8_t code)
 Queue an ICMPv6 Destination Unreachable for delivery to the IoT node.
 
void nat64_queue_icmp6_unreach_tuple (const uip_ip6addr_t *ip6_src, uint16_t src_port, const uip_ip4addr_t *ip4_dst, uint16_t dst_port, uint8_t ipproto, uint8_t code)
 Queue an ICMPv6 Destination Unreachable for a 5-tuple whose connection failed.
 
void nat64_flush_icmp6 (void)
 Drain the queue of pending ICMPv6 errors into the uIP stack.
 

ICMPv6 Destination Unreachable codes (RFC 4443 §3.1)

#define NAT64_ICMP6_NOROUTE   0
 No route to destination.
 
#define NAT64_ICMP6_ADMIN   1
 Communication administratively prohibited.
 
#define NAT64_ICMP6_ADDR   3
 Address unreachable.
 
#define NAT64_ICMP6_PORT   4
 Port unreachable.
 

Detailed Description

Stateful NAT64 service that lets IPv6-only IoT nodes reach IPv4 servers through a Contiki-NG border router. The implementation targets outbound, client-initiated flows over 6LoWPAN/RPL and deliberately omits RFC 6146 features that have no practical use in a constrained network (hairpinning, inbound bindings, full TCP state machine, ...). See os/services/nat64/README.md for the full design rationale and standards-compliance matrix.

The module is split into:

Macro Definition Documentation

◆ BUILD_WITH_NAT64

#define BUILD_WITH_NAT64   1

Defined when the NAT64 module is built into the image.

Other modules can test this macro to conditionally enable code that depends on the NAT64 service being present.

Definition at line 54 of file module-macros.h.

◆ NAT64_6LOWPAN_PREFIX_BYTES

#define NAT64_6LOWPAN_PREFIX_BYTES
Value:
0x00, 0x64, 0xff, 0x9b, \
0x00, 0x00, 0x00, 0x00

Upper 64 bits of the NAT64 prefix as 8 bytes.

Defaults to the well-known 64:ff9b::/96 (RFC 6052). Override only for a non-standard prefix; both ends must match.

Definition at line 62 of file nat64-6lowpan.h.

Enumeration Type Documentation

◆ nat64_session_proto

Transport protocol tracked by a NAT64 session.

For NAT64_PROTO_ICMP, the session's ip6_peer_port field stores the ICMPv6 Echo identifier and ip4_remote_port is unused.

Definition at line 64 of file nat64-platform.h.

◆ nat64_tcp_state

TCP connection state within the NAT64 splice proxy.

Enumerator
NAT64_TCP_CONNECTING 

Non-blocking connect() in progress.

NAT64_TCP_ESTABLISHED 

Connection open, data can flow.

NAT64_TCP_CLOSING 

Half-closed (SHUT_WR sent).

Definition at line 74 of file nat64-platform.h.

Function Documentation

◆ errno_to_icmp6_code()

static uint8_t errno_to_icmp6_code ( int err)
static

Map a Linux errno to an ICMPv6 Destination Unreachable code.

Parameters
errA errno value reported by a connect()/send()/recv() failure on an IPv4 socket.
Returns
One of the NAT64_ICMP6_* codes (RFC 4443 §3.1).

Used by the platform layer to translate socket-level failures into the ICMPv6 errors returned to the IoT node via nat64_queue_icmp6_unreach_tuple. Unrecognized errors fall back to "no route to destination".

Definition at line 99 of file nat64-sock.c.

References NAT64_ICMP6_ADDR, NAT64_ICMP6_ADMIN, NAT64_ICMP6_NOROUTE, and NAT64_ICMP6_PORT.

Referenced by nat64_platform_icmp_send(), nat64_platform_tcp_connect(), and nat64_platform_udp_send().

◆ expire_session()

static void expire_session ( struct nat64_session * s)
static

Reap an expired session, notifying its peer if applicable.

Parameters
sThe session whose expiry timer has fired.

For ESTABLISHED TCP sessions this synthesizes a FIN toward the IoT node before tearing down, so the IoT-side TCP layer doesn't keep a zombie connection until its own keepalive fires.

Definition at line 145 of file nat64-sock.c.

References nat64_tcp_closed(), NAT64_TCP_ESTABLISHED, nat64_session::proto, and nat64_session::tcp_state.

◆ handle_icmp6_output()

static int handle_icmp6_output ( const uint8_t * pkt,
const struct v6hdr * ip6,
const uip_ip4addr_t * dst4,
uint16_t payload_len )
static

Translate an outbound ICMPv6 Echo Request to ICMPv4 and send it.

Parameters
pktOriginal IPv6 packet (header + payload).
ip6Parsed IPv6 header (alias for pkt).
dst4Pre-extracted IPv4 destination address.
payload_lenLength of the IPv6 payload (ICMPv6 message).
Returns
1 on success, 0 on parse or send error.

Only Echo Request (type 128) is forwarded — all other ICMPv6 types are link-local control traffic (Neighbor Discovery, MLD, ...) that never traverses NAT64. The translation rewrites the type byte and recomputes the checksum (ICMPv4 has no pseudo-header) before handing the message to the platform layer for delivery on a Linux unprivileged ICMP socket.

Definition at line 474 of file nat64.c.

References ICMP6_ECHO_REQUEST, and nat64_platform_icmp_send().

Referenced by nat64_output().

◆ handle_udp_output()

static int handle_udp_output ( const uint8_t * pkt,
const struct v6hdr * ip6,
const uip_ip4addr_t * dst4,
uint16_t payload_len )
static

Forward an outbound IPv6/UDP datagram to its IPv4 destination.

Parameters
pktOriginal IPv6 packet (header + payload).
ip6Parsed IPv6 header (alias for pkt).
dst4Pre-extracted IPv4 destination address.
payload_lenLength of the IPv6 payload (UDP header + data).
Returns
1 if the packet was forwarded, 0 on a parse or send error.

If the destination port is 53, a private copy of the payload is passed through nat64_dns64_6to4 so the upstream resolver receives an A query rather than the original AAAA query. All other UDP traffic is forwarded verbatim through the platform layer.

Definition at line 416 of file nat64.c.

References nat64_dns64_6to4(), nat64_platform_udp_send(), and UIP_HTONS.

Referenced by nat64_output().

◆ inject_tcp()

static void inject_tcp ( const struct nat64_session * s,
struct tcp_seqstate * ts,
uint8_t flags,
const uint8_t * payload,
uint16_t payload_len )
static

Fabricate and inject an IPv6+TCP segment toward the IoT node.

Parameters
sThe NAT64 session this segment belongs to.
tsPer-session sequence state (provides seq/ack numbers).
flagsTCP flag byte (combination of TCP_SYN/ACK/FIN/PSH/RST).
payloadOptional segment payload, or NULL for header-only.
payload_lenPayload length in bytes, or 0.

Builds the IPv6 and TCP headers in uip_buf, copies the payload, computes the TCP checksum (with IPv6 pseudo-header) and hands the resulting packet to tcpip_input for delivery up the uIP stack. The seqstate's sequence/ack counters are NOT advanced here — the caller is responsible for updating them after the segment is sent.

Definition at line 339 of file nat64-tcp.c.

References flags, nat64_session::ip4_remote, nat64_session::ip4_remote_port, nat64_session::ip6_peer, nat64_session::ip6_peer_port, tcpip_input(), uip_buf, UIP_BUFSIZE, uip_htons(), and uip_len.

Referenced by nat64_tcp_ack_confirmed(), nat64_tcp_closed(), nat64_tcp_established(), nat64_tcp_flush_acks(), and nat64_tcp_send_pending().

◆ ipv4_dst_is_forbidden()

static bool ipv4_dst_is_forbidden ( const uip_ip4addr_t * addr)
static

Reject IPv4 destinations that must not be reached via NAT64.

Parameters
addrCandidate IPv4 destination address.
Returns
true if the destination falls in a special-use range and must be dropped, false if it is a globally routable address.

Covers loopback, private (RFC 1918), CGNAT, link-local, multicast, documentation, benchmarking and other special-use ranges per RFC 5735 / RFC 6890. Forwarding such addresses across the NAT64 gateway would either leak link-local traffic onto the upstream IPv4 network or expose the gateway operator's private IPv4 LAN to the IoT mesh, so the gateway responds with an ICMPv6 Destination Unreachable (Communication Administratively Prohibited) instead.

Definition at line 148 of file nat64.c.

References addr.

Referenced by nat64_output().

◆ nat64_activate()

void nat64_activate ( void )

Initialize the NAT64 gateway.

Called by the platform layer after session state has been set up.

Definition at line 687 of file nat64.c.

References nat64_tcp_init().

Referenced by nat64_platform_init().

◆ nat64_dns64_4to6()

uint16_t nat64_dns64_4to6 ( const uint8_t * ipv4data,
uint16_t ipv4len,
uint8_t * ipv6data,
uint16_t ipv6len,
uint16_t ipv6bufsiz )

Rewrite an incoming DNS response from A to AAAA.

Parameters
ipv4dataOriginal DNS response from the IPv4 server (read-only).
ipv4lenLength of the original response.
ipv6dataOutput buffer for the rewritten response.
ipv6lenLength of the data already copied into ipv6data.
ipv6bufsizTotal size of the ipv6data output buffer.
Returns
New payload length (>= ipv6len due to 4-to-16 byte address growth).

Converts A records to AAAA records by synthesizing IPv6 addresses using the NAT64 prefix. Each A record grows by 12 bytes. Stops translating if the output would exceed ipv6bufsiz.

Definition at line 144 of file nat64-dns64.c.

Referenced by nat64_udp_input().

◆ nat64_dns64_6to4()

void nat64_dns64_6to4 ( uint8_t * data,
uint16_t len )

Rewrite an outgoing DNS query from AAAA to A.

Parameters
dataDNS payload buffer (modified in place).
lenLength of the DNS payload.

Modifies QTYPE fields in-place so that the upstream IPv4 DNS server receives an A query instead of AAAA (RFC 6147).

Definition at line 109 of file nat64-dns64.c.

Referenced by handle_udp_output().

◆ nat64_flush_icmp6()

void nat64_flush_icmp6 ( void )

Drain the queue of pending ICMPv6 errors into the uIP stack.

Called from the platform layer's select-loop set_fd callback, outside the uip_buf processing path, to avoid re-entrancy.

Definition at line 379 of file nat64.c.

References tcpip_input(), uip_buf, UIP_BUFSIZE, and uip_len.

◆ nat64_icmp_input()

void nat64_icmp_input ( struct nat64_session * s,
const uint8_t * icmp_pkt,
uint16_t len )

Inject an ICMPv4 Echo Reply received from an IPv4 host.

Parameters
sThe ICMP session that received the reply.
icmp_pktICMPv4 reply bytes (type 0 + code + checksum + identifier + sequence + data).
lenLength of icmp_pkt in bytes.

Translates the ICMPv4 Echo Reply (type 0) into an ICMPv6 Echo Reply (type 129), preserving the original identifier from the session, and injects it into the uIP stack.

Definition at line 630 of file nat64.c.

References ICMP6_ECHO_REPLY, nat64_session::ip4_remote, nat64_session::ip6_peer, nat64_session::ip6_peer_port, tcpip_input(), uip_buf, UIP_BUFSIZE, and uip_len.

◆ nat64_is_enabled()

bool nat64_is_enabled ( void )

Check whether the NAT64 gateway has been enabled at runtime.

Returns
true if the user passed the platform's NAT64 enable option (e.g., --nat64 on the native border router), false otherwise.

Implemented by each platform layer alongside the option callback that sets the underlying flag.

Definition at line 717 of file nat64-sock.c.

◆ nat64_is_ip64_addr()

bool nat64_is_ip64_addr ( const uip_ip6addr_t * addr)

Check whether an IPv6 address embeds an IPv4 address via the NAT64 prefix.

Parameters
addrThe IPv6 address to check.
Returns
true if the address matches the configured NAT64 prefix.

Definition at line 397 of file nat64.c.

References addr.

◆ nat64_output()

int nat64_output ( const uint8_t * ipv6_pkt,
uint16_t len )

Process an outgoing IPv6 packet destined for an IPv4 host.

Parameters
ipv6_pktPointer to the raw IPv6 packet (header + payload).
lenTotal length of the packet in bytes.
Returns
1 if the packet was handled, 0 otherwise.

Dispatches the packet to the appropriate transport handler (UDP or TCP) based on the IPv6 next-header field. Packets with a NAT64 source address are silently dropped (RFC 6146 Section 3.5).

< Communication administratively prohibited.

Definition at line 518 of file nat64.c.

References handle_icmp6_output(), handle_udp_output(), ipv4_dst_is_forbidden(), NAT64_ICMP6_ADMIN, nat64_queue_icmp6_unreach(), and nat64_tcp_output().

◆ nat64_platform_icmp_send()

int nat64_platform_icmp_send ( const uip_ip4addr_t * dst,
const uip_ip6addr_t * ip6_src,
uint16_t identifier,
const uint8_t * icmp_pkt,
uint16_t icmp_len )

Forward an ICMPv4 Echo Request to an IPv4 destination.

Parameters
dstIPv4 destination address.
ip6_srcIoT node's IPv6 source address.
identifierICMPv6 Echo identifier (host byte order).
icmp_pktICMPv4 Echo Request bytes (type 8 + code + checksum
  • identifier + sequence + data).
icmp_lenLength of icmp_pkt in bytes.
Returns
Number of bytes sent, or -1 on error.

Allocates a session keyed on (ip6_src, identifier, dst) and a Linux unprivileged ICMP socket (SOCK_DGRAM, IPPROTO_ICMP). The session receives matching Echo Replies and forwards them via nat64_icmp_input().

Definition at line 596 of file nat64-sock.c.

References nat64_session::active, errno_to_icmp6_code(), nat64_session::expiry, nat64_session::fd, NAT64_ICMP6_ADMIN, nat64_queue_icmp6_unreach_tuple(), and timer_set().

Referenced by handle_icmp6_output().

◆ nat64_platform_init()

bool nat64_platform_init ( void )

Initialize the platform layer.

Returns
true on success, false on failure.

Allocates the session table and calls nat64_activate().

Definition at line 683 of file nat64-sock.c.

References nat64_session::fd, nat64_activate(), and nat64_tcp_set_isn_secret().

◆ nat64_platform_tcp_abort()

void nat64_platform_tcp_abort ( struct nat64_session * s)

Abort a TCP session by sending RST upstream.

Parameters
sThe session to abort.

Sets SO_LINGER with a zero linger time so that close() emits a TCP RST instead of a graceful FIN, then tears down the session as in nat64_platform_tcp_destroy. Used when the IoT node sends a RST, so the IPv4 server sees an equivalent abort rather than a delayed graceful close.

Definition at line 579 of file nat64-sock.c.

References nat64_session::fd.

Referenced by nat64_tcp_flush_acks(), and nat64_tcp_output().

◆ nat64_platform_tcp_close()

void nat64_platform_tcp_close ( struct nat64_session * s)

Half-close a TCP session (send FIN).

Parameters
sThe session to close.

Definition at line 554 of file nat64-sock.c.

References nat64_session::fd.

Referenced by nat64_tcp_established(), and nat64_tcp_output().

◆ nat64_platform_tcp_connect()

struct nat64_session * nat64_platform_tcp_connect ( const uip_ip4addr_t * dst,
uint16_t dstport,
const uip_ip6addr_t * ip6_src,
uint16_t srcport,
uint32_t peer_isn )

Initiate a TCP connection to an IPv4 server.

Parameters
dstIPv4 destination address.
dstportDestination port (host byte order).
ip6_srcIoT node's IPv6 source address.
srcportSource port (host byte order).
peer_isnThe IoT node's initial sequence number.
Returns
The session, or NULL on failure.

Uses non-blocking connect(). Calls nat64_tcp_established() asynchronously when the connection completes.

Definition at line 463 of file nat64-sock.c.

References errno_to_icmp6_code(), nat64_session::fd, NAT64_ICMP6_ADMIN, nat64_queue_icmp6_unreach_tuple(), NAT64_TCP_CONNECTING, nat64_session::peer_isn, and nat64_session::tcp_state.

Referenced by nat64_tcp_output().

◆ nat64_platform_tcp_destroy()

void nat64_platform_tcp_destroy ( struct nat64_session * s)

Fully tear down a TCP session.

Parameters
sThe session to destroy.

Closes the IPv4 socket, releases the per-session sequence state, and frees the platform-layer session slot. After this call the session pointer is no longer valid. Use this when both sides have FIN'd and the connection is fully closed; for RST/abort semantics use nat64_platform_tcp_abort instead.

Definition at line 569 of file nat64-sock.c.

References nat64_session::fd.

Referenced by nat64_tcp_output().

◆ nat64_platform_tcp_send()

int nat64_platform_tcp_send ( struct nat64_session * s,
const uint8_t * data,
uint16_t len )

Send data on an established TCP session.

Parameters
sThe session (must be in ESTABLISHED state).
dataData to send.
lenData length.
Returns
Number of bytes sent, 0 if would block, or -1 on error.

Definition at line 518 of file nat64-sock.c.

References nat64_session::expiry, nat64_session::fd, NAT64_TCP_ESTABLISHED, nat64_session::tcp_state, and timer_set().

Referenced by nat64_tcp_output().

◆ nat64_platform_udp_send()

int nat64_platform_udp_send ( const uip_ip4addr_t * dst,
uint16_t dstport,
const uip_ip6addr_t * ip6_src,
uint16_t srcport,
const uint8_t * payload,
uint16_t len )

Forward a UDP payload to an IPv4 server.

Parameters
dstIPv4 destination address.
dstportDestination port (host byte order).
ip6_srcIoT node's IPv6 source address (used for session lookup).
srcportSource port (host byte order).
payloadUDP payload bytes.
lenPayload length.
Returns
Number of bytes sent, or -1 on error.

Creates a new session and UDP socket if no matching session exists.

Definition at line 411 of file nat64-sock.c.

References errno_to_icmp6_code(), nat64_session::expiry, nat64_session::fd, NAT64_ICMP6_ADMIN, nat64_queue_icmp6_unreach_tuple(), and timer_set().

Referenced by handle_udp_output().

◆ nat64_queue_icmp6_unreach()

void nat64_queue_icmp6_unreach ( const uint8_t * invoking_pkt,
uint16_t invoking_len,
uint8_t code )

Queue an ICMPv6 Destination Unreachable for delivery to the IoT node.

Parameters
invoking_pktThe original IPv6 packet that triggered the error.
invoking_lenLength of the invoking packet in bytes.
codeICMPv6 Code (NAT64_ICMP6_*).

As much of the invoking packet as fits is embedded in the error, so the IoT node's transport layer can match the error to the right socket.

Definition at line 283 of file nat64.c.

References ICMP6_DST_UNREACH, and uip_htons().

Referenced by nat64_output(), and nat64_queue_icmp6_unreach_tuple().

◆ nat64_queue_icmp6_unreach_tuple()

void nat64_queue_icmp6_unreach_tuple ( const uip_ip6addr_t * ip6_src,
uint16_t src_port,
const uip_ip4addr_t * ip4_dst,
uint16_t dst_port,
uint8_t ipproto,
uint8_t code )

Queue an ICMPv6 Destination Unreachable for a 5-tuple whose connection failed.

Parameters
ip6_srcIoT node's IPv6 address.
src_portIoT node's transport port (host byte order).
ip4_dstIPv4 destination that could not be reached.
dst_portDestination port (host byte order).
ipprotoTransport protocol (6 for TCP, 17 for UDP).
codeICMPv6 Code (NAT64_ICMP6_*).

Used when the original IPv6 packet is no longer available (e.g., asynchronous TCP connect failure). Fabricates a minimal invoking packet from the 5-tuple.

Definition at line 351 of file nat64.c.

References nat64_queue_icmp6_unreach().

Referenced by nat64_platform_icmp_send(), nat64_platform_tcp_connect(), and nat64_platform_udp_send().

◆ nat64_tcp_ack_confirmed()

static void nat64_tcp_ack_confirmed ( struct tcp_seqstate * ts)
static

Promote the in-flight segment to acknowledged and queue what's next.

Parameters
tsThe sequence state whose latest segment has been ACKed.

Advances rxbuf_offset and our_seq past the now-acknowledged bytes, clears the retransmit state, and either sends the next chunk, emits a previously-deferred server FIN, or leaves the session idle.

Definition at line 602 of file nat64-tcp.c.

References inject_tcp(), and nat64_tcp_send_pending().

Referenced by nat64_tcp_output().

◆ nat64_tcp_closed()

void nat64_tcp_closed ( struct nat64_session * s)

Notify that an IPv4 server closed a TCP connection.

Parameters
sThe session that was closed.

Sends a FIN to the IoT node.

Definition at line 715 of file nat64-tcp.c.

References inject_tcp().

Referenced by expire_session().

◆ nat64_tcp_data_in()

void nat64_tcp_data_in ( struct nat64_session * s,
const uint8_t * data,
uint16_t len )

Forward TCP data from an IPv4 server to the IoT node.

Parameters
sThe established TCP session.
dataPointer to the received data.
lenData length in bytes.

Data is buffered per session and delivered in NAT64_TCP_SEGMENT_SIZE (76-byte) ACK-paced segments to fit a single 802.15.4 frame without 6LoWPAN fragmentation.

Definition at line 687 of file nat64-tcp.c.

References nat64_tcp_send_pending().

◆ nat64_tcp_established()

void nat64_tcp_established ( struct nat64_session * s)

Notify that a TCP connection to an IPv4 server completed.

Parameters
sThe session whose connect() succeeded.

Sends a SYN-ACK to the IoT node to complete the three-way handshake.

Definition at line 672 of file nat64-tcp.c.

References inject_tcp(), nat64_platform_tcp_close(), and nat64_session::peer_isn.

◆ nat64_tcp_flush_acks()

void nat64_tcp_flush_acks ( void )

Flush deferred TCP ACKs.

Called from the platform select loop, outside the uip_buf processing path, to avoid re-entrancy with tcpip_input().

Definition at line 629 of file nat64-tcp.c.

References inject_tcp(), nat64_platform_tcp_abort(), timer_expired(), and timer_reset().

◆ nat64_tcp_free_seqstate()

void nat64_tcp_free_seqstate ( const struct nat64_session * s)

Free any TCP sequence state associated with a session.

Parameters
sThe session being closed.

Must be called when a session is closed or expires to prevent stale seqstate from matching if the session slot is reused.

Definition at line 766 of file nat64-tcp.c.

◆ nat64_tcp_has_pending_data()

bool nat64_tcp_has_pending_data ( const struct nat64_session * s)

Check whether a session has buffered data awaiting delivery.

Parameters
sThe session to check.
Returns
true if data is pending, false otherwise.

Used by the platform layer to suppress reading from the IPv4 socket while previous data is still being paced to the IoT node.

Definition at line 752 of file nat64-tcp.c.

◆ nat64_tcp_init()

void nat64_tcp_init ( void )

Initialize the TCP splice proxy.

Clears the per-session sequence number state table.

Definition at line 740 of file nat64-tcp.c.

Referenced by nat64_activate().

◆ nat64_tcp_output()

int nat64_tcp_output ( const uint8_t * pkt,
uint16_t len )

Process an outgoing IPv6+TCP packet from an IoT node.

Parameters
pktPointer to the raw IPv6 packet.
lenTotal packet length in bytes.
Returns
1 if the packet was handled, 0 otherwise.

Handles SYN (initiates connect), data (forwards to server), FIN (half-closes), and RST (aborts).

Definition at line 393 of file nat64-tcp.c.

References nat64_platform_tcp_abort(), nat64_platform_tcp_close(), nat64_platform_tcp_connect(), nat64_platform_tcp_destroy(), nat64_platform_tcp_send(), nat64_tcp_ack_confirmed(), NAT64_TCP_CLOSING, nat64_tcp_send_pending(), and nat64_session::tcp_state.

Referenced by nat64_output().

◆ nat64_tcp_peer_fin_received()

bool nat64_tcp_peer_fin_received ( const struct nat64_session * s)

Check whether the IoT node has already half-closed the session.

Parameters
sThe session to check.
Returns
true if the IoT-side FIN has been received, false otherwise.

Used by the platform layer when the IPv4 server closes its end: if the IoT side had already FIN'd, both halves are now closed and the platform can destroy the session immediately rather than waiting for the idle timer to reap it.

Definition at line 759 of file nat64-tcp.c.

◆ nat64_tcp_send_pending()

static void nat64_tcp_send_pending ( struct tcp_seqstate * ts)
static

Inject the next paced chunk from a session's receive buffer.

Parameters
tsThe sequence state whose rxbuf has data to deliver.

Sends up to NAT64_TCP_SEGMENT_SIZE bytes per call, fitting one 802.15.4 frame after 6LoWPAN compression. Stop-and-wait: only one segment is in flight at a time, with the retransmit timer armed for recovery if the IoT node never ACKs (e.g., radio loss). The sequence number and rxbuf offset are NOT advanced here — that happens in nat64_tcp_ack_confirmed once the ACK arrives.

Definition at line 567 of file nat64-tcp.c.

References inject_tcp(), and timer_set().

Referenced by nat64_tcp_ack_confirmed(), nat64_tcp_data_in(), and nat64_tcp_output().

◆ nat64_tcp_set_isn_secret()

void nat64_tcp_set_isn_secret ( const uint8_t key[16])

Set the 128-bit secret key for TCP ISN generation.

Parameters
key16 bytes of cryptographically random data.

Must be called before any TCP sessions are created. The key is used as input to HMAC-SHA-256 per RFC 6528.

Definition at line 746 of file nat64-tcp.c.

Referenced by nat64_platform_init().

◆ nat64_udp_input()

void nat64_udp_input ( struct nat64_session * s,
const uint8_t * payload,
uint16_t len )

Inject a UDP response from an IPv4 server.

Parameters
sThe session that received the data.
payloadUDP payload bytes (DNS responses are rewritten inline).
lenPayload length in bytes.

Definition at line 567 of file nat64.c.

References nat64_session::ip4_remote, nat64_session::ip4_remote_port, nat64_session::ip6_peer, nat64_session::ip6_peer_port, nat64_dns64_4to6(), tcpip_input(), uip_buf, UIP_BUFSIZE, uip_htons(), and uip_len.