17f3dea24SPeter Wemm.\" $FreeBSD$ 20b992c1dSWolfram Schneider.\" 3*8624f434SGleb Smirnoff.Dd August 30, 2022 493e0e116SJulian Elischer.Dt DIVERT 4 53d45e180SRuslan Ermilov.Os 693e0e116SJulian Elischer.Sh NAME 793e0e116SJulian Elischer.Nm divert 893e0e116SJulian Elischer.Nd kernel packet diversion mechanism 993e0e116SJulian Elischer.Sh SYNOPSIS 1032eef9aeSRuslan Ermilov.In sys/types.h 1132eef9aeSRuslan Ermilov.In sys/socket.h 1232eef9aeSRuslan Ermilov.In netinet/in.h 1393e0e116SJulian Elischer.Ft int 14*8624f434SGleb Smirnoff.Fn socket PF_DIVERT SOCK_RAW 0 15e1bd11beSDaniel Gerzo.Pp 16e1bd11beSDaniel GerzoTo enable support for divert sockets, place the following lines in the 17e1bd11beSDaniel Gerzokernel configuration file: 18e1bd11beSDaniel Gerzo.Bd -ragged -offset indent 19e1bd11beSDaniel Gerzo.Cd "options IPFIREWALL" 20e1bd11beSDaniel Gerzo.Cd "options IPDIVERT" 21e1bd11beSDaniel Gerzo.Ed 22e1bd11beSDaniel Gerzo.Pp 23e1bd11beSDaniel GerzoAlternatively, to load 247646a841SJoel Dahlthe driver 25e1bd11beSDaniel Gerzoas a module at boot time, add the following lines into the 26e1bd11beSDaniel Gerzo.Xr loader.conf 5 27e1bd11beSDaniel Gerzofile: 28e1bd11beSDaniel Gerzo.Bd -literal -offset indent 29e1bd11beSDaniel Gerzoipfw_load="YES" 30e1bd11beSDaniel Gerzoipdivert_load="YES" 31e1bd11beSDaniel Gerzo.Ed 3293e0e116SJulian Elischer.Sh DESCRIPTION 33*8624f434SGleb SmirnoffDivert sockets allow to intercept and re-inject packets flowing through 34*8624f434SGleb Smirnoffthe 35*8624f434SGleb Smirnoff.Xr ipfw 4 36*8624f434SGleb Smirnofffirewall. 37*8624f434SGleb SmirnoffA divert socket can be bound to a specific 3893e0e116SJulian Elischer.Nm 3993e0e116SJulian Elischerport via the 4093e0e116SJulian Elischer.Xr bind 2 416d249eeeSSheldon Hearnsystem call. 42*8624f434SGleb SmirnoffThe sockaddr argument shall be sockaddr_in with sin_port set to the 43*8624f434SGleb Smirnoffdesired value. 44*8624f434SGleb SmirnoffNote that the 45*8624f434SGleb Smirnoff.Nm 46*8624f434SGleb Smirnoffport has nothing to do with TCP/UDP ports. 47*8624f434SGleb SmirnoffIt is just a cookie number, that allows to differentiate between different 48*8624f434SGleb Smirnoffdivert points in the 49*8624f434SGleb Smirnoff.Xr ipfw 4 50*8624f434SGleb Smirnoffruleset. 5193e0e116SJulian ElischerA divert socket bound to a divert port will receive all packets diverted 52*8624f434SGleb Smirnoffto that port by 53*8624f434SGleb Smirnoff.Xr ipfw 4 . 54*8624f434SGleb SmirnoffPackets may also be written to a divert port, in which case they re-enter 55*8624f434SGleb Smirnofffirewall processing at the next rule. 5693e0e116SJulian Elischer.Pp 576d249eeeSSheldon HearnBy reading from and writing to a divert socket, matching packets 5893e0e116SJulian Elischercan be passed through an arbitrary ``filter'' as they travel through 5993e0e116SJulian Elischerthe host machine, special routing tricks can be done, etc. 6093e0e116SJulian Elischer.Sh READING PACKETS 6193e0e116SJulian ElischerPackets are diverted either as they are ``incoming'' or ``outgoing.'' 6293e0e116SJulian ElischerIncoming packets are diverted after reception on an IP interface, 6393e0e116SJulian Elischerwhereas outgoing packets are diverted before next hop forwarding. 6493e0e116SJulian Elischer.Pp 6593e0e116SJulian ElischerDiverted packets may be read unaltered via 6693e0e116SJulian Elischer.Xr read 2 , 6793e0e116SJulian Elischer.Xr recv 2 , 6893e0e116SJulian Elischeror 6993e0e116SJulian Elischer.Xr recvfrom 2 . 7093e0e116SJulian ElischerIn the latter case, the address returned will have its port set to 7171678683SGiorgos Keramidassome tag supplied by the packet diverter, (usually the ipfw rule number) 729355ecfcSJulian Elischerand the IP address set to the (first) address of 7309b4b086SMike Pritchardthe interface on which the packet was received (if the packet 7493e0e116SJulian Elischerwas incoming) or 7593e0e116SJulian Elischer.Dv INADDR_ANY 76a10c9747SDaniel Harris(if the packet was outgoing). 77a10c9747SDaniel HarrisThe interface name (if defined 78a10c9747SDaniel Harrisfor the packet) will be placed in the 8 bytes following the address, 79a10c9747SDaniel Harrisif it fits. 8093e0e116SJulian Elischer.Sh WRITING PACKETS 8193e0e116SJulian ElischerWriting to a divert socket is similar to writing to a raw IP socket; 8293e0e116SJulian Elischerthe packet is injected ``as is'' into the normal kernel IP packet 8385432d40SGleb Smirnoffprocessing using 8485432d40SGleb Smirnoff.Xr sendto 2 8585432d40SGleb Smirnoffand minimal error checking is done. 8685432d40SGleb SmirnoffPackets are distinguished as either incoming or outgoing. 8785432d40SGleb SmirnoffIf 8893e0e116SJulian Elischer.Xr sendto 2 8993e0e116SJulian Elischeris used with a destination IP address of 9093e0e116SJulian Elischer.Dv INADDR_ANY , 9193e0e116SJulian Elischerthen the packet is treated as if it were outgoing, i.e., destined 92b5e7e999SRuslan Ermilovfor a non-local address. 93b5e7e999SRuslan ErmilovOtherwise, the packet is assumed to be 9493e0e116SJulian Elischerincoming and full packet routing is done. 9593e0e116SJulian Elischer.Pp 9693e0e116SJulian ElischerIn the latter case, the 97436c7212SJulian ElischerIP address specified must match the address of some local interface, 98436c7212SJulian Elischeror an interface name 996d249eeeSSheldon Hearnmust be found after the IP address. 1006d249eeeSSheldon HearnIf an interface name is found, 101436c7212SJulian Elischerthat interface will be used and the value of the IP address will be 102436c7212SJulian Elischerignored (other than the fact that it is not 10394ba280cSRuslan Ermilov.Dv INADDR_ANY ) . 104b5e7e999SRuslan ErmilovThis is to indicate on which interface the packet 105b5e7e999SRuslan Ermilov.Dq arrived . 10693e0e116SJulian Elischer.Pp 10793e0e116SJulian ElischerNormally, packets read as incoming should be written as incoming; 108b5e7e999SRuslan Ermilovsimilarly for outgoing packets. 109b5e7e999SRuslan ErmilovWhen reading and then writing back 11093e0e116SJulian Elischerpackets, passing the same socket address supplied by 11193e0e116SJulian Elischer.Xr recvfrom 2 11293e0e116SJulian Elischerunmodified to 11393e0e116SJulian Elischer.Xr sendto 2 1149355ecfcSJulian Elischersimplifies things (see below). 1159355ecfcSJulian Elischer.Pp 1169355ecfcSJulian ElischerThe port part of the socket address passed to the 1179355ecfcSJulian Elischer.Xr sendto 2 1186d249eeeSSheldon Hearncontains a tag that should be meaningful to the diversion module. 1196d249eeeSSheldon HearnIn the 1209355ecfcSJulian Elischercase of 121f38ca148SRuslan Ermilov.Xr ipfw 8 122f38ca148SRuslan Ermilovthe tag is interpreted as the rule number 1239355ecfcSJulian Elischer.Em after which 1249355ecfcSJulian Elischerrule processing should restart. 12593e0e116SJulian Elischer.Sh LOOP AVOIDANCE 126d7ec3e91SRuslan ErmilovPackets written into a divert socket 127c4d9468eSRuslan Ermilov(using 128c4d9468eSRuslan Ermilov.Xr sendto 2 ) 129d7ec3e91SRuslan Ermilovre-enter the packet filter at the rule number 1309355ecfcSJulian Elischerfollowing the tag given in the port part of the socket address, which 1319355ecfcSJulian Elischeris usually already set at the rule number that caused the diversion 1325203edcdSRuslan Ermilov(not the next rule if there are several at the same number). 1335203edcdSRuslan ErmilovIf the 'tag' 1349355ecfcSJulian Elischeris altered to indicate an alternative re-entry point, care should be taken 1359355ecfcSJulian Elischerto avoid loops, where the same packet is diverted more than once at the 1369355ecfcSJulian Elischersame rule. 13793e0e116SJulian Elischer.Sh DETAILS 13893e0e116SJulian ElischerIf a packet is diverted but no socket is bound to the 13993e0e116SJulian Elischerport, or if 14093e0e116SJulian Elischer.Dv IPDIVERT 14124fc79b0SAndre Oppermannis not enabled or loaded in the kernel, the packet is dropped. 14293e0e116SJulian Elischer.Pp 14393e0e116SJulian ElischerIncoming packet fragments which get diverted are fully reassembled 14493e0e116SJulian Elischerbefore delivery; the diversion of any one fragment causes the entire 14593e0e116SJulian Elischerpacket to get diverted. 14693e0e116SJulian ElischerIf different fragments divert to different ports, 14793e0e116SJulian Elischerthen which port ultimately gets chosen is unpredictable. 14893e0e116SJulian Elischer.Pp 14913177659SAndre OppermannNote that packets arriving on the divert socket by the 15013177659SAndre Oppermann.Xr ipfw 8 15113177659SAndre Oppermann.Cm tee 15213177659SAndre Oppermannaction are delivered as-is and packet fragments do not get reassembled 15313177659SAndre Oppermannin this case. 15413177659SAndre Oppermann.Pp 15504f36f75SBrian SomersPackets are received and sent unchanged, except that 156dd121c1eSArchie Cobbspackets read as outgoing have invalid IP header checksums, and 15704f36f75SBrian Somerspackets written as outgoing have their IP header checksums overwritten 15893e0e116SJulian Elischerwith the correct value. 15993e0e116SJulian ElischerPackets written as incoming and having incorrect checksums will be dropped. 16093e0e116SJulian ElischerOtherwise, all header fields are unchanged (and therefore in network order). 16193e0e116SJulian Elischer.Pp 16204f36f75SBrian SomersBinding to port numbers less than 1024 requires super-user access, as does 163*8624f434SGleb Smirnoffcreating a 164*8624f434SGleb Smirnoff.Nm 165*8624f434SGleb Smirnoffsocket. 16693e0e116SJulian Elischer.Sh ERRORS 16793e0e116SJulian ElischerWriting to a divert socket can return these errors, along with 16893e0e116SJulian Elischerthe usual errors possible when writing raw packets: 16993e0e116SJulian Elischer.Bl -tag -width Er 17093e0e116SJulian Elischer.It Bq Er EINVAL 17193e0e116SJulian ElischerThe packet had an invalid header, or the IP options in the packet 17293e0e116SJulian Elischerand the socket options set were incompatible. 17393e0e116SJulian Elischer.It Bq Er EADDRNOTAVAIL 17493e0e116SJulian ElischerThe destination address contained an IP address not equal to 17593e0e116SJulian Elischer.Dv INADDR_ANY 17693e0e116SJulian Elischerthat was not associated with any interface. 17793e0e116SJulian Elischer.El 17893e0e116SJulian Elischer.Sh SEE ALSO 17993e0e116SJulian Elischer.Xr bind 2 , 1800b992c1dSWolfram Schneider.Xr recvfrom 2 , 181aab5e1b6SMike Pritchard.Xr sendto 2 , 1820b992c1dSWolfram Schneider.Xr socket 2 , 183e1bd11beSDaniel Gerzo.Xr ipfw 4 , 1840b992c1dSWolfram Schneider.Xr ipfw 8 1859cbda590SRuslan Ermilov.Sh AUTHORS 1866c899950SBaptiste Daroussin.An Archie Cobbs Aq Mt archie@FreeBSD.org , 1879cbda590SRuslan ErmilovWhistle Communications Corp. 18893e0e116SJulian Elischer.Sh BUGS 18993e0e116SJulian ElischerThis is an attempt to provide a clean way for user mode processes 19093e0e116SJulian Elischerto implement various IP tricks like address translation, but it 19136a142c4SRuslan Ermilovcould be cleaner, and it is too dependent on 19293e0e116SJulian Elischer.Xr ipfw 8 . 19393e0e116SJulian Elischer.Pp 19436a142c4SRuslan ErmilovIt is questionable whether incoming fragments should be reassembled 1956d249eeeSSheldon Hearnbefore being diverted. 1966d249eeeSSheldon HearnFor example, if only some fragments of a 1970227791bSRuslan Ermilovpacket destined for another machine do not get routed through the 1986d249eeeSSheldon Hearnlocal machine, the packet is lost. 1996d249eeeSSheldon HearnThis should probably be 20093e0e116SJulian Elischera settable socket option in any case. 201