xref: /freebsd/share/man/man4/divert.4 (revision b2c76c41be32f904179efed29c0ca04d53f3996c)
10b992c1dSWolfram Schneider.\"
28624f434SGleb Smirnoff.Dd August 30, 2022
393e0e116SJulian Elischer.Dt DIVERT 4
43d45e180SRuslan Ermilov.Os
593e0e116SJulian Elischer.Sh NAME
693e0e116SJulian Elischer.Nm divert
793e0e116SJulian Elischer.Nd kernel packet diversion mechanism
893e0e116SJulian Elischer.Sh SYNOPSIS
932eef9aeSRuslan Ermilov.In sys/types.h
1032eef9aeSRuslan Ermilov.In sys/socket.h
1132eef9aeSRuslan Ermilov.In netinet/in.h
1293e0e116SJulian Elischer.Ft int
138624f434SGleb Smirnoff.Fn socket PF_DIVERT SOCK_RAW 0
14e1bd11beSDaniel Gerzo.Pp
15e1bd11beSDaniel GerzoTo enable support for divert sockets, place the following lines in the
16e1bd11beSDaniel Gerzokernel configuration file:
17e1bd11beSDaniel Gerzo.Bd -ragged -offset indent
18e1bd11beSDaniel Gerzo.Cd "options IPFIREWALL"
19e1bd11beSDaniel Gerzo.Cd "options IPDIVERT"
20e1bd11beSDaniel Gerzo.Ed
21e1bd11beSDaniel Gerzo.Pp
22e1bd11beSDaniel GerzoAlternatively, to load
237646a841SJoel Dahlthe driver
24e1bd11beSDaniel Gerzoas a module at boot time, add the following lines into the
25e1bd11beSDaniel Gerzo.Xr loader.conf 5
26e1bd11beSDaniel Gerzofile:
27e1bd11beSDaniel Gerzo.Bd -literal -offset indent
28e1bd11beSDaniel Gerzoipfw_load="YES"
29e1bd11beSDaniel Gerzoipdivert_load="YES"
30e1bd11beSDaniel Gerzo.Ed
3193e0e116SJulian Elischer.Sh DESCRIPTION
328624f434SGleb SmirnoffDivert sockets allow to intercept and re-inject packets flowing through
338624f434SGleb Smirnoffthe
348624f434SGleb Smirnoff.Xr ipfw 4
358624f434SGleb Smirnofffirewall.
368624f434SGleb SmirnoffA divert socket can be bound to a specific
3793e0e116SJulian Elischer.Nm
3893e0e116SJulian Elischerport via the
3993e0e116SJulian Elischer.Xr bind 2
406d249eeeSSheldon Hearnsystem call.
418624f434SGleb SmirnoffThe sockaddr argument shall be sockaddr_in with sin_port set to the
428624f434SGleb Smirnoffdesired value.
438624f434SGleb SmirnoffNote that the
448624f434SGleb Smirnoff.Nm
458624f434SGleb Smirnoffport has nothing to do with TCP/UDP ports.
468624f434SGleb SmirnoffIt is just a cookie number, that allows to differentiate between different
478624f434SGleb Smirnoffdivert points in the
488624f434SGleb Smirnoff.Xr ipfw 4
498624f434SGleb Smirnoffruleset.
5093e0e116SJulian ElischerA divert socket bound to a divert port will receive all packets diverted
518624f434SGleb Smirnoffto that port by
528624f434SGleb Smirnoff.Xr ipfw 4 .
538624f434SGleb SmirnoffPackets may also be written to a divert port, in which case they re-enter
548624f434SGleb Smirnofffirewall processing at the next rule.
5593e0e116SJulian Elischer.Pp
566d249eeeSSheldon HearnBy reading from and writing to a divert socket, matching packets
5793e0e116SJulian Elischercan be passed through an arbitrary ``filter'' as they travel through
5893e0e116SJulian Elischerthe host machine, special routing tricks can be done, etc.
5993e0e116SJulian Elischer.Sh READING PACKETS
6093e0e116SJulian ElischerPackets are diverted either as they are ``incoming'' or ``outgoing.''
6193e0e116SJulian ElischerIncoming packets are diverted after reception on an IP interface,
6293e0e116SJulian Elischerwhereas outgoing packets are diverted before next hop forwarding.
6393e0e116SJulian Elischer.Pp
6493e0e116SJulian ElischerDiverted packets may be read unaltered via
6593e0e116SJulian Elischer.Xr read 2 ,
6693e0e116SJulian Elischer.Xr recv 2 ,
6793e0e116SJulian Elischeror
6893e0e116SJulian Elischer.Xr recvfrom 2 .
6993e0e116SJulian ElischerIn the latter case, the address returned will have its port set to
7071678683SGiorgos Keramidassome tag supplied by the packet diverter, (usually the ipfw rule number)
719355ecfcSJulian Elischerand the IP address set to the (first) address of
7209b4b086SMike Pritchardthe interface on which the packet was received (if the packet
7393e0e116SJulian Elischerwas incoming) or
7493e0e116SJulian Elischer.Dv INADDR_ANY
75a10c9747SDaniel Harris(if the packet was outgoing).
76a10c9747SDaniel HarrisThe interface name (if defined
77a10c9747SDaniel Harrisfor the packet) will be placed in the 8 bytes following the address,
78a10c9747SDaniel Harrisif it fits.
7993e0e116SJulian Elischer.Sh WRITING PACKETS
8093e0e116SJulian ElischerWriting to a divert socket is similar to writing to a raw IP socket;
8193e0e116SJulian Elischerthe packet is injected ``as is'' into the normal kernel IP packet
8285432d40SGleb Smirnoffprocessing using
8385432d40SGleb Smirnoff.Xr sendto 2
8485432d40SGleb Smirnoffand minimal error checking is done.
8585432d40SGleb SmirnoffPackets are distinguished as either incoming or outgoing.
8685432d40SGleb SmirnoffIf
8793e0e116SJulian Elischer.Xr sendto 2
8893e0e116SJulian Elischeris used with a destination IP address of
8993e0e116SJulian Elischer.Dv INADDR_ANY ,
9093e0e116SJulian Elischerthen the packet is treated as if it were outgoing, i.e., destined
91b5e7e999SRuslan Ermilovfor a non-local address.
92b5e7e999SRuslan ErmilovOtherwise, the packet is assumed to be
9393e0e116SJulian Elischerincoming and full packet routing is done.
9493e0e116SJulian Elischer.Pp
9593e0e116SJulian ElischerIn the latter case, the
96436c7212SJulian ElischerIP address specified must match the address of some local interface,
97436c7212SJulian Elischeror an interface name
986d249eeeSSheldon Hearnmust be found after the IP address.
996d249eeeSSheldon HearnIf an interface name is found,
100436c7212SJulian Elischerthat interface will be used and the value of the IP address will be
101436c7212SJulian Elischerignored (other than the fact that it is not
10294ba280cSRuslan Ermilov.Dv INADDR_ANY ) .
103b5e7e999SRuslan ErmilovThis is to indicate on which interface the packet
104b5e7e999SRuslan Ermilov.Dq arrived .
10593e0e116SJulian Elischer.Pp
10693e0e116SJulian ElischerNormally, packets read as incoming should be written as incoming;
107b5e7e999SRuslan Ermilovsimilarly for outgoing packets.
108b5e7e999SRuslan ErmilovWhen reading and then writing back
10993e0e116SJulian Elischerpackets, passing the same socket address supplied by
11093e0e116SJulian Elischer.Xr recvfrom 2
11193e0e116SJulian Elischerunmodified to
11293e0e116SJulian Elischer.Xr sendto 2
1139355ecfcSJulian Elischersimplifies things (see below).
1149355ecfcSJulian Elischer.Pp
1159355ecfcSJulian ElischerThe port part of the socket address passed to the
1169355ecfcSJulian Elischer.Xr sendto 2
1176d249eeeSSheldon Hearncontains a tag that should be meaningful to the diversion module.
1186d249eeeSSheldon HearnIn the
1199355ecfcSJulian Elischercase of
120f38ca148SRuslan Ermilov.Xr ipfw 8
121f38ca148SRuslan Ermilovthe tag is interpreted as the rule number
1229355ecfcSJulian Elischer.Em after which
1239355ecfcSJulian Elischerrule processing should restart.
12493e0e116SJulian Elischer.Sh LOOP AVOIDANCE
125d7ec3e91SRuslan ErmilovPackets written into a divert socket
126c4d9468eSRuslan Ermilov(using
127c4d9468eSRuslan Ermilov.Xr sendto 2 )
128d7ec3e91SRuslan Ermilovre-enter the packet filter at the rule number
1299355ecfcSJulian Elischerfollowing the tag given in the port part of the socket address, which
1309355ecfcSJulian Elischeris usually already set at the rule number that caused the diversion
1315203edcdSRuslan Ermilov(not the next rule if there are several at the same number).
1325203edcdSRuslan ErmilovIf the 'tag'
1339355ecfcSJulian Elischeris altered to indicate an alternative re-entry point, care should be taken
1349355ecfcSJulian Elischerto avoid loops, where the same packet is diverted more than once at the
1359355ecfcSJulian Elischersame rule.
13693e0e116SJulian Elischer.Sh DETAILS
13793e0e116SJulian ElischerIf a packet is diverted but no socket is bound to the
13893e0e116SJulian Elischerport, or if
13993e0e116SJulian Elischer.Dv IPDIVERT
14024fc79b0SAndre Oppermannis not enabled or loaded in the kernel, the packet is dropped.
14193e0e116SJulian Elischer.Pp
14293e0e116SJulian ElischerIncoming packet fragments which get diverted are fully reassembled
14393e0e116SJulian Elischerbefore delivery; the diversion of any one fragment causes the entire
14493e0e116SJulian Elischerpacket to get diverted.
14593e0e116SJulian ElischerIf different fragments divert to different ports,
14693e0e116SJulian Elischerthen which port ultimately gets chosen is unpredictable.
14793e0e116SJulian Elischer.Pp
14813177659SAndre OppermannNote that packets arriving on the divert socket by the
14913177659SAndre Oppermann.Xr ipfw 8
15013177659SAndre Oppermann.Cm tee
15113177659SAndre Oppermannaction are delivered as-is and packet fragments do not get reassembled
15213177659SAndre Oppermannin this case.
15313177659SAndre Oppermann.Pp
15404f36f75SBrian SomersPackets are received and sent unchanged, except that
155dd121c1eSArchie Cobbspackets read as outgoing have invalid IP header checksums, and
15604f36f75SBrian Somerspackets written as outgoing have their IP header checksums overwritten
15793e0e116SJulian Elischerwith the correct value.
15893e0e116SJulian ElischerPackets written as incoming and having incorrect checksums will be dropped.
15993e0e116SJulian ElischerOtherwise, all header fields are unchanged (and therefore in network order).
16093e0e116SJulian Elischer.Pp
161*f1fb0517SGleb SmirnoffCreating a
1628624f434SGleb Smirnoff.Nm
163*f1fb0517SGleb Smirnoffsocket requires super-user access.
16493e0e116SJulian Elischer.Sh ERRORS
16593e0e116SJulian ElischerWriting to a divert socket can return these errors, along with
16693e0e116SJulian Elischerthe usual errors possible when writing raw packets:
16793e0e116SJulian Elischer.Bl -tag -width Er
16893e0e116SJulian Elischer.It Bq Er EINVAL
16993e0e116SJulian ElischerThe packet had an invalid header, or the IP options in the packet
17093e0e116SJulian Elischerand the socket options set were incompatible.
17193e0e116SJulian Elischer.It Bq Er EADDRNOTAVAIL
17293e0e116SJulian ElischerThe destination address contained an IP address not equal to
17393e0e116SJulian Elischer.Dv INADDR_ANY
17493e0e116SJulian Elischerthat was not associated with any interface.
17593e0e116SJulian Elischer.El
17693e0e116SJulian Elischer.Sh SEE ALSO
17793e0e116SJulian Elischer.Xr bind 2 ,
1780b992c1dSWolfram Schneider.Xr recvfrom 2 ,
179aab5e1b6SMike Pritchard.Xr sendto 2 ,
1800b992c1dSWolfram Schneider.Xr socket 2 ,
181e1bd11beSDaniel Gerzo.Xr ipfw 4 ,
1820b992c1dSWolfram Schneider.Xr ipfw 8
1839cbda590SRuslan Ermilov.Sh AUTHORS
1846c899950SBaptiste Daroussin.An Archie Cobbs Aq Mt archie@FreeBSD.org ,
1859cbda590SRuslan ErmilovWhistle Communications Corp.
18693e0e116SJulian Elischer.Sh BUGS
18793e0e116SJulian ElischerThis is an attempt to provide a clean way for user mode processes
18893e0e116SJulian Elischerto implement various IP tricks like address translation, but it
18936a142c4SRuslan Ermilovcould be cleaner, and it is too dependent on
19093e0e116SJulian Elischer.Xr ipfw 8 .
19193e0e116SJulian Elischer.Pp
19236a142c4SRuslan ErmilovIt is questionable whether incoming fragments should be reassembled
1936d249eeeSSheldon Hearnbefore being diverted.
1946d249eeeSSheldon HearnFor example, if only some fragments of a
1950227791bSRuslan Ermilovpacket destined for another machine do not get routed through the
1966d249eeeSSheldon Hearnlocal machine, the packet is lost.
1976d249eeeSSheldon HearnThis should probably be
19893e0e116SJulian Elischera settable socket option in any case.
199