1999-08-28 00:22:10 +00:00
|
|
|
.\" $FreeBSD$
|
1996-12-26 16:16:37 +00:00
|
|
|
.\"
|
2004-12-17 12:59:20 +00:00
|
|
|
.Dd December 17, 2004
|
1996-07-10 19:44:30 +00:00
|
|
|
.Dt DIVERT 4
|
2001-07-10 15:31:11 +00:00
|
|
|
.Os
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh NAME
|
2000-10-06 08:33:43 +00:00
|
|
|
.Nm divert
|
1996-07-10 19:44:30 +00:00
|
|
|
.Nd kernel packet diversion mechanism
|
|
|
|
.Sh SYNOPSIS
|
2001-10-01 16:09:29 +00:00
|
|
|
.In sys/types.h
|
|
|
|
.In sys/socket.h
|
|
|
|
.In netinet/in.h
|
1996-07-10 19:44:30 +00:00
|
|
|
.Ft int
|
|
|
|
.Fn socket PF_INET SOCK_RAW IPPROTO_DIVERT
|
2006-09-24 13:58:44 +00:00
|
|
|
.Pp
|
|
|
|
To enable support for divert sockets, place the following lines in the
|
|
|
|
kernel configuration file:
|
|
|
|
.Bd -ragged -offset indent
|
|
|
|
.Cd "options IPFIREWALL"
|
|
|
|
.Cd "options IPDIVERT"
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Alternatively, to load
|
|
|
|
.Ns Nm
|
|
|
|
as a module at boot time, add the following lines into the
|
|
|
|
.Xr loader.conf 5
|
|
|
|
file:
|
|
|
|
.Bd -literal -offset indent
|
|
|
|
ipfw_load="YES"
|
|
|
|
ipdivert_load="YES"
|
|
|
|
.Ed
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh DESCRIPTION
|
|
|
|
Divert sockets are similar to raw IP sockets, except that they
|
|
|
|
can be bound to a specific
|
|
|
|
.Nm
|
|
|
|
port via the
|
|
|
|
.Xr bind 2
|
2000-03-01 14:50:24 +00:00
|
|
|
system call.
|
|
|
|
The IP address in the bind is ignored; only the port
|
1996-07-10 19:44:30 +00:00
|
|
|
number is significant.
|
|
|
|
A divert socket bound to a divert port will receive all packets diverted
|
|
|
|
to that port by some (here unspecified) kernel mechanism(s).
|
|
|
|
Packets may also be written to a divert port, in which case they
|
|
|
|
re-enter kernel IP packet processing.
|
|
|
|
.Pp
|
2000-10-06 08:33:43 +00:00
|
|
|
Divert sockets are normally used in conjunction with
|
2000-11-14 11:20:58 +00:00
|
|
|
.Fx Ns 's
|
|
|
|
packet filtering implementation and the
|
1996-07-10 19:44:30 +00:00
|
|
|
.Xr ipfw 8
|
2000-03-01 14:50:24 +00:00
|
|
|
program.
|
|
|
|
By reading from and writing to a divert socket, matching packets
|
1996-07-10 19:44:30 +00:00
|
|
|
can be passed through an arbitrary ``filter'' as they travel through
|
|
|
|
the host machine, special routing tricks can be done, etc.
|
|
|
|
.Sh READING PACKETS
|
|
|
|
Packets are diverted either as they are ``incoming'' or ``outgoing.''
|
|
|
|
Incoming packets are diverted after reception on an IP interface,
|
|
|
|
whereas outgoing packets are diverted before next hop forwarding.
|
|
|
|
.Pp
|
|
|
|
Diverted packets may be read unaltered via
|
|
|
|
.Xr read 2 ,
|
|
|
|
.Xr recv 2 ,
|
|
|
|
or
|
|
|
|
.Xr recvfrom 2 .
|
|
|
|
In the latter case, the address returned will have its port set to
|
2002-03-13 18:37:40 +00:00
|
|
|
some tag supplied by the packet diverter, (usually the ipfw rule number)
|
1998-06-05 23:20:12 +00:00
|
|
|
and the IP address set to the (first) address of
|
1996-07-11 02:08:31 +00:00
|
|
|
the interface on which the packet was received (if the packet
|
1996-07-10 19:44:30 +00:00
|
|
|
was incoming) or
|
|
|
|
.Dv INADDR_ANY
|
2003-07-08 13:24:42 +00:00
|
|
|
(if the packet was outgoing).
|
|
|
|
The interface name (if defined
|
|
|
|
for the packet) will be placed in the 8 bytes following the address,
|
|
|
|
if it fits.
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh WRITING PACKETS
|
|
|
|
Writing to a divert socket is similar to writing to a raw IP socket;
|
|
|
|
the packet is injected ``as is'' into the normal kernel IP packet
|
2004-12-17 11:24:33 +00:00
|
|
|
processing using
|
|
|
|
.Xr sendto 2
|
|
|
|
and minimal error checking is done.
|
|
|
|
Packets are distinguished as either incoming or outgoing.
|
|
|
|
If
|
1996-07-10 19:44:30 +00:00
|
|
|
.Xr sendto 2
|
|
|
|
is used with a destination IP address of
|
|
|
|
.Dv INADDR_ANY ,
|
|
|
|
then the packet is treated as if it were outgoing, i.e., destined
|
2003-06-28 23:53:39 +00:00
|
|
|
for a non-local address.
|
|
|
|
Otherwise, the packet is assumed to be
|
1996-07-10 19:44:30 +00:00
|
|
|
incoming and full packet routing is done.
|
|
|
|
.Pp
|
|
|
|
In the latter case, the
|
1998-05-25 08:44:31 +00:00
|
|
|
IP address specified must match the address of some local interface,
|
|
|
|
or an interface name
|
2000-03-01 14:50:24 +00:00
|
|
|
must be found after the IP address.
|
|
|
|
If an interface name is found,
|
1998-05-25 08:44:31 +00:00
|
|
|
that interface will be used and the value of the IP address will be
|
|
|
|
ignored (other than the fact that it is not
|
2001-08-10 17:35:21 +00:00
|
|
|
.Dv INADDR_ANY ) .
|
2003-06-28 23:53:39 +00:00
|
|
|
This is to indicate on which interface the packet
|
|
|
|
.Dq arrived .
|
1996-07-10 19:44:30 +00:00
|
|
|
.Pp
|
|
|
|
Normally, packets read as incoming should be written as incoming;
|
2003-06-28 23:53:39 +00:00
|
|
|
similarly for outgoing packets.
|
|
|
|
When reading and then writing back
|
1996-07-10 19:44:30 +00:00
|
|
|
packets, passing the same socket address supplied by
|
|
|
|
.Xr recvfrom 2
|
|
|
|
unmodified to
|
|
|
|
.Xr sendto 2
|
1998-06-05 23:20:12 +00:00
|
|
|
simplifies things (see below).
|
1996-07-10 19:44:30 +00:00
|
|
|
.Pp
|
1998-06-05 23:20:12 +00:00
|
|
|
The port part of the socket address passed to the
|
2000-10-06 08:33:43 +00:00
|
|
|
.Xr sendto 2
|
2000-03-01 14:50:24 +00:00
|
|
|
contains a tag that should be meaningful to the diversion module.
|
|
|
|
In the
|
1998-06-05 23:20:12 +00:00
|
|
|
case of
|
2000-10-06 08:33:43 +00:00
|
|
|
.Xr ipfw 8
|
|
|
|
the tag is interpreted as the rule number
|
1998-06-05 23:20:12 +00:00
|
|
|
.Em after which
|
|
|
|
rule processing should restart.
|
|
|
|
.Sh LOOP AVOIDANCE
|
2000-01-11 11:54:25 +00:00
|
|
|
Packets written into a divert socket
|
2001-08-07 15:48:51 +00:00
|
|
|
(using
|
|
|
|
.Xr sendto 2 )
|
2000-01-11 11:54:25 +00:00
|
|
|
re-enter the packet filter at the rule number
|
1998-06-05 23:20:12 +00:00
|
|
|
following the tag given in the port part of the socket address, which
|
|
|
|
is usually already set at the rule number that caused the diversion
|
2004-07-03 18:29:24 +00:00
|
|
|
(not the next rule if there are several at the same number).
|
|
|
|
If the 'tag'
|
1998-06-05 23:20:12 +00:00
|
|
|
is altered to indicate an alternative re-entry point, care should be taken
|
|
|
|
to avoid loops, where the same packet is diverted more than once at the
|
|
|
|
same rule.
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh DETAILS
|
|
|
|
If a packet is diverted but no socket is bound to the
|
|
|
|
port, or if
|
|
|
|
.Dv IPDIVERT
|
2004-10-22 19:12:01 +00:00
|
|
|
is not enabled or loaded in the kernel, the packet is dropped.
|
1996-07-10 19:44:30 +00:00
|
|
|
.Pp
|
|
|
|
Incoming packet fragments which get diverted are fully reassembled
|
|
|
|
before delivery; the diversion of any one fragment causes the entire
|
|
|
|
packet to get diverted.
|
|
|
|
If different fragments divert to different ports,
|
|
|
|
then which port ultimately gets chosen is unpredictable.
|
|
|
|
.Pp
|
2004-09-14 09:35:10 +00:00
|
|
|
Note that packets arriving on the divert socket by the
|
|
|
|
.Xr ipfw 8
|
|
|
|
.Cm tee
|
|
|
|
action are delivered as-is and packet fragments do not get reassembled
|
|
|
|
in this case.
|
|
|
|
.Pp
|
1997-02-06 11:16:21 +00:00
|
|
|
Packets are received and sent unchanged, except that
|
2001-02-12 02:03:28 +00:00
|
|
|
packets read as outgoing have invalid IP header checksums, and
|
1997-02-06 11:16:21 +00:00
|
|
|
packets written as outgoing have their IP header checksums overwritten
|
1996-07-10 19:44:30 +00:00
|
|
|
with the correct value.
|
|
|
|
Packets written as incoming and having incorrect checksums will be dropped.
|
|
|
|
Otherwise, all header fields are unchanged (and therefore in network order).
|
|
|
|
.Pp
|
1997-02-06 11:16:21 +00:00
|
|
|
Binding to port numbers less than 1024 requires super-user access, as does
|
|
|
|
creating a socket of type SOCK_RAW.
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh ERRORS
|
|
|
|
Writing to a divert socket can return these errors, along with
|
|
|
|
the usual errors possible when writing raw packets:
|
|
|
|
.Bl -tag -width Er
|
|
|
|
.It Bq Er EINVAL
|
|
|
|
The packet had an invalid header, or the IP options in the packet
|
|
|
|
and the socket options set were incompatible.
|
|
|
|
.It Bq Er EADDRNOTAVAIL
|
|
|
|
The destination address contained an IP address not equal to
|
|
|
|
.Dv INADDR_ANY
|
|
|
|
that was not associated with any interface.
|
|
|
|
.El
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr bind 2 ,
|
1996-12-26 16:16:37 +00:00
|
|
|
.Xr recvfrom 2 ,
|
1996-12-09 07:45:59 +00:00
|
|
|
.Xr sendto 2 ,
|
1996-12-26 16:16:37 +00:00
|
|
|
.Xr socket 2 ,
|
2006-09-24 13:58:44 +00:00
|
|
|
.Xr ipfw 4 ,
|
1996-12-26 16:16:37 +00:00
|
|
|
.Xr ipfw 8
|
2005-01-21 08:36:40 +00:00
|
|
|
.Sh AUTHORS
|
|
|
|
.An Archie Cobbs Aq archie@FreeBSD.org ,
|
|
|
|
Whistle Communications Corp.
|
1996-07-10 19:44:30 +00:00
|
|
|
.Sh BUGS
|
|
|
|
This is an attempt to provide a clean way for user mode processes
|
|
|
|
to implement various IP tricks like address translation, but it
|
2005-02-13 23:45:54 +00:00
|
|
|
could be cleaner, and it is too dependent on
|
1996-07-10 19:44:30 +00:00
|
|
|
.Xr ipfw 8 .
|
|
|
|
.Pp
|
2005-02-13 23:45:54 +00:00
|
|
|
It is questionable whether incoming fragments should be reassembled
|
2000-03-01 14:50:24 +00:00
|
|
|
before being diverted.
|
|
|
|
For example, if only some fragments of a
|
2005-02-13 22:25:33 +00:00
|
|
|
packet destined for another machine do not get routed through the
|
2000-03-01 14:50:24 +00:00
|
|
|
local machine, the packet is lost.
|
|
|
|
This should probably be
|
1996-07-10 19:44:30 +00:00
|
|
|
a settable socket option in any case.
|