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