Go to main content

man pages section 4: File Formats

Exit Print View

Updated: July 2017



ipnat, ipnat.conf - IP NAT file format




The ipnat or ipnat.conf configuration files are associated with the Solaris IP Filter feature. See ipfilter(5).

The format for files accepted by ipnat is described by the following grammar:

ipmap :: = mapblock | redir | map .

map ::= mapit ifname ipmask "->" dstipmask [ mapport | mapproxy ] \
map ::= mapit ifname fromto "->" dstipmask [ mapport ] mapoptions.
mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] \
redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport \
           rdroptions .

dport ::= "port" port-number [ "-" port-number ] .
ports ::= "ports" numports | "auto" .
rdrport ::= "port" port-number .
mapit ::= "map" | "bimap" .
fromto ::= "from" object "to" object .
ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
dstipmask ::= ipmask | "range" ip "-" ip .
mapport ::= "portmap" tcpudp portspec .
mapoptions ::= [ tcpudp ] [ "frag" ] [ age ] [ clamp ] [ mapproxy ] .
rdroptions ::= rdrproto [ rr ] [ "frag" ] [ age ] [ clamp ] \
               [ rdrproxy ] .

object :: = addr [ port-comp | port-range ] .
addr :: = "any" | nummask | host-name [ "mask" ipaddr | "mask" \
           hexnumber ] .
port-comp :: = "port" compare port-number .
port-range :: = "port" port-number range port-number .
rdrproto ::= tcpudp | protocol .

rr ::= "round-robin" .
age ::= "age" decnumber [ "/" decnumber ] .
clamp ::= "mssclamp" decnumber .
tcpudp ::= "tcp/udp" | protocol .
mapproxy ::= "proxy" "port" port proxy-name '/' protocol
rdrproxy ::= "proxy" proxy-name .

protocol ::= protocol-name | decnumber .
nummask ::= host-name [ "/" decnumber ] .
portspec ::= "auto" | port-number ":" port-number .
port ::= port-number | port-name .
port-number ::= number { numbers } .
ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers .

numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .

For standard NAT functionality, a rule should start with map and then proceed to specify the interface for which outgoing packets will have their source address rewritten.

Packets that will be rewritten can only be selected by matching the original source address. When specifying an address for matching, a netmask must be specified with the IP address.

