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