1.\" $Id: divert.4,v 1.7 1997/02/22 13:24:27 peter Exp $ 2.\" 3.Dd June 18, 1996 4.Dt DIVERT 4 5.Os FreeBSD 6.Sh NAME 7.Nm divert 8.Nd kernel packet diversion mechanism 9.Sh SYNOPSIS 10.Fd #include <sys/types.h> 11.Fd #include <sys/socket.h> 12.Fd #include <netinet/in.h> 13.Ft int 14.Fn socket PF_INET SOCK_RAW IPPROTO_DIVERT 15.Sh DESCRIPTION 16.Pp 17Divert sockets are similar to raw IP sockets, except that they 18can be bound to a specific 19.Nm 20port via the 21.Xr bind 2 22system call. The IP address in the bind is ignored; only the port 23number is significant. 24A divert socket bound to a divert port will receive all packets diverted 25to that port by some (here unspecified) kernel mechanism(s). 26Packets may also be written to a divert port, in which case they 27re-enter kernel IP packet processing. 28.Pp 29Divert sockets are normally used in conjunction with 30FreeBSD's packet filtering implementation and the 31.Xr ipfw 8 32program. By reading from and writing to a divert socket, matching packets 33can be passed through an arbitrary ``filter'' as they travel through 34the host machine, special routing tricks can be done, etc. 35.Sh READING PACKETS 36Packets are diverted either as they are ``incoming'' or ``outgoing.'' 37Incoming packets are diverted after reception on an IP interface, 38whereas outgoing packets are diverted before next hop forwarding. 39.Pp 40Diverted packets may be read unaltered via 41.Xr read 2 , 42.Xr recv 2 , 43or 44.Xr recvfrom 2 . 45In the latter case, the address returned will have its port set to 46the divert port and the IP address set to the (first) address of 47the interface on which the packet was received (if the packet 48was incoming) or 49.Dv INADDR_ANY 50(if the packet was outgoing). 51.Sh WRITING PACKETS 52Writing to a divert socket is similar to writing to a raw IP socket; 53the packet is injected ``as is'' into the normal kernel IP packet 54processing and minimal error checking is done. 55Packets are written as either incoming or outgoing: 56if 57.Xr write 2 58or 59.Xr send 2 60is used to deliver the packet, or if 61.Xr sendto 2 62is used with a destination IP address of 63.Dv INADDR_ANY , 64then the packet is treated as if it were outgoing, i.e., destined 65for a non-local address. Otherwise, the packet is assumed to be 66incoming and full packet routing is done. 67.Pp 68In the latter case, the 69IP address specified must match the address of some local interface. 70This is to indicate on which interface the packet ``arrived.'' 71.Pp 72Normally, packets read as incoming should be written as incoming; 73similarly for outgoing packets. When reading and then writing back 74packets, passing the same socket address supplied by 75.Xr recvfrom 2 76unmodified to 77.Xr sendto 2 78simplifies things. 79.Sh LOOP AVOIDANCE 80To avoid having a packet sent from a divert socket rediverted back 81to the same socket, use the 82.Xr sendto 2 83system call supplying any non-zero destination port number. 84This indicates to 85.Xr ipfw 8 86and other diverting mechanisms to not divert the packet back 87to the same socket it was written from. 88.Pp 89Since 90.Xr ipfw 91checks incoming as well as outgoing packets, 92a packet written as incoming may get checked twice. 93Loop avoidance will be enabled for both checks. 94.Sh DETAILS 95To enable divert sockets, your kernel must be compiled with the option 96.Dv IPDIVERT . 97.Pp 98If a packet is diverted but no socket is bound to the 99port, or if 100.Dv IPDIVERT 101is not enabled in the kernel, the packet is dropped. 102.Pp 103Incoming packet fragments which get diverted are fully reassembled 104before delivery; the diversion of any one fragment causes the entire 105packet to get diverted. 106If different fragments divert to different ports, 107then which port ultimately gets chosen is unpredictable. 108.Pp 109Packets are received and sent unchanged, except that 110packets written as outgoing have their IP header checksums overwritten 111with the correct value. 112Packets written as incoming and having incorrect checksums will be dropped. 113Otherwise, all header fields are unchanged (and therefore in network order). 114.Pp 115Binding to port numbers less than 1024 requires super-user access, as does 116creating a socket of type SOCK_RAW. 117.Sh ERRORS 118Writing to a divert socket can return these errors, along with 119the usual errors possible when writing raw packets: 120.Bl -tag -width Er 121.It Bq Er EINVAL 122The packet had an invalid header, or the IP options in the packet 123and the socket options set were incompatible. 124.It Bq Er EADDRNOTAVAIL 125The destination address contained an IP address not equal to 126.Dv INADDR_ANY 127that was not associated with any interface. 128.El 129.Sh SEE ALSO 130.Xr bind 2 , 131.Xr recvfrom 2 , 132.Xr sendto 2 , 133.Xr socket 2 , 134.Xr ipfw 8 135.Sh BUGS 136This is an attempt to provide a clean way for user mode processes 137to implement various IP tricks like address translation, but it 138could be cleaner, and it's too dependent on 139.Xr ipfw 8 . 140.Pp 141It's questionable whether incoming fragments should be reassembled 142before being diverted. For example, if only some fragments of a 143packet destined for another machine don't get routed through the 144local machine, the packet is lost. This should probably be 145a settable socket option in any case. 146.Sh AUTHOR 147Archie Cobbs <archie@whistle.com>, Whistle Communications Corp. 148