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: openvpn-devel@lists.sourceforge.net
Date: Sat, 7 Feb 2004 22:03:35 +0100
From: Henning Brauer <lists-open...@bsws.de>
To: Julien TOUCHE <julien.tou...@lycos.com>
References: <40255088.6020...@lycos.com>

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);
}





Reply via email to