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