17f3dea24SPeter Wemm.\" $FreeBSD$ 20b992c1dSWolfram Schneider.\" 393e0e116SJulian Elischer.Dd June 18, 1996 493e0e116SJulian Elischer.Dt DIVERT 4 593e0e116SJulian Elischer.Os FreeBSD 693e0e116SJulian Elischer.Sh NAME 793e0e116SJulian Elischer.Nm divert 893e0e116SJulian Elischer.Nd kernel packet diversion mechanism 993e0e116SJulian Elischer.Sh SYNOPSIS 10ddbd0698SBruce Evans.Fd #include <sys/types.h> 1193e0e116SJulian Elischer.Fd #include <sys/socket.h> 1293e0e116SJulian Elischer.Fd #include <netinet/in.h> 1393e0e116SJulian Elischer.Ft int 1493e0e116SJulian Elischer.Fn socket PF_INET SOCK_RAW IPPROTO_DIVERT 1593e0e116SJulian Elischer.Sh DESCRIPTION 1693e0e116SJulian Elischer.Pp 1793e0e116SJulian ElischerDivert sockets are similar to raw IP sockets, except that they 1893e0e116SJulian Elischercan be bound to a specific 1993e0e116SJulian Elischer.Nm 2093e0e116SJulian Elischerport via the 2193e0e116SJulian Elischer.Xr bind 2 2293e0e116SJulian Elischersystem call. The IP address in the bind is ignored; only the port 2393e0e116SJulian Elischernumber is significant. 2493e0e116SJulian ElischerA divert socket bound to a divert port will receive all packets diverted 2593e0e116SJulian Elischerto that port by some (here unspecified) kernel mechanism(s). 2693e0e116SJulian ElischerPackets may also be written to a divert port, in which case they 2793e0e116SJulian Elischerre-enter kernel IP packet processing. 2893e0e116SJulian Elischer.Pp 2993e0e116SJulian ElischerDivert sockets are normally used in conjunction with 3093e0e116SJulian ElischerFreeBSD's packet filtering implementation and the 3193e0e116SJulian Elischer.Xr ipfw 8 3293e0e116SJulian Elischerprogram. By reading from and writing to a divert socket, matching packets 3393e0e116SJulian Elischercan be passed through an arbitrary ``filter'' as they travel through 3493e0e116SJulian Elischerthe host machine, special routing tricks can be done, etc. 3593e0e116SJulian Elischer.Sh READING PACKETS 3693e0e116SJulian ElischerPackets are diverted either as they are ``incoming'' or ``outgoing.'' 3793e0e116SJulian ElischerIncoming packets are diverted after reception on an IP interface, 3893e0e116SJulian Elischerwhereas outgoing packets are diverted before next hop forwarding. 3993e0e116SJulian Elischer.Pp 4093e0e116SJulian ElischerDiverted packets may be read unaltered via 4193e0e116SJulian Elischer.Xr read 2 , 4293e0e116SJulian Elischer.Xr recv 2 , 4393e0e116SJulian Elischeror 4493e0e116SJulian Elischer.Xr recvfrom 2 . 4593e0e116SJulian ElischerIn the latter case, the address returned will have its port set to 469355ecfcSJulian Elischerthe some tag supplied by the packet diverter, (usually the ipfw rule number) 479355ecfcSJulian Elischerand the IP address set to the (first) address of 4809b4b086SMike Pritchardthe interface on which the packet was received (if the packet 4993e0e116SJulian Elischerwas incoming) or 5093e0e116SJulian Elischer.Dv INADDR_ANY 51436c7212SJulian Elischer(if the packet was outgoing). In the case of an incoming packet the interface 52436c7212SJulian Elischername will also be placed in the 8 bytes following the address, 53436c7212SJulian Elischer(assuming it fits). 5493e0e116SJulian Elischer.Sh WRITING PACKETS 5593e0e116SJulian ElischerWriting to a divert socket is similar to writing to a raw IP socket; 5693e0e116SJulian Elischerthe packet is injected ``as is'' into the normal kernel IP packet 5793e0e116SJulian Elischerprocessing and minimal error checking is done. 5893e0e116SJulian ElischerPackets are written as either incoming or outgoing: 5993e0e116SJulian Elischerif 6093e0e116SJulian Elischer.Xr write 2 6193e0e116SJulian Elischeror 6293e0e116SJulian Elischer.Xr send 2 6393e0e116SJulian Elischeris used to deliver the packet, or if 6493e0e116SJulian Elischer.Xr sendto 2 6593e0e116SJulian Elischeris used with a destination IP address of 6693e0e116SJulian Elischer.Dv INADDR_ANY , 6793e0e116SJulian Elischerthen the packet is treated as if it were outgoing, i.e., destined 6893e0e116SJulian Elischerfor a non-local address. Otherwise, the packet is assumed to be 6993e0e116SJulian Elischerincoming and full packet routing is done. 7093e0e116SJulian Elischer.Pp 7193e0e116SJulian ElischerIn the latter case, the 72436c7212SJulian ElischerIP address specified must match the address of some local interface, 73436c7212SJulian Elischeror an interface name 74436c7212SJulian Elischermust be found after the IP address. If an interface name is found, 75436c7212SJulian Elischerthat interface will be used and the value of the IP address will be 76436c7212SJulian Elischerignored (other than the fact that it is not 77436c7212SJulian Elischer.Dv INADDR_ANY 78436c7212SJulian Elischer). 7993e0e116SJulian ElischerThis is to indicate on which interface the packet ``arrived.'' 8093e0e116SJulian Elischer.Pp 8193e0e116SJulian ElischerNormally, packets read as incoming should be written as incoming; 8293e0e116SJulian Elischersimilarly for outgoing packets. When reading and then writing back 8393e0e116SJulian Elischerpackets, passing the same socket address supplied by 8493e0e116SJulian Elischer.Xr recvfrom 2 8593e0e116SJulian Elischerunmodified to 8693e0e116SJulian Elischer.Xr sendto 2 879355ecfcSJulian Elischersimplifies things (see below). 889355ecfcSJulian Elischer.Pp 899355ecfcSJulian ElischerThe port part of the socket address passed to the 909355ecfcSJulian Elischer.Xr sendto 2 919355ecfcSJulian Elischercontains a tag that should be meaningful to the diversion module. In the 929355ecfcSJulian Elischercase of 939355ecfcSJulian Elischer.Xr Ipfw 8 949355ecfcSJulian Elischerthe tag is interpretted as the rule number 959355ecfcSJulian Elischer.Em after which 969355ecfcSJulian Elischerrule processing should restart. 9793e0e116SJulian Elischer.Sh LOOP AVOIDANCE 98d7ec3e91SRuslan ErmilovPackets written into a divert socket 99d7ec3e91SRuslan Ermilov.Po 100d7ec3e91SRuslan Ermilovusing 1019355ecfcSJulian Elischer.Xr sendto 2 102d7ec3e91SRuslan Ermilov.Pc 103d7ec3e91SRuslan Ermilovre-enter the packet filter at the rule number 1049355ecfcSJulian Elischerfollowing the tag given in the port part of the socket address, which 1059355ecfcSJulian Elischeris usually already set at the rule number that caused the diversion 1069355ecfcSJulian Elischer(not the next rule if there are several at the same number). If the 'tag' 1079355ecfcSJulian Elischeris altered to indicate an alternative re-entry point, care should be taken 1089355ecfcSJulian Elischerto avoid loops, where the same packet is diverted more than once at the 1099355ecfcSJulian Elischersame rule. 11093e0e116SJulian Elischer.Sh DETAILS 11193e0e116SJulian ElischerTo enable divert sockets, your kernel must be compiled with the option 11293e0e116SJulian Elischer.Dv IPDIVERT . 11393e0e116SJulian Elischer.Pp 11493e0e116SJulian ElischerIf a packet is diverted but no socket is bound to the 11593e0e116SJulian Elischerport, or if 11693e0e116SJulian Elischer.Dv IPDIVERT 11793e0e116SJulian Elischeris not enabled in the kernel, the packet is dropped. 11893e0e116SJulian Elischer.Pp 11993e0e116SJulian ElischerIncoming packet fragments which get diverted are fully reassembled 12093e0e116SJulian Elischerbefore delivery; the diversion of any one fragment causes the entire 12193e0e116SJulian Elischerpacket to get diverted. 12293e0e116SJulian ElischerIf different fragments divert to different ports, 12393e0e116SJulian Elischerthen which port ultimately gets chosen is unpredictable. 12493e0e116SJulian Elischer.Pp 12504f36f75SBrian SomersPackets are received and sent unchanged, except that 12604f36f75SBrian Somerspackets written as outgoing have their IP header checksums overwritten 12793e0e116SJulian Elischerwith the correct value. 12893e0e116SJulian ElischerPackets written as incoming and having incorrect checksums will be dropped. 12993e0e116SJulian ElischerOtherwise, all header fields are unchanged (and therefore in network order). 13093e0e116SJulian Elischer.Pp 13104f36f75SBrian SomersBinding to port numbers less than 1024 requires super-user access, as does 13204f36f75SBrian Somerscreating a socket of type SOCK_RAW. 13393e0e116SJulian Elischer.Sh ERRORS 13493e0e116SJulian ElischerWriting to a divert socket can return these errors, along with 13593e0e116SJulian Elischerthe usual errors possible when writing raw packets: 13693e0e116SJulian Elischer.Bl -tag -width Er 13793e0e116SJulian Elischer.It Bq Er EINVAL 13893e0e116SJulian ElischerThe packet had an invalid header, or the IP options in the packet 13993e0e116SJulian Elischerand the socket options set were incompatible. 14093e0e116SJulian Elischer.It Bq Er EADDRNOTAVAIL 14193e0e116SJulian ElischerThe destination address contained an IP address not equal to 14293e0e116SJulian Elischer.Dv INADDR_ANY 14393e0e116SJulian Elischerthat was not associated with any interface. 14493e0e116SJulian Elischer.El 14593e0e116SJulian Elischer.Sh SEE ALSO 14693e0e116SJulian Elischer.Xr bind 2 , 1470b992c1dSWolfram Schneider.Xr recvfrom 2 , 148aab5e1b6SMike Pritchard.Xr sendto 2 , 1490b992c1dSWolfram Schneider.Xr socket 2 , 1500b992c1dSWolfram Schneider.Xr ipfw 8 15193e0e116SJulian Elischer.Sh BUGS 15293e0e116SJulian ElischerThis is an attempt to provide a clean way for user mode processes 15393e0e116SJulian Elischerto implement various IP tricks like address translation, but it 15493e0e116SJulian Elischercould be cleaner, and it's too dependent on 15593e0e116SJulian Elischer.Xr ipfw 8 . 15693e0e116SJulian Elischer.Pp 15793e0e116SJulian ElischerIt's questionable whether incoming fragments should be reassembled 15893e0e116SJulian Elischerbefore being diverted. For example, if only some fragments of a 15993e0e116SJulian Elischerpacket destined for another machine don't get routed through the 16093e0e116SJulian Elischerlocal machine, the packet is lost. This should probably be 16193e0e116SJulian Elischera settable socket option in any case. 162aaf1f16eSPhilippe Charnier.Sh AUTHORS 163aaf1f16eSPhilippe Charnier.An Archie Cobbs Aq archie@whistle.com , 164aaf1f16eSPhilippe CharnierWhistle Communications Corp. 165