The address selected for replacing the original is chosen from an IP address/netmask pair. A netmask of all 1's, indicating a hostname, is valid. A netmask of thirty-one 1's ( is considered invalid, because there is no space for allocating host IP addresses after consideration for broadcast and network addresses.

When remapping TCP and UDP packets, it is also possible to change the source port number. Either TCP or UDP or both can be selected by each rule, with a range of port numbers to remap into given as port-number:port-number.


The following commands are recognized by IP Filter's NAT code:


Used for mapping one address or network to another in an unregulated round-robin fashion.


Used for redirecting packets to one IP address and port pair to another.


Used for setting up bidirectional NAT between an external IP address and an internal IP address.


Sets up static IP-address-based translation, based on an algorithm to squeeze the addresses to be translated into the destination range.


For basic NAT and redirection of packets, the address subject to change is used along with its protocol to check if a packet should be altered. The packet matching part of the rule is to the left of the symbol in each rule.

The IPFilter software allows for complex matching of packets. In place of the address which is to be translated, an IP address and port number comparison can be made using the same expressions available with ipf. A simple NAT rule could be written as:

map de0 ->
map de0 fec0:1::/64 -> fec0:2::2/128

or as

map de0 from to any ->
map de0 from fec0:1::/64 to any -> fec0:2::2/128

As is true of all NAT rules, you can compare against only IP address and port numbers. In addition, you cannot specify both IPv4 and IPv6 addresses in the same rule.


To the right of the is the address and port specification that will be written into the packet, provided it has already successfully matched the prior constraints. The case of redirections (rdr) is the simplest: the new destination address is that specified in the rule. For map rules, the destination address will be one for which the tuple combining the new source and destination is known to be unique.

If the packet is either a TCP or UDP packet, the destination and source ports enter into the comparison also. If the tuple already exists, the IP Filter software increments the port number first, within the available range specified by portmap, and, if there is no unique tuple, the source address is incremented within the specified netmask. If a unique tuple cannot be determined, then the packet will not be translated.

The map-block is more limited in how it searches for a new, free, and unique tuple, in that it will use an algorithm to determine what the new source address should be, staying within the range of available ports. The IP address is never changed, nor does the port number ever exceed its allotted range.


ICMP messages can be divided into two groups, errors and queries. ICMP errors are generated as a response to another IP packet. IP Filter will take care that ICMP errors that are the response of a NAT-ed IP packet are handled properly.

For four types of ICMP queries (echo request, timestamp request, information request and address mask request), IP Filter supports an additional mapping called “ICMP id mapping”. These four types of ICMP queries use a unique identifier called the ICMP id. This id is set by the process sending the ICMP query and is usually equal to the process id. The receiver of the ICMP query will use the same id in its response, thus enabling the sender to recognize that the incoming ICMP reply is intended for him and is an answer to a query that he made. The ICMP id mapping feature modifies these ICMP ids in a way identical to the modification performed by portmap for TCP or UDP.

When using the ICMP id mapping feature, you do not need an IP address per host behind the NAT box that wants to perform ICMP queries. The two numbers that follow the icmpidmap keyword are the first and the last icmp id numbers that can be used. There is one important caveat: if you map to an IP address that belongs to the NAT box itself (notably if you have only a single public IP address), then you must ensure that the NAT box does not use the icmpidmap range that you specified in the map rule. Since the ICMP id is usually the process id, it is wise to restrict the largest permittable process id (PID) on your operating system to a value such as 63999 and use the range 64000:65535 for ICMP id mapping.

Kernel Proxies

The IP Filter software comes with a few, simple, proxies built into the code that is loaded into the kernel to allow secondary channels to be opened without forcing the packets through a user program. Kernel proxies are not supported for IPv6 NAT-ing.

Transparent Proxies

True transparent proxying should be performed using the redirect (rdr) rules directing ports to localhost (, with the proxy program doing a lookup through /dev/ipnat to determine the real source and address of the connection.

Load Balancing

Two options for use with rdr are available to support primitive, round-robin-based load balancing. The first option allows for a rdr to specify a second destination, as follows:

rdr le0 port 80 ->, port 80 tcp
rdr net1 port 80 ->, port 80 tcp

The preceding would send alternate connections to either or In scenarios where the load is being spread among a larger set of servers, you can use:

rdr le0 port 80 ->, port 80 tcp \

rdr le0 port 80 -> port 80 tcp round-robin
round-robin 1

In this case, a connection will be redirected to, then, and then before going back to In the above example, the trailing 1 is considered the round-robin id. Supplying the id number forces the round-robin rules with same id to act together, and prevents other rules that match the same packets (whether or not they are part of any load balancing) from inadvertently impacting the round-robin operation for the specific group of rules.


Example 1 Using the map Command

The following are variations of the map command.

To change IP addresses used internally from network 10 into an ISP-provided 8-bit subnet at through the ppp0 interface, use the following:

map ppp0 ->

An obvious problem is that you are trying to squeeze over sixteen million IP addresses into a 254-address space. To increase the scope, remapping for TCP and/or UDP, port remapping can be used, as follows:

map ppp0 -> portmap tcp/udp 1025:65000

The preceding falls only 527,566 addresses short of the space available in network 10. If we combine these rules, they would need to be specified as follows:

map ppp0 -> portmap tcp/udp 1025:65000
map ppp0 ->

...so that all TCP/UDP packets were port mapped and only other protocols, such as ICMP, have their IP address changed. In some instaces, it is more appropriate to use the keyword auto in place of an actual range of port numbers if you want to guarantee simultaneous access to all within the given range. However, in the preceding case, it would default to one port per IP address, because you need to squeeze 24 bits of address space into eight bits. A good example of how auto is used is:

map ppp0 -> portmap tcp/udp auto

This would result in each IP address being given a small range of ports to use (252). The problem here is that the map directive tells the NAT code to use the next address/port pair available for an outgoing connection, resulting in no easily discernible relation between external addresses/ports and internal ones. This is overcome by using map-block as follows:

map-block ppp0 -> ports auto

For example, this would result in being mapped to with each address, from to having 252 ports of its own. As distinguished from the preceding use of map, if, for some reason, the user of (say) wanted 260 simultaneous connections going out, he would be limited to 252 with map-block but would just move on to the next IP address with the map command.

Example 2 Mapping from Class B Network to Single Address

The following directive maps from a class B network to a single address.

map de0 ->

An equivalent directive is:

map de0 from to any ->



Location of rules file that is read upon startup of IP Filter feature.

  • /dev/ipnat

  • /etc/services

  • /etc/hosts


See attributes(5) for a description of the following attributes:

Interface Stability

See Also

ipf(1M), ipnat(1M), ipf(4), hosts(4), attributes(5), ipfilter(5)

Managing IP Quality of Service in Oracle Solaris 11.3