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 <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/route.h> #include <err.h> #include <errno.h> #include <arpa/inet.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> 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; }