735 lines
23 KiB
Plaintext
735 lines
23 KiB
Plaintext
Divert Sockets mini-HOWTO
|
||
Ilia Baldine, ibaldin@anr.mcnc.org
|
||
v1.1, 27 February 2000
|
||
|
||
This document describes how to get, compile and use FreeBSD divert
|
||
sockets under Linux 2.2.12.
|
||
______________________________________________________________________
|
||
|
||
Table of Contents
|
||
|
||
|
||
1. Copyright
|
||
|
||
2. Disclaimer
|
||
|
||
3. Foreword
|
||
|
||
4. Introduction
|
||
|
||
5. Getting and Compiling the Source Code
|
||
|
||
5.1 Getting *The Source*
|
||
5.2 Compiling
|
||
5.2.1 AID CDATA comp-time
|
||
|
||
6. Using Divert Sockets
|
||
|
||
6.1 Divert sockets vs. other stuff
|
||
6.1.1 Netlink sockets
|
||
6.1.2 Raw sockets
|
||
6.1.3 libpcap
|
||
6.2 Discussion on firewall chains
|
||
6.3 Using ipchains
|
||
6.4 Plain vanilla example
|
||
6.4.1 Example program
|
||
6.5 The sky's the limit
|
||
|
||
7. Advanced issues
|
||
|
||
7.1 Packet Mangling
|
||
7.2 Injection with no interception
|
||
7.3 Fragmentation
|
||
|
||
8. Geting More Information
|
||
|
||
8.1 The website
|
||
8.2 The mailing list
|
||
|
||
9. Future work
|
||
|
||
|
||
|
||
______________________________________________________________________
|
||
|
||
1. Copyright
|
||
|
||
Copyright 1999(c) by Ilia Baldine. This document may be distributed
|
||
only subject to the terms and conditions set forth in the LDP License
|
||
at, except that this document must not be distributed in modified form
|
||
without the author's consent.
|
||
|
||
|
||
2. Disclaimer
|
||
|
||
|
||
|
||
This work has been done as part of a DARPA-funded network security
|
||
project. Neither I (Ilia Baldine), nor my employer (MCNC) nor DARPA
|
||
can be held accountable for any damage real or potential that can come
|
||
to you through the use by you or other parties of the code and/or
|
||
procedures described in this document. As many other network
|
||
mechanisms, divert sockets can be used as much for evil as for good
|
||
and its your choice!
|
||
|
||
|
||
3. Foreword
|
||
|
||
|
||
|
||
Here's an easy game to play,
|
||
Here's an easy thing to say:
|
||
|
||
If a packet hits a pocket
|
||
on a socket on a port
|
||
And the bus is interrupted
|
||
as a very last resort,
|
||
And the address of the memory
|
||
makes your floppy disk abort,
|
||
Then the socket packet pocket
|
||
has an error to report!!
|
||
|
||
If your cursor finds a menu item
|
||
followed by a dash,
|
||
And the double clicking icon puts your
|
||
window in the trash,
|
||
And your data is corrupted 'cause the
|
||
index doesn't hash,
|
||
Then the situation's hopeless, and your
|
||
system's gonna crash!
|
||
|
||
YOU CAN'T SAY THIS? WHAT A SHAME SIR!
|
||
WE'LL FIND ANOTHER GAME SIR
|
||
|
||
If the label on the cable on the table
|
||
at your house,
|
||
Says the network is connected to
|
||
the button on your mouse,
|
||
But your packets want to tunnel
|
||
on another protocol,
|
||
That's repeatedly rejected
|
||
by the printer down the hall,
|
||
And your screen is all distorted
|
||
by the side effects of gauss
|
||
So your icons in the window are
|
||
as wavy as a souse,
|
||
Then you may as well reboot and
|
||
go out with a bang,
|
||
the sucker's gonna hang!
|
||
When the copy of your floppy's
|
||
getting sloppy on the disk
|
||
And the microcode instructions cause
|
||
unnecessary risc,
|
||
Then you have to flash your memory and
|
||
you'll want to RAM your ROM
|
||
Quickly turn off your computer and
|
||
be sure to tell your mom!
|
||
|
||
-- Anonymous
|
||
|
||
|
||
|
||
4. Introduction
|
||
|
||
Ever wish you could intercept packets traveling up or down the IP
|
||
stack of your host? And I'm not talking about listening in, like raw
|
||
sockets or libpcap (tcpdump). I mean literally stop the packet from
|
||
further propagating through the IP stack and then (possibly after some
|
||
changes), reinjecting it back? Well, the time to dream is over,
|
||
because divert sockets for Linux are here!
|
||
|
||
|
||
Divert sockets do exactly that - they filter out certain packets based
|
||
on firewall specifications and bring them to you in user space. You
|
||
then have the freedom of simply reinjecting them back as if nothing
|
||
happened, mangling them first and then reinjecting them, or not
|
||
reinjecting them at all.
|
||
|
||
|
||
As the name suggests, this mechanism utilizes a special type of RAW
|
||
socket called divert (IPPROTO_DIVERT) that allow you to receive and
|
||
send on them just like regular sockets. The difference is that a
|
||
divert socket is bound to a port, into which the firewall can be
|
||
instructed to send certain packets. Anything that a firewall can
|
||
filter out can be sent into a divert socket.
|
||
|
||
|
||
Divert sockets first appeared as part of FreeBSD. Divert sockets under
|
||
Linux is a port of this mechanism that strives to be source-code
|
||
compatible in terms of user-space programs that utilize it.
|
||
|
||
|
||
5. Getting and Compiling the Source Code
|
||
|
||
In order to use divert sockets under Linux you will need two things -
|
||
the kernel source code that has been patched for divert sockets and
|
||
the source code to ipchains-1.3.9 that, also, has been patched to use
|
||
divert sockets.
|
||
|
||
|
||
5.1. Getting *The Source*
|
||
|
||
Both pieces of source code can be retrieved from the divert socket
|
||
web-site http://www.anr.mcnc.org/~divert
|
||
<http://www.anr.mcnc.org/~divert> You can get the source code for
|
||
divert sockets kernel in two forms - as a patch to linux-2.2.12 that
|
||
you have to apply to a fresh 2.2.12 source, or as an already patched
|
||
kernel tarball (much larger than the patch). ipchains source is
|
||
provided as complete source tarball only.
|
||
|
||
|
||
5.2. Compiling
|
||
|
||
Compiling ipchains is straightforward - simply say
|
||
|
||
|
||
make
|
||
|
||
|
||
|
||
in the ipchains-1.3.9 subdirectory.
|
||
|
||
|
||
When compiling the divert-socket kernel - use your favorite way of
|
||
configuring it:
|
||
|
||
|
||
make config
|
||
|
||
|
||
|
||
make menuconfig
|
||
|
||
|
||
|
||
make xconfig
|
||
|
||
|
||
|
||
Don't forget to enable "Prompt for development and/or incomplete
|
||
code/drivers" before proceeding. There are only three compile-time
|
||
options that affect the behavior of divert sockets and they are
|
||
explained in the following ``section''
|
||
|
||
|
||
5.2.1. Kernel compile-time options
|
||
|
||
In order to enable divert sockets in your kernel you must enable
|
||
firewalling and IP firewalling first. The three kernel compile-time
|
||
options that affect the behavior of divert sockets are:
|
||
|
||
IP: divert sockets
|
||
Enables the divert sockets in your kernel.
|
||
|
||
IP: divert pass-through
|
||
Changes the behavior of DIVERT rules: by default if a DIVERT
|
||
rule is present in a firewall and no application is listening on
|
||
the port that the rule specifies, any packet that satisfies the
|
||
rule is silently dropped, as if it were a DENY rule.
|
||
|
||
Enabling the pass-through mode results in such packets
|
||
continuing their way through the IP stack as if nothing
|
||
happened. This could be helpful if you want to have a static
|
||
rule in the firewall, but don't always want to listen on it.
|
||
|
||
IP: always defragment
|
||
Changes the way that the sockets deal with fragmentation. By
|
||
default the divert socket receives individual fragments of
|
||
packets that are larger than MTU, which it then forwards to user
|
||
space. The burden of defragmentation in this case lies with the
|
||
application listening on the divert socket. Also, an application
|
||
cannot inject any fragments that are larger than MTU, because
|
||
they will be dropped (this is the limitation of the kernel, not
|
||
the divert sockets - Linux kernels up to 2.2.x do NOT fragment
|
||
raw packets with IP_HDRINCL option set). Typically, thats OK,
|
||
since if you simply reinject the fragments the way you received
|
||
them, everything will work fine, since none of them are going to
|
||
be larger than MTU.
|
||
|
||
If you enable the always defragment option, then all the
|
||
defragmentation will be done for you in the kernel. This
|
||
severely affects the performance of the interception mechanism,
|
||
since now every large packet you want intercepted will first
|
||
have to be reassembled prior to being forwarded to you, and
|
||
then, if you choose to reinject it - it will have to be
|
||
fragmented again (the kernel with this option will be enabled to
|
||
fragment raw packets with IP_HDRINCL)
|
||
|
||
|
||
This was the only option available for divert sockets under
|
||
Linux 2.0.36 because of the way the firewall code was structured
|
||
- it only looked at the first fragment of every packet and
|
||
passed all other fragments without looking at them. This way, if
|
||
the first fragment were dropped by the firewall, the rest of
|
||
them would be eventually discarded by the defragmenter. That's
|
||
why in order for DIVERT sockets to work you were forced to
|
||
compile the always defragment option in, so that you would
|
||
always get the whole packet diverted to you and not just the
|
||
first fragment.
|
||
|
||
|
||
In 2.2.12, thanks to changes in the firewall code you now have
|
||
an option of having the kernel or yourself doing
|
||
fragmentation/defragmentation.
|
||
|
||
|
||
NOTE: the defragmentation feature has not been added as of
|
||
release 1.0.4 of divert sockets. It is in the works though.
|
||
|
||
|
||
6. Using Divert Sockets
|
||
|
||
This section will give you examples of how divert sockets can be used
|
||
and how they are different of other packet interception mechanisms out
|
||
there.
|
||
|
||
|
||
6.1. Divert sockets vs. other stuff
|
||
|
||
There are other mechanisms out there that have similar functionality.
|
||
Here is why they are different:
|
||
|
||
|
||
6.1.1. Netlink sockets
|
||
|
||
Netlink sockets can intercept packets just like divert sockets by
|
||
using firewall filter. They have a special type (AF_NETLINK) and on
|
||
the surface seem to do the same thing. Two major differences are:
|
||
|
||
<20> Netlink sockets have no ports, so it is difficult to have multiple
|
||
processes intercepting different things (divert sockets have a
|
||
standard 16-bit port space, which means you can have 65535
|
||
processes diverting packets independently)
|
||
|
||
<20> Netlink sockets have no easy way of injecting the packets that are
|
||
outbound (going on the wire) because no special precautions are
|
||
taken not to reintercept the same packet over and over again as it
|
||
is injected. Divert sockets do this automatically
|
||
|
||
To be fair, the scope of netlink sockets is wider than this. In
|
||
general, netlink mechanism is intended to allow communication
|
||
between kernel and user space. There are, for instance, netlink
|
||
routing sockets that allow you to communicate with the routing
|
||
subsystem. However, as a packet interception mechanism, they are
|
||
not as robust as divert sockets.
|
||
|
||
|
||
6.1.2. Raw sockets
|
||
|
||
RAW sockets can be a good way to listen in on traffic (especially
|
||
under Linux, where RAW sockets can listen in on TCP and UDP traffic,
|
||
although most other UNI*s do not allow that) but a RAW socket can't
|
||
stop a packet from propagating through the IP stack - it simply gives
|
||
you a copy of the packet and there is no way to inject it inbound (on
|
||
the way up the stack) - only outbound. Also, you can only filter
|
||
pockets out by the protocol number, which you specify when you open a
|
||
RAW socket. There is no link between the firewall and RAW sockets.
|
||
|
||
6.1.3. libpcap
|
||
|
||
More commonly known for the tool it facilitates - tcpdump, libpcap
|
||
lets you listen in on traffic that hits your interface (whether it be
|
||
ppp or eth or whatever). For ethernet it can also put your NIC into a
|
||
promiscuous mode, so that it will forward to IP the traffic that not
|
||
only is link-layer addressed to it, but to others on the same segment.
|
||
Of course, libpcap allows for no way of actually stopping packets from
|
||
propagating and no way to inject. In fact, libpcap is in many ways
|
||
orthogonal to divert sockets.
|
||
|
||
|
||
6.2. Discussion on firewall chains
|
||
|
||
Linux provides you with three default chains: input, output and
|
||
forward. There are also accounting chains, but they are of no
|
||
consequence here. Depending on the packet origin it traverses one or
|
||
more of these chains:
|
||
|
||
Input chain
|
||
is traversed by all packets that come into the host - packets
|
||
that are addressed to it and packets that will be forwarded by
|
||
it.
|
||
|
||
Output chain
|
||
is traversed by all packets originating in the host and by all
|
||
forwarded packets
|
||
|
||
Forward chain
|
||
is traversed only by the forwarded packets.
|
||
|
||
|
||
The order in which a forwarded packet traverses the chains is:
|
||
|
||
1. Input
|
||
|
||
2. Forward
|
||
|
||
3. Output
|
||
|
||
This may sometimes create problems for the interception if you are
|
||
interested in a certain type of packets that may or may not
|
||
originate on your host. A lot of times it is not clear which chain
|
||
to use.
|
||
|
||
|
||
As a rule of thumb, forward chain should only be used to filter
|
||
packets that are forwarded and are not originating and are not
|
||
addressed to your host. If you are interested in a combination of both
|
||
forwarded packets and packets that are originating or addressed to
|
||
your host, then use input or output chain instead. Intercepting on
|
||
forward and input or output chain for the same type of packet at the
|
||
same time will create problems in reinjection and, more importantly,
|
||
is unnecessary.
|
||
|
||
|
||
6.3. Using ipchains
|
||
|
||
The patched version of ipchains that you will need to retrieve from
|
||
the website, is the tool that allows you to modify firewall rules from
|
||
a shell (most people want that). It is also possible to set up
|
||
firewall rules programmatically. See the example code for this -
|
||
setting up a DIVERT rule would be similar to setting up a REDIRECT
|
||
rule - specify DIVERT as a target and the divert port and you are set
|
||
to go.
|
||
|
||
The ipchains syntax for setting up firewall rules remains the same. To
|
||
specify a DIVERT rule you must specify -j DIVERT <port num> as a
|
||
target, everything else remains the same. For instance
|
||
|
||
|
||
ipchains -A input -p ICMP -j DIVERT 1234
|
||
|
||
|
||
|
||
would set up a divert rule for ICMP packets to be diverted from input
|
||
chain to a port 1234.
|
||
|
||
|
||
The following section explains how to use ipchains in conjunction with
|
||
an interceptor user-space program.
|
||
|
||
|
||
6.4. Plain vanilla example
|
||
|
||
6.4.1. Example program
|
||
|
||
Here is an example program that reads packets from a divert socket,
|
||
displays them and then reinjects them back. It requires that the
|
||
divert port is specified on the command line.
|
||
|
||
|
||
|
||
#include <stdio.h>
|
||
#include <errno.h>
|
||
#include <limits.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <unistd.h>
|
||
#include <getopt.h>
|
||
#include <netdb.h>
|
||
#include <netinet/in.h>
|
||
#include <sys/types.h>
|
||
#include <signal.h>
|
||
|
||
#include <netinet/ip.h>
|
||
#include <netinet/tcp.h>
|
||
#include <netinet/udp.h>
|
||
#include <net/if.h>
|
||
#include <sys/param.h>
|
||
|
||
#include <linux/types.h>
|
||
#include <linux/icmp.h>
|
||
#include <linux/ip_fw.h>
|
||
|
||
#define IPPROTO_DIVERT 254
|
||
#define BUFSIZE 65535
|
||
|
||
char *progname;
|
||
|
||
#ifdef FIREWALL
|
||
|
||
char *fw_policy="DIVERT";
|
||
char *fw_chain="output";
|
||
struct ip_fw fw;
|
||
struct ip_fwuser ipfu;
|
||
struct ip_fwchange ipfc;
|
||
int fw_sock;
|
||
|
||
/* remove the firewall rule when exit */
|
||
void intHandler (int signo) {
|
||
|
||
if (setsockopt(fw_sock, IPPROTO_IP, IP_FW_DELETE, &ipfc, sizeof(ipfc))==-1) {
|
||
fprintf(stderr, "%s: could not remove rule: %s\n", progname, strerror(errno));
|
||
exit(2);
|
||
}
|
||
|
||
close(fw_sock);
|
||
exit(0);
|
||
}
|
||
|
||
#endif
|
||
|
||
int main(int argc, char** argv) {
|
||
int fd, rawfd, fdfw, ret, n;
|
||
int on=1;
|
||
struct sockaddr_in bindPort, sin;
|
||
int sinlen;
|
||
struct iphdr *hdr;
|
||
unsigned char packet[BUFSIZE];
|
||
struct in_addr addr;
|
||
int i, direction;
|
||
struct ip_mreq mreq;
|
||
|
||
if (argc!=2) {
|
||
fprintf(stderr, "Usage: %s <port number>\n", argv[0]);
|
||
exit(1);
|
||
}
|
||
progname=argv[0];
|
||
fprintf(stderr,"%s:Creating a socket\n",argv[0]);
|
||
/* open a divert socket */
|
||
fd=socket(AF_INET, SOCK_RAW, IPPROTO_DIVERT);
|
||
|
||
if (fd==-1) {
|
||
fprintf(stderr,"%s:We could not open a divert socket\n",argv[0]);
|
||
exit(1);
|
||
}
|
||
|
||
bindPort.sin_family=AF_INET;
|
||
bindPort.sin_port=htons(atol(argv[1]));
|
||
bindPort.sin_addr.s_addr=0;
|
||
|
||
fprintf(stderr,"%s:Binding a socket\n",argv[0]);
|
||
ret=bind(fd, &bindPort, sizeof(struct sockaddr_in));
|
||
|
||
if (ret!=0) {
|
||
close(fd);
|
||
fprintf(stderr, "%s: Error bind(): %s",argv[0],strerror(ret));
|
||
exit(2);
|
||
}
|
||
#ifdef FIREWALL
|
||
/* fill in the rule first */
|
||
bzero(&fw, sizeof (struct ip_fw));
|
||
fw.fw_proto=1; /* ICMP */
|
||
fw.fw_redirpt=htons(bindPort.sin_port);
|
||
fw.fw_spts[1]=0xffff;
|
||
fw.fw_dpts[1]=0xffff;
|
||
fw.fw_outputsize=0xffff;
|
||
|
||
/* fill in the fwuser structure */
|
||
ipfu.ipfw=fw;
|
||
memcpy(ipfu.label, fw_policy, strlen(fw_policy));
|
||
|
||
/* fill in the fwchange structure */
|
||
ipfc.fwc_rule=ipfu;
|
||
memcpy(ipfc.fwc_label, fw_chain, strlen(fw_chain));
|
||
|
||
/* open a socket */
|
||
if ((fw_sock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==-1) {
|
||
fprintf(stderr, "%s: could not create a raw socket: %s\n", argv[0], strerror(errno));
|
||
exit(2);
|
||
}
|
||
|
||
/* write a rule into it */
|
||
if (setsockopt(fw_sock, IPPROTO_IP, IP_FW_APPEND, &ipfc, sizeof(ipfc))==-1) {
|
||
fprintf(stderr, "%s could not set rule: %s\n", argv[0], strerror(errno));
|
||
exit(2);
|
||
}
|
||
|
||
/* install signal handler to delete the rule */
|
||
signal(SIGINT, intHandler);
|
||
#endif /* FIREWALL */
|
||
|
||
printf("%s: Waiting for data...\n",argv[0]);
|
||
/* read data in */
|
||
sinlen=sizeof(struct sockaddr_in);
|
||
while(1) {
|
||
n=recvfrom(fd, packet, BUFSIZE, 0, &sin, &sinlen);
|
||
hdr=(struct iphdr*)packet;
|
||
|
||
printf("%s: The packet looks like this:\n",argv[0]);
|
||
for( i=0; i<40; i++) {
|
||
printf("%02x ", (int)*(packet+i));
|
||
if (!((i+1)%16)) printf("\n");
|
||
};
|
||
printf("\n");
|
||
|
||
addr.s_addr=hdr->saddr;
|
||
printf("%s: Source address: %s\n",argv[0], inet_ntoa(addr));
|
||
addr.s_addr=hdr->daddr;
|
||
printf("%s: Destination address: %s\n", argv[0], inet_ntoa(addr));
|
||
printf("%s: Receiving IF address: %s\n", argv[0], inet_ntoa(sin.sin_addr));
|
||
printf("%s: Protocol number: %i\n", argv[0], hdr->protocol);
|
||
|
||
/* reinjection */
|
||
|
||
#ifdef MULTICAST
|
||
if (IN_MULTICAST((ntohl(hdr->daddr)))) {
|
||
printf("%s: Multicast address!\n", argv[0]);
|
||
addr.s_addr = hdr->saddr;
|
||
errno = 0;
|
||
if (sin.sin_addr.s_addr == 0)
|
||
printf("%s: set_interface returns %i with errno =%i\n", argv[0], setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)), errno);
|
||
}
|
||
#endif
|
||
|
||
#ifdef REINJECT
|
||
printf("%s Reinjecting DIVERT %i bytes\n", argv[0], n);
|
||
n=sendto(fd, packet, n ,0, &sin, sinlen);
|
||
printf("%s: %i bytes reinjected.\n", argv[0], n);
|
||
|
||
if (n<=0)
|
||
printf("%s: Oops: errno = %i\n", argv[0], errno);
|
||
if (errno == EBADRQC)
|
||
printf("errno == EBADRQC\n");
|
||
if (errno == ENETUNREACH)
|
||
printf("errno == ENETUNREACH\n");
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
|
||
You can simply cut-n-paste the code and compile it with your favorite
|
||
compiler. If you want to enable reinjection - compile it with the
|
||
-DREINJECT flag, otherwise it will only do the interception.
|
||
|
||
|
||
In order to get it to work, compile the kernel and ipchains-1.3.8 as
|
||
described ``above''. Insert a rule into any of the firewall chains:
|
||
input, output or forward, then send the packets that would match the
|
||
rule and watch them as they fly through the screen - your interceptor
|
||
program will display them and then reinject them back, if
|
||
appropriately compiled.
|
||
|
||
|
||
For example:
|
||
|
||
|
||
ipchains -A output -p TCP -s 172.16.128.10 -j DIVERT 4321
|
||
interceptor 4321
|
||
|
||
|
||
|
||
will divert and display all TCP packets originating on host
|
||
172.16.128.10 (for instance if your host is a gateway). It will inter<65>
|
||
cept them on the output just before they go on the wire.
|
||
|
||
If you did not compile the pass through option into the kernel, then
|
||
inserting the rule effectively will create a DENY rule in the firewall
|
||
for the packets you specified until you start the interceptor program.
|
||
See more on that ``above''
|
||
|
||
|
||
If you want to set a firewall rule through your program, compile it
|
||
with -DFIREWALL option and it will divert all ICMP packets from the
|
||
output chain. It will also remove the DIVERT rule from the firewall
|
||
when you use Ctrl-C to exit the program. In this case using pass-
|
||
through vs. non-pass-through divert sockets makes virtually no
|
||
difference.
|
||
|
||
|
||
6.5. The sky's the limit
|
||
|
||
As far as what you can use divert sockets for - your imagination would
|
||
be the limiting factor. I would be interested to hear about
|
||
applications that utilize divert sockets.
|
||
|
||
|
||
So, have fun!
|
||
|
||
|
||
7. Advanced issues
|
||
|
||
7.1. Packet Mangling
|
||
|
||
After you intercept a packet, it is possible to change its header or
|
||
contents before reinjecting it back. Here are a few rules you might
|
||
need to keep in mind:
|
||
|
||
<20> IP header checksum is always recalculated on injection
|
||
|
||
<20> IP ID field is filled in for you if you leave it 0.
|
||
|
||
<20> The length of the packet is updated for you.
|
||
|
||
All other parts of the IP header can be modified and its up to you
|
||
to insure their sanity.
|
||
|
||
|
||
7.2. Injection with no interception
|
||
|
||
It is not necessary to intercept a packet in order to inject it. You
|
||
can form your own packets and inject them into an open and bound
|
||
divert socket. The header rules from above apply.
|
||
|
||
|
||
In addition, you need to pass to the divert socket a sockaddr_in
|
||
structure (see example program), which will tell the socket where to
|
||
inject. If you leave the structure 0-ed out or pass a NULL - the
|
||
divert socket will attempt to inject the packet in the outbound
|
||
direction (on the wire). If instead you fill the sockaddr_in structure
|
||
with the address of one of the local interfaces, the divert socket
|
||
will attempt to inject the packet inbound, as if it came from that
|
||
interface. All addresses, of course, should be in network byte order.
|
||
|
||
|
||
Injection of packets that look like they are being forwarded by your
|
||
host must include an address of the incoming interface (actually - any
|
||
valid interface address will probably work).
|
||
|
||
|
||
|
||
7.3. Fragmentation
|
||
|
||
As of this reading, the divert sockets do not handle the
|
||
defragmentation and fragmentation of diverted packets - you always get
|
||
the fragments as they are on the wire and you should not inject
|
||
fragments larger than PMTU. It is anticipated that the
|
||
fragmentation/defragmentation capability will be added in the near
|
||
future.
|
||
|
||
|
||
8. Geting More Information
|
||
|
||
8.1. The website
|
||
|
||
As mentioned above, most of the information about divert sockets can
|
||
be found on the Divert Sockets for Linux website
|
||
http://www.anr.mcnc.org/~divert <http://www.anr.mcnc.org/~divert>.
|
||
|
||
|
||
8.2. The mailing list
|
||
|
||
There is also a mailing list, whose archive can be found at the
|
||
website. To join the mailing list send email with an empty subject
|
||
and the following line in the body:
|
||
|
||
|
||
subscribe divert
|
||
|
||
|
||
|
||
to anr-majordomo@list.anr.mcnc.org <mailto:anr-major<6F>
|
||
domo@list.anr.mcnc.org>. The list address is divert@list.anr.mcnc.org
|
||
<mailto:divert@list.anr.mcnc.org>.
|
||
|
||
|
||
To unsubscribe, send mail to anr-majordomo@list.anr.mcnc.org
|
||
<mailto:anr-majordomo@list.anr.mcnc.org> with an empty subject and the
|
||
following line in the body:
|
||
|
||
|
||
unsubscribe divert
|
||
|
||
|
||
|
||
9. Future work
|
||
|
||
As mentioned in the disclaimer, work on divert sockets is done as part
|
||
of a DARPA-funded network security effort. We will continue to port
|
||
divert sockets to further versions of the kernel as time permits.
|
||
Given that 2.4 kernel is on the horizon, in all likelihood we will
|
||
skip 2.3.x series altogether.
|
||
|
||
|
||
|