Added silc_net_bit2addr, silc_htonl, silc_ntohl, silc_htons, silc_ntohs
[runtime.git] / lib / silcutil / silcnet.c
index d2121556ef91c77372556f591d329279794ead7f..47ca9fce33713f4fcfa764c9019638b4a3b77f31 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2007 Pekka Riikonen
+  Copyright (C) 1997 - 2008 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
@@ -16,9 +16,8 @@
   GNU General Public License for more details.
 
 */
-/* $Id$ */
 
-#include "silc.h"
+#include "silcruntime.h"
 
 /* Returns bound port from listener */
 
@@ -112,7 +111,7 @@ 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)
 {
-  int ret = getsockopt(sock, level, option, optval, opt_len);
+  int ret = getsockopt(sock, level, option, optval, (unsigned int *)opt_len);
   if (ret < 0)
     silc_set_errno_posix(errno);
   return ret;
@@ -300,6 +299,11 @@ void silc_net_gethostbyname_async(const char *name,
 {
   SilcNetResolveContext r = silc_calloc(1, sizeof(*r));
 
+  if (!schedule) {
+    schedule = silc_schedule_get_global();
+    SILC_VERIFY(schedule);
+  }
+
   r->completion = completion;
   r->context = context;
   r->prefer_ipv6 = prefer_ipv6;
@@ -356,6 +360,11 @@ void silc_net_gethostbyaddr_async(const char *addr,
 {
   SilcNetResolveContext r = silc_calloc(1, sizeof(*r));
 
+  if (!schedule) {
+    schedule = silc_schedule_get_global();
+    SILC_VERIFY(schedule);
+  }
+
   r->completion = completion;
   r->context = context;
   r->schedule = schedule;
@@ -373,7 +382,8 @@ SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
                                     char **ip)
 {
   char host[1024];
-  int rval, len;
+  int rval;
+  unsigned int len;
 
 #ifdef HAVE_IPV6
   struct sockaddr_storage remote;
@@ -452,7 +462,8 @@ SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
                                      char **ip)
 {
   char host[1024];
-  int rval, len;
+  int rval;
+  unsigned int len;
 
 #ifdef HAVE_IPV6
   struct sockaddr_storage local;
@@ -530,7 +541,7 @@ SilcUInt16 silc_net_get_remote_port(SilcSocket sock)
 {
 #ifdef HAVE_IPV6
   struct sockaddr_storage remote;
-  int len;
+  unsigned int len;
   char s[NI_MAXSERV];
 
   memset(&remote, 0, sizeof(remote));
@@ -545,7 +556,7 @@ SilcUInt16 silc_net_get_remote_port(SilcSocket sock)
   return atoi(s);
 #else
   struct sockaddr_in remote;
-  int len;
+  unsigned int len;
 
   memset(&remote, 0, sizeof(remote));
   len = sizeof(remote);
@@ -562,7 +573,7 @@ SilcUInt16 silc_net_get_local_port(SilcSocket sock)
 {
 #ifdef HAVE_IPV6
   struct sockaddr_storage local;
-  int len;
+  unsigned int len;
   char s[NI_MAXSERV];
 
   memset(&local, 0, sizeof(local));
@@ -577,7 +588,7 @@ SilcUInt16 silc_net_get_local_port(SilcSocket sock)
   return atoi(s);
 #else
   struct sockaddr_in local;
-  int len;
+  unsigned int len;
 
   memset(&local, 0, sizeof(local));
   len = sizeof(local);
@@ -619,3 +630,83 @@ char *silc_net_localip(void)
 
   return silc_strdup(ip_addr);
 }
+
+/* Convert network byte order IP to string */
+
+SilcBool silc_net_bin2addr(const void *bin, SilcUInt32 bin_len,
+                          char *addr, SilcUInt32 addr_size)
+{
+  if (!addr || !addr_size)
+    return TRUE;
+
+  if (bin_len == 16) {
+#ifdef HAVE_IPV6
+    struct sockaddr_in6 ipv6;
+    memset(&ipv6, 0, sizeof(ipv6));
+    ipv6.sin6_family = AF_INET6;
+    memcpy(&ipv6.sin6_addr, bin, sizeof(ipv6.sin6_addr));
+    if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
+                    addr, addr_size, NULL, 0, NI_NUMERICHOST))
+    return TRUE;
+#else
+    return FALSE;
+#endif /* HAVE_IPV6 */
+  } else if (bin_len == 4) {
+    struct in_addr ipv4;
+    char *a;
+
+    memcpy(&ipv4.s_addr, bin, 4);
+    a = inet_ntoa(ipv4);
+    if (!a)
+      return FALSE;
+
+    silc_snprintf(addr, addr_size, a);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* Host to network byte order */
+
+SilcUInt32 silc_htonl(SilcUInt32 host)
+{
+#ifdef WORDS_BIGENDIAN
+  return host;
+#else
+  return SILC_SWAB_32(host);
+#endif /* WORDS_BIGENDIAN */
+}
+
+/* Network to host byte order */
+
+SilcUInt32 silc_ntohl(SilcUInt32 net)
+{
+#ifdef WORDS_BIGENDIAN
+  return net;
+#else
+  return SILC_SWAB_32(net);
+#endif /* WORDS_BIGENDIAN */
+}
+
+/* Host to network byte order */
+
+SilcUInt16 silc_htons(SilcUInt16 host)
+{
+#ifdef WORDS_BIGENDIAN
+  return net;
+#else
+  return SILC_SWAB_16(host);
+#endif /* WORDS_BIGENDIAN */
+}
+
+/* Network to host byte order */
+
+SilcUInt16 silc_ntohs(SilcUInt16 net)
+{
+#ifdef WORDS_BIGENDIAN
+  return net;
+#else
+  return SILC_SWAB_16(net);
+#endif /* WORDS_BIGENDIAN */
+}