IP(3) IP(3)
NAME
ip, esp, gre, icmp, icmpv6, ipmux, rudp, tcp, udp, il -
network protocols over IP
SYNOPSIS
bind -a #Ispec /net /net/icmp
/net/icmpv6
/net/ipifc /net/ipmux
/net/ipifc/clone /net/rudp
/net/ipifc/stats /net/tcp
/net/ipifc/n /net/udp
/net/ipifc/n/status /net/il
/net/ipifc/n/ctl
... /net/tcp/clone
/net/arp /net/tcp/stats
/net/bootp /net/tcp/n
/net/iproute /net/tcp/n/data
/net/ipselftab /net/tcp/n/ctl
/net/log /net/tcp/n/local
/net/ndb /net/tcp/n/remote
/net/tcp/n/status
/net/esp /net/tcp/n/listen
/net/gre ...
DESCRIPTION
The ip device provides the interface to Internet Protocol
stacks. Spec is an integer starting from 0 identifying a
stack. Each stack implements IPv4 and IPv6. Each stack is
independent of all others: the only information transfer
between them is via programs that mount multiple stacks.
Normally a system uses only one stack. However multiple
stacks can be used for debugging new IP networks or imple-
menting firewalls or proxy services.
All addresses used are 16-byte IPv6 addresses. IPv4
addresses are a subset of the IPv6 addresses and both stan-
dard ASCII formats are accepted. In binary representation,
all v4 addresses start with the 12 bytes, in hex:
00 00 00 00 00 00 00 00 00 00 ff ff
Configuring interfaces
Each stack may have multiple interfaces and each interface
may have multiple addresses. The /net/ipifc directory con-
tains a clone file, a stats file, and numbered subdirecto-
ries for each physical interface.
Opening the clone file reserves an interface. The file
descriptor returned from the open(2) will point to the con-
trol file, ctl, of the newly allocated interface. Reading
ctl returns a text string representing the number of the
Page 1 Plan 9 (printed 11/17/25)
IP(3) IP(3)
interface. Writing ctl alters aspects of the interface.
The possible ctl messages are those described under Protocol
directories below and these:
bind ether path
Treat the device mounted at path as an Ether-
net medium carrying IP and ARP packets and
associate it with this interface. The kernel
will dial(2) path!0x800, path!0x86DD and
path!0x806 and use the three connections for
IPv4, IPv6 and ARP respectively.
bind pkt Treat this interface as a packet interface.
Assume a user program will read and write the
data file to receive and transmit IP packets
to the kernel. This is used by programs such
as ppp(8) to mediate IP packet transfer
between the kernel and a PPP encoded device.
bind netdev path
Treat this interface as a packet interface.
The kernel will open path and read and write
the resulting file descriptor to receive and
transmit IP packets.
bind loopback Treat this interface as a local loopback.
Anything written to it will be looped back.
unbind Disassociate the physical device from an IP
interface.
add local mask remote mtu proxy|trans
try local mask remote mtu proxy|trans
Add a local IP address to the interface. Try
adds the local address as a tentative address
if it's an IPv6 address. The mask, remote,
mtu, proxy, and (Reg.)arguments are all
optional. The default mask is the class mask
for the local address. The default remote
address is local ANDed with mask. The default
mtu (maximum transmission unit) is 1514 for
Ethernet and 4096 for packet media. The mtu
is the size in bytes of the largest packet
that this interface can send. Specifying a
mtu of 0 will use the default. Proxy, if
specified, means that this machine should
answer ARP requests for the remote address.
Ppp(8) does this to make remote machines
appear to be connected to the local Ethernet.
The trans argument enables source address
translation for packets routed to the
Page 2 Plan 9 (printed 11/17/25)
IP(3) IP(3)
interface. Adding the special null-address
0.0.0.0 or :: in local to a interface makes
the ip stack accept all incoming connections
regardless of the destination IP address.
This is used temporarily by ipconfig(8) to
accept DHCP answers when no IP address has
been assigned yet. This can also be used to
implement a NAT gateway by accepting all
incoming connections and proxying them with
trampoline(8) to a different ip stack.
del local mask Delete a local IP address from an interface.
mtu n Set the maximum transfer unit for this device
to n. The mtu is the maximum size of the
packet including any medium-specific headers.
speed n Set the maximum transmit speed in bits per
second.
delay n Set the maximum burst delay in milliseconds.
(Default is 40ms) When speed has been set and
packets in flight exceed the maximum burst
delay then packets send on the interface are
discarded until the load drops below the max-
imum.
iprouting n Allow (n is missing or non-zero) or disallow
(n is 0) forwarding packets between this
interface and others.
reflect n When forwarding, allow packets from this
interface to be echoed back on the same
interface.
reassemble n Reassemble IP fragments before forwarding to
this interface
add6 v6addr pfx-len [onlink auto validlt preflt]
Add the local IPv6 address v6addr with prefix
length pfx-len to this interface. See RFC
2461 §6.2.1 for more detail. The remaining
arguments are optional:
onlink flag: address is `on-link'
auto flag: autonomous
validlt valid life-time in seconds
preflt preferred life-time in seconds
del6 Delete local IPv6 addresses that have expired
ther valid life-time.
Page 3 Plan 9 (printed 11/17/25)
IP(3) IP(3)
ra6 keyword value ...
Set IPv6 router advertisement (RA) parameter
keyword's value. Known keywords and the mean-
ings of their values follow. See RFC 2461
§6.2.1 for more detail. Flags are true iff
non-zero.
recvra flag: receive and process RAs.
sendra flag: generate and send RAs.
mflag flag: ``Managed address configura-
tion'', goes into RAs.
oflag flag: ``Other stateful configura-
tion'', goes into RAs.
maxraint ``maximum time allowed between
sending unsolicited multicast''
RAs from the interface, in ms.
minraint ``minimum time allowed between
sending unsolicited multicast''
RAs from the interface, in ms.
linkmtu ``value to be placed in MTU
options sent by the router.''
Zero indicates none.
reachtime sets the Reachable Time field in
RAs sent by the router. ``Zero
means unspecified (by this
router).''
rxmitra sets the Retrans Timer field in
RAs sent by the router. ``Zero
means unspecified (by this
router).''
ttl default value of the Cur Hop Limit
field in RAs sent by the router.
Should be set to the ``current
diameter of the Internet.''
``Zero means unspecified (by this
router).''
routerlt sets the Router Lifetime field of
RAs sent from the interface, in
seconds. Zero means the router is
not to be used as a default
router.
Reading the interface's status file returns information
about the interface. The first line is composed of white-
space-separated fields, the first two fields are: device and
maxmtu. Subsequent lines list the ip addresses assigned to
that inferface. The colums are: ip address, network mask,
network address and valid/preferred life times in millisec-
onds. See readipifc in ip(2).
Routing
The file iproute controls information about IP routing.
Page 4 Plan 9 (printed 11/17/25)
IP(3) IP(3)
When read, it returns one line per routing entry. Each line
contains eight white-space-separated fields: target address,
target mask, address of next hop, flags, tag, interface num-
ber, source address, source mask. The entry used for rout-
ing an IP packet is the one with the longest destination and
source mask for which destination address ANDed with target
mask equals the target and also the source ANDed with the
source mask equals the source address. The one-character
flags are:
4 IPv4 route
6 IPv6 route
i local interface
b broadcast address
u local unicast address
m multicast route
p point-to-point route
y proxy ARP for this route
t network source address translation
The tag is an arbitrary, up to 4 character, string. It is
normally used to indicate what routing protocol originated
the route.
Writing to /net/iproute changes the route table. The mes-
sages are:
flush tag Remove routes of the specified tag, or all
routes if tag is omitted.
tag string Associate the tag, string, with all subsequent
routes added via this file descriptor.
add target mask nexthop
add target mask nexthop interface
add target mask nexthop source smask
add target mask nexthop interface source smask
add target mask nexthop flags interface source smask
add target mask nexthop flags tag interface source smask.
Add the route to the table. If one already
exists with the same target and mask, replace
it. The destination interface can be specified
as either the interface's /net/ipifc/n directory
number, a local IP address on the desired inter-
face, its bound device name or as - when unspec-
ified, in which case the interface will be
Page 5 Plan 9 (printed 11/17/25)
IP(3) IP(3)
choosen based on the source and nexthop.
del target mask
del target mask nexthop
del target mask source smask
del target mask nexthop source smask
del target mask nexthop interface source smask
del target mask nexthop flags interface source smask
del target mask nexthop flags tag interface source smask
Delete the matching route.
Address resolution
The file /net/arp controls information about address resolu-
tion. The kernel automatically updates the v4 ARP and v6
Neighbour Discovery information for Ethernet interfaces.
When read, the file returns one line per address containing
the type of medium, the status of the entry (OK, WAIT), the
IP address, the medium address and the IP address of the
interface where the entry is valid. Writing to /net/arp
administers the ARP information. The control messages are:
add type IP-addr Media-addr Interface-IP-addr
Add an entry or replace an existing one for
the same IP address. The optional interface IP
address specifies the interface where the ARP
entry will be valid. This is needed for IPv6
link local addresses.
del IP-addr Delete an individual entry.
flush Remove all entries.
garp IP-addr Send a gratious ARP response for the specified
IP address.
ARP entries do not time out. The ARP table is a cache with
an LRU replacement policy. The IP stack listens for all ARP
requests and, if the requester is in the table, the entry is
updated. Also, whenever a new address is configured onto an
Ethernet, an ARP request is sent to help update the table on
other systems.
Currently, the only medium type is ether.
Page 6 Plan 9 (printed 11/17/25)
IP(3) IP(3)
Debugging and stack information
If any process is holding /net/log open, the IP stack queues
debugging information to it. This is intended primarily for
debugging the IP stack. The information provided is
implementation-defined; see the source for details. Gener-
ally, what is returned is error messages about bad packets.
Writing to /net/log controls debugging. The control mes-
sages are:
set arglist Arglist is a space-separated list of items
for which to enable debugging. The possible
items are: ppp, ip, fs, tcp, il, icmp, udp,
compress, ilmsg, gre, tcpwin, tcprxmt,
udpmsg, ipmsg, and esp.
clear arglist Arglist is a space-separated list of items
for which to disable debugging.
only addr If addr is non-zero, restrict debugging to
only those packets whose source or destina-
tion is that address.
The file /net/ndb can be read or written by programs. It is
normally used by ipconfig(8) to leave configuration informa-
tion for other programs such as dns and cs (see ndb(8)).
/net/ndb may contain up to 1024 bytes.
The file /net/ipselftab is a read-only file containing all
the IP addresses considered local. Each line in the file
contains three white-space-separated fields: IP address,
usage count, and flags. The usage count is the number of
interfaces to which the address applies. The flags are the
same as for routing entries.
Protocol directories
The ip device supports IP as well as several protocols that
run over it: TCP, UDP, RUDP, ICMP, IL, GRE, and ESP. TCP
and UDP provide the standard Internet protocols for reliable
stream and unreliable datagram communication. RUDP is a
locally-developed reliable datagram protocol based on UDP.
ICMP is IP's catch-all control protocol used to send low
level error messages and to implement ping(8). GRE is a gen-
eral encapsulation protocol. ESP is the encapsulation pro-
tocol for IPsec. IL provides a reliable datagram service
for communication between Plan 9 machines but is now depre-
cated.
Each protocol is a subdirectory of the IP stack. The top
level directory of each protocol contains a clone file, a
stats file, and subdirectories numbered from zero to the
Page 7 Plan 9 (printed 11/17/25)
IP(3) IP(3)
number of connections opened for this protocol.
Opening the clone file reserves a connection. The file
descriptor returned from the open(2) will point to the con-
trol file, ctl, of the newly allocated connection. Reading
ctl returns a text string representing the number of the
connection. Connections may be used either to listen for
incoming calls or to initiate calls to other machines.
A connection is controlled by writing text strings to the
associated ctl file. After a connection has been estab-
lished data may be read from and written to data. A connec-
tion can be actively established using the connect message
(see also dial(2)). A connection can be established pas-
sively by first using an announce message (see dial(2)) to
bind to a local port and then opening the listen file (see
dial(2)) to receive incoming calls.
The following control messages are supported:
connect ip-address!port!r local
Establish a connection to the remote ip-address
and port. If local is specified, it is used as
the local port number. If local is not speci-
fied but !r is, the system will allocate a
restricted port number (less than 1024) for the
connection to allow communication with Unix
login and exec services. Otherwise a free port
number starting at 5000 is chosen. The connect
fails if the combination of local and remote
address/port pairs are already assigned to
another port.
announce [ip-address!]port
Set the local IP address and port number and
accept calls there. If ip-address is left out,
accept calls on any address. If port is 0, a
port is automatically choosen that is not yet
announced. If the address is `*', accept calls
on any address. If port is `*', accept calls
on any port. If port is `*', and the address
is left out, accept calls on any address and
port. Announce fails if the connection is
already announced.
bind [ip-address!]port
Set the local IP address and port number like
for a server connection similar to the announce
command. If ip-address is left out, an address
is automatically selected. If port is 0, a
port is automatically choosen that is not yet
Page 8 Plan 9 (printed 11/17/25)
IP(3) IP(3)
announced. This command has no actual effect,
beyond remembering the parameters and possibly
selecting an unused port. The commands
announce and connect reset both the local
address and the port according to their own
parameters. This command also does not reserve
the IP address and port, another connection can
use them, even while they are registered in a
connection by this command. This exists to
support emulation of BSD sockets by the APE
libraries (see pcc(1)) and is not otherwise
used.
ttl n Set the time to live IP field in outgoing pack-
ets to n.
tos n Set the service type IP field in outgoing pack-
ets to n.
ignoreadvice Don't break (UDP) connections because of ICMP
errors.
addmulti ifc-ip [ mcast-ip ]
Treat ifc-ip on this multicast interface as a
local address. If mcast-ip is present, use it
as the interface's multicast address.
delmulti ip Delete the address ip from this multicast
interface.
Port numbers must be in the range 1 to 32767.
Several files report the status of a connection. The remote
and local files contain the IP address and port number for
the remote and local side of the connection. The status
file contains protocol-dependent information to help debug
network connections. On receiving and error or EOF reading
or writing the data file, the err file contains the reason
for error.
A process may accept incoming connections by open(2)ing the
listen file. The open will block until a new connection
request arrives. Then open will return an open file
descriptor which points to the control file of the newly
accepted connection. This procedure will accept all calls
for the given protocol. See dial(2).
TCP
TCP connections are reliable point-to-point byte streams;
there are no message delimiters. A connection is determined
by the address and port numbers of the two ends. TCP ctl
files support the following additional messages:
Page 9 Plan 9 (printed 11/17/25)
IP(3) IP(3)
hangup close down this TCP connection
close graceful hangup
keepalive n turn on keep alive messages. N, if given, is
the milliseconds between keepalives (default
120000).
checksum n emit TCP checksums of zero if n is zero; other-
wise, and by default, TCP checksums are com-
puted and sent normally.
UDP
UDP connections carry unreliable and unordered datagrams. A
read from data will return the next datagram, discarding
anything that doesn't fit in the read buffer. A write is
sent as a single datagram.
By default, a UDP connection is a point-to-point link.
Either a connect establishes a local and remote address/port
pair or after an announce, each datagram coming from a dif-
ferent remote address/port pair establishes a new incoming
connection. However, many-to-one semantics is also possi-
ble.
If, after an announce, the message `headers' is written to
ctl, then all messages sent to the announced port are
received on the announced connection prefixed with the cor-
responding structure, declared in <ip.h>:
typedef struct Udphdr Udphdr;
struct Udphdr
{
uchar raddr[16]; /* V6 remote address */
uchar laddr[16]; /* V6 local address */
uchar ifcaddr[16]; /* V6 interface address (receive only) */
uchar rport[2]; /* remote port */
uchar lport[2]; /* local port */
};
Before a write, a user must prefix a similar structure to
each message. The system overrides the user specified local
port with the announced one. If the user specifies an
address that isn't a unicast address in /net/ipselftab, that
too is overridden. Since the prefixed structure is the same
in read and write, it is relatively easy to write a server
that responds to client requests by just copying new data
into the message body and then writing back the same buffer
that was read.
In this case (writing `headers' to the ctl file), no listen
nor accept is needed; otherwise, the usual sequence of
Page 10 Plan 9 (printed 11/17/25)
IP(3) IP(3)
announce, listen, accept must be executed before performing
I/O on the corresponding data file.
RUDP
RUDP is a reliable datagram protocol based on UDP, currently
only for IPv4. Packets are delivered in order. RUDP does
not support listen. One must write either `connect' or
`announce' followed immediately by `headers' to ctl.
Unlike TCP, the reboot of one end of a connection does not
force a closing of the connection. Communications will
resume when the rebooted machine resumes talking. Any unac-
knowledged packets queued before the reboot will be lost. A
reboot can be detected by reading the err file. It will
contain the message
hangup address!port
where address and port are of the far side of the connec-
tion. Retransmitting a datagram more than 10 times is
treated like a reboot: all queued messages are dropped, an
error is queued to the err file, and the conversation
resumes.
RUDP ctl files accept the following messages:
headers Corresponds to the `headers' format of
UDP.
hangup IP port Drop the connection to address IP and
port.
randdrop [ percent ] Randomly drop percent of outgoing
packets. Default is 10%.
ICMP
ICMP is a datagram protocol for IPv4 used to exchange con-
trol requests and their responses with other machines' IP
implementations. ICMP is primarily a kernel-to-kernel pro-
tocol, but it is possible to generate `echo request' and
read `echo reply' packets from user programs.
ICMPV6
ICMPv6 is the IPv6 equivalent of ICMP. If, after an
announce, the message `headers' is written to ctl, then
before a write, a user must prefix each message with a cor-
responding structure, declared in <ip.h>:
/*
* user level icmpv6 with control message "headers"
*/
typedef struct Icmp6hdr Icmp6hdr;
struct Icmp6hdr {
uchar unused[8];
Page 11 Plan 9 (printed 11/17/25)
IP(3) IP(3)
uchar laddr[IPaddrlen]; /* local address */
uchar raddr[IPaddrlen]; /* remote address */
};
In this case (writing `headers' to the ctl file), no listen
nor accept is needed; otherwise, the usual sequence of
announce, listen, accept must be executed before performing
I/O on the corresponding data file.
IL
IL is a reliable point-to-point datagram protocol that runs
over IPv4. Like TCP, IL delivers datagrams reliably and in
order. Also like TCP, a connection is determined by the
address and port numbers of the two ends. Like UDP, each
read and write transfers a single datagram.
IL is efficient for LANs but doesn't have the congestion
control features needed for use through the Internet. It is
no longer necessary, except to communicate with old stan-
dalone fs(4) file servers. Its use is now deprecated.
GRE
GRE is the encapsulation protocol used by PPTP. The kernel
implements just enough of the protocol to multiplex it. Our
implementation encapsulates in IPv4, per RFC 1702. Announce
is not allowed in GRE, only connect. Since GRE has no port
numbers, the port number in the connect is actually the 16
bit eproto field in the GRE header.
Reads and writes transfer a GRE datagram starting at the GRE
header. On write, the kernel fills in the eproto field with
the port number specified in the connect message.
ESP
ESP is the Encapsulating Security Payload (RFC 1827, obso-
leted by RFC 4303) for IPsec (RFC 4301). We currently
implement only tunnel mode, not transport mode. It is used
to set up an encrypted tunnel between machines. Like GRE,
ESP has no port numbers. Instead, the port number in the
connect message is the SPI (Security Association Identifier
(sic)). IP packets are written to and read from data. The
kernel encrypts any packets written to data, appends a MAC,
and prefixes an ESP header before sending to the other end
of the tunnel. Received packets are checked against their
MAC's, decrypted, and queued for reading from data. In the
following, secret is the hexadecimal encoding of a key,
without a leading `0x'. The control messages are:
esp alg secret Encrypt with the algorithm, alg, using
secret as the key. Possible algorithms are:
null, des_56_cbc, des3_cbc, and eventually
Page 12 Plan 9 (printed 11/17/25)
IP(3) IP(3)
aes_128_cbc, and aes_ctr.
ah alg secret Use the hash algorithm, alg, with secret as
the key for generating the MAC. Possible
algorithms are: null, hmac_sha1_96,
hmac_md5_96, and eventually aes_xcbc_mac_96.
header Turn on header mode. Every buffer read from
data starts with 4 unused bytes, and the
first 4 bytes of every buffer written to
data are ignored.
noheader Turn off header mode.
IP packet filter
The directory /net/ipmux looks like another protocol direc-
tory. It is a packet filter built on top of IP. Each num-
bered subdirectory represents a different filter. The con-
nect messages written to the ctl file describe the filter.
Packets matching the filter can be read on the data file.
Packets written to the data file are routed to an interface
and transmitted.
A filter is a semicolon-separated list of relations. Each
relation describes a portion of a packet to match. The pos-
sible relations are:
ver=n the IP version must be n.
proto=n the IP protocol number must be n.
data[n:m]=expr bytes n through m following the IP header
must match expr.
iph[n:m]=expr bytes n through m of the IP packet header
must match expr.
ifc=expr the packet must have been received on an
interface whose address matches expr.
src=expr The source address in the packet must match
expr.
dst=expr The destination address in the packet must
match expr.
Expr is of the form:
value
value|value|...
Page 13 Plan 9 (printed 11/17/25)
IP(3) IP(3)
value&mask
value|value&mask
If a mask is given, the relevant field is first ANDed with
the mask. The result is compared against the value or list
of values for a match. In the case of ifc, dst, and src the
value is a dot-formatted IP address and the mask is a dot-
formatted IP mask. In the case of data, iph and proto, both
value and mask are strings of 2 hexadecimal digits repre-
senting 8-bit values.
A packet is delivered to only one filter. The filters are
merged into a single comparison tree. If two filters match
the same packet, the following rules apply in order (here
'>' means is preferred to):
1) protocol > data > source > destination > interface
2) lower data offsets > higher data offsets
3) longer matches > shorter matches
4) older > younger
So far this has just been used to implement a version of
OSPF in Inferno and 6to4 tunnelling.
Statistics
The stats files are read only and contain statistics useful
to network monitoring.
Reading /net/ipifc/stats returns a list of 19 tagged and
newline-separated fields representing:
forwarding status (0 and 2 mean foourtwpaurtdipnagckoeftfs,
1 means on) output packets discarded
default TTL output packets with no route
input packets timed out fragments in reassembly queue
input header errors requested reassemblies
input address errors successful reassemblies
packets forwarded failed reassemblies
input packets for unknown protocoslusccessful fragmentations
input packets discarded unsuccessful fragmentations
input packets delivered to higherfrlaegvmeelntpsroctroecaotlesd
Page 14 Plan 9 (printed 11/17/25)
IP(3) IP(3)
Reading /net/icmp/stats returns a list of 26 tagged and
newline-separated fields representing:
messages received messages sent
bad received messages transmission errors
unreachables received unreachables sent
time exceededs received time exceededs sent
input parameter problems receivedinput parameter problems sent
source quenches received source quenches sent
redirects received redirects sent
echo requests received echo requests sent
echo replies received echo replies sent
timestamps received timestamps sent
timestamp replies received timestamp replies sent
address mask requests received address mask requests sent
address mask replies received address mask replies sent
Reading /net/tcp/stats returns a list of 11 tagged and
newline-separated fields representing:
maximum number of connections segments sent
total outgoing calls segments retransmitted
total incoming calls retransmit timeouts
number of established connectionsbatdorbeecerievseedtsegments
number of currently established ctornannescmtiisosnison failures
segments received
Reading /net/udp/stats returns a list of 4 tagged and
newline-separated fields representing:
datagrams received malformed datagrams received
datagrams received for bad portsdatagrams sent
Reading /net/il/stats returns a list of 6 tagged and
newline-separated fields representing:
checksum errors retransmitted messages
header length errors duplicate messages
out of order messages duplicate bytes
Reading /net/gre/stats returns a list of 1 tagged number
representing:
header length errors
SEE ALSO
dial(2), ip(2), ndb(6), listen(8)
/lib/rfc/rfc2460 IPv6
/lib/rfc/rfc4291 IPv6 address architecture
/lib/rfc/rfc4443 ICMPv6
SOURCE
/sys/src/9/ip
BUGS
Ipmux has not been heavily used and should be considered
experimental. It may disappear in favor of a more
Page 15 Plan 9 (printed 11/17/25)
IP(3) IP(3)
traditional packet filter in the future.
Page 16 Plan 9 (printed 11/17/25)