IP(3) IP(3)
NAME
ip - network protocols over IP
SYNOPSIS
bind -a #Ispec /net
/net/ipifc
/net/ipifc/clone
/net/ipifc/stats
/net/ipifc/n
/net/ipifc/n/status
/net/ipifc/n/ctl
...
/net/arp
/net/log
/net/ndb
/net/iproute
/net/ipselftab
/net/esp
/net/gre
/net/icmp
/net/il
/net/ipmux
/net/rudp
/net/tcp
/net/udp
/net/tcp/clone
/net/tcp/stats
/net/tcp/n
/net/tcp/n/data
/net/tcp/n/ctl
/net/tcp/n/local
/net/tcp/n/remote
/net/tcp/n/status
/net/tcp/n/listen
...
DESCRIPTION
The IP device provides the interface to Internet protocol
stacks. Spec is an integer from 0 to 15 identifying a
stack. Each stack is physically 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 implementing firewalls or proxy services.
All addresses used are 16-byte IPv6 addresses. Though we
Page 1 Plan 9 (printed 11/21/25)
IP(3) IP(3)
currently implement only IPv4, the IPv6 format is intended
to prepare the way for an IPv6 implementation. IPv4
addresses are a subset of the IPv6 addresses and both stan-
dard ASCII formats are accepted. In binary, all v4
addresses start with the 12 bytes:
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
interface. Writing ctl alters aspects of the interface.
The possible ctl messages are:
bind ether path
Treat the device mounted at path as an Ethernet medium
carrying IP and ARP packets and associate it with this
interface. The kernel will dial(2) path!0x800 and
path!0x806 and use the two connections for IP 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.
unbind
Disassociate the physical device from an IP interface.
add local mask remote mtu proxy
Add a local IP address to the interface. The mask,
remote, mtu, and proxy 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 is 1514 for Ethernet and 4096 for
packet media. 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.
Page 2 Plan 9 (printed 11/21/25)
IP(3) IP(3)
remove local mask
Remove 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.
iprouting n
Allow (nismissing or non-zero) or disallow (n is 0)
forwarding packets between this interface and others.
addmulti addr
Treat the multicast addr on this interface as a local
address.
remmulti addr
Remove the multicast address addr from this interface.
Reading the interface's status file returns information
about the interface, one line for each local address on that
interface. The first line has 9 white-space-separated
fields: device, mtu, local address, mask, remote or network
address, packets in, packets out, input errors, output
errors. Each subsequent line contains all but the device
and mtu. See readipifc in ip(2).
Routing
The file iproute controls information about IP routing.
When read, it returns one line per routing entry. Each line
contains six white-space-separated fields: target address,
target mask, address of next hop, flags, tag, and interface
number. The entry used for routing an IP packet is the one
with the longest mask for which destination address ANDed
with target mask equals the target address. The one charac-
ter 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
The tag is an arbitrary, up to 4 character, string. It is
Page 3 Plan 9 (printed 11/21/25)
IP(3) IP(3)
normally used to indicate what routing protocol originated
the route.
Writing to /net/iproute changes the route table. The mes-
sages are:
flush
Remove all routes.
tag string
Associate the tag, string, with all subsequent routes
added via this file descriptor.
add target mask nexthop
Add the route to the table. If one already exists with
the same target and mask, replace it.
remove target mask
Remove a route with a matching target and mask.
Address resolution
The file /net/arp controls information about address resolu-
tion. The kernel automatically updates the ARP 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, and the medium
address. Writing to /net/arp administers the ARP informa-
tion. The control messages are:
flush
Remove all entries.
add type IP-addr Media-addr
Add an entry or replace an existing one for the same 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.
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.
Page 4 Plan 9 (printed 11/21/25)
IP(3) IP(3)
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, udb, compress, ilmsg, gre, tcpmsg,
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 destination 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 tp 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, IL, UDP, GRE, ESP, ICMP, and RUDP. TCP
and UDP provide the standard Internet protocols for reliable
stream and unreliable datagram communication. IL provides a
reliable datagram service for communication between Plan 9
machines. GRE is a general encapsulation protocol. ESP is
the encapsulation protocol for IPSEC. ICMP is IP's catch-
all control protocol used to send low level error messages
and to implement ping(8). RUDP is a locally developed reli-
able datagram protocol based on UDP. IL is the protocol of
choice for most Plan 9 services.
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
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
Page 5 Plan 9 (printed 11/21/25)
IP(3) IP(3)
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 ipaddress!port!r local
Establish a connection to the remote address ipaddress
and remote port port. If local is specified, it is used
as the local port number. If local is not specified
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. Oth-
erwise 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 X
X is a decimal port number or `*'. Set the local port
number to X and accept calls to X. If X is `*', accept
calls for any port that no process has explicitly
announced. The local IP address cannot be set.
Announce fails if the connection is already announced
or connected.
bind X
X is a decimal port number or `*'. Set the local port
number to X. This exists to support emulation of BSD
sockets byt the APE libraries (see pcc(1)) and is not
otherwise used.
backlog n
Set the maximum number of unanswered (queued) incoming
connections to an announced port to n. By default n is
set to five. If more than n connections are pending,
further requests for a service will be rejected.
ttl n
Set the time to live IP field in outgoing packets to n.
tos n
Set the service type IP field in outgoing packets to n.
Port numbers must be in the range 1 to 32767.
Page 6 Plan 9 (printed 11/21/25)
IP(3) IP(3)
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:
hangup
close down a TCP connection
keepalive n
turn on keep alive messages. N, if given, is the mil-
liseconds between keepalives (default 30000).
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, one of the following messages is
written to ctl, then all messages sent to the announced port
are received on the announced connection prefixed with the
given structure.
headers4
typedef struct Udphdr4 Udphdr4;
struct Udphdr
{
uchar raddr[4]; /* v4 remote address and port */
uchar laddr[4]; /* v4 local address and port */
Page 7 Plan 9 (printed 11/21/25)
IP(3) IP(3)
uchar rport[2];
uchar lport[2];
};
headers
typedef struct Udphdr Udphdr;
struct Udphdr
{
uchar raddr[16]; /* v6 remote address and port */
uchar laddr[16]; /* v6 local address and port */
uchar rport[2];
uchar lport[2];
};
The only difference in the two is the type of address, IPv4
or IPv6. 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 written.
RUDP
RUDP is a reliable datagram protocol based on UDP. Packets
are delivered in order. RUDP does not support listen. One
must use either connect or announce followed immediately by
headers or headers4.
Unlike IL or 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
have 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.
IL
IL is a reliable point-to-point datagram protocol. Like
TCP, IL delivers datagrams reliably and in order. Also like
TCP, a connection is determined by the address and port num-
bers of the two ends. Like UDP, each read and write trans-
fers a single datagram.
Page 8 Plan 9 (printed 11/21/25)
IP(3) IP(3)
IL is efficient for LANs but doesn't have the congestion
control features needed for use through the Internet.
GRE
GRE is the encapsulation protocol used by PPTP. The kernel
implements just enough of the protocol to multiplex it.
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). 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 Identi-
fier (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.
The control messages are:
esp alg secret
Encrypt with the algorithm, alg, using secret as the
key. Possible algorithms are: null, des_56_cbc, and
rc4_128.
ah alg secret
Use the hash algorithm, alg, with secret as the key for
generating the MAC. Possible algorithms are: null,
hmac_sha1_96, and hmac_md5_96.
header
Turn on header mode. Every buffer read from data
starts with 4 unsued 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.
Page 9 Plan 9 (printed 11/21/25)
IP(3) IP(3)
A filter is a semicolon-separated list of relations. Each
relation describes a portion of a packet to match. The pos-
sible relations are:
proto=n
the IP protocol number must be n.
dat[n:m]=expr
bytes n through m following the IP packet 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|...
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 dat, both value and mask
are strings of 2 character hexadecimal digits representing 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
Page 10 Plan 9 (printed 11/21/25)
IP(3) IP(3)
So far this has just been used to implement a version of
OSPF in Inferno.
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 new
line separated fields representing:
forwarding status (0 and 2 mean forwarding off, 1 means on)
default TTL
input packets
input header errors
input address errors
packets forwarded
input packets for unknown protocols
input packets discarded
input packets delivered to higher level protocols
output packets
output packets discarded
output packets with no route
timed out fragments in reassembly queue
requested reassemblies
successful reassemblies
failed reassemblies
successful fragmentations
unsuccessful fragmentations
fragments created
Reading /net/icmp/stats returns a list of 25 tagged and new
line separated fields representing:
messages received
bad received messages
unreachables received
time exceededs received
input parameter problems received
source quenches received
redirects received
echo requests received
echo replies received
timestamps received
timestamp replies received
address mask requests received
address mask replies received
messages sent
transmission errors
unreachables sent
time exceededs sent
input parameter problems sent
source quenches sent
redirects sent
echo requests sent
Page 11 Plan 9 (printed 11/21/25)
IP(3) IP(3)
echo replies sent
timestamps sent
timestamp replies sent
address mask requests sent
address mask replies sent
Reading /net/tcp/stats returns a list of 11 tagged and new
line separated fields representing:
maximum number of connections
total outgoing calls
total incoming calls
number of established connections to be reset
number of currently esablished connections
segments received
segments sent
segments retransmitted
retransmit timeouts
bad received segments
transmission failures
Reading /net/udp/stats returns a list of 4 tagged and new
line separated fields representing:
datagrams received
datagrams received for bad ports
malformed datagrams received
datagrams sent
Reading /net/il/stats returns a list of 7 tagged and new
line separated fields representing:
checksum errors
header length errors
out of order messages
retransmitted messages
duplicate messages
duplicate bytes
Reading /net/gre/stats returns a list of 1 tagged number
representing:
header length errors
SEE ALSO
listen(8), dial(2), ndb(6)
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 tradi-
tional packet filter in the future.
Page 12 Plan 9 (printed 11/21/25)