[Openvpn-devel] --redirect-gateway on FreeBSD

2004-03-05 Thread Juan Rodriguez Hervella
Hello,

I've just subscribed to this list, but I've read on the
archives that the --redirect-gateway function is not
working yet on FreeBSD because of the problem of
retreiving the address of the default gateway.

I've just written a small program which makes that,
looking at /usr/src/sbin/route.c

Hope this helps, I've tested it on both FreeBSD-4.9
and FreeBSD-5.2

It uses PF_ROUTE sockets.

hope this helps!
-- 
**
JFRH
**

Go climb a gravity well!
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

struct {
struct rt_msghdr m_rtm;
char   m_space[512];
} m_rtmsg;

#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))

#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))

char aux[INET_ADDRSTRLEN];
struct sockaddr so_dst, so_mask;


char *routename( struct sockaddr *sa )
{
inet_ntop( AF_INET, &((struct sockaddr_in *)sa)->sin_addr, aux, 
INET_ADDRSTRLEN );

return aux;
}


void print_getmsg(struct rt_msghdr *rtm, int msglen)   
{
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;
struct sockaddr *sa;
char *cp;
int i;

(void) printf("   route to: %s\n", routename(&so_dst));
if (rtm->rtm_version != RTM_VERSION) {
warnx("routing message version %d not understood",
 rtm->rtm_version);
return;
}
if (rtm->rtm_msglen > msglen) {
warnx("message length mismatch, in packet %d, returned %d",
  rtm->rtm_msglen, msglen);
}
if (rtm->rtm_errno)  {
errno = rtm->rtm_errno;
warn("message indicates error %d", errno);
return;
}
cp = ((char *)(rtm + 1));
if (rtm->rtm_addrs)
for (i = 1; i; i <<= 1)
if (i & rtm->rtm_addrs) {
sa = (struct sockaddr *)cp;
switch (i) {
case RTA_DST:
dst = sa;
break;
case RTA_GATEWAY:
gate = sa;
break;
case RTA_NETMASK:
mask = sa;
break;
}
ADVANCE(cp, sa);
}

if (dst)
(void)printf("destination: %s\n", routename(dst));

if (mask)
(void)printf("   mask: %s\n", routename(mask)); 
   

if (gate && rtm->rtm_flags & RTF_GATEWAY)
(void)printf("gateway: %s\n", routename(gate));
}



int main()
{
  int s, seq, l, pid, rtm_addrs;
  char *cp = m_rtmsg.m_space; 

#define NEXTADDR(w, u) \
if (rtm_addrs & (w)) {\
l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
}

#define rtm m_rtmsg.m_rtm

  pid = getpid();
  seq = 0;
  rtm_addrs = RTA_DST | RTA_NETMASK;

  bzero(&so_dst, sizeof(so_dst));
  bzero(&so_mask, sizeof(so_mask));
  bzero(&rtm, sizeof(struct rt_msghdr));

  rtm.rtm_type = RTM_GET;
  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
  rtm.rtm_version = RTM_VERSION;
  rtm.rtm_seq = ++seq;
  rtm.rtm_addrs = rtm_addrs; 

  NEXTADDR(RTA_DST, so_dst);
  NEXTADDR(RTA_NETMASK, so_mask);

  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;

  s = socket(PF_ROUTE, SOCK_RAW, 0);

  if (write(s, (char *)&m_rtmsg, l) < 0) {
warn("writing to routing socket");
return (-1);
  }

  do {
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));


  print_getmsg(&rtm, l);

  return 0;
}



Re: [Openvpn-devel] --redirect-gateway on FreeBSD

2004-03-05 Thread James Yonan
Juan Rodriguez Hervella  said:

> Hello,
> 
> I've just subscribed to this list, but I've read on the
> archives that the --redirect-gateway function is not
> working yet on FreeBSD because of the problem of
> retreiving the address of the default gateway.
> 
> I've just written a small program which makes that,
> looking at /usr/src/sbin/route.c
> 
> Hope this helps, I've tested it on both FreeBSD-4.9
> and FreeBSD-5.2
> 
> It uses PF_ROUTE sockets.
> 
> hope this helps!
> -- 
> **
> JFRH
> **
> 
> Go climb a gravity well!

Juan,

It would be ideal if you could code this into OpenVPN's route.c, following the
form of the other platforms, i.e.:

..

#elif defined(TARGET_FREEBSD)

static bool
get_default_gateway (in_addr_t *ret)
{
  /* code me -- put gateway address into *ret */
}

#else

..

James




Re: [Openvpn-devel] --redirect-gateway on FreeBSD

2004-03-08 Thread Juan Rodriguez Hervella
Hello!

I attach the patches. I've tested it and I think it's 
working fine.

If something goes wrong, just tell me and i will
be glad to fix it up.

Seeyou!

On Friday 05 March 2004 16:02, James Yonan wrote:
> Juan Rodriguez Hervella  said:
> > Hello,
> >
> > I've just subscribed to this list, but I've read on the
> > archives that the --redirect-gateway function is not
> > working yet on FreeBSD because of the problem of
> > retreiving the address of the default gateway.
> >
> > I've just written a small program which makes that,
> > looking at /usr/src/sbin/route.c
> >
> > Hope this helps, I've tested it on both FreeBSD-4.9
> > and FreeBSD-5.2
> >
> > It uses PF_ROUTE sockets.
> >
> > hope this helps!
> > --
> > **
> > JFRH
> > **
> >
> > Go climb a gravity well!
>
> Juan,
>
> It would be ideal if you could code this into OpenVPN's route.c, following
> the form of the other platforms, i.e.:
>
> ..
>
> #elif defined(TARGET_FREEBSD)
>
> static bool
> get_default_gateway (in_addr_t *ret)
> {
>   /* code me -- put gateway address into *ret */
> }
>
> #else
>
> ..
>
> James

-- 
**
JFRH
**

Paul's Law:
In America, it's not how much an item costs, it's how much you
save.
*** route.c_1.6rc1	Fri Mar  5 18:38:51 2004
--- route.c	Mon Mar  8 12:50:18 2004
***
*** 45,50 
--- 45,62 

  #include "memdbg.h"

+ #if defined(TARGET_FREEBSD)
+ #include 
+ #include 
+ #include 
+ 
+ struct {
+   struct rt_msghdr m_rtm;
+   char   m_space[512];
+ } m_rtmsg;
+ 
+ #endif
+ 
  static void add_route (struct route *r);
  static void delete_route (const struct route *r);
  static bool get_default_gateway (in_addr_t *ret);
***
*** 810,815 
--- 822,917 
  }
return false;
  }
+ 
+ #elif defined(TARGET_FREEBSD)
+ 
+ #define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+ 
+ static bool
+ get_default_gateway (in_addr_t *ret)
+ {
+   int s, seq, l, pid, rtm_addrs, i;
+   struct sockaddr so_dst, so_mask;
+   char *cp = m_rtmsg.m_space; 
+   struct sockaddr *gate = NULL, *sa;
+   struct  rt_msghdr *rtm_aux;
+ 
+ #define NEXTADDR(w, u) \
+ if (rtm_addrs & (w)) {\
+ l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
+ }
+ 
+ #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+ 
+ #define rtm m_rtmsg.m_rtm
+ 
+   pid = getpid();
+   seq = 0;
+   rtm_addrs = RTA_DST | RTA_NETMASK;
+ 
+   bzero(&so_dst, sizeof(so_dst));
+   bzero(&so_mask, sizeof(so_mask));
+   bzero(&rtm, sizeof(struct rt_msghdr));
+ 
+   rtm.rtm_type = RTM_GET;
+   rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
+   rtm.rtm_version = RTM_VERSION;
+   rtm.rtm_seq = ++seq;
+   rtm.rtm_addrs = rtm_addrs; 
+ 
+   so_dst.sa_family = AF_INET;
+   so_dst.sa_len = sizeof(struct sockaddr_in);
+   so_mask.sa_family = AF_INET;
+   so_mask.sa_len = sizeof(struct sockaddr_in);
+ 
+   NEXTADDR(RTA_DST, so_dst);
+   NEXTADDR(RTA_NETMASK, so_mask);
+ 
+   rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
+ 
+   s = socket(PF_ROUTE, SOCK_RAW, 0);
+ 
+   if (write(s, (char *)&m_rtmsg, l) < 0) {
+ warn("writing to routing socket");
+ return false;
+   }
+ 
+   do {
+ l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
+   } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
+ 
+ 
+   rtm_aux = &rtm;
+ 
+   cp = ((char *)(rtm_aux + 1));
+   if (rtm_aux->rtm_addrs) {
+ for (i = 1; i; i <<= 1)
+  if (i & rtm_aux->rtm_addrs) {
+sa = (struct sockaddr *)cp;
+ 		   if( i == RTA_GATEWAY )
+   gate = sa;
+ADVANCE(cp, sa);
+ 	 }
+   }
+   else
+ 	return false;
+ 
+ 
+   if( gate != NULL )
+   {
+ 	*ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
+ #if 1
+ msg (M_INFO, "gw %s",
+  print_in_addr_t ((in_addr_t) *ret, false));
+ #endif
+ 
+ 	return true;
+   }
+   else
+ 	return false;
+ }
+ 

  #else

*** route.h_1.6rc1	Mon Mar  8 12:57:47 2004
--- route.h	Fri Mar  5 18:38:37 2004
***
*** 32,37 
--- 32,90 

  #define MAX_ROUTES 50

+ #if defined(TARGET_FREEBSD)
+ 
+ /* all of this is taken from  in FreeBSD */
+ #define RTA_DST 0x1
+ #define RTA_GATEWAY 0x2
+ #define RTA_NETMASK 0x4
+ 
+ #define RTM_GET 0x4
+ #define RTM_VERSION 5
+ 
+ #define RTF_UP  0x1
+ #define RTF_GATEWAY 0x2
+ 
+ /*
+  * These numbers are used by reliable protocols for determining
+  * retransmission behavior and are included in the routing structure.
+  */
+ struct rt_metrics {
+ u_long  rmx_locks;  /* Kernel must leave these values alone */
+ u_long  rmx_mtu;/* MTU for this path */
+ u_long  rmx_hopcount;   /* max hops expected */
+ u_long  rmx_expire; /* lifetime for route, e.g. redirect */
+ u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */
+ u_long  rmx_sendpipe;   /* outbound delay-bandwidth product */
+