Changeset 4139


Ignore:
Timestamp:
Dec 13, 2007, 1:07:34 AM (14 years ago)
Author:
charles
Message:

break things in a new, different way

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/third-party/libnatpmp/getgateway.c

    r4138 r4139  
    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 
    171#include <stdio.h>
    182#include <stdlib.h>
    193#include <string.h>
     4#include <errno.h>
     5#if defined(BSD) || defined(__APPLE__)
     6
     7#include <sys/types.h>
     8#include <sys/socket.h>
     9#include <netinet/in.h>
     10#include <arpa/inet.h>
     11#include <netinet/in.h> /* struct in_addr */
     12#include <sys/sysctl.h>
     13#include <net/route.h>
     14
     15static uint8_t *
     16getroute( int * buflen );
     17static int
     18parseroutes( uint8_t * buf, int len, struct in_addr * addr );
     19
     20int
     21getdefaultgateway( struct in_addr * addr )
     22{
     23    uint8_t * buf;
     24    int len;
     25
     26    buf = getroute( &len );
     27    if( NULL == buf )
     28    {
     29        fprintf(stderr, "failed to get default route (BSD)" );
     30        return 1;
     31    }
     32
     33    len = parseroutes( buf, len, addr );
     34    free( buf );
     35
     36    return len;
     37}
     38
     39#ifndef SA_SIZE
     40#define ROUNDUP( a, size ) \
     41    ( ( (a) & ( (size) - 1 ) ) ? ( 1 + ( (a) | ( (size) - 1 ) ) ) : (a) )
     42#define SA_SIZE( sap ) \
     43    ( sap->sa_len ? ROUNDUP( (sap)->sa_len, sizeof( u_long ) ) : \
     44                    sizeof( u_long ) )
     45#endif /* !SA_SIZE */
     46#define NEXT_SA( sap ) \
     47    (struct sockaddr *) ( (caddr_t) (sap) + ( SA_SIZE( (sap) ) ) )
     48
     49static uint8_t *
     50getroute( int * buflen )
     51{
     52    int     mib[6];
     53    size_t  len;
     54    uint8_t * buf;
     55
     56    mib[0] = CTL_NET;
     57    mib[1] = PF_ROUTE;
     58    mib[2] = 0;
     59    mib[3] = AF_INET;
     60    mib[4] = NET_RT_FLAGS;
     61    mib[5] = RTF_GATEWAY;
     62
     63    if( sysctl( mib, 6, NULL, &len, NULL, 0 ) )
     64    {
     65        if( ENOENT != errno )
     66        {
     67            fprintf(stderr, "sysctl net.route.0.inet.flags.gateway failed (%s)",
     68                    strerror( errno ) );
     69        }
     70        *buflen = 0;
     71        return NULL;
     72    }
     73
     74    buf = malloc( len );
     75    if( NULL == buf )
     76    {
     77        *buflen = 0;
     78        return NULL;
     79    }
     80
     81    if( sysctl( mib, 6, buf, &len, NULL, 0 ) )
     82    {
     83        fprintf(stderr, "sysctl net.route.0.inet.flags.gateway failed (%s)",
     84                strerror( errno ) );
     85        free( buf );
     86        *buflen = 0;
     87        return NULL;
     88    }
     89
     90    *buflen = len;
     91
     92    return buf;
     93}
     94
     95static int
     96parseroutes( uint8_t * buf, int len, struct in_addr * addr )
     97{
     98    uint8_t            * end;
     99    struct rt_msghdr   * rtm;
     100    struct sockaddr    * sa;
     101    struct sockaddr_in * sin;
     102    int                  ii;
     103    struct in_addr       dest, gw;
     104
     105    end = buf + len;
     106    while( end > buf + sizeof( *rtm ) )
     107    {
     108        rtm = (struct rt_msghdr *) buf;
     109        buf += rtm->rtm_msglen;
     110        if( end >= buf )
     111        {
     112            dest.s_addr = INADDR_NONE;
     113            gw.s_addr   = INADDR_NONE;
     114            sa = (struct sockaddr *) ( rtm + 1 );
     115
     116            for( ii = 0; ii < RTAX_MAX && (uint8_t *) sa < buf; ii++ )
     117            {
     118                if( buf < (uint8_t *) NEXT_SA( sa ) )
     119                {
     120                    break;
     121                }
     122
     123                if( rtm->rtm_addrs & ( 1 << ii ) )
     124                {
     125                    if( AF_INET == sa->sa_family )
     126                    {
     127                        sin = (struct sockaddr_in *) sa;
     128                        switch( ii )
     129                        {
     130                            case RTAX_DST:
     131                                dest = sin->sin_addr;
     132                                break;
     133                            case RTAX_GATEWAY:
     134                                gw = sin->sin_addr;
     135                                break;
     136                        }
     137                    }
     138                    sa = NEXT_SA( sa );
     139                }
     140            }
     141
     142            if( INADDR_ANY == dest.s_addr && INADDR_NONE != gw.s_addr )
     143            {
     144                *addr = gw;
     145                return 0;
     146            }
     147        }
     148    }
     149
     150    return 1;
     151}
     152
     153#elif defined( linux ) || defined( __linux ) || defined( __linux__ )
     154
     155#include <stdio.h>
    20156#include <ctype.h>
    21157#include <netinet/in.h>
    22158#include <sys/param.h>
    23 #include "getgateway.h"
    24 
    25 #ifdef __linux__
     159
    26160int getdefaultgateway(in_addr_t * addr)
    27161{
     
    56190        return -1;
    57191}
     192
     193#else /* not BSD or Linux */
     194
     195int getdefaultgateway( struct in_addr * addr  )
     196{
     197    printf( "don't know how to get default route on this platform" );
     198    return 1;
     199}
     200
    58201#endif
    59 
    60 #if defined(BSD) || defined(__APPLE__)
    61 
    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 
    205 #endif
Note: See TracChangeset for help on using the changeset viewer.