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