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__ |
---|
29 | int 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 | |
---|
68 | int 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 |
---|