source: trunk/third-party/libnatpmp/getgateway.c @ 5094

Last change on this file since 5094 was 4151, checked in by charles, 14 years ago

update to libnatpmp-20071213

File size: 3.0 KB
Line 
1/* $Id: getgateway.c,v 1.6 2007/12/13 14:46:06 nanard Exp $ */
2/* libnatpmp
3 * Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16#include <stdio.h>
17#include <ctype.h>
18#include <netinet/in.h>
19#include <sys/param.h>
20#if defined(BSD) || defined(__APPLE__)
21#include <stdlib.h>
22#include <sys/sysctl.h>
23#include <sys/socket.h>
24#include <net/route.h>
25#endif
26#include "getgateway.h"
27
28#ifdef __linux__
29int getdefaultgateway(in_addr_t * addr)
30{
31        long d, g;
32        char buf[256];
33        int line = 0;
34        FILE * f;
35        char * p;
36        f = fopen("/proc/net/route", "r");
37        if(!f)
38                return -1;
39        while(fgets(buf, sizeof(buf), f)) {
40                if(line > 0) {
41                        p = buf;
42                        while(*p && !isspace(*p))
43                                p++;
44                        while(*p && isspace(*p))
45                                p++;
46                        if(sscanf(p, "%lx%lx", &d, &g)==2) {
47                                if(d == 0) { /* default */
48                                        *addr = g;
49                                        fclose(f);
50                                        return 0;
51                                }
52                        }
53                }
54                line++;
55        }
56        /* not found ! */
57        if(f)
58                fclose(f);
59        return -1;
60}
61#endif
62
63#if defined(BSD) || defined(__APPLE__)
64
65#define ROUNDUP(a) \
66        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
67
68int getdefaultgateway(in_addr_t * addr)
69{
70#if 0
71        /* net.route.0.inet.dump.0.0 ? */
72        int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
73                     NET_RT_DUMP, 0, 0/*tableid*/};
74#endif
75        /* net.route.0.inet.flags.gateway */
76        int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
77                     NET_RT_FLAGS, RTF_GATEWAY};
78        size_t l;
79        char * buf, * p;
80        struct rt_msghdr * rt;
81        struct sockaddr * sa;
82        struct sockaddr * sa_tab[RTAX_MAX];
83        int i;
84        int r = -1;
85        if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
86                return -1;
87        }
88        if(l>0) {
89                buf = malloc(l);
90                if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
91                        return -1;
92                }
93                for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
94                        rt = (struct rt_msghdr *)p;
95                        sa = (struct sockaddr *)(rt + 1);
96                        for(i=0; i<RTAX_MAX; i++) {
97                                if(rt->rtm_addrs & (1 << i)) {
98                                        sa_tab[i] = sa;
99                                        sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
100                                } else {
101                                        sa_tab[i] = NULL;
102                                }
103                        }
104                        if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
105              && sa_tab[RTAX_DST]->sa_family == AF_INET
106              && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
107                                if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
108                                        *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
109                                        r = 0;
110                                }
111                        }
112                }
113                free(buf);
114        }
115        return r;
116}
117#endif
Note: See TracBrowser for help on using the repository browser.