IPFW + Divert and multicast IPv6
Julien DHERSIN
dhersin at gmail.com
Wed Apr 11 12:42:14 UTC 2007
Hi,
I would like to know if anyone has already tried to divert multicast
IPv6 packets and to reinject them in the IPv6 stack ?
The idea is to filter the multicast IPv6 packets (UDP:54321) according
to the option data in the header.
My IPFW script is quite short :
#!/bin/sh
/sbin/ipfw -q flush
/sbin/ipfw add divert 1234 udp from any to any 54321
I found the following code in a mini howto but it is not working :
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
#include <arpa/inet.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <math.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <termios.h>
#include <unistd.h>
#define BUFSIZE 65535
int
main(int argc, char **argv)
{
int fd,
rawfd,
fdfw,
ret,
n;
int on = 1;
struct sockaddr_in6 bindPort, sin;
int sinlen;
int port_nb;
struct ip6_hdr *hdr;
unsigned char packet[BUFSIZE];
struct in6_addr addr;
int i,
direction;
struct ip_mreq mreq;
if (argc != 2)
{
fprintf(stderr, "Usage: %s <port number>\n", argv[0]);
exit(1);
}
bindPort.sin6_family = AF_INET6;
bindPort.sin6_port = htons(atol(argv[1]));
bindPort.sin6_addr = in6addr_any;
fprintf(stderr, "%s:Creating a socket\n", argv[0]);
/* open a divert socket */
fd = socket(AF_INET6, SOCK_RAW, IPPROTO_DIVERT);
if (fd == -1)
{
fprintf(stderr, "%s:We could not open a divert socket\n", argv[0]);
exit(1);
}
fprintf(stderr, "%s:Binding a socket\n", argv[0]);
ret = bind(fd, (struct sockaddr6*)&bindPort, sizeof(struct sockaddr_in6));
if (ret != 0)
{
close(fd);
fprintf(stderr, "%s: Error bind(): %s", argv[0], strerror(ret));
exit(2);
}
printf("%s: Waiting for data...\n", argv[0]);
/* read data in */
sinlen = sizeof(struct sockaddr_in);
while (1)
{
n = recvfrom(fd, packet, BUFSIZE, 0, (struct sockaddr6*)&sin, &sinlen);
hdr = (struct ip6_hdr *) packet;
printf("%s: The packet looks like this:\n", argv[0]);
for (i = 0; i < 80; i++)
{
printf("%02x ", (int)*(packet + i));
if (!((i + 1) % 16))
printf("\n");
};
printf("\n");
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);
}
}
Thanks for your help.
Regards,
Julien
More information about the freebsd-ipfw
mailing list