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

Last change on this file since 4095 was 4095, checked in by charles, 15 years ago

add libnatpmp by Thomas Bernard

File size: 2.8 KB
Line 
1/* $Id: getgateway.c,v 1.4 2007/11/22 18:01:37 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#ifdef BSD
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#ifdef BSD
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        int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
71                     NET_RT_DUMP, 0, 0/*tableid*/};
72        size_t l;
73        char * buf, * p;
74        struct rt_msghdr * rt;
75        struct sockaddr * sa;
76        struct sockaddr * sa_tab[RTAX_MAX];
77        int i;
78        int r = -1;
79        if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
80                return -1;
81        }
82        if(l>0) {
83                buf = malloc(l);
84                if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
85                        return -1;
86                }
87                for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
88                        rt = (struct rt_msghdr *)p;
89                        sa = (struct sockaddr *)(rt + 1);
90                        for(i=0; i<RTAX_MAX; i++) {
91                                if(rt->rtm_addrs & (1 << i)) {
92                                        sa_tab[i] = sa;
93                                        sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
94                                } else {
95                                        sa_tab[i] = NULL;
96                                }
97                        }
98                        if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
99              && sa_tab[RTAX_DST]->sa_family == AF_INET
100              && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
101                                if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
102                                        *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
103                                        r = 0;
104                                }
105                        }
106                }
107                free(buf);
108        }
109        return r;
110}
111#endif
Note: See TracBrowser for help on using the repository browser.