Print this page
10522 Convert ipnat(7I) to mandoc
   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