xref: /freebsd/share/man/man4/divert.4 (revision 436c7212e69c3933c0f0d875293c10f142f86fe9)
1436c7212SJulian Elischer.\"	$Id: divert.4,v 1.10 1998/03/12 07:30:16 charnier Exp $
20b992c1dSWolfram Schneider.\"
393e0e116SJulian Elischer.Dd June 18, 1996
493e0e116SJulian Elischer.Dt DIVERT 4
593e0e116SJulian Elischer.Os FreeBSD
693e0e116SJulian Elischer.Sh NAME
793e0e116SJulian Elischer.Nm divert
893e0e116SJulian Elischer.Nd kernel packet diversion mechanism
993e0e116SJulian Elischer.Sh SYNOPSIS
10ddbd0698SBruce Evans.Fd #include <sys/types.h>
1193e0e116SJulian Elischer.Fd #include <sys/socket.h>
1293e0e116SJulian Elischer.Fd #include <netinet/in.h>
1393e0e116SJulian Elischer.Ft int
1493e0e116SJulian Elischer.Fn socket PF_INET SOCK_RAW IPPROTO_DIVERT
1593e0e116SJulian Elischer.Sh DESCRIPTION
1693e0e116SJulian Elischer.Pp
1793e0e116SJulian ElischerDivert sockets are similar to raw IP sockets, except that they
1893e0e116SJulian Elischercan be bound to a specific
1993e0e116SJulian Elischer.Nm
2093e0e116SJulian Elischerport via the
2193e0e116SJulian Elischer.Xr bind 2
2293e0e116SJulian Elischersystem call. The IP address in the bind is ignored; only the port
2393e0e116SJulian Elischernumber is significant.
2493e0e116SJulian ElischerA divert socket bound to a divert port will receive all packets diverted
2593e0e116SJulian Elischerto that port by some (here unspecified) kernel mechanism(s).
2693e0e116SJulian ElischerPackets may also be written to a divert port, in which case they
2793e0e116SJulian Elischerre-enter kernel IP packet processing.
2893e0e116SJulian Elischer.Pp
2993e0e116SJulian ElischerDivert sockets are normally used in conjunction with
3093e0e116SJulian ElischerFreeBSD's packet filtering implementation and the
3193e0e116SJulian Elischer.Xr ipfw 8
3293e0e116SJulian Elischerprogram. By reading from and writing to a divert socket, matching packets
3393e0e116SJulian Elischercan be passed through an arbitrary ``filter'' as they travel through
3493e0e116SJulian Elischerthe host machine, special routing tricks can be done, etc.
3593e0e116SJulian Elischer.Sh READING PACKETS
3693e0e116SJulian ElischerPackets are diverted either as they are ``incoming'' or ``outgoing.''
3793e0e116SJulian ElischerIncoming packets are diverted after reception on an IP interface,
3893e0e116SJulian Elischerwhereas outgoing packets are diverted before next hop forwarding.
3993e0e116SJulian Elischer.Pp
4093e0e116SJulian ElischerDiverted packets may be read unaltered via
4193e0e116SJulian Elischer.Xr read 2 ,
4293e0e116SJulian Elischer.Xr recv 2 ,
4393e0e116SJulian Elischeror
4493e0e116SJulian Elischer.Xr recvfrom 2 .
4593e0e116SJulian ElischerIn the latter case, the address returned will have its port set to
4693e0e116SJulian Elischerthe divert port and the IP address set to the (first) address of
4709b4b086SMike Pritchardthe interface on which the packet was received (if the packet
4893e0e116SJulian Elischerwas incoming) or
4993e0e116SJulian Elischer.Dv INADDR_ANY
50436c7212SJulian Elischer(if the packet was outgoing). In the case of an incoming packet the interface
51436c7212SJulian Elischername will also be placed in the 8 bytes following the address,
52436c7212SJulian Elischer(assuming it fits).
5393e0e116SJulian Elischer.Sh WRITING PACKETS
5493e0e116SJulian ElischerWriting to a divert socket is similar to writing to a raw IP socket;
5593e0e116SJulian Elischerthe packet is injected ``as is'' into the normal kernel IP packet
5693e0e116SJulian Elischerprocessing and minimal error checking is done.
5793e0e116SJulian ElischerPackets are written as either incoming or outgoing:
5893e0e116SJulian Elischerif
5993e0e116SJulian Elischer.Xr write 2
6093e0e116SJulian Elischeror
6193e0e116SJulian Elischer.Xr send 2
6293e0e116SJulian Elischeris used to deliver the packet, or if
6393e0e116SJulian Elischer.Xr sendto 2
6493e0e116SJulian Elischeris used with a destination IP address of
6593e0e116SJulian Elischer.Dv INADDR_ANY ,
6693e0e116SJulian Elischerthen the packet is treated as if it were outgoing, i.e., destined
6793e0e116SJulian Elischerfor a non-local address.  Otherwise, the packet is assumed to be
6893e0e116SJulian Elischerincoming and full packet routing is done.
6993e0e116SJulian Elischer.Pp
7093e0e116SJulian ElischerIn the latter case, the
71436c7212SJulian ElischerIP address specified must match the address of some local interface,
72436c7212SJulian Elischeror an interface name
73436c7212SJulian Elischermust be found after the IP address. If an interface name is found,
74436c7212SJulian Elischerthat interface will be used and the value of the IP address will be
75436c7212SJulian Elischerignored (other than the fact that it is not
76436c7212SJulian Elischer.Dv INADDR_ANY
77436c7212SJulian Elischer).
7893e0e116SJulian ElischerThis is to indicate on which interface the packet ``arrived.''
7993e0e116SJulian Elischer.Pp
8093e0e116SJulian ElischerNormally, packets read as incoming should be written as incoming;
8193e0e116SJulian Elischersimilarly for outgoing packets.  When reading and then writing back
8293e0e116SJulian Elischerpackets, passing the same socket address supplied by
8393e0e116SJulian Elischer.Xr recvfrom 2
8493e0e116SJulian Elischerunmodified to
8593e0e116SJulian Elischer.Xr sendto 2
8693e0e116SJulian Elischersimplifies things.
8793e0e116SJulian Elischer.Sh LOOP AVOIDANCE
8836700156SBrian SomersPackets written into a divert socket (using
8936700156SBrian Somers.Xr sendto 2 )
9036700156SBrian Somersare never rediverted back to the same socket.  This means that a
9136700156SBrian Somersgiven packet (either incoming or outgoing) will be diverted to a
9236700156SBrian Somersgiven socket once and once only.
9393e0e116SJulian Elischer.Pp
9436700156SBrian Somers.Xr Ipfw 8
9536700156SBrian Somersrules are executed in order, each time the packet passes through
9636700156SBrian Somersthe kernel, but only up until a matching
9736700156SBrian Somers.Nm
9836700156SBrian Somersrule applies.  On the second pass, after the packet has been diverted,
9936700156SBrian Somersthe divert rule is ignored and any subsequent
10036700156SBrian Somers.Xr ipfw 8
10136700156SBrian Somersrules are applied.  For this reason, it is normally best to specify your
10236700156SBrian Somersdivert rules prior to any others.
10393e0e116SJulian Elischer.Sh DETAILS
10493e0e116SJulian ElischerTo enable divert sockets, your kernel must be compiled with the option
10593e0e116SJulian Elischer.Dv IPDIVERT .
10693e0e116SJulian Elischer.Pp
10793e0e116SJulian ElischerIf a packet is diverted but no socket is bound to the
10893e0e116SJulian Elischerport, or if
10993e0e116SJulian Elischer.Dv IPDIVERT
11093e0e116SJulian Elischeris not enabled in the kernel, the packet is dropped.
11193e0e116SJulian Elischer.Pp
11293e0e116SJulian ElischerIncoming packet fragments which get diverted are fully reassembled
11393e0e116SJulian Elischerbefore delivery; the diversion of any one fragment causes the entire
11493e0e116SJulian Elischerpacket to get diverted.
11593e0e116SJulian ElischerIf different fragments divert to different ports,
11693e0e116SJulian Elischerthen which port ultimately gets chosen is unpredictable.
11793e0e116SJulian Elischer.Pp
11804f36f75SBrian SomersPackets are received and sent unchanged, except that
11904f36f75SBrian Somerspackets written as outgoing have their IP header checksums overwritten
12093e0e116SJulian Elischerwith the correct value.
12193e0e116SJulian ElischerPackets written as incoming and having incorrect checksums will be dropped.
12293e0e116SJulian ElischerOtherwise, all header fields are unchanged (and therefore in network order).
12393e0e116SJulian Elischer.Pp
12404f36f75SBrian SomersBinding to port numbers less than 1024 requires super-user access, as does
12504f36f75SBrian Somerscreating a socket of type SOCK_RAW.
12693e0e116SJulian Elischer.Sh ERRORS
12793e0e116SJulian ElischerWriting to a divert socket can return these errors, along with
12893e0e116SJulian Elischerthe usual errors possible when writing raw packets:
12993e0e116SJulian Elischer.Bl -tag -width Er
13093e0e116SJulian Elischer.It Bq Er EINVAL
13193e0e116SJulian ElischerThe packet had an invalid header, or the IP options in the packet
13293e0e116SJulian Elischerand the socket options set were incompatible.
13393e0e116SJulian Elischer.It Bq Er EADDRNOTAVAIL
13493e0e116SJulian ElischerThe destination address contained an IP address not equal to
13593e0e116SJulian Elischer.Dv INADDR_ANY
13693e0e116SJulian Elischerthat was not associated with any interface.
13793e0e116SJulian Elischer.El
13893e0e116SJulian Elischer.Sh SEE ALSO
13993e0e116SJulian Elischer.Xr bind 2 ,
1400b992c1dSWolfram Schneider.Xr recvfrom 2 ,
141aab5e1b6SMike Pritchard.Xr sendto 2 ,
1420b992c1dSWolfram Schneider.Xr socket 2 ,
1430b992c1dSWolfram Schneider.Xr ipfw 8
14493e0e116SJulian Elischer.Sh BUGS
14593e0e116SJulian ElischerThis is an attempt to provide a clean way for user mode processes
14693e0e116SJulian Elischerto implement various IP tricks like address translation, but it
14793e0e116SJulian Elischercould be cleaner, and it's too dependent on
14893e0e116SJulian Elischer.Xr ipfw 8 .
14993e0e116SJulian Elischer.Pp
15093e0e116SJulian ElischerIt's questionable whether incoming fragments should be reassembled
15193e0e116SJulian Elischerbefore being diverted. For example, if only some fragments of a
15293e0e116SJulian Elischerpacket destined for another machine don't get routed through the
15393e0e116SJulian Elischerlocal machine, the packet is lost. This should probably be
15493e0e116SJulian Elischera settable socket option in any case.
155aaf1f16eSPhilippe Charnier.Sh AUTHORS
156aaf1f16eSPhilippe Charnier.An Archie Cobbs Aq archie@whistle.com ,
157aaf1f16eSPhilippe CharnierWhistle Communications Corp.
158