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(_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(_dst, sizeof(so_dst));
bzero(_mask, sizeof(so_mask));
bzero(, 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 *)_rtmsg;
s = socket(PF_ROUTE, SOCK_RAW, 0);
if (write(s, (char *)_rtmsg, l) < 0) {
warn("writing to routing socket");
return (-1);
}
do {
l = read(s, (char *)_rtmsg, sizeof(m_rtmsg));
} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
print_getmsg(, l);
return 0;
}