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 <j...@it.uc3m.es> 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 <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ 
+ 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 <net/route.h> 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 */
+         u_long  rmx_ssthresh;   /* outbound gateway buffer limit */
+         u_long  rmx_rtt;        /* estimated round trip time */
+         u_long  rmx_rttvar;     /* estimated rtt variance */
+         u_long  rmx_pksent;     /* packets sent using this route */
+         u_long  rmx_filler[4];  /* will be used for T/TCP later */
+ };
+ 
+ 
+ /*
+  * Structures for routing messages.
+  */
+ struct rt_msghdr {
+         u_short rtm_msglen;     /* to skip over non-understood messages */
+         u_char  rtm_version;    /* future binary compatibility */
+         u_char  rtm_type;       /* message type */
+         u_short rtm_index;      /* index for associated ifp */
+         int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */
+         int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */
+         pid_t   rtm_pid;        /* identify sender */
+         int     rtm_seq;        /* for sender to identify action */
+         int     rtm_errno;      /* why failed */
+         int     rtm_use;        /* from rtentry */
+         u_long  rtm_inits;      /* which metrics we are initializing */
+         struct  rt_metrics rtm_rmx; /* metrics themselves */
+ };
+ 
+ #endif
+ 
+ 
  struct route_special_addr
  {
    in_addr_t remote_endpoint;

Reply via email to