Print this page
12315 errors in section 7i of the manual
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/man/man7i/ipnat.7i.man.txt
+++ new/usr/src/man/man7i/ipnat.7i.man.txt
1 1 IPNAT(7I) Ioctl Requests IPNAT(7I)
2 2
3 3 NAME
4 4 ipnat - IP Filter/NAT module interface
5 5
6 6 DESCRIPTION
7 - The ipnat device provides interfaction with the NAT features of the
8 - Solaris IPFilter.
7 + The ipnat device provides interaction with the NAT features of the
8 + illumos IP Filter.
9 9
10 10 APPLICATION PROGRAMMING INTERFACE
11 - The NAT features programming model is a component of the Solaris IP
11 + The NAT features programming model is a component of the illumos IP
12 12 Filter and is accessed via the NAT device file /dev/ipnat. Opening the
13 13 device for reading or writing determines which ioctl calls can be
14 14 successfully made.
15 15
16 16 IOCTLS
17 17 The caller must construct a ipfobj structure when issuing a SIOCGNATL or
18 18 SIOCSTPUT ioctl. The ipfobj structure is then passed to the ioctl call
19 19 and is filled out with ipfo_type set to IPFOBJ_value. IPFOBJ_value
20 20 provides a matching name for the structure, while ipfo_size is set to the
21 21 total size of the structure being passed and ipfo_ptr is set to the
22 22 structure address. The ipfo_rev structure should be set to the current
23 23 value of IPFILTER_VERSION, while ipfo_offset and ipfo_xxxpad should be
24 24 set to 0.
25 25
26 26 /*
27 27 * Structure used with SIOCGNATL/SIOCSTPUT.
28 28 */
29 29
30 30 /*
31 31 * Object structure description. For passing through in ioctls.
32 32 */
33 33 typedef struct ipfobj {
34 34 u_32_t ipfo_rev; /* IPFilter version (IPFILTER_VERSION) */
35 35 u_32_t ipfo_size; /* size of object at ipfo_ptr */
36 36 void *ipfo_ptr; /* pointer to object */
37 37 int ipfo_type; /* type of object being pointed to */
38 38 int ipfo_offset; /* bytes from ipfo_ptr where to start */
39 39 u_char ipfo_xxxpad[32]; /* reserved for future use */
40 40 } ipfobj_t;
41 41
42 42 #define IPFILTER_VERSION 4010901 /* IPFilter version */
43 43 #define IPFOBJ_NATSAVE 8 /* struct nat_save */
44 44 #define IPFOBJ_NATLOOKUP 9 /* struct natlookup */
45 45
46 46 The following ioctl(2) calls may be used to manipulate the ipnat sub-
47 47 system inside of ipf. Note that the ipnat driver only accept calls from
48 48 applications using the same data model as the kernel. In other words,
49 49 64-bit kernels can only accept calls from 64-bit applications. Calls
50 50 from 32-bit applications fail with EINVAL.
51 51
52 52 SIOCSTLCK Set or clear the NAT lock to prevent table updates
53 53 attributable to packet flow-through.
54 54
55 55 SIOCGNATL Search the NAT table for the rdr entry that matches the fields
56 56 in the natlookup structure. The caller must populate the
57 57 structure with the address/port information of the accepted
58 58 TCP connection (nl_inip, nl_inport) and the address/port
59 59 information of the peer (nl_outip, nl_outport). The nl_flags
60 60 field must have the IPN_TCP option set. All other fields must
61 61 be set to 0. If the call succeeds, nl_realip and nl_realport
62 62 are set to the real destination address and port,
63 63 respectively. The nl_inport and nl_outport fields must be in
64 64 host byte order. If IPN_FINDFORWARD is set in nl_flags, a
65 65 check is made to see if it is possible to create an outgoing
66 66 NAT session by checking if a packet coming from (nl_realip,
67 67 nl_realport) and destined for (nl_outip, nl_outport) can be
68 68 translated. If translation is possible, the flag remains set,
69 69 otherwise it is cleared in the structure returned to the
70 70 caller.
71 71
72 72 /*
73 73 * Structure used with SIOCGNATL.
74 74 */
75 75 typedef struct natlookup {
76 76 i6addr_t nl_inipaddr;
77 77 i6addr_t nl_outipaddr;
78 78 i6addr_t nl_realipaddr;
79 79 int nl_v;
80 80 int nl_flags;
81 81 u_short nl_inport;
82 82 u_short nl_outport;
83 83 u_short nl_realport;
84 84 } natlookup_t
85 85
86 86 #define nl_inip nl_inipaddr.in4
87 87 #define nl_outip nl_outipaddr.in4
88 88 #define nl_realip nl_realipaddr.in4
89 89 #define nl_inip6 nl_inipaddr.in6
90 90 #define nl_outip6 nl_outipaddr.in6
91 91 #define nl_realip6 nl_realipaddr.in6
92 92
93 93 /*
94 94 * Accepted values for nl_flags
95 95 */
96 96 #define IPN_TCP 0x00001
97 97 #define IPN_FINDFORWARD 0x400000
98 98
99 99 SIOCSTPUT Move a NAT mapping structure from user space into the kernel.
100 100 This ioctl is used by ipfs(1M) to restore NAT sessions saved
101 101 in /var/db/ipf/ipnat.ipf. The nat_save structure must have
102 102 its ipn_nat and ipn_ipnat structures filled out correctly.
103 103 Fields not assigned a value must be initialised to 0. All
104 104 pointer fields are adjusted, as appropriate, once the
105 105 structure is passed into the kernel and none are preserved.
106 106
107 107 To create a translation, the following fields must be set:
108 108
109 109 Interface name
110 110 The interface name on which the host is to be exited must
111 111 be set in nat_ifnames[0].
112 112
113 113 Local IP address and port number
114 114 The connection's local IP address and port number are
115 115 stored in network byte order using nat_inip/nat_inport.
116 116
117 117 Destination address/port
118 118 The destination address/port are stored in
119 119 nat_oip/nat_oport.
120 120
121 121 Target address/port
122 122 The translation's target address/port is stored in
123 123 nat_outip/nat_outport.
124 124
125 125 The caller must also precalculate the checksum adjustments
126 126 necessary to complete the translation and store those values
127 127 in nat_sumd (delta required for TCP header) and nat_ipsumd
128 128 (delta required for IP header).
129 129
130 130 /*
131 131 * Structures used with SIOCSTPUT.
132 132 */
133 133 typedef struct nat_save {
134 134 void *ipn_next;
135 135 struct nat ipn_nat;
136 136 struct ipnat ipn_ipnat;
137 137 struct frentry ipn_fr;
138 138 int ipn_dsize;
139 139 char ipn_data[4];
140 140 } nat_save_t;
141 141
142 142 typedef struct nat {
143 143 ipfmutex_t nat_lock;
144 144 struct nat *nat_next;
145 145 struct nat **nat_pnext;
146 146 struct nat *nat_hnext[2];
147 147 struct nat **nat_phnext[2];
148 148 struct hostmap *nat_hm;
149 149 void *nat_data;
150 150 struct nat **nat_me;
151 151 struct ipstate *nat_state;
152 152 struct ap_session *nat_aps;
153 153 frentry_t *nat_fr;
154 154 struct ipnat *nat_ptr;
155 155 void *nat_ifps[2];
156 156 void *nat_sync;
157 157 ipftqent_t nat_tqe;
158 158 u_32_t nat_flags;
159 159 u_32_t nat_sumd[2];
160 160 u_32_t nat_ipsumd;
161 161 u_32_t nat_mssclamp;
162 162 i6addr_t nat_inip6;
163 163 i6addr_t nat_outip6;
164 164 i6addr_t nat_oip6;
165 165 U_QUAD_T nat_pkts[2];
166 166 U_QUAD_T nat_bytes[2];
167 167 union {
168 168 udpinfo_t nat_unu;
169 169 tcpinfo_t nat_unt;
170 170 icmpinfo_t nat_uni;
171 171 greinfo_t nat_ugre;
172 172 } nat_un;
173 173 u_short nat_oport;
174 174 u_short nat_use;
175 175 u_char nat_p;
176 176 int nat_dir;
177 177 int nat_ref;
178 178 int nat_hv[2];
179 179 char nat_ifnames[2][LIFNAMSIZ];
180 180 int nat_rev;
181 181 int nat_v;
182 182 } nat_t;
183 183
184 184 #define nat_inip nat_inip6.in4
185 185 #define nat_outip nat_outip6.in4
186 186 #define nat_oip nat_oip6.in4
187 187 #define nat_inport nat_un.nat_unt.ts_sport
188 188 #define nat_outport nat_un.nat_unt.ts_dport
189 189 /*
190 190 * Values for nat_dir
191 191 */
192 192 #define NAT_INBOUND 0
193 193 #define NAT_OUTBOUND 1
194 194 /*
195 195 * Definitions for nat_flags
196 196 */
197 197 #define NAT_TCP 0x0001 /* IPN_TCP */
198 198
199 199 EXAMPLES
200 200 The following example shows how to prepare and use SIOCSTPUT to insert a
201 201 NAT session directly into the table. Note that the usual TCP/IP code is
202 202 omitted is this example.
203 203
204 204 In the code segment below, incoming_fd is the TCP connection file
205 205 descriptor that is accepted as part of the redirect process, while
206 206 remote_fd is the outgoing TCP connection to the remote server being
207 207 translated back to the original IP address/port pair.
208 208
209 209 Note -- The following ipnat headers must be included before you can use
210 210 the code shown in this example:
211 211
212 212 #include <netinet/in.h>
213 213 #include <arpa/inet.h>
214 214 #include <net/if.h>
215 215 #include <netinet/ipl.h>
216 216 #include <netinet/ip_compat.h>
217 217 #include <netinet/ip_fil.h>
218 218 #include <netinet/ip_nat.h>
219 219 #include <string.h>
220 220 #include <fcntl.h>
221 221
222 222 Note -- In the example below, various code fragments have been excluded
223 223 to enhance clarity.
224 224
225 225 int
226 226 translate_connection(int incoming_fd)
227 227 {
228 228 struct sockaddr_in usin;
229 229 struct natlookup nlp;
230 230 struct nat_save ns;
231 231 struct ipfobj obj;
232 232 struct nat *nat;
233 233 int remote_fd;
234 234 int nat_fd;
235 235 int onoff;
236 236
237 237 memset(&ns, 0, sizeof(ns));
238 238 nat = &ns.ipn_nat
239 239
240 240 namelen = sizeof(usin);
241 241 getsockname(remote_fd, (struct sockaddr *)&usin, &namelen);
242 242
243 243 namelen = sizeof(sin);
244 244 getpeername(incoming_fd, (struct sockaddr *) &sin, &namelen);
245 245
246 246 namelen = sizeof(sloc);
247 247 getsockname(incoming_fd, (struct sockaddr *) &sloc, &namelen);
248 248
249 249 bzero((char *) &obi, sizeof(obj));
250 250 obj.ipfo_rev = IPFILTER_VERSION;
251 251 obj.ipfo_size = sizeof(nlp);
252 252 obj.ipfo_ptr = &nip;
253 253 obj.ipfo_type = IPFOBJ_NATLOOKUP;
254 254
255 255 /*
256 256 * Build up the NAT natlookup structure.
257 257 */
258 258 bzero((char *) &nlp, sizeof(nlp));
259 259 nlp.nl_outip = sin.sin_addr;
260 260 nlp.nl_inip = sloc.sin_addr;
261 261 nlp.nl_flags = IPN_TCP;
262 262 nlp.nl_outport = ntohs(sin.sin_port);
263 263 nlp.nl_inport = ntohs(sloc.sin_port);
264 264
265 265 /*
266 266 * Open the NAT device and lookup the mapping pair.
267 267 */
268 268 nat_fd = open(IPNAT_NAME, O_RDWR);
269 269 if (ioctl(nat_fd, SIOCGNATL, &obj) != 0)
270 270 return -1;
271 271
272 272 nat->nat_inip = usin.sin_addr;
273 273 nat->nat_outip = nlp.nl_outip;
274 274 nat->nat_oip = nlp.nl_realip;
275 275
276 276 sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr)) +
277 277 ntohs(usin.sin_port);
278 278 sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)) +
279 279 ntohs(nlp.nl_outport);
280 280 CALC_SUMD(sum1, sum2, sumd);
281 281 nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
282 282 nat->nat_sumd[1] = nat->nat_sumd[0];
283 283
284 284 sum1 = LONG_SUM(ntohl(usin.sin_addr.s_addr));
285 285 sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
286 286 CALC_SUMD(sum1, sum2, sumd);
287 287 nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
288 288
289 289 nat->nat_inport = usin.sin_port;
290 290 nat->nat_outport = nlp.nl_outport;
291 291 nat->nat_oport = nlp.nl_realport;
292 292
293 293 nat->nat_flags = IPN_TCPUDP;
294 294
295 295 /*
296 296 * Prepare the ipfobj structure, accordingly.
297 297 */
298 298 bzero((char *)&obi, sizeof(obj));
299 299 obj.ipfo_rev = IPFILTER_VERSION;
300 300 obj.ipfo_size = sizeof(*nsp);
301 301 obj.ipfo_ptr = nsp;
302 302 obj.ipfo_type = IPFOBJ_NATSAVE;
303 303
304 304 onoff = 1;
305 305 if (ioctl(nat_fd, SIOCSTPUT, &obj) != 0)
306 306 fprintf(stderr, "Error occurred\n");
307 307
308 308 return connect(rem_fd, (struct sockaddr)&usin, sizeof(usin));
309 309 }
310 310
311 311 ERRORS
312 312 EPERM The device has been opened for reading only. To
313 313 succeed, the ioctl call must be opened for both
314 314 reading and writing. The call may be returned if it
315 315 is privileged and the calling process did not assert
316 316 {PRIV_SYS_NET_CONFIG} in the effective set.
317 317
318 318 ENOMEM More memory was allocated than the kernel can provide.
319 319 The call may also be returned if the application
320 320 inserts a NAT entry that exceeds the hash bucket
321 321 chain's maximum length.
322 322
323 323 EFAULT The calling process specified an invalid pointer in
324 324 the ipfobj structure.
325 325
326 326 EINVAL The calling process detected a parameter or field set
↓ open down ↓ |
305 lines elided |
↑ open up ↑ |
327 327 to an unacceptable value.
328 328
329 329 EEXIST The calling process, via SIOCSTPUT, attempted to add a
330 330 NAT entry that already exists in the NAT table.
331 331
332 332 ESRCH The calling process called SIOCSTPUT before setting
333 333 the SI_NEWFR flag and providing a pointer in the
334 334 nat_fr field that cannot be found in the current rule
335 335 set.
336 336
337 - EACESS The calling process issued a SIOCSTPUT before issuing
337 + EACCES The calling process issued a SIOCSTPUT before issuing
338 338 a SIOCSTLCK.
339 339
340 340 INTERFACE STABILITY
341 341 Committed
342 342
343 343 SEE ALSO
344 344 ipfs(1M), ipnat(1M), ioctl(2), attributes(5)
345 345
346 -illumos October 23, 2017 illumos
346 +illumos February 17, 2020 illumos
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX