one answer from misc@openbsd
or read file /etc/mygate (but not really portable)
Regards
Julien
-------- Original Message --------
Subject: Re: get gateway address in c
List-Post: [email protected]
Date: Sat, 7 Feb 2004 22:03:35 +0100
From: Henning Brauer <[email protected]>
To: Julien TOUCHE <[email protected]>
References: <[email protected]>
you could fetch the default route. this is not exactly trivial, but not
too hard either - in usr.sbin/bgpd/kroute.c, fetchtable() has the code
to do that. might be an inspiration.
no, it's not trivial ;-)
--
http://2suck.net/hhwl.html - http://www.bsws.de/
Unix is very simple, but it takes a genius to understand the simplicity.
(Dennis Ritchie)
<<< from kroute.c >>>
int
fetchtable(void)
{
size_t len;
int mib[6];
char *buf, *next, *lim;
struct rt_msghdr *rtm;
struct sockaddr *sa, *rti_info[RTAX_MAX];
struct sockaddr_in *sa_in;
struct kroute_node *kr;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
log_warn("sysctl");
return (-1);
}
if ((buf = malloc(len)) == NULL) {
log_warn("fetchtable");
return (-1);
}
if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) {
log_warn("sysctl");
return (-1);
}
lim = buf + len;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sa = (struct sockaddr *)(rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
if ((sa = rti_info[RTAX_DST]) == NULL)
continue;
if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */
continue;
if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) {
log_warn("fetchtable");
return (-1);
}
kr->r.flags = F_KERNEL;
switch (sa->sa_family) {
case AF_INET:
kr->r.prefix.s_addr =
((struct sockaddr_in *)sa)->sin_addr.s_addr;
sa_in = (struct sockaddr_in
*)rti_info[RTAX_NETMASK];
if (kr->r.prefix.s_addr == 0) /* default route */
kr->r.prefixlen = 0;
else if (sa_in != NULL)
kr->r.prefixlen =
mask2prefixlen(sa_in->sin_addr.s_addr);
else if (rtm->rtm_flags & RTF_HOST)
kr->r.prefixlen = 32;
else
kr->r.prefixlen =
prefixlen_classful(kr->r.prefix.s_addr);
break;
default:
continue;
/* not reached */
}
if ((sa = rti_info[RTAX_GATEWAY]) != NULL)
switch (sa->sa_family) {
case AF_INET:
kr->r.nexthop.s_addr =
((struct sockaddr_in
*)sa)->sin_addr.s_addr;
break;
case AF_LINK:
kr->r.flags |= F_CONNECTED;
kr->r.ifindex = rtm->rtm_index;
break;
}
kroute_insert(kr);
}
free(buf);
return (0);
}