Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2005 Pekka Riikonen
+ Copyright (C) 1997 - 2006 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
+
+/* Returns bound port from listener */
+
+SilcUInt16 *silc_net_listener_get_port(SilcNetListener listener,
+ SilcUInt32 *port_count)
+{
+ SilcUInt16 *ports;
+ int i;
+
+ ports = silc_calloc(listener->socks_count, sizeof(*ports));
+ if (!ports)
+ return NULL;
+
+ for (i = 0; i < listener->socks_count; i++)
+ ports[i] = silc_net_get_local_port(listener->socks[i]);
+
+ if (port_count)
+ *port_count = listener->socks_count;
+
+ return ports;
+}
+
+/* Return bound IP from listener */
+
+char **silc_net_listener_get_ip(SilcNetListener listener,
+ SilcUInt32 *ip_count)
+{
+ char **ips = NULL, *ip;
+ int i, k;
+
+ ips = silc_calloc(listener->socks_count, sizeof(*ips));
+ if (!ips)
+ return NULL;
+
+ for (i = 0, k = 0; i < listener->socks_count; i++) {
+ if (silc_net_check_local_by_sock(listener->socks[i], NULL, &ip))
+ ips[k++] = ip;
+ }
+
+ if (ip_count)
+ *ip_count = k;
+
+ return ips;
+}
+
+/* Return bound hostname from listener */
+
+char **silc_net_listener_get_hostname(SilcNetListener listener,
+ SilcUInt32 *hostname_count)
+{
+ char **hs = NULL, *h;
+ int i, k;
+
+ hs = silc_calloc(listener->socks_count, sizeof(*hs));
+ if (!hs)
+ return NULL;
+
+ for (i = 0, k = 0; i < listener->socks_count; i++) {
+ if (silc_net_check_local_by_sock(listener->socks[i], &h, NULL))
+ hs[k++] = h;
+ }
+
+ if (hostname_count)
+ *hostname_count = k;
+
+ return hs;
+}
+
+static const char *silc_net_error[] = {
+ "Ok",
+ "Unknown IP address",
+ "Unknown hostname",
+ "Destination unreachable",
+ "Connection refused",
+ "Connection timeout",
+ "System out of memory",
+ "Unexpected error",
+};
+
+/* Return error as string */
+
+const char *silc_net_get_error_string(SilcNetStatus error)
+{
+ if (error < SILC_NET_OK || error > SILC_NET_ERROR)
+ return "";
+ return silc_net_error[error];
+}
/* Accepts a connection from a particular socket */
int count = 0;
while (*addr) {
- if (*addr != '.' && !isdigit(*addr))
+ if (*addr != '.' && !isdigit((int)*addr))
return FALSE;
if (*addr == '.')
count++;
{
/* XXX does this work with all kinds of IPv6 addresses? */
while (*addr) {
- if (*addr != ':' && !isxdigit(*addr))
+ if (*addr != ':' && !isxdigit((int)*addr))
return FALSE;
addr++;
}
/* Resolves IP address for hostname. */
-SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6, char *address,
- SilcUInt32 address_len)
+SilcBool silc_net_gethostbyname(const char *name,
+ SilcBool prefer_ipv6, char *address,
+ SilcUInt32 address_len)
{
#ifdef HAVE_IPV6
struct addrinfo hints, *ai, *tmp, *ip4 = NULL, *ip6 = NULL;
struct in_addr ip;
char *tmp;
+ if (silc_net_is_ip4(name)) {
+ memset(address, 0, address_len);
+ if (address_len < strlen(name))
+ return FALSE;
+ strncpy(address, name, strlen(name));
+ return TRUE;
+ }
+
hp = gethostbyname(name);
if (!hp)
return FALSE;
/* Resolves hostname by IP address. */
-SilcBool silc_net_gethostbyaddr(const char *addr, char *name, SilcUInt32 name_len)
+SilcBool silc_net_gethostbyaddr(const char *addr, char *name,
+ SilcUInt32 name_len)
{
#ifdef HAVE_IPV6
struct addrinfo req, *ai;
freeaddrinfo(ai);
#else
struct hostent *hp;
- unsigned char a[16];
+ unsigned char a[4];
if (!silc_net_addr2bin(addr, a, sizeof(a)))
return FALSE;
silc_thread_create(silc_net_gethostbyaddr_thread, r, FALSE);
}
+#ifndef SILC_SYMBIAN
+
/* Performs lookups for remote name and IP address. This peforms reverse
lookup as well to verify that the IP has FQDN. */
-SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
+SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
+ char **ip)
{
char host[1024];
int rval, len;
/* Performs lookups for local name and IP address. This peforms reverse
lookup as well to verify that the IP has FQDN. */
-SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
+SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
+ char **ip)
{
char host[1024];
int rval, len;
/* Return remote port by socket. */
-SilcUInt16 silc_net_get_remote_port(int sock)
+SilcUInt16 silc_net_get_remote_port(SilcSocket sock)
{
#ifdef HAVE_IPV6
struct sockaddr_storage remote;
/* Return local port by socket. */
-SilcUInt16 silc_net_get_local_port(int sock)
+SilcUInt16 silc_net_get_local_port(SilcSocket sock)
{
#ifdef HAVE_IPV6
struct sockaddr_storage local;
return ntohs(local.sin_port);
#endif
}
+#endif /* !SILC_SYMBIAN */
/* Return name of localhost. */