349b89bb47
ok dcoppa@, benoit@
183 lines
4.9 KiB
Plaintext
183 lines
4.9 KiB
Plaintext
$OpenBSD: patch-route_c,v 1.5 2010/11/10 13:50:04 fkr Exp $
|
|
--- route.c.orig Thu Nov 4 20:29:40 2010
|
|
+++ route.c Fri Nov 5 21:12:15 2010
|
|
@@ -1948,7 +1948,7 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmas
|
|
}
|
|
}
|
|
|
|
-#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
|
|
+#elif defined(TARGET_NETBSD)
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
@@ -1997,6 +1997,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 */
|
|
};
|
|
|