1 '\" te
2 .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved
3 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
4 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
5 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
6 .TH IPNAT 7I "May 22, 2008"
7 .SH NAME
8 ipnat \- IP Filter/NAT module interface
9 .SH DESCRIPTION
10 .sp
11 .LP
12 The \fBipnat\fR device provides interfaction with the NAT features of the
13 Solaris IPFilter.
14 .SH APPLICATION PROGRAMMING INTERFACE
15 .sp
16 .LP
17 The NAT features programming model is a component of the Solaris IP Filter and
18 is accessed via the NAT device file \fB/dev/ipnat\fR. Opening the device for
19 reading or writing determines which ioctl calls can be successfully made.
20 .SH IOCTLS
21 .sp
22 .LP
23 The caller must construct a \fBipfobj\fR structure when issuing a
24 \fBSIOCGNATL\fR or \fBSIOCSTPUT\fR. The \fBipfobj\fR structure is then passed
25 to the ioctl call and is filled out with ipfo_type set to \fBIPFOBJ_value\fR.
26 \fBIPFOBJ_ value\fR provides a matching name for the structure, while ipfo_size
27 is set to the total size of the structure being passed and ipfo_ptr is set to
28 the structure address. The ipfo_rev structure should be set to the current
29 value of IPFILTER_VERSION, while ipfo_offset and ipfo_xxxpad should be set to
30 0.
31 .sp
32 .in +2
33 .nf
34 /*
35 * Structure used with SIOCGNATL/SIOCSTPUT.
36 */
37 /*
38 * Object structure description. For passing through in ioctls.
39 */
40 typedef struct ipfobj {
41 u_32_t ipfo_rev; /* IPFilter version (IPFILTER_VERSION) */
42 u_32_t ipfo_size; /* size of object at ipfo_ptr */
43 void *ipfo_ptr; /* pointer to object */
44 int ipfo_type; /* type of object being pointed to */
45 int ipfo_offset; /* bytes from ipfo_ptr where to start */
46 u_char ipfo_xxxpad[32]; /* reserved for future use */
47 } ipfobj_t;
48
49 #define IPFILTER_VERSION 4010901 /* IPFilter version */
50 #define IPFOBJ_NATSAVE 8 /* struct nat_save */
51 #define IPFOBJ_NATLOOKUP 9 /* struct natlookup */
52 .fi
53 .in -2
54
55 .sp
56 .LP
57 The following ioctl() calls may be used to manipulate the ipnat sub-system
58 inside of ipf. Note that the ipnat driver only accept calls from applications
59 using the same data model as the kernel. In other words, 64-bit kernels can
60 only accept calls from 64-bit applications. Calls from 32-bit applications fail
61 with \fBEINVAL\fR.
62 .sp
63 .ne 2
64 .na
65 \fB\fBSIOCSTLCK\fR\fR
66 .ad
67 .RS 13n
68 Set or clear the NAT lock to prevent table updates attributable to packet
69 flow-through.
70 .RE
71
72 .sp
73 .ne 2
74 .na
75 \fB\fBSIOCGNATL\fR\fR
76 .ad
77 .RS 13n
78 Search the NAT table for the rdr entry that matches the fields in the natlookup
79 structure. The caller must populate the structure with the address/port
80 information of the accepted TCP connection (nl_inip, nl_inport) and the
81 address/port information of the peer (nl_outip, nl_outport). The nl_flags field
82 must have the IPN_TCP option set. All other fields must be set to 0. If the
83 call succeeds, nl_realip and nl_realport are set to the real destination
84 address and port, respectively. The nl_inport and nl_outport fields must be in
85 host byte order.
86 .sp
87 If \fBIPN_FINDFORWARD\fR is set in nl_flags, a check is made to see if it is
88 possible to create an outgoing NAT session by checking if a packet coming from
89 (nl_realip,nl_realport) and destined for (nl_outip,nl_outport) can be
90 translated. If translation is possible, the flag remains set, otherwise it is
91 cleared in the structure returned to the caller.
92 .sp
93 .in +2
94 .nf
95 /*
96 * Structure used with SIOCGNATL.
97 */
98 typedef struct natlookup {
99 i6addr_t nl_inipaddr;
100 i6addr_t nl_outipaddr;
101 i6addr_t nl_realipaddr;
102 int nl_v;
103 int nl_flags;
104 u_short nl_inport;
105 u_short nl_outport;
106 u_short nl_realport;
107 } natlookup_t
108
109 #define nl_inip nl_inipaddr.in4
110 #define nl_outip nl_outipaddr.in4
111 #define nl_realip nl_realipaddr.in4
112 #define nl_inip6 nl_inipaddr.in6
113 #define nl_outip6 nl_outipaddr.in6
114 #define nl_realip6 nl_realipaddr.in6
115
116 /*
117 * Accepted values for nl_flags
118 */
119 #define IPN_TCP 0x00001
120 #define IPN_FINDFORWARD 0x400000
121 .fi
122 .in -2
123
124 .RE
125
126 .sp
127 .ne 2
128 .na
129 \fB\fBSIOCSTPUT\fR\fR
130 .ad
131 .RS 13n
132 Move a NAT mapping structure from user space into the kernel. This ioctl is
133 used by \fBipfs\fR(1M) to restore NAT sessions saved in
134 \fB/var/db/ipf/ipnat.ipf\fR. The nat_save structure must have its ipn_nat and
135 ipn_ipnat structures filled out correctly. Fields not assigned a value must be
136 initialised to 0. All pointer fields are adjusted, as appropriate, once the
137 structure is passed into the kernel and none are preserved.
138 .sp
139 To create a translation, the following fields must be set:
140 .br
141 .in +2
142 Interface name - The interface name on which the host is to be exited must be
143 set in nat_ifnames[0].
144 .in -2
145 .br
146 .in +2
147 Local IP address and port number - The connection's local IP address and port
148 number are stored in network byte order using nat_inip/nat_inport.
149 .in -2
150 .br
151 .in +2
152 Destination address/port - The destination address/port are stored in
153 nat_oip/nat_oport.
154 .in -2
155 .br
156 .in +2
157 Target address/port - The translation's target address/port is stored in
158 nat_outip/nat_outport.
159 .in -2
160 The caller must also precalculate the checksum adjustments necessary to
161 complete the translation and store those values in nat_sumd (delta required for
162 TCP header) and nat_ipsumd (delta required for IP header).
163 .sp
164 .in +2
165 .nf
166 /*
167 * Structures used with SIOCSTPUT.
168 */
169 typedef struct nat_save {
170 void *ipn_next;
171 struct nat ipn_nat;
172 struct ipnat ipn_ipnat;
173 struct frentry ipn_fr;
174 int ipn_dsize;
175 char ipn_data[4];
176 } nat_save_t;
177
178 typedef struct nat {
179 ipfmutex_t nat_lock;
180 struct nat *nat_next;
181 struct nat **nat_pnext;
182 struct nat *nat_hnext[2];
183 struct nat **nat_phnext[2];
184 struct hostmap *nat_hm;
185 void *nat_data;
186 struct nat **nat_me;
187 struct ipstate *nat_state;
188 struct ap_session *nat_aps;
189 frentry_t *nat_fr;
190 struct ipnat *nat_ptr;
191 void *nat_ifps[2];
192 void *nat_sync;
193 ipftqent_t nat_tqe;
194 u_32_t nat_flags;
195 u_32_t nat_sumd[2];
196 u_32_t nat_ipsumd;
197 u_32_t nat_mssclamp;
198 i6addr_t nat_inip6;
199 i6addr_t nat_outip6;
200 i6addr_t nat_oip6;
201 U_QUAD_T nat_pkts[2];
202 U_QUAD_T nat_bytes[2];
203 union {
204 udpinfo_t nat_unu;
205 tcpinfo_t nat_unt;
206 icmpinfo_t nat_uni;
207 greinfo_t nat_ugre;
208 } nat_un;
209 u_short nat_oport;
210 u_short nat_use;
211 u_char nat_p;
212 int nat_dir;
213 int nat_ref;
214 int nat_hv[2];
215 char nat_ifnames[2][LIFNAMSIZ];
216 int nat_rev;
217 int nat_v;
218 } nat_t;
219
220 #define nat_inip nat_inip6.in4
221 #define nat_outip nat_outip6.in4
222 #define nat_oip nat_oip6.in4
223 #define nat_inport nat_un.nat_unt.ts_sport
224 #define nat_outport nat_un.nat_unt.ts_dport
225 /*
226 * Values for nat_dir
227 */
228 #define NAT_INBOUND 0
229 #define NAT_OUTBOUND 1
230 /*
231 * Definitions for nat_flags
232 */
233 #define NAT_TCP 0x0001 /* IPN_TCP */
234 .fi
235 .in -2
236
237 .RE
238
239 .SH EXAMPLES
240 .sp
241 .LP
242 The following example shows how to prepare and use \fBSIOCSTPUT\fR to insert a
243 NAT session directly into the table. Note that the usual TCP/IP code is omitted
244 is this example.
245 .sp
246 .LP
247 In the code segment below, incoming_fd is the TCP connection file descriptor
248 that is accepted as part of the redirect process, while remote_fd is the
249 outgoing TCP connection to the remote server being translated back to the
250 original IP address/port pair.
251 .LP
252 Note -
253 .sp
254 .RS 2
255 The following ipnat headers must be included before you can use the code shown
256 in this example:
257 .sp
258 .in +2
259 .nf
260 #include <netinet/in.h>
261 #include <arpa/inet.h>
262 #include <net/if.h>
263 #include <netinet/ipl.h>
264 #include <netinet/ip_compat.h>
265 #include <netinet/ip_fil.h>
266 #include <netinet/ip_nat.h>
267 #include <string.h>
268 #include <fcntl.h>
269 .fi
270 .in -2
271
272 .RE
273 .LP
274 Note -
275 .sp
276 .RS 2
277 In the example below, various code fragments have been excluded to enhance
278 clarity.
279 .RE
280 .sp
281 .in +2
282 .nf
283 int
284 translate_connection(int incoming_fd)
285 {
286 struct sockaddr_in usin;
287 struct natlookup nlp;
288 struct nat_save ns;
289 struct ipfobj obj;
290 struct nat *nat;
291 int remote_fd;
292 int nat_fd;
293 int onoff;
294
295 memset(&ns, 0, sizeof(ns));
296 nat = &ns.ipn_nat
297
298 namelen = sizeof(usin);
299 getsockname(remote_fd, (struct sockaddr *)&usin, &namelen);
300
301 namelen = sizeof(sin);
302 getpeername(incoming_fd, (struct sockaddr *) &sin, &namelen);
303
304 namelen = sizeof(sloc);
305 getsockname(incoming_fd, (struct sockaddr *) &sloc, &namelen);
346
347 nat->nat_inport = usin.sin_port;
348 nat->nat_outport = nlp.nl_outport;
349 nat->nat_oport = nlp.nl_realport;
350
351 nat->nat_flags = IPN_TCPUDP;
352
353 /*
354 * Prepare the ipfobj structure, accordingly.
355 */
356 bzero((char *)&obi, sizeof(obj));
357 obj.ipfo_rev = IPFILTER_VERSION;
358 obj.ipfo_size = sizeof(*nsp);
359 obj.ipfo_ptr = nsp;
360 obj.ipfo_type = IPFOBJ_NATSAVE;
361
362 onoff = 1;
363 if (ioctl(nat_fd, SIOCSTPUT, &obj) != 0)
364 fprintf(stderr, "Error occurred\en");
365
366 return connect(rem_fd, (struct sockaddr ) &usin, sizeof(usin));
367 }
368 .fi
369 .in -2
370
371 .SH ERRORS
372 .sp
373 .ne 2
374 .na
375 \fBEPERM\fR
376 .ad
377 .RS 10n
378 The device has been opened for reading only. To succeed, the ioctl call must be
379 opened for both reading and writing. The call may be returned if it is
380 privileged and the calling process did not assert {\fBPRIV_SYS_NET_CONFIG\fR}
381 in the effective set.
382 .RE
383
384 .sp
385 .ne 2
386 .na
387 \fBENOMEM\fR
388 .ad
389 .RS 10n
390 More memory was allocated than the kernel can provide. The call may also be
391 returned if the application inserts a NAT entry that exceeds the hash bucket
392 chain's maximum length.
393 .RE
394
395 .sp
396 .ne 2
397 .na
398 \fBEFAULT\fR
399 .ad
400 .RS 10n
401 The calling process specified an invalid pointer in the ipfobj structure.
402 .RE
403
404 .sp
405 .ne 2
406 .na
407 \fBEINVAL\fR
408 .ad
409 .RS 10n
410 The calling process detected a parameter or field set to an unacceptable value.
411 .RE
412
413 .sp
414 .ne 2
415 .na
416 \fBEEXIST\fR
417 .ad
418 .RS 10n
419 The calling process, via \fBSIOCSTPUT\fR, attempted to add a NAT entry that
420 already exists in the NAT table.
421 .RE
422
423 .sp
424 .ne 2
425 .na
426 \fBESRCH\fR
427 .ad
428 .RS 10n
429 The calling process called \fBSIOCSTPUT\fR before setting the SI_NEWFR flag and
430 providing a pointer in the nat_fr field that cannot be found in the current
431 rule set.
432 .RE
433
434 .sp
435 .ne 2
436 .na
437 \fBEACESS\fR
438 .ad
439 .RS 10n
440 The calling process issued a \fBSIOCSTPUT\fR before issuing a SIOCSTLCK.
441 .RE
442
443 .SH ATTRIBUTES
444 .sp
445 .LP
446 See \fBattributes\fR(5) for descriptions of the following attributes:
447 .sp
448
449 .sp
450 .TS
451 box;
452 c | c
453 l | l .
454 ATTRIBUTE TYPE ATTRIBUTE VALUE
455 _
456 Interface Stability Committed
457 .TE
458
459 .SH SEE ALSO
460 .sp
461 .LP
462 \fBipfs\fR(1M), \fBipnat\fR(1M), \fBioctl\fR(2), \fBattributes\fR(5)
|
1 .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved
2 .\" Copyright (c) 2017, Joyent, Inc.
3 .\" The contents of this file are subject to the terms of the
4 .\" Common Development and Distribution License (the "License").
5 .\" You may not use this file except in compliance with the License.
6 .\"
7 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
8 .\" or http://www.opensolaris.org/os/licensing.
9 .\" See the License for the specific language governing permissions
10 .\" and limitations under the License.
11 .\"
12 .\" When distributing Covered Code, include this CDDL HEADER in each
13 .\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
14 .\" If applicable, add the following below this CDDL HEADER, with the
15 .\" fields enclosed by brackets "[]" replaced with your own identifying
16 .\" information: Portions Copyright [yyyy] [name of copyright owner]
17 .Dd October 23, 2017
18 .Dt IPNAT 7I
19 .Os
20 .Sh NAME
21 .Nm ipnat
22 .Nd IP Filter/NAT module interface
23 .Sh DESCRIPTION
24 The
25 .Sy ipnat
26 device provides interfaction with the NAT features of the Solaris IPFilter.
27 .Sh APPLICATION PROGRAMMING INTERFACE
28 The NAT features programming model is a component of the Solaris IP Filter and
29 is accessed via the NAT device file
30 .Pa /dev/ipnat .
31 Opening the device for
32 reading or writing determines which ioctl calls can be successfully made.
33 .Sh IOCTLS
34 The caller must construct a
35 .Vt ipfobj
36 structure when issuing a
37 .Sy SIOCGNATL
38 or
39 SIOCSTPUT
40 ioctl.
41 The
42 .Vt ipfobj
43 structure is then passed
44 to the ioctl call and is filled out with
45 .Fa ipfo_type
46 set to
47 .Dv IPFOBJ_ Ns value .
48 .Dv IPFOBJ_ Ns value
49 provides a matching name for the structure, while
50 .Fa ipfo_size
51 is set to the total size of the structure being passed and
52 .Fa ipfo_ptr
53 is set to the structure address.
54 The
55 .Fa ipfo_rev
56 structure should be set to the current value of
57 .Dv IPFILTER_VERSION ,
58 while
59 .Fa ipfo_offset
60 and
61 .Fa ipfo_xxxpad
62 should be set to 0.
63 .Bd -literal -offset 2n
64 /*
65 * Structure used with SIOCGNATL/SIOCSTPUT.
66 */
67
68 /*
69 * Object structure description. For passing through in ioctls.
70 */
71 typedef struct ipfobj {
72 u_32_t ipfo_rev; /* IPFilter version (IPFILTER_VERSION) */
73 u_32_t ipfo_size; /* size of object at ipfo_ptr */
74 void *ipfo_ptr; /* pointer to object */
75 int ipfo_type; /* type of object being pointed to */
76 int ipfo_offset; /* bytes from ipfo_ptr where to start */
77 u_char ipfo_xxxpad[32]; /* reserved for future use */
78 } ipfobj_t;
79
80 #define IPFILTER_VERSION 4010901 /* IPFilter version */
81 #define IPFOBJ_NATSAVE 8 /* struct nat_save */
82 #define IPFOBJ_NATLOOKUP 9 /* struct natlookup */
83 .Ed
84 .Pp
85 The following
86 .Xr ioctl 2
87 calls may be used to manipulate the ipnat sub-system inside of ipf.
88 Note that the ipnat driver only accept calls from applications
89 using the same data model as the kernel.
90 In other words, 64-bit kernels can only accept calls from 64-bit applications.
91 Calls from 32-bit applications fail
92 with
93 .Er EINVAL .
94 .Bl -tag -width SIOCSTLCK
95 .It Dv SIOCSTLCK
96 Set or clear the NAT lock to prevent table updates attributable to packet
97 flow-through.
98 .It Dv SIOCGNATL
99 Search the NAT table for the rdr entry that matches the fields in the natlookup
100 structure.
101 The caller must populate the structure with the address/port
102 information of the accepted TCP connection
103 .Pq Fa nl_inip , Fa nl_inport
104 and the
105 address/port information of the peer
106 .Pq Fa nl_outip , Fa nl_outport .
107 The
108 .Fa nl_flags
109 field must have the
110 .Dv IPN_TCP
111 option set.
112 All other fields must be set to 0.
113 If the call succeeds,
114 .Fa nl_realip
115 and
116 .Fa nl_realport
117 are set to the real destination address and port, respectively.
118 The
119 .Fa nl_inport
120 and
121 .Fa nl_outport
122 fields must be in host byte order.
123 If
124 .Dv IPN_FINDFORWARD
125 is set in
126 .Fa nl_flags ,
127 a check is made to see if it is
128 possible to create an outgoing NAT session by checking if a packet coming from
129 .Pq Fa nl_realip , Fa nl_realport
130 and destined for
131 .Pq Fa nl_outip , Fa nl_outport
132 can be translated.
133 If translation is possible, the flag remains set, otherwise it is
134 cleared in the structure returned to the caller.
135 .Bd -literal -offset indent
136 /*
137 * Structure used with SIOCGNATL.
138 */
139 typedef struct natlookup {
140 i6addr_t nl_inipaddr;
141 i6addr_t nl_outipaddr;
142 i6addr_t nl_realipaddr;
143 int nl_v;
144 int nl_flags;
145 u_short nl_inport;
146 u_short nl_outport;
147 u_short nl_realport;
148 } natlookup_t
149
150 #define nl_inip nl_inipaddr.in4
151 #define nl_outip nl_outipaddr.in4
152 #define nl_realip nl_realipaddr.in4
153 #define nl_inip6 nl_inipaddr.in6
154 #define nl_outip6 nl_outipaddr.in6
155 #define nl_realip6 nl_realipaddr.in6
156
157 /*
158 * Accepted values for nl_flags
159 */
160 #define IPN_TCP 0x00001
161 #define IPN_FINDFORWARD 0x400000
162 .Ed
163 .It Dv SIOCSTPUT
164 Move a NAT mapping structure from user space into the kernel.
165 This ioctl is used by
166 .Xr ipfs 1M
167 to restore NAT sessions saved in
168 .Pa /var/db/ipf/ipnat.ipf .
169 The
170 .Vt nat_save
171 structure must have its
172 .Fa ipn_nat
173 and
174 .Fa ipn_ipnat
175 structures filled out correctly.
176 Fields not assigned a value must be initialised to 0.
177 All pointer fields are adjusted, as appropriate, once the
178 structure is passed into the kernel and none are preserved.
179 .Pp
180 To create a translation, the following fields must be set:
181 .\" Force item bodies to next line using 2n width
182 .Bl -tag -width 2n
183 .It "Interface name"
184 The interface name on which the host is to be exited must be
185 set in
186 .Fa nat_ifnames[0] .
187 .It "Local IP address and port number"
188 The connection's local IP address and port
189 number are stored in network byte order using
190 .Fa nat_inip Ns / Ns Fa nat_inport .
191 .It "Destination address/port"
192 The destination address/port are stored in
193 .Fa nat_oip Ns / Ns Fa nat_oport .
194 .It "Target address/port"
195 The translation's target address/port is stored in
196 .Fa nat_outip Ns / Ns Fa nat_outport .
197 .El
198 .Pp
199 The caller must also precalculate the checksum adjustments necessary to
200 complete the translation and store those values in
201 .Fa nat_sumd
202 (delta required for TCP header) and
203 .Fa nat_ipsumd
204 (delta required for IP header).
205 .Bd -literal -offset indent
206 /*
207 * Structures used with SIOCSTPUT.
208 */
209 typedef struct nat_save {
210 void *ipn_next;
211 struct nat ipn_nat;
212 struct ipnat ipn_ipnat;
213 struct frentry ipn_fr;
214 int ipn_dsize;
215 char ipn_data[4];
216 } nat_save_t;
217
218 typedef struct nat {
219 ipfmutex_t nat_lock;
220 struct nat *nat_next;
221 struct nat **nat_pnext;
222 struct nat *nat_hnext[2];
223 struct nat **nat_phnext[2];
224 struct hostmap *nat_hm;
225 void *nat_data;
226 struct nat **nat_me;
227 struct ipstate *nat_state;
228 struct ap_session *nat_aps;
229 frentry_t *nat_fr;
230 struct ipnat *nat_ptr;
231 void *nat_ifps[2];
232 void *nat_sync;
233 ipftqent_t nat_tqe;
234 u_32_t nat_flags;
235 u_32_t nat_sumd[2];
236 u_32_t nat_ipsumd;
237 u_32_t nat_mssclamp;
238 i6addr_t nat_inip6;
239 i6addr_t nat_outip6;
240 i6addr_t nat_oip6;
241 U_QUAD_T nat_pkts[2];
242 U_QUAD_T nat_bytes[2];
243 union {
244 udpinfo_t nat_unu;
245 tcpinfo_t nat_unt;
246 icmpinfo_t nat_uni;
247 greinfo_t nat_ugre;
248 } nat_un;
249 u_short nat_oport;
250 u_short nat_use;
251 u_char nat_p;
252 int nat_dir;
253 int nat_ref;
254 int nat_hv[2];
255 char nat_ifnames[2][LIFNAMSIZ];
256 int nat_rev;
257 int nat_v;
258 } nat_t;
259
260 #define nat_inip nat_inip6.in4
261 #define nat_outip nat_outip6.in4
262 #define nat_oip nat_oip6.in4
263 #define nat_inport nat_un.nat_unt.ts_sport
264 #define nat_outport nat_un.nat_unt.ts_dport
265 /*
266 * Values for nat_dir
267 */
268 #define NAT_INBOUND 0
269 #define NAT_OUTBOUND 1
270 /*
271 * Definitions for nat_flags
272 */
273 #define NAT_TCP 0x0001 /* IPN_TCP */
274 .Ed
275 .El
276 .Sh EXAMPLES
277 The following example shows how to prepare and use
278 .Fa SIOCSTPUT
279 to insert a NAT session directly into the table.
280 Note that the usual TCP/IP code is omitted is this example.
281 .Pp
282 In the code segment below,
283 .Fa incoming_fd
284 is the TCP connection file descriptor
285 that is accepted as part of the redirect process, while
286 .Fa remote_fd
287 is the outgoing TCP connection to the remote server being translated back to the
288 original IP address/port pair.
289 .Pp
290 Note \(em
291 The following ipnat headers must be included before you can use the code shown
292 in this example:
293 .Bd -literal -offset 2n
294 #include <netinet/in.h>
295 #include <arpa/inet.h>
296 #include <net/if.h>
297 #include <netinet/ipl.h>
298 #include <netinet/ip_compat.h>
299 #include <netinet/ip_fil.h>
300 #include <netinet/ip_nat.h>
301 #include <string.h>
302 #include <fcntl.h>
303 .Ed
304 .Pp
305 Note \(em
306 In the example below, various code fragments have been excluded to enhance
307 clarity.
308 .Bd -literal -offset 2n
309 int
310 translate_connection(int incoming_fd)
311 {
312 struct sockaddr_in usin;
313 struct natlookup nlp;
314 struct nat_save ns;
315 struct ipfobj obj;
316 struct nat *nat;
317 int remote_fd;
318 int nat_fd;
319 int onoff;
320
321 memset(&ns, 0, sizeof(ns));
322 nat = &ns.ipn_nat
323
324 namelen = sizeof(usin);
325 getsockname(remote_fd, (struct sockaddr *)&usin, &namelen);
326
327 namelen = sizeof(sin);
328 getpeername(incoming_fd, (struct sockaddr *) &sin, &namelen);
329
330 namelen = sizeof(sloc);
331 getsockname(incoming_fd, (struct sockaddr *) &sloc, &namelen);
372
373 nat->nat_inport = usin.sin_port;
374 nat->nat_outport = nlp.nl_outport;
375 nat->nat_oport = nlp.nl_realport;
376
377 nat->nat_flags = IPN_TCPUDP;
378
379 /*
380 * Prepare the ipfobj structure, accordingly.
381 */
382 bzero((char *)&obi, sizeof(obj));
383 obj.ipfo_rev = IPFILTER_VERSION;
384 obj.ipfo_size = sizeof(*nsp);
385 obj.ipfo_ptr = nsp;
386 obj.ipfo_type = IPFOBJ_NATSAVE;
387
388 onoff = 1;
389 if (ioctl(nat_fd, SIOCSTPUT, &obj) != 0)
390 fprintf(stderr, "Error occurred\en");
391
392 return connect(rem_fd, (struct sockaddr)&usin, sizeof(usin));
393 }
394 .Ed
395 .Sh ERRORS
396 .Bl -tag -width Er
397 .It Er EPERM
398 The device has been opened for reading only.
399 To succeed, the ioctl call must be opened for both reading and writing.
400 The call may be returned if it is
401 privileged and the calling process did not assert
402 .Brq Sy PRIV_SYS_NET_CONFIG
403 in the effective set.
404 .It Er ENOMEM
405 More memory was allocated than the kernel can provide.
406 The call may also be returned if the application inserts a NAT entry that
407 exceeds the hash bucket chain's maximum length.
408 .It Er EFAULT
409 The calling process specified an invalid pointer in the ipfobj structure.
410 .It Er EINVAL
411 The calling process detected a parameter or field set to an unacceptable value.
412 .It Er EEXIST
413 The calling process, via
414 .Dv SIOCSTPUT ,
415 attempted to add a NAT entry that already exists in the NAT table.
416 .It Er ESRCH
417 The calling process called
418 .Dv SIOCSTPUT
419 before setting the
420 .Dv SI_NEWFR
421 flag and providing a pointer in the
422 .Fa nat_fr
423 field that cannot be found in the current rule set.
424 .It Er EACESS
425 The calling process issued a
426 .Dv SIOCSTPUT
427 before issuing a
428 .Dv SIOCSTLCK .
429 .El
430 .Sh INTERFACE STABILITY
431 Committed
432 .Sh SEE ALSO
433 .Xr ipfs 1M ,
434 .Xr ipnat 1M ,
435 .Xr ioctl 2 ,
436 .Xr attributes 5
|