183 lines
5.5 KiB
C
183 lines
5.5 KiB
C
/*-
|
|
* Copyright (c) 2017-2019 Carsten Sonne Larsen <cs@innolan.net>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "net_getaddrinfo.h"
|
|
#include "message.h"
|
|
|
|
int errno;
|
|
int gai_h_errno;
|
|
|
|
#ifdef AOS3
|
|
int h_errno;
|
|
#endif
|
|
|
|
static const char *bsdSocketName = "bsdsocket.library";
|
|
static const char *openSocketLibraryError = "Cannot open %s %ld.0";
|
|
static const char *openSocketResourceError = "Cannot open %s";
|
|
struct Library *SocketBase = NULL;
|
|
|
|
#define BSDLIB_NAME ((STRPTR)bsdSocketName)
|
|
#define BSDLIB_REV 03L
|
|
|
|
int OpenSocketLibrary(void)
|
|
{
|
|
char message[SETTINGMESSAGELEN];
|
|
|
|
if (SocketBase != NULL)
|
|
{
|
|
return LIB_OK;
|
|
}
|
|
|
|
if (!(SocketBase = OpenLibrary((STRPTR)BSDLIB_NAME, BSDLIB_REV)))
|
|
{
|
|
SNPrintf(message, SETTINGMESSAGELEN, openSocketLibraryError, BSDLIB_NAME, BSDLIB_REV);
|
|
SendErrorMessage(message);
|
|
return LIB_ERROR;
|
|
}
|
|
|
|
SNPrintf(message, SETTINGMESSAGELEN, "Opened %s", (char *)SocketBase->lib_IdString);
|
|
SendTraceMessage(message);
|
|
|
|
if (SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (int)&errno,
|
|
SBTM_SETVAL(SBTC_HERRNOLONGPTR), (int)&h_errno, TAG_DONE))
|
|
{
|
|
SNPrintf(message, SETTINGMESSAGELEN, openSocketResourceError, BSDLIB_NAME);
|
|
SendErrorMessage(message);
|
|
CloseLibrary(SocketBase);
|
|
return LIB_ERROR;
|
|
}
|
|
|
|
return LIB_OK;
|
|
}
|
|
|
|
void CloseSocketLibrary(void)
|
|
{
|
|
if (SocketBase != NULL)
|
|
{
|
|
char message[SETTINGMESSAGELEN];
|
|
SNPrintf(message, SETTINGMESSAGELEN, "Closing %s", (char *)SocketBase->lib_IdString);
|
|
SendTraceMessage(message);
|
|
CloseLibrary(SocketBase);
|
|
SocketBase = NULL;
|
|
}
|
|
}
|
|
|
|
const char *GetErrorText(void)
|
|
{
|
|
switch (errno)
|
|
{
|
|
case ENOTSOCK:
|
|
return "Socket operation on non-socket";
|
|
case EDESTADDRREQ:
|
|
return "Destination address required";
|
|
case EMSGSIZE:
|
|
return "Message too long";
|
|
case EPROTOTYPE:
|
|
return "Protocol wrong type for socket";
|
|
case ENOPROTOOPT:
|
|
return "Protocol not available";
|
|
case EPROTONOSUPPORT:
|
|
return "Protocol not supported";
|
|
case ESOCKTNOSUPPORT:
|
|
return "Socket type not supported";
|
|
case EOPNOTSUPP:
|
|
return "Operation not supported";
|
|
case EPFNOSUPPORT:
|
|
return "Protocol family not supported";
|
|
case EAFNOSUPPORT:
|
|
return "Address family not supported by protocol family";
|
|
case EADDRINUSE:
|
|
return "Address already in use";
|
|
case EADDRNOTAVAIL:
|
|
return "Can't assign requested address";
|
|
case ENETDOWN:
|
|
return "Network is down";
|
|
case ENETUNREACH:
|
|
return "Network is unreachable";
|
|
case ENETRESET:
|
|
return "Network dropped connection on reset";
|
|
case ECONNABORTED:
|
|
return "Software caused connection abort";
|
|
case ECONNRESET:
|
|
return "Connection reset by peer";
|
|
case ENOBUFS:
|
|
return "No buffer space available";
|
|
case EISCONN:
|
|
return "Socket is already connected";
|
|
case ENOTCONN:
|
|
return "Socket is not connected";
|
|
case ESHUTDOWN:
|
|
return "Can't send after socket shutdown";
|
|
case ETIMEDOUT:
|
|
return "Operation timed out";
|
|
case ECONNREFUSED:
|
|
return "Connection refused";
|
|
case EHOSTDOWN:
|
|
return "Host is down";
|
|
case EHOSTUNREACH:
|
|
return "No route to host";
|
|
default:
|
|
return "Socket error";
|
|
}
|
|
}
|
|
|
|
const char *GetHostErrorText(void)
|
|
{
|
|
if (gai_h_errno != 0)
|
|
{
|
|
return gai_h_errno == EAI_SYSTEM
|
|
? GetErrorText()
|
|
: gai_strerror(gai_h_errno);
|
|
}
|
|
|
|
switch (h_errno)
|
|
{
|
|
case EAI_BADFLAGS:
|
|
return "Invalid value for ai_flags";
|
|
case EAI_NONAME:
|
|
return "Name or service is not known";
|
|
case EAI_AGAIN:
|
|
return "Temporary failure in name resolution";
|
|
case EAI_FAIL:
|
|
return "Non-recoverable failure in name resolution";
|
|
case EAI_FAMILY:
|
|
return "ai_family not supported";
|
|
case EAI_SOCKTYPE:
|
|
return "ai_socktype not supported";
|
|
case EAI_SERVICE:
|
|
return "Service not supported for ai_socktype";
|
|
case EAI_ADDRFAMILY:
|
|
return "Address family for name not supported";
|
|
case EAI_MEMORY:
|
|
return "Memory allocation failure";
|
|
case EAI_SYSTEM:
|
|
return GetErrorText();
|
|
default:
|
|
return "DNS error";
|
|
}
|
|
}
|