Annotation of embedaddon/libnet/src/libnet_resolve.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *  $Id: libnet_resolve.c,v 1.20 2004/03/04 20:52:26 kkuehl Exp $
                      3:  *
                      4:  *  libnet
                      5:  *  libnet_resolve.c - various name resolution type routines
                      6:  *
                      7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
                      8:  *  All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  *
                     31:  */
                     32: 
                     33: #if (HAVE_CONFIG_H)
                     34: #include "../include/config.h"
                     35: #endif
                     36: #if (!(_WIN32) || (__CYGWIN__)) 
                     37: #include "../include/libnet.h"
                     38: #else
                     39: #include "../include/win32/libnet.h"
                     40: #endif
                     41: 
                     42: char *
                     43: libnet_addr2name4(u_int32_t in, u_int8_t use_name)
                     44: {
                     45:        #define HOSTNAME_SIZE 512
                     46:     static char hostname[HOSTNAME_SIZE+1], hostname2[HOSTNAME_SIZE+1];
                     47:     static u_int16_t which;
                     48:     u_int8_t *p;
                     49: 
                     50:     struct hostent *host_ent = NULL;
                     51:     struct in_addr addr;
                     52: 
                     53:     /*
                     54:      *  Swap to the other buffer.  We swap static buffers to avoid having to
                     55:      *  pass in a int8_t *.  This makes the code that calls this function more
                     56:      *  intuitive, but makes this function ugly.  This function is seriously
                     57:      *  non-reentrant.  For threaded applications (or for signal handler code)
                     58:      *  use host_lookup_r().
                     59:      */
                     60:     which++;
                     61:     
                     62:     if (use_name == LIBNET_RESOLVE)
                     63:     {
                     64:                addr.s_addr = in;
                     65:         host_ent = gethostbyaddr((int8_t *)&addr, sizeof(struct in_addr), AF_INET);
                     66:         /* if this fails, we silently ignore the error and move to plan b! */
                     67:     }
                     68:     if (!host_ent)
                     69:     {
                     70: 
                     71:         p = (u_int8_t *)&in;
                     72:                snprintf(((which % 2) ? hostname : hostname2), HOSTNAME_SIZE,
                     73:                  "%d.%d.%d.%d",
                     74:                  (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
                     75:     }
                     76:     else if (use_name == LIBNET_RESOLVE)
                     77:     {
                     78:                char *ptr = ((which % 2) ? hostname : hostname2);
                     79:                strncpy(ptr, host_ent->h_name, HOSTNAME_SIZE);
                     80:                ptr[HOSTNAME_SIZE] = '\0';
                     81:        
                     82:     }
                     83:     return (which % 2) ? (hostname) : (hostname2);
                     84: }
                     85: 
                     86: void
                     87: libnet_addr2name4_r(u_int32_t in, u_int8_t use_name, char *hostname,
                     88:         int hostname_len)
                     89: {
                     90:     u_int8_t *p;
                     91:     struct hostent *host_ent = NULL;
                     92:     struct in_addr addr;
                     93: 
                     94:     if (use_name == LIBNET_RESOLVE)
                     95:     {   
                     96:                addr.s_addr = in;
                     97:         host_ent = gethostbyaddr((int8_t *)&addr, sizeof(struct in_addr),
                     98:                 AF_INET);
                     99:     }
                    100:     if (!host_ent)
                    101:     {
                    102:         p = (u_int8_t *)&in;
                    103:         snprintf(hostname, hostname_len, "%d.%d.%d.%d",
                    104:                 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
                    105:     }
                    106:     else
                    107:     {
                    108:         strncpy(hostname, host_ent->h_name, hostname_len - 1);
                    109:                hostname[sizeof(hostname) - 1] = '\0';
                    110:     }
                    111: }
                    112: 
                    113: u_int32_t
                    114: libnet_name2addr4(libnet_t *l, char *host_name, u_int8_t use_name)
                    115: {
                    116:     struct in_addr addr;
                    117:     struct hostent *host_ent; 
                    118:     u_int32_t m;
                    119:     u_int val;
                    120:     int i;
                    121: 
                    122:     if (use_name == LIBNET_RESOLVE)
                    123:     {
                    124:                if ((addr.s_addr = inet_addr(host_name)) == -1)
                    125:         {
                    126:             if (!(host_ent = gethostbyname(host_name)))
                    127:             {
                    128:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    129:                         "%s(): %s\n", __func__, strerror(errno));
                    130:                 /* XXX - this is actually 255.255.255.255 */
                    131:                 return (-1);
                    132:             }
                    133:             memcpy(&addr.s_addr, host_ent->h_addr, host_ent->h_length);
                    134:         }
                    135:         /* network byte order */
                    136:         return (addr.s_addr);
                    137:     }
                    138:     else
                    139:     {
                    140:         /*
                    141:          *  We only want dots 'n decimals.
                    142:          */
                    143:         if (!isdigit(host_name[0]))
                    144:         {
                    145:             if (l)
                    146:             {
                    147:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    148:                     "%s(): expecting dots and decimals\n", __func__);
                    149:             }
                    150:             /* XXX - this is actually 255.255.255.255 */
                    151:             return (-1);
                    152:         }
                    153: 
                    154:         m = 0;
                    155:         for (i = 0; i < 4; i++)
                    156:         {
                    157:             m <<= 8;
                    158:             if (*host_name)
                    159:             {
                    160:                 val = 0;
                    161:                 while (*host_name && *host_name != '.')
                    162:                 {   
                    163:                     val *= 10;
                    164:                     val += *host_name - '0';
                    165:                     if (val > 255)
                    166:                     {
                    167:                         if (l)
                    168:                         {
                    169:                             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    170:                             "%s(): value greater than 255\n", __func__);
                    171:                         }
                    172:                         /* XXX - this is actually 255.255.255.255 */
                    173:                         return (-1);
                    174:                     }
                    175:                     host_name++;
                    176:                 }
                    177:                 m |= val;
                    178:                 if (*host_name)
                    179:                 {
                    180:                     host_name++;
                    181:                 }
                    182:             }
                    183:         }
                    184:         /* host byte order */
                    185:        return (ntohl(m));
                    186:     }
                    187: }
                    188: 
                    189: void
                    190: libnet_addr2name6_r(struct libnet_in6_addr addr, u_int8_t use_name,
                    191:             char *host_name, int host_name_len)
                    192: {
                    193:     struct hostent *host_ent = NULL;
                    194: 
                    195:     if (use_name == LIBNET_RESOLVE)
                    196:     {    
                    197: #ifdef HAVE_SOLARIS 
                    198: #ifdef HAVE_SOLARIS_IPV6
                    199:         host_ent = getipnodebyaddr((int8_t *)&addr, sizeof(struct in_addr),
                    200:                 AF_INET6, NULL);
                    201: #else
                    202:         /* XXX - Gah!  Can't report error! */
                    203:         host_ent = NULL;
                    204: #endif
                    205: #else
                    206:         host_ent = gethostbyaddr((int8_t *)&addr, sizeof(struct in_addr),
                    207:                 AF_INET6);
                    208: #endif
                    209:     }
                    210:     if (!host_ent)
                    211:     {
                    212: #if !defined(__WIN32__) /* Silence Win32 warning */
                    213:         inet_ntop(AF_INET6, &addr, host_name, host_name_len);
                    214: #endif
                    215:     }
                    216:     else
                    217:     {
                    218:         strncpy(host_name, host_ent->h_name, host_name_len -1);
                    219:                host_name[sizeof(host_name) - 1] = '\0';
                    220:     }
                    221: }
                    222: 
                    223: const struct libnet_in6_addr in6addr_error = IN6ADDR_ERROR_INIT;
                    224: 
                    225: struct libnet_in6_addr
                    226: libnet_name2addr6(libnet_t *l, char *host_name, u_int8_t use_name)
                    227: {
                    228: #if !defined (__WIN32__)
                    229:     struct libnet_in6_addr addr;
                    230:     struct hostent *host_ent; 
                    231: #endif
                    232:    
                    233:     if (use_name == LIBNET_RESOLVE)
                    234:     {
                    235: #ifdef __WIN32__
                    236:         /* XXX - we don't support this yet */
                    237:         if (l)
                    238:         {        
                    239:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    240:                 "%s(): can't resolve IPv6 addresses\n", __func__);
                    241:         }
                    242:         return (in6addr_error);
                    243: #else
                    244: #ifdef HAVE_SOLARIS 
                    245: #ifdef HAVE_SOLARIS_IPV6
                    246:         if (!(host_ent = getipnodebyname((int8_t *)&addr,
                    247:                 sizeof(struct in_addr), AF_INET6, NULL)))
                    248: #else
                    249:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
                    250:                 "%s(): %s\n", __func__, strerror(errno));
                    251:         return (in6addr_error);
                    252: #endif
                    253: #else
                    254:         if (!(host_ent = gethostbyname2(host_name, AF_INET6)))
                    255: #endif
                    256:         {
                    257:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    258:                     "%s(): %s", __func__, strerror(errno));
                    259:             return (in6addr_error);
                    260:         }
                    261:         memcpy(&addr, host_ent->h_addr, host_ent->h_length);
                    262:         return (addr);
                    263: #endif  /* !__WIN32__ */
                    264:     }
                    265:     else
                    266:     {
                    267:                #if defined(__WIN32__) /* Silence Win32 warning */
                    268:                if (l)
                    269:         {        
                    270:                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    271:                 "%s(): can't resolve IPv6 addresses.\n", __func__);
                    272:         }
                    273:         return (in6addr_error);
                    274:         #else
                    275:         if(!inet_pton(AF_INET6, host_name, &addr))
                    276:         {
                    277:             if (l)
                    278:             {
                    279:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    280:                     "%s(): invalid IPv6 address\n", __func__);
                    281:             }
                    282:             return (in6addr_error);
                    283:         }
                    284:         return (addr);
                    285:         #endif
                    286:     }
                    287: }
                    288: 
                    289: struct libnet_in6_addr
                    290: libnet_get_ipaddr6(libnet_t *l)
                    291: {
                    292:     snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    293:            "%s(): not yet Implemented\n", __func__);
                    294:     return (in6addr_error);
                    295: }
                    296: 
                    297: #if !defined(__WIN32__)
                    298: u_int32_t
                    299: libnet_get_ipaddr4(libnet_t *l)
                    300: {
                    301:     struct ifreq ifr;
                    302:     register struct sockaddr_in *sin;
                    303:     int fd;
                    304: 
                    305:     if (l == NULL)
                    306:     {
                    307:         return (-1);
                    308:     }
                    309: 
                    310:     /* create dummy socket to perform an ioctl upon */
                    311:     fd = socket(PF_INET, SOCK_DGRAM, 0);
                    312:     if (fd == -1)
                    313:     {
                    314:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    315:                 "%s(): socket(): %s\n", __func__, strerror(errno));
                    316:         return (-1);
                    317:     }
                    318: 
                    319:     sin = (struct sockaddr_in *)&ifr.ifr_addr;
                    320: 
                    321:     if (l->device == NULL)
                    322:     {
                    323:         if (libnet_select_device(l) == -1)
                    324:         {
                    325:             /* error msg set in libnet_select_device() */
                    326:             close(fd);
                    327:             return (-1);
                    328:         }
                    329:     }
                    330:     strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name) -1);
                    331:        ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
                    332:        
                    333:     ifr.ifr_addr.sa_family = AF_INET;
                    334: 
                    335:     if (ioctl(fd, SIOCGIFADDR, (int8_t*) &ifr) < 0)
                    336:     {
                    337:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    338:                 "%s(): ioctl(): %s\n", __func__, strerror(errno));
                    339:         close(fd);
                    340:         return (-1);
                    341:     }
                    342:     close(fd);
                    343:     return (sin->sin_addr.s_addr);
                    344: }
                    345: #else
                    346: #include <Packet32.h>
                    347: u_int32_t
                    348: libnet_get_ipaddr4(libnet_t *l)
                    349: {
                    350:     long npflen = 0;
                    351:     struct sockaddr_in sin;
                    352:     struct npf_if_addr ipbuff;
                    353: 
                    354:     memset(&sin,0,sizeof(sin));
                    355:     memset(&ipbuff,0,sizeof(ipbuff));
                    356: 
                    357:     npflen = sizeof(ipbuff);
                    358:     if (PacketGetNetInfoEx(l->device, &ipbuff, &npflen))
                    359:     {
                    360:         sin = *(struct sockaddr_in *)&ipbuff.IPAddress;
                    361:     }
                    362:     return (sin.sin_addr.s_addr);
                    363: }
                    364: #endif /* WIN32 */
                    365: 
                    366: u_int8_t *
                    367: libnet_hex_aton(int8_t *s, int *len)
                    368: {
                    369:     u_int8_t *buf;
                    370:     int i;
                    371:     int32_t l;
                    372:     int8_t *pp;
                    373:         
                    374:     while (isspace(*s))
                    375:     {
                    376:         s++;
                    377:     }
                    378:     for (i = 0, *len = 0; s[i]; i++)
                    379:     {
                    380:         if (s[i] == ':')
                    381:         {
                    382:             (*len)++;
                    383:         }
                    384:     }
                    385:     buf = malloc(*len + 1);
                    386:     if (buf == NULL)
                    387:     {
                    388:         return (NULL);
                    389:     }
                    390:     /* expect len hex octets separated by ':' */
                    391:     for (i = 0; i < *len + 1; i++)
                    392:     {
                    393:         l = strtol(s, (char **)&pp, 16);
                    394:         if (pp == s || l > 0xff || l < 0)
                    395:         {
                    396:             *len = 0;
                    397:             free(buf);
                    398:             return (NULL);
                    399:         }
                    400:         if (!(*pp == ':' || (i == *len && (isspace(*pp) || *pp == '\0'))))
                    401:         {
                    402:             *len = 0;
                    403:             free(buf);
                    404:             return (NULL);
                    405:         }
                    406:         buf[i] = (u_int8_t)l;
                    407:         s = pp + 1;
                    408:     }
                    409:     /* return int8_tacter after the octets ala strtol(3) */
                    410:     (*len)++;
                    411:     return (buf);
                    412: }
                    413: 
                    414: /* EOF */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>