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