On Tue, Jan 24, 2012 at 09:48:48PM -0500, Lawrence Teo wrote:
> While working with divert(4), I found that there is a lack of
> documentation that describes how to actually use it.
> 
> This diff attempts to address that by adding an EXAMPLE section to the
> divert(4) manpage. The example consists of a PF rule and a simple
> program that uses the divert port. It is designed to be simple enough
> that someone can try this on their desktop.
> 
> Comments?
> 
> Thanks,
> Lawrence
> 

committed, thanks. i did tweak the wording a little.

for future reference for man diffs - new sentences should begin on new
lines. and the header name is EXAMPLES (plural), not EXAMPLE (singular).

thanks again,
jmc

> 
> Index: divert.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/divert.4,v
> retrieving revision 1.6
> diff -u -p -r1.6 divert.4
> --- divert.4  6 Dec 2009 18:32:43 -0000       1.6
> +++ divert.4  25 Jan 2012 02:37:36 -0000
> @@ -77,6 +77,94 @@ Receive and send divert socket buffer sp
>  .Xr sysctl 8 .
>  .Xr netstat 1
>  shows information relevant to divert sockets.
> +.Sh EXAMPLE
> +The following PF rule queues outbound IPv4 packets to TCP port 80
> +(and the return traffic) on the em0 interface to divert port 700:
> +.Bd -literal -offset indent
> +pass out on em0 inet proto tcp to port 80 divert-packet port 700
> +.Ed
> +.Pp
> +The following program reads packets on divert port 700 and reinjects them
> +back into the kernel. This program does not perform any processing of the
> +packets, apart from discarding invalid IP packets.
> +.Bd -literal
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <netinet/in_systm.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip_var.h>
> +#include <netinet/tcp.h>
> +#include <netinet/tcpip.h>
> +#include <arpa/inet.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <err.h>
> +
> +#define DIVERT_PORT 700
> +
> +int
> +main(int argc, char *argv[])
> +{
> +     int fd, s;
> +     struct sockaddr_in sin;
> +     socklen_t sin_len;
> +
> +     fd = socket(AF_INET, SOCK_RAW, IPPROTO_DIVERT);
> +     if (fd == -1)
> +             err(1, "socket");
> +
> +     bzero(&sin, sizeof(sin));
> +     sin.sin_family = AF_INET;
> +     sin.sin_port = htons(DIVERT_PORT);
> +     sin.sin_addr.s_addr = 0;
> +
> +     sin_len = sizeof(struct sockaddr_in);
> +
> +     s = bind(fd, (struct sockaddr *) &sin, sin_len);
> +     if (s == -1)
> +             err(1, "bind");
> +
> +     for (;;) {
> +             ssize_t n;
> +             char packet[10000];
> +             struct ip *ip_hdr;
> +             struct tcpiphdr *tcpip_hdr;
> +             char srcip[40], dstip[40];
> +
> +             bzero(packet, sizeof(packet));
> +             n = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr *) 
> &sin,
> +                 &sin_len);
> +
> +             tcpip_hdr = (struct tcpiphdr *) packet;
> +             ip_hdr = (struct ip *) packet;
> +
> +             bzero(srcip, sizeof(srcip));
> +             bzero(dstip, sizeof(dstip));
> +
> +             if (inet_ntop(AF_INET, &ip_hdr->ip_src, srcip, sizeof(srcip)) 
> == NULL) {
> +                     fprintf(stderr, "Invalid IPv4 source packet\en");
> +                     continue;
> +             }
> +             if (inet_ntop(AF_INET, &ip_hdr->ip_dst, dstip, sizeof(dstip)) 
> == NULL) {
> +                     fprintf(stderr, "Invalid IPv4 destination packet\en");
> +                     continue;
> +             }
> +
> +             printf("%s:%u -> %s:%u\en",
> +                     srcip,
> +                     ntohs(tcpip_hdr->ti_sport),
> +                     dstip,
> +                     ntohs(tcpip_hdr->ti_dport)
> +             );
> +
> +             n = sendto(fd, packet, n, 0, (struct sockaddr *) &sin, sin_len);
> +     }
> +
> +     return 0;
> +}
> +.Ed
>  .Sh SEE ALSO
>  .Xr socket 2 ,
>  .Xr ip 4 ,

Reply via email to