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