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