Annotation of embedaddon/libnet/src/libnet_resolve.c, revision 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>