Changeset 4138
- Timestamp:
- Dec 13, 2007, 12:55:48 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/third-party/libnatpmp/getgateway.c
r4101 r4138 14 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 16 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 17 20 #include <ctype.h> 18 21 #include <netinet/in.h> 19 22 #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 #endif26 23 #include "getgateway.h" 27 24 … … 63 60 #if defined(BSD) || defined(__APPLE__) 64 61 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 } 62 #include <errno.h> 63 #include <stdlib.h> 64 #include <sys/types.h> 65 #include <sys/socket.h> 66 #include <netinet/in.h> 67 #include <arpa/inet.h> 68 #include <netinet/in.h> /* struct in_addr */ 69 #include <sys/sysctl.h> 70 #include <net/route.h> 71 72 #ifndef SA_SIZE 73 #define ROUNDUP( a, size ) \ 74 ( ( (a) & ( (size) - 1 ) ) ? ( 1 + ( (a) | ( (size) - 1 ) ) ) : (a) ) 75 #define SA_SIZE( sap ) \ 76 ( sap->sa_len ? ROUNDUP( (sap)->sa_len, sizeof( u_long ) ) : \ 77 sizeof( u_long ) ) 78 #endif /* !SA_SIZE */ 79 #define NEXT_SA( sap ) \ 80 (struct sockaddr *) ( (caddr_t) (sap) + ( SA_SIZE( (sap) ) ) ) 81 82 static uint8_t * 83 getroute( int * buflen ) 84 { 85 int mib[6]; 86 size_t len; 87 uint8_t * buf; 88 89 mib[0] = CTL_NET; 90 mib[1] = PF_ROUTE; 91 mib[2] = 0; 92 mib[3] = AF_INET; 93 mib[4] = NET_RT_FLAGS; 94 mib[5] = RTF_GATEWAY; 95 96 if( sysctl( mib, 6, NULL, &len, NULL, 0 ) ) 97 { 98 if( ENOENT != errno ) 99 { 100 fprintf(stderr, "sysctl net.route.0.inet.flags.gateway failed (%s)", 101 strerror( errno ) ); 102 } 103 *buflen = 0; 104 return NULL; 105 } 106 107 buf = malloc( len ); 108 if( NULL == buf ) 109 { 110 *buflen = 0; 111 return NULL; 112 } 113 114 if( sysctl( mib, 6, buf, &len, NULL, 0 ) ) 115 { 116 fprintf(stderr, "sysctl net.route.0.inet.flags.gateway failed (%s)", 117 strerror( errno ) ); 118 free( buf ); 119 *buflen = 0; 120 return NULL; 121 } 122 123 *buflen = len; 124 125 return buf; 126 } 127 128 static int 129 parseroutes( uint8_t * buf, int len, struct in_addr * addr ) 130 { 131 uint8_t * end; 132 struct rt_msghdr * rtm; 133 struct sockaddr * sa; 134 struct sockaddr_in * sin; 135 int ii; 136 struct in_addr dest, gw; 137 138 end = buf + len; 139 while( end > buf + sizeof( *rtm ) ) 140 { 141 rtm = (struct rt_msghdr *) buf; 142 buf += rtm->rtm_msglen; 143 if( end >= buf ) 144 { 145 dest.s_addr = INADDR_NONE; 146 gw.s_addr = INADDR_NONE; 147 sa = (struct sockaddr *) ( rtm + 1 ); 148 149 for( ii = 0; ii < RTAX_MAX && (uint8_t *) sa < buf; ii++ ) 150 { 151 if( buf < (uint8_t *) NEXT_SA( sa ) ) 152 { 153 break; 154 } 155 156 if( rtm->rtm_addrs & ( 1 << ii ) ) 157 { 158 if( AF_INET == sa->sa_family ) 159 { 160 sin = (struct sockaddr_in *) sa; 161 switch( ii ) 162 { 163 case RTAX_DST: 164 dest = sin->sin_addr; 165 break; 166 case RTAX_GATEWAY: 167 gw = sin->sin_addr; 168 break; 169 } 170 } 171 sa = NEXT_SA( sa ); 172 } 173 } 174 175 if( INADDR_ANY == dest.s_addr && INADDR_NONE != gw.s_addr ) 176 { 177 *addr = gw; 178 return 0; 179 } 180 } 181 } 182 183 return 1; 184 } 185 186 int 187 getdefaultgateway( struct in_addr * addr ) 188 { 189 uint8_t * buf; 190 int len; 191 192 buf = getroute( &len ); 193 if( NULL == buf ) 194 { 195 fprintf(stderr, "failed to get default route (BSD)" ); 196 return 1; 197 } 198 199 len = parseroutes( buf, len, addr ); 200 free( buf ); 201 202 return len; 203 } 204 111 205 #endif
Note: See TracChangeset
for help on using the changeset viewer.