On -current OpenVPN no longer works because of their brain damaged way to talk to the routing socket to get the default gateway. Instead of pulling in net/route.h they copied parts of the contents into their code -- with the usual maze of #if defined(YOURFAVORITEOS) around it.
What amazes me is the amount of autohell/configure crap they add to their code but even the simplest concept of moving platform dependent stuff into seperate files is above their mindset. Another thing that amuses me is that crappy nature of their routing handler code. Lucky me that I don't have to use this everyday. fkr@ informed me about the issue but I'm not sure if I should thank him for that :) Please test. -- :wq Claudio Index: Makefile =================================================================== RCS file: /cvs/ports/net/openvpn/Makefile,v retrieving revision 1.14 diff -u -p -r1.14 Makefile --- Makefile 27 Jul 2007 21:20:29 -0000 1.14 +++ Makefile 6 Sep 2007 12:43:24 -0000 @@ -5,6 +5,7 @@ COMMENT= easy-to-use, robust, and highly VERSION= 2.0.9 DISTNAME= openvpn-${VERSION} +PKGNAME= ${DISTNAME}p0 CATEGORIES= net security HOMEPAGE= http://openvpn.net/ Index: patches/patch-route_c =================================================================== RCS file: patches/patch-route_c diff -N patches/patch-route_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-route_c 6 Sep 2007 07:35:39 -0000 @@ -0,0 +1,182 @@ +$OpenBSD$ +--- route.c.orig Wed Apr 5 08:13:55 2006 ++++ route.c Thu Sep 6 09:35:31 2007 +@@ -1622,7 +1622,7 @@ get_default_gateway (in_addr_t *ret) + } + } + +-#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) ++#elif defined(TARGET_NETBSD) + + #include <sys/types.h> + #include <sys/socket.h> +@@ -1671,6 +1671,169 @@ struct rt_msghdr { + 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 */ ++}; ++ ++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)) ++ ++static bool ++get_default_gateway (in_addr_t *ret) ++{ ++ struct gc_arena gc = gc_new (); ++ int s, seq, l, rtm_addrs, i; ++ pid_t pid; ++ 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"); ++ gc_free (&gc); ++ close(s); ++ return false; ++ } ++ ++ do { ++ l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); ++ } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); ++ ++ close(s); ++ ++ 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 ++ { ++ gc_free (&gc); ++ 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, 0, &gc)); ++#endif ++ ++ gc_free (&gc); ++ return true; ++ } ++ else ++ { ++ gc_free (&gc); ++ return false; ++ } ++} ++ ++#elif defined(TARGET_OPENBSD) ++ ++#include <sys/types.h> ++#include <sys/socket.h> ++#include <netinet/in.h> ++ ++/* all of this is taken from <net/route.h> in OpenBSD 3.6 */ ++#define RTA_DST 0x1 /* destination sockaddr present */ ++#define RTA_GATEWAY 0x2 /* gateway sockaddr present */ ++#define RTA_NETMASK 0x4 /* netmask sockaddr present */ ++ ++#define RTM_GET 0x4 /* Report Metrics */ ++ ++#define RTM_VERSION 4 /* Up the ante and ignore older versions */ ++ ++#define RTF_UP 0x1 /* route usable */ ++#define RTF_GATEWAY 0x2 /* destination is a gateway */ ++ ++/* ++ * Huge version for userland compatibility. ++ */ ++struct rt_metrics { ++ u_int64_t rmx_pksent; /* packets sent using this route */ ++ u_int rmx_locks; /* Kernel must leave these values */ ++ u_int rmx_mtu; /* MTU for this path */ ++ u_int rmx_expire; /* lifetime for route, e.g. redirect */ ++ u_int rmx_refcnt; /* # references hold */ ++ /* some apps may still need these no longer used metrics */ ++ u_int rmx_hopcount; /* max hops expected */ ++ u_int rmx_recvpipe; /* inbound delay-bandwidth product */ ++ u_int rmx_sendpipe; /* outbound delay-bandwidth product */ ++ u_int rmx_ssthresh; /* outbound gateway buffer limit */ ++ u_int rmx_rtt; /* estimated round trip time */ ++ u_int rmx_rttvar; /* estimated rtt variance */ ++}; ++ ++/* ++ * 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_hdrlen; /* sizeof(rt_msghdr) to skip over the header */ ++ u_short rtm_index; /* index for associated ifp */ ++ u_short rtm_tableid; /* routing table id */ ++ u_char rtm_prio; /* routing priority */ ++ u_char rtm_pad; ++ int rtm_addrs; /* bitmask identifying sockaddrs in msg */ ++ int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ ++ int rtm_fmask; /* bitmask used in RTM_CHANGE message */ ++ pid_t rtm_pid; /* identify sender */ ++ int rtm_seq; /* for sender to identify action */ ++ int rtm_errno; /* why failed */ ++ u_int rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ + }; +