NetUtils.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 /*
00018  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
00019  *      The Regents of the University of California.  All rights reserved.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that: (1) source code distributions
00023  * retain the above copyright notice and this paragraph in its entirety, (2)
00024  * distributions including binary code include the above copyright notice and
00025  * this paragraph in its entirety in the documentation or other materials
00026  * provided with the distribution, and (3) all advertising materials mentioning
00027  * features or use of this software display the following acknowledgement:
00028  * ``This product includes software developed by the University of California,
00029  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
00030  * the University nor the names of its contributors may be used to endorse
00031  * or promote products derived from this software without specific prior
00032  * written permission.
00033  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00034  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00035  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00036  *
00037  */
00038 
00039 #include "config.h"
00040 #include "NetUtils.h"
00041 #include "compat/inet_aton.h"
00042 #include "debug/DebugUtils.h"
00043 #include "debug/Log.h"
00044 #include "thread/SpinLock.h"
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <sys/socket.h>
00048 #include <netdb.h>
00049 
00050 namespace oasys {
00051 
00052 /*
00053  * A faster replacement for inet_ntoa().
00054  * (Copied from the tcpdump source ).
00055  *
00056  * Modified to take the buffer as an argument.
00057  * Returns a pointer within buf where the string starts
00058  *
00059  */
00060 const char *
00061 _intoa(u_int32_t addr, char* buf, size_t bufsize)
00062 {
00063         register char *cp;
00064         register u_int byte;
00065         register int n;
00066         
00067         addr = ntohl(addr);
00068         cp = &buf[bufsize];
00069         *--cp = '\0';
00070 
00071         n = 4;
00072         do {
00073                 byte = addr & 0xff;
00074                 *--cp = byte % 10 + '0';
00075                 byte /= 10;
00076                 if (byte > 0) {
00077                         *--cp = byte % 10 + '0';
00078                         byte /= 10;
00079                         if (byte > 0)
00080                                 *--cp = byte + '0';
00081                 }
00082                 *--cp = '.';
00083                 addr >>= 8;
00084         } while (--n > 0);
00085 
00086         return cp + 1;
00087 }
00088 
00089 int
00090 gethostbyname(const char* name, in_addr_t* addr)
00091 {
00092     ASSERT(addr);
00093 
00094     // name is a numerical address
00095     if (inet_aton(name, (struct in_addr*)addr) != 0) {
00096         return 0;
00097     }
00098 
00099 #if defined(HAVE_GETHOSTBYNAME_R)
00100     
00101     struct hostent h;
00102     char buf[2048];
00103     struct hostent* ret = 0;
00104     (void)ret;
00105     int h_err;
00106 
00107     
00108 #if defined(__sun__) // solaris has different args
00109     if (::gethostbyname_r(name, &h, buf, sizeof(buf), &h_err) < 0) {
00110         logf("/oasys/net", LOG_ERR, "error return from gethostbyname_r(%s): %s",
00111              name, strerror(h_err));
00112         return -1;
00113     }
00114 #else
00115     if (::gethostbyname_r(name, &h, buf, sizeof(buf), &ret, &h_err) < 0) {
00116         logf("/oasys/net", LOG_ERR, "error return from gethostbyname_r(%s): %s",
00117              name, strerror(h_err));
00118         return -1;
00119     }
00120     if (ret == NULL) {
00121         return -1;
00122     }
00123 #endif
00124 
00125     *addr = ((struct in_addr**)h.h_addr_list)[0]->s_addr;
00126 
00127     if (*addr == INADDR_NONE) {
00128         logf("/oasys/net", LOG_ERR, "gethostbyname_r(%s) returned INADDR_NONE", name);
00129         return -1;
00130     }
00131     return 0;
00132 
00133 #elif defined(HAVE_GETADDRINFO)
00134 
00135     struct addrinfo hints;
00136     struct addrinfo *res;
00137     int              err;
00138 
00139     memset(&hints, 0, sizeof(hints));
00140     hints.ai_family = PF_INET;
00141     
00142     err = getaddrinfo(name, 0, &hints, &res);
00143     if(err != 0) 
00144         return -1;
00145     
00146     ASSERT(res != 0);
00147     ASSERT(res->ai_family == PF_INET);
00148     *addr = ((struct sockaddr_in*) res->ai_addr)->sin_addr.s_addr;
00149     
00150     freeaddrinfo(res);
00151 
00152     if (*addr == INADDR_NONE) {
00153         logf("/oasys/net", LOG_ERR, "getaddrinfo(%s) returned INADDR_NONE", name);
00154         return -1;
00155     }
00156     return 0;
00157     
00158 #elif defined(HAVE_GETHOSTBYNAME)
00159     // make it thread-safe by using a global lock
00160     static SpinLock gethostbyname_lock;
00161     ScopeLock l(&gethostbyname_lock, "gethostbyname");
00162     
00163     struct hostent *hent;
00164     hent = ::gethostbyname(name);
00165     if (hent == NULL) {
00166         logf("/net", LOG_ERR, "error return from gethostbyname(%s): %s",
00167              name, strerror(h_errno));
00168         return -1;
00169     }
00170 
00171     *addr = ((struct in_addr**)hent->h_addr_list)[0]->s_addr;
00172     
00173     if (*addr == INADDR_NONE) {
00174         logf("/oasys/net", LOG_ERR, "gethostbyname(%s) returned INADDR_NONE", name);
00175         return -1;
00176     }
00177 
00178     return 0;
00179     
00180 #else
00181 #error No gethostbyname equivalent available for this platform
00182 #endif    
00183 }
00184 
00185 } // namespace oasys

Generated on Thu Jun 7 12:54:28 2007 for DTN Reference Implementation by  doxygen 1.5.1