xref: /freebsd/share/man/man4/divert.4 (revision 8f76bb7dad48538c6832c2fb466a433d2a3f8cd5)
1.\"
2.Dd August 30, 2022
3.Dt DIVERT 4
4.Os
5.Sh NAME
6.Nm divert
7.Nd kernel packet diversion mechanism
8.Sh SYNOPSIS
9.In sys/types.h
10.In sys/socket.h
11.In netinet/in.h
12.Ft int
13.Fn socket PF_DIVERT SOCK_RAW 0
14.Pp
15To enable support for divert sockets, place the following lines in the
16kernel configuration file:
17.Bd -ragged -offset indent
18.Cd "options IPFIREWALL"
19.Cd "options IPDIVERT"
20.Ed
21.Pp
22Alternatively, to load
23the driver
24as a module at boot time, add the following lines into the
25.Xr loader.conf 5
26file:
27.Bd -literal -offset indent
28ipfw_load="YES"
29ipdivert_load="YES"
30.Ed
31.Sh DESCRIPTION
32Divert sockets allow to intercept and re-inject packets flowing through
33the
34.Xr ipfw 4
35firewall.
36A divert socket can be bound to a specific
37.Nm
38port via the
39.Xr bind 2
40system call.
41The sockaddr argument shall be sockaddr_in with sin_port set to the
42desired value.
43Note that the
44.Nm
45port has nothing to do with TCP/UDP ports.
46It is just a cookie number, that allows to differentiate between different
47divert points in the
48.Xr ipfw 4
49ruleset.
50A divert socket bound to a divert port will receive all packets diverted
51to that port by
52.Xr ipfw 4 .
53Packets may also be written to a divert port, in which case they re-enter
54firewall processing at the next rule.
55.Pp
56By reading from and writing to a divert socket, matching packets
57can be passed through an arbitrary ``filter'' as they travel through
58the host machine, special routing tricks can be done, etc.
59.Sh READING PACKETS
60Packets are diverted either as they are ``incoming'' or ``outgoing.''
61Incoming packets are diverted after reception on an IP interface,
62whereas outgoing packets are diverted before next hop forwarding.
63.Pp
64Diverted packets may be read unaltered via
65.Xr read 2 ,
66.Xr recv 2 ,
67or
68.Xr recvfrom 2 .
69In the latter case, the address returned will have its port set to
70some tag supplied by the packet diverter, (usually the ipfw rule number)
71and the IP address set to the (first) address of
72the interface on which the packet was received (if the packet
73was incoming) or
74.Dv INADDR_ANY
75(if the packet was outgoing).
76The interface name (if defined
77for the packet) will be placed in the 8 bytes following the address,
78if it fits.
79.Sh WRITING PACKETS
80Writing to a divert socket is similar to writing to a raw IP socket;
81the packet is injected ``as is'' into the normal kernel IP packet
82processing using
83.Xr sendto 2
84and minimal error checking is done.
85Packets are distinguished as either incoming or outgoing.
86If
87.Xr sendto 2
88is used with a destination IP address of
89.Dv INADDR_ANY ,
90then the packet is treated as if it were outgoing, i.e., destined
91for a non-local address.
92Otherwise, the packet is assumed to be
93incoming and full packet routing is done.
94.Pp
95In the latter case, the
96IP address specified must match the address of some local interface,
97or an interface name
98must be found after the IP address.
99If an interface name is found,
100that interface will be used and the value of the IP address will be
101ignored (other than the fact that it is not
102.Dv INADDR_ANY ) .
103This is to indicate on which interface the packet
104.Dq arrived .
105.Pp
106Normally, packets read as incoming should be written as incoming;
107similarly for outgoing packets.
108When reading and then writing back
109packets, passing the same socket address supplied by
110.Xr recvfrom 2
111unmodified to
112.Xr sendto 2
113simplifies things (see below).
114.Pp
115The port part of the socket address passed to the
116.Xr sendto 2
117contains a tag that should be meaningful to the diversion module.
118In the
119case of
120.Xr ipfw 8
121the tag is interpreted as the rule number
122.Em after which
123rule processing should restart.
124.Sh LOOP AVOIDANCE
125Packets written into a divert socket
126(using
127.Xr sendto 2 )
128re-enter the packet filter at the rule number
129following the tag given in the port part of the socket address, which
130is usually already set at the rule number that caused the diversion
131(not the next rule if there are several at the same number).
132If the 'tag'
133is altered to indicate an alternative re-entry point, care should be taken
134to avoid loops, where the same packet is diverted more than once at the
135same rule.
136.Sh DETAILS
137If a packet is diverted but no socket is bound to the
138port, or if
139.Dv IPDIVERT
140is not enabled or loaded in the kernel, the packet is dropped.
141.Pp
142Incoming packet fragments which get diverted are fully reassembled
143before delivery; the diversion of any one fragment causes the entire
144packet to get diverted.
145If different fragments divert to different ports,
146then which port ultimately gets chosen is unpredictable.
147.Pp
148Note that packets arriving on the divert socket by the
149.Xr ipfw 8
150.Cm tee
151action are delivered as-is and packet fragments do not get reassembled
152in this case.
153.Pp
154Packets are received and sent unchanged, except that
155packets read as outgoing have invalid IP header checksums, and
156packets written as outgoing have their IP header checksums overwritten
157with the correct value.
158Packets written as incoming and having incorrect checksums will be dropped.
159Otherwise, all header fields are unchanged (and therefore in network order).
160.Pp
161Creating a
162.Nm
163socket requires super-user access.
164.Sh ERRORS
165Writing to a divert socket can return these errors, along with
166the usual errors possible when writing raw packets:
167.Bl -tag -width Er
168.It Bq Er EINVAL
169The packet had an invalid header, or the IP options in the packet
170and the socket options set were incompatible.
171.It Bq Er EADDRNOTAVAIL
172The destination address contained an IP address not equal to
173.Dv INADDR_ANY
174that was not associated with any interface.
175.El
176.Sh SEE ALSO
177.Xr bind 2 ,
178.Xr recvfrom 2 ,
179.Xr sendto 2 ,
180.Xr socket 2 ,
181.Xr ipfw 4 ,
182.Xr ipfw 8
183.Sh AUTHORS
184.An Archie Cobbs Aq Mt archie@FreeBSD.org ,
185Whistle Communications Corp.
186.Sh BUGS
187This is an attempt to provide a clean way for user mode processes
188to implement various IP tricks like address translation, but it
189could be cleaner, and it is too dependent on
190.Xr ipfw 8 .
191.Pp
192It is questionable whether incoming fragments should be reassembled
193before being diverted.
194For example, if only some fragments of a
195packet destined for another machine do not get routed through the
196local machine, the packet is lost.
197This should probably be
198a settable socket option in any case.
199