diff options
Diffstat (limited to 'src/InetAddress.cpp')
-rw-r--r-- | src/InetAddress.cpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/src/InetAddress.cpp b/src/InetAddress.cpp new file mode 100644 index 0000000..8915285 --- /dev/null +++ b/src/InetAddress.cpp @@ -0,0 +1,259 @@ +/* + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the + Queen in Right of Canada (Communications Research Center Canada) + */ +/* + This file is part of CRC-DabMux. + + CRC-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + CRC-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CRC-DabMux. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "InetAddress.h" +#include <iostream> +#include <stdio.h> + +#ifdef _WIN32 +#else +# include <errno.h> +# include <string.h> +#endif + +#ifdef TRACE_ON +# ifndef TRACE_CLASS +# define TRACE_CLASS(clas, func) cout <<"-" <<(clas) <<"\t(" <<this <<")::" <<(func) <<endl +# define TRACE_STATIC(clas, func) cout <<"-" <<(clas) <<"\t(static)::" <<(func) <<endl +# endif +#else +# ifndef TRACE_CLASS +# define TRACE_CLASS(clas, func) +# define TRACE_STATIC(clas, func) +# endif +#endif + + +int inetErrNo = 0; +const char *inetErrMsg = NULL; +const char *inetErrDesc = NULL; + + +/** + * Constructs an IP address. + * @param port The port of this address + * @param name The name of this address + */ +InetAddress::InetAddress(int port, const char* name) { + TRACE_CLASS("InetAddress", "InetAddress(int, char)"); + addr.sin_family = PF_INET; + addr.sin_addr.s_addr = htons(INADDR_ANY); + addr.sin_port = htons(port); + if (name) + setAddress(name); +} + + +/** + * Constructs a copy of inet + * @param inet The address to be copied + */ +InetAddress::InetAddress(const InetAddress &inet) { + TRACE_CLASS("InetAddress", "InetAddress(InetAddress)"); + memcpy(&addr, &inet.addr, sizeof(addr)); +} + + +/// Destructor +InetAddress::~InetAddress() { + TRACE_CLASS("InetAddress" ,"~InetAddress()"); +} + + +/// Returns the raw IP address of this InetAddress object. +sockaddr *InetAddress::getAddress() { + TRACE_CLASS("InetAddress", "getAddress()"); + return (sockaddr *)&addr; +} + + +/// Return the port of this address. +int InetAddress::getPort() +{ + TRACE_CLASS("InetAddress", "getPort()"); + return ntohs(addr.sin_port); +} + + +/** + * Returns the IP address string "%d.%d.%d.%d". + * @return IP address + */ +const char *InetAddress::getHostAddress() { + TRACE_CLASS("InetAddress", "getHostAddress()"); + return inet_ntoa(addr.sin_addr); +} + + +/// Returns true if this address is multicast +bool InetAddress::isMulticastAddress() { + TRACE_CLASS("InetAddress", "isMulticastAddress()"); + return IN_MULTICAST(ntohl(addr.sin_addr.s_addr)); // a modifier +} + + +/** + * Set the port number + * @param port The new port number + */ +void InetAddress::setPort(int port) +{ + TRACE_CLASS("InetAddress", "setPort(int)"); + addr.sin_port = htons(port); +} + + +/** + * Set the address + * @param name The new address name + * @return 0 if ok + * -1 if error + */ +int InetAddress::setAddress(const char *name) +{ + TRACE_CLASS("InetAddress", "setAddress(char*)"); + if (name) { + if (atoi(name)) { // If it start with a number + if ((addr.sin_addr.s_addr = inet_addr(name)) == INADDR_NONE) { + addr.sin_addr.s_addr = htons(INADDR_ANY); + inetErrNo = 0; + inetErrMsg = "Invalid address"; + inetErrDesc = name; + return -1; + } + } else { // Assume it's a real name + hostent *host = gethostbyname(name); + if (host) { + addr.sin_addr = *(in_addr *)(host->h_addr); + } else { + addr.sin_addr.s_addr = htons(INADDR_ANY); + inetErrNo = 0; + inetErrMsg = "Could not find address"; + inetErrDesc = name; + return -1; + } + } + } else { + addr.sin_addr.s_addr = INADDR_ANY; + } + return 0; +} + + +void setInetError(const char* description) +{ + inetErrNo = 0; +#ifdef _WIN32 + inetErrNo = WSAGetLastError(); + switch (inetErrNo) { + case WSANOTINITIALISED: + inetErrMsg = "WSANOTINITIALISED A successful WSAStartup must occur before using this function."; + break; + case WSAENETDOWN: + inetErrMsg = "WSAENETDOWN The network subsystem has failed."; + break; + case WSAEFAULT: + inetErrMsg = "WSAEFAULT The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address."; + break; + case WSAEINTR: + inetErrMsg = "WSAEINTR The (blocking) call was canceled through WSACancelBlockingCall."; + break; + case WSAEINPROGRESS: + inetErrMsg = "WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function."; + break; + case WSAEINVAL: + inetErrMsg = "WSAEINVAL The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative."; + break; + case WSAEISCONN: + inetErrMsg = "WSAEISCONN The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless."; + break; + case WSAENETRESET: + inetErrMsg = "WSAENETRESET The connection has been broken due to the \"keep-alive\" activity detecting a failure while the operation was in progress."; + break; + case WSAENOTSOCK: + inetErrMsg = "WSAENOTSOCK The descriptor is not a socket."; + break; + case WSAEOPNOTSUPP: + inetErrMsg = "WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations."; + break; + case WSAESHUTDOWN: + inetErrMsg = "WSAESHUTDOWN The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH."; + break; + case WSAEWOULDBLOCK: + inetErrMsg = "WSAEWOULDBLOCK The socket is marked as nonblocking and the recvfrom operation would block."; + break; + case WSAEMSGSIZE: + inetErrMsg = "WSAEMSGSIZE The message was too large to fit into the specified buffer and was truncated."; + break; + case WSAETIMEDOUT: + inetErrMsg = "WSAETIMEDOUT The connection has been dropped, because of a network failure or because the system on the other end went down without notice."; + break; + case WSAECONNRESET: + inetErrMsg = "WSAECONNRESET"; + break; + case WSAEACCES: + inetErrMsg = "WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST parameter to allow the use of the broadcast address."; + break; + case WSAENOBUFS: + inetErrMsg = "WSAENOBUFS No buffer space is available."; + break; + case WSAENOTCONN: + inetErrMsg = "WSAENOTCONN The socket is not connected (connection-oriented sockets only)"; + break; + case WSAEHOSTUNREACH: + inetErrMsg = "WSAEHOSTUNREACH The remote host cannot be reached from this host at this time."; + break; + case WSAECONNABORTED: + inetErrMsg = "WSAECONNABORTED The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable."; + break; + case WSAEADDRNOTAVAIL: + inetErrMsg = "WSAEADDRNOTAVAIL The remote address is not a valid address, for example, ADDR_ANY."; + break; + case WSAEAFNOSUPPORT: + inetErrMsg = "WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket."; + break; + case WSAEDESTADDRREQ: + inetErrMsg = "WSAEDESTADDRREQ A destination address is required."; + break; + case WSAENETUNREACH: + inetErrMsg = "WSAENETUNREACH The network cannot be reached from this host at this time."; + break; + case WSAEMFILE: + inetErrMsg = "No more socket descriptors are available."; + break; + case WSAEPROTONOSUPPORT: + inetErrMsg = "The specified protocol is not supported."; + break; + case WSAEPROTOTYPE: + inetErrMsg = "The specified protocol is the wrong type for this socket."; + break; + case WSAESOCKTNOSUPPORT: + inetErrMsg = "The specified socket type is not supported in this address family."; + break; + default: + inetErrMsg = "Unknown"; + }; +#else + inetErrNo = errno; + inetErrMsg = strerror(inetErrNo); +#endif + inetErrDesc = description; +} |