Contiki-NG
Loading...
Searching...
No Matches
nat64-platform.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2026, RISE Research Institutes of Sweden AB.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * \addtogroup nat64
33 * @{
34 *
35 * \file
36 * NAT64 platform interface — socket-based.
37 *
38 * Defines the session structure shared between the
39 * protocol-agnostic core and the platform layer, plus the
40 * small set of "send to IPv4" entry points the core invokes
41 * to forward packets out. The session struct is exposed
42 * (rather than opaque) so that nat64.c and nat64-tcp.c can
43 * read the address/port fields directly without accessor
44 * overhead, while the platform layer remains the sole owner
45 * of the file descriptor and connection state.
46 * \author
47 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
48 */
49
50#ifndef NAT64_PLATFORM_H_
51#define NAT64_PLATFORM_H_
52
53#include <stdbool.h>
54#include <stdint.h>
55#include "net/ipv6/uip.h"
56#include "sys/timer.h"
57
58/**
59 * \brief Transport protocol tracked by a NAT64 session.
60 *
61 * For NAT64_PROTO_ICMP, the session's ip6_peer_port field stores the
62 * ICMPv6 Echo identifier and ip4_remote_port is unused.
63 */
65 NAT64_PROTO_NONE,
66 NAT64_PROTO_UDP,
67 NAT64_PROTO_TCP,
68 NAT64_PROTO_ICMP,
69};
70
71/**
72 * \brief TCP connection state within the NAT64 splice proxy.
73 */
75 NAT64_TCP_CONNECTING, /**< Non-blocking connect() in progress. */
76 NAT64_TCP_ESTABLISHED, /**< Connection open, data can flow. */
77 NAT64_TCP_CLOSING, /**< Half-closed (SHUT_WR sent). */
78};
79
80/**
81 * \brief A NAT64 session binding an IoT node's IPv6 flow to an IPv4 socket.
82 */
84 bool active; /**< Session slot in use. */
85 enum nat64_session_proto proto; /**< UDP or TCP. */
86 int fd; /**< IPv4 socket file descriptor. */
87 uip_ip6addr_t ip6_peer; /**< IoT node's IPv6 address. */
88 uint16_t ip6_peer_port; /**< IoT node's transport port. */
89 uip_ip4addr_t ip4_remote; /**< IPv4 server address. */
90 uint16_t ip4_remote_port; /**< IPv4 server port. */
91 uint32_t peer_isn; /**< IoT node's ISN (TCP only). */
92 enum nat64_tcp_state tcp_state; /**< TCP connection state. */
93 struct timer expiry; /**< Session lifetime timer. */
94};
95
96/**
97 * \brief Initialize the platform layer.
98 * \return true on success, false on failure.
99 *
100 * Allocates the session table and calls nat64_activate().
101 */
102bool nat64_platform_init(void);
103
104/**
105 * \brief Check whether the NAT64 gateway has been enabled at runtime.
106 * \return true if the user passed the platform's NAT64 enable option
107 * (e.g., `--nat64` on the native border router), false otherwise.
108 *
109 * Implemented by each platform layer alongside the option callback that
110 * sets the underlying flag.
111 */
112bool nat64_is_enabled(void);
113
114/**
115 * \brief Forward a UDP payload to an IPv4 server.
116 * \param dst IPv4 destination address.
117 * \param dstport Destination port (host byte order).
118 * \param ip6_src IoT node's IPv6 source address (used for session lookup).
119 * \param srcport Source port (host byte order).
120 * \param payload UDP payload bytes.
121 * \param len Payload length.
122 * \return Number of bytes sent, or -1 on error.
123 *
124 * Creates a new session and UDP socket if no matching session exists.
125 */
126int nat64_platform_udp_send(const uip_ip4addr_t *dst, uint16_t dstport,
127 const uip_ip6addr_t *ip6_src, uint16_t srcport,
128 const uint8_t *payload, uint16_t len);
129
130/**
131 * \brief Initiate a TCP connection to an IPv4 server.
132 * \param dst IPv4 destination address.
133 * \param dstport Destination port (host byte order).
134 * \param ip6_src IoT node's IPv6 source address.
135 * \param srcport Source port (host byte order).
136 * \param peer_isn The IoT node's initial sequence number.
137 * \return The session, or NULL on failure.
138 *
139 * Uses non-blocking connect(). Calls nat64_tcp_established()
140 * asynchronously when the connection completes.
141 */
143 const uip_ip4addr_t *dst, uint16_t dstport,
144 const uip_ip6addr_t *ip6_src, uint16_t srcport,
145 uint32_t peer_isn);
146
147/**
148 * \brief Send data on an established TCP session.
149 * \param s The session (must be in ESTABLISHED state).
150 * \param data Data to send.
151 * \param len Data length.
152 * \return Number of bytes sent, 0 if would block, or -1 on error.
153 */
155 const uint8_t *data, uint16_t len);
156
157/**
158 * \brief Half-close a TCP session (send FIN).
159 * \param s The session to close.
160 */
162
163/**
164 * \brief Fully tear down a TCP session.
165 * \param s The session to destroy.
166 *
167 * Closes the IPv4 socket, releases the per-session sequence state, and
168 * frees the platform-layer session slot. After this call the session
169 * pointer is no longer valid. Use this when both sides have FIN'd and
170 * the connection is fully closed; for RST/abort semantics use
171 * ::nat64_platform_tcp_abort instead.
172 */
174
175/**
176 * \brief Abort a TCP session by sending RST upstream.
177 * \param s The session to abort.
178 *
179 * Sets SO_LINGER with a zero linger time so that close() emits a TCP
180 * RST instead of a graceful FIN, then tears down the session as in
181 * ::nat64_platform_tcp_destroy. Used when the IoT node sends a RST,
182 * so the IPv4 server sees an equivalent abort rather than a delayed
183 * graceful close.
184 */
186
187/**
188 * \brief Forward an ICMPv4 Echo Request to an IPv4 destination.
189 * \param dst IPv4 destination address.
190 * \param ip6_src IoT node's IPv6 source address.
191 * \param identifier ICMPv6 Echo identifier (host byte order).
192 * \param icmp_pkt ICMPv4 Echo Request bytes (type 8 + code + checksum
193 * + identifier + sequence + data).
194 * \param icmp_len Length of icmp_pkt in bytes.
195 * \return Number of bytes sent, or -1 on error.
196 *
197 * Allocates a session keyed on (ip6_src, identifier, dst) and a
198 * Linux unprivileged ICMP socket (SOCK_DGRAM, IPPROTO_ICMP). The
199 * session receives matching Echo Replies and forwards them via
200 * nat64_icmp_input().
201 */
203 const uip_ip6addr_t *ip6_src,
204 uint16_t identifier,
205 const uint8_t *icmp_pkt, uint16_t icmp_len);
206
207/** @} */
208
209#endif /* NAT64_PLATFORM_H_ */
void nat64_platform_tcp_destroy(struct nat64_session *s)
Fully tear down a TCP session.
Definition nat64-sock.c:569
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.
Definition nat64-sock.c:411
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.
Definition nat64-sock.c:596
nat64_session_proto
Transport protocol tracked by a NAT64 session.
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.
Definition nat64-sock.c:463
void nat64_platform_tcp_close(struct nat64_session *s)
Half-close a TCP session (send FIN).
Definition nat64-sock.c:554
bool nat64_platform_init(void)
Initialize the platform layer.
Definition nat64-sock.c:683
void nat64_platform_tcp_abort(struct nat64_session *s)
Abort a TCP session by sending RST upstream.
Definition nat64-sock.c:579
int nat64_platform_tcp_send(struct nat64_session *s, const uint8_t *data, uint16_t len)
Send data on an established TCP session.
Definition nat64-sock.c:518
bool nat64_is_enabled(void)
Check whether the NAT64 gateway has been enabled at runtime.
Definition nat64-sock.c:717
nat64_tcp_state
TCP connection state within the NAT64 splice proxy.
@ NAT64_TCP_ESTABLISHED
Connection open, data can flow.
@ NAT64_TCP_CONNECTING
Non-blocking connect() in progress.
@ NAT64_TCP_CLOSING
Half-closed (SHUT_WR sent).
A NAT64 session binding an IoT node's IPv6 flow to an IPv4 socket.
bool active
Session slot in use.
uint16_t ip4_remote_port
IPv4 server port.
struct timer expiry
Session lifetime timer.
int fd
IPv4 socket file descriptor.
uip_ip6addr_t ip6_peer
IoT node's IPv6 address.
enum nat64_session_proto proto
UDP or TCP.
enum nat64_tcp_state tcp_state
TCP connection state.
uint32_t peer_isn
IoT node's ISN (TCP only).
uip_ip4addr_t ip4_remote
IPv4 server address.
uint16_t ip6_peer_port
IoT node's transport port.
A timer.
Definition timer.h:84
Timer library header file.
Header file for the uIP TCP/IP stack.
Representation of an IP address.
Definition uip.h:95