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