X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcnet.c;h=d2121556ef91c77372556f591d329279794ead7f;hb=20bb4767d7d7f5a9f3147c5cb47291932320dfff;hp=c4686c6ef791a20e82b17d0b6f7372b1e415f4e3;hpb=c27a4ecc3e616e8a5ee09b8ca888ed6ff3e501f7;p=crypto.git diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index c4686c6e..d2121556 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2005 Pekka Riikonen + Copyright (C) 1997 - 2007 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 @@ -18,20 +18,93 @@ */ /* $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; +} /* Accepts a connection from a particular socket */ int silc_net_accept_connection(int sock) { - return accept(sock, 0, 0); + int ret = accept(sock, 0, 0); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Sets a option for a socket. */ int silc_net_set_socket_opt(int sock, int level, int option, int on) { - return setsockopt(sock, level, option, (void *)&on, sizeof(on)); + int ret = setsockopt(sock, level, option, (void *)&on, sizeof(on)); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Get socket options */ @@ -39,7 +112,10 @@ int silc_net_set_socket_opt(int sock, int level, int option, int on) int silc_net_get_socket_opt(int sock, int level, int option, void *optval, int *opt_len) { - return getsockopt(sock, level, option, optval, opt_len); + int ret = getsockopt(sock, level, option, optval, opt_len); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Checks whether IP address sent as argument is valid IPv4 address. */ @@ -49,7 +125,7 @@ SilcBool silc_net_is_ip4(const char *addr) int count = 0; while (*addr) { - if (*addr != '.' && !isdigit(*addr)) + if (*addr != '.' && !isdigit((int)*addr)) return FALSE; if (*addr == '.') count++; @@ -68,7 +144,7 @@ SilcBool silc_net_is_ip6(const char *addr) { /* XXX does this work with all kinds of IPv6 addresses? */ while (*addr) { - if (*addr != ':' && !isxdigit(*addr)) + if (*addr != ':' && !isxdigit((int)*addr)) return FALSE; addr++; } @@ -117,7 +193,7 @@ static void *silc_net_gethostbyname_thread(void *context) char tmp[64]; if (silc_net_gethostbyname(r->input, r->prefer_ipv6, tmp, sizeof(tmp))) - r->result = strdup(tmp); + r->result = silc_strdup(tmp); silc_schedule_task_add(schedule, 0, silc_net_resolve_completion, r, 0, 1, SILC_TASK_TIMEOUT); @@ -134,7 +210,7 @@ static void *silc_net_gethostbyaddr_thread(void *context) char tmp[256]; if (silc_net_gethostbyaddr(r->input, tmp, sizeof(tmp))) - r->result = strdup(tmp); + r->result = silc_strdup(tmp); silc_schedule_task_add(schedule, 0, silc_net_resolve_completion, r, 0, 1, SILC_TASK_TIMEOUT); @@ -144,8 +220,9 @@ static void *silc_net_gethostbyaddr_thread(void *context) /* 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; @@ -188,6 +265,14 @@ SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6, char *ad 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; @@ -219,14 +304,15 @@ void silc_net_gethostbyname_async(const char *name, r->context = context; r->prefer_ipv6 = prefer_ipv6; r->schedule = schedule; - r->input = strdup(name); + r->input = silc_strdup(name); silc_thread_create(silc_net_gethostbyname_thread, r, 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; @@ -244,7 +330,7 @@ SilcBool silc_net_gethostbyaddr(const char *addr, char *name, SilcUInt32 name_le freeaddrinfo(ai); #else struct hostent *hp; - unsigned char a[16]; + unsigned char a[4]; if (!silc_net_addr2bin(addr, a, sizeof(a))) return FALSE; @@ -273,15 +359,18 @@ void silc_net_gethostbyaddr_async(const char *addr, r->completion = completion; r->context = context; r->schedule = schedule; - r->input = strdup(addr); + r->input = silc_strdup(addr); 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; @@ -359,7 +448,8 @@ SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip) /* 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; @@ -436,7 +526,7 @@ SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip) /* 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; @@ -468,7 +558,7 @@ SilcUInt16 silc_net_get_remote_port(int sock) /* 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; @@ -497,6 +587,7 @@ SilcUInt16 silc_net_get_local_port(int sock) return ntohs(local.sin_port); #endif } +#endif /* !SILC_SYMBIAN */ /* Return name of localhost. */ @@ -508,10 +599,10 @@ char *silc_net_localhost(void) return NULL; if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) - return strdup(hostname); + return silc_strdup(hostname); silc_net_gethostbyaddr(ip_addr, hostname, sizeof(hostname)); - return strdup(hostname); + return silc_strdup(hostname); } /* Returns local IP address */ @@ -526,5 +617,5 @@ char *silc_net_localip(void) if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) return NULL; - return strdup(ip_addr); + return silc_strdup(ip_addr); }