dodan override za lintian
[ossec-hids.git] / src / os_net / os_net.c
index 7ec960f..08e1352 100755 (executable)
@@ -1,30 +1,29 @@
-/* @(#) $Id: os_net.c,v 1.34 2009/06/24 17:06:31 dcid Exp $ */
+/* @(#) $Id: ./src/os_net/os_net.c, 2011/09/08 dcid Exp $
+ */
 
 /* Copyright (C) 2009 Trend Micro Inc.
  * All rights reserved.
  *
  * This program is a free software; you can redistribute it
  * and/or modify it under the terms of the GNU General Public
- * License (version 3) as published by the FSF - Free Software 
+ * License (version 2) as published by the FSF - Free Software
  * Foundation
  *
  * License details at the LICENSE file included with OSSEC or
  * online at: http://www.ossec.net/en/licensing.html
  */
 
-/* OS_net Library. 
+/* OS_net Library.
  * APIs for many network operations.
  */
 
 
+
+#include <errno.h>
 #include "shared.h"
 #include "os_net.h"
 
 
-struct sockaddr_in _c;     /* Client socket */
-socklen_t _cl;              /* Client socket length */
 
 
 /* Unix socket -- not for windows */
@@ -38,8 +37,12 @@ socklen_t us_l = sizeof(n_us);
                                      + strlen ((ptr)->sun_path))
 #endif /* Sun_LEN */
 
-#else
-int ENOBUFS = 0;
+#else /* WIN32 */
+/*int ENOBUFS = 0;*/
+# ifndef ENOBUFS
+# define ENOBUFS 0
+# endif
+
 #endif /* WIN32*/
 
 
@@ -47,15 +50,21 @@ int ENOBUFS = 0;
  * Bind a specific port
  * v0.2: Added REUSEADDR.
  */
-int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip)
+int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip, int ipv6)
 {
     int ossock;
     struct sockaddr_in server;
 
-    
+    #ifndef WIN32
+    struct sockaddr_in6 server6;
+    #else
+    ipv6 = 0;
+    #endif
+
+
     if(_proto == IPPROTO_UDP)
     {
-        if((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+        if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
         {
             return OS_SOCKTERR;
         }
@@ -63,14 +72,15 @@ int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip)
     else if(_proto == IPPROTO_TCP)
     {
         int flag = 1;
-        if((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+        if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
         {
             return(int)(OS_SOCKTERR);
         }
-            
-        if(setsockopt(ossock, SOL_SOCKET, SO_REUSEADDR, 
+
+        if(setsockopt(ossock, SOL_SOCKET, SO_REUSEADDR,
                               (char *)&flag,  sizeof(flag)) < 0)
         {
+            OS_CloseSocket(ossock);
             return(OS_SOCKTERR);
         }
     }
@@ -79,30 +89,54 @@ int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip)
         return(OS_INVALID);
     }
 
-    memset(&server, 0, sizeof(server));
-    server.sin_family = AF_INET;
-    server.sin_port = htons( _port );
+    if(ipv6)
+    {
+        #ifndef WIN32
+        memset(&server6, 0, sizeof(server6));
+        server6.sin6_family = AF_INET6;
+        server6.sin6_port = htons( _port );
+        server6.sin6_addr = in6addr_any;
 
-    if((_ip == NULL)||(_ip[0] == '\0'))
-        server.sin_addr.s_addr = htonl(INADDR_ANY);
-    else
-        server.sin_addr.s_addr = inet_addr(_ip);
 
-    if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0)
+        if(bind(ossock, (struct sockaddr *) &server6, sizeof(server6)) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
+        #endif
+    }
+    else
     {
-        return(OS_SOCKTERR);
+        memset(&server, 0, sizeof(server));
+        server.sin_family = AF_INET;
+        server.sin_port = htons( _port );
+
+
+        if((_ip == NULL)||(_ip[0] == '\0'))
+            server.sin_addr.s_addr = htonl(INADDR_ANY);
+        else
+            server.sin_addr.s_addr = inet_addr(_ip);
+
+
+        if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
     }
 
+
+
     if(_proto == IPPROTO_TCP)
     {
         if(listen(ossock, 32) < 0)
         {
+            OS_CloseSocket(ossock);
             return(OS_SOCKTERR);
         }
     }
-    
-    
-    _cl = sizeof(_c);
+
+
     return(ossock);
 }
 
@@ -110,18 +144,18 @@ int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip)
 /* OS_Bindporttcp v 0.1
  * Bind a TCP port, using the OS_Bindport
  */
-int OS_Bindporttcp(unsigned int _port, char *_ip)
+int OS_Bindporttcp(unsigned int _port, char *_ip, int ipv6)
 {
-    return(OS_Bindport(_port, IPPROTO_TCP, _ip));
+    return(OS_Bindport(_port, IPPROTO_TCP, _ip, ipv6));
 }
 
 
 /* OS_Bindportudp v 0.1
  * Bind a UDP port, using the OS_Bindport
  */
-int OS_Bindportudp(unsigned int _port, char *_ip)
+int OS_Bindportudp(unsigned int _port, char *_ip, int ipv6)
 {
-    return(OS_Bindport(_port, IPPROTO_UDP, _ip));
+    return(OS_Bindport(_port, IPPROTO_UDP, _ip, ipv6));
 }
 
 #ifndef WIN32
@@ -136,36 +170,47 @@ int OS_BindUnixDomain(char * path, int mode, int max_msg_size)
 
     /* Making sure the path isn't there */
     unlink(path);
-    
+
     memset(&n_us, 0, sizeof(n_us));
     n_us.sun_family = AF_UNIX;
     strncpy(n_us.sun_path, path, sizeof(n_us.sun_path)-1);
 
-    if((ossock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
+    if((ossock = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0)
         return(OS_SOCKTERR);
 
     if(bind(ossock, (struct sockaddr *)&n_us, SUN_LEN(&n_us)) < 0)
     {
-        close(ossock);
+        OS_CloseSocket(ossock);
         return(OS_SOCKTERR);
     }
-    
+
     /* Changing permissions */
-    chmod(path,mode);
-    
-    
+    if(chmod(path,mode) < 0)
+    {
+        OS_CloseSocket(ossock);
+        return(OS_SOCKTERR);
+    }
+
+
     /* Getting current maximum size */
     if(getsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1)
+    {
+        OS_CloseSocket(ossock);
         return(OS_SOCKTERR);
-    
-                    
+    }
+
+
     /* Setting socket opt */
     if(len < max_msg_size)
     {
         len = max_msg_size;
-        setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen);
+        if(setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
     }
-                                            
+
     return(ossock);
 }
 
@@ -185,9 +230,9 @@ int OS_ConnectUnixDomain(char * path, int max_msg_size)
     n_us.sun_family = AF_UNIX;
 
     /* Setting up path */
-    strncpy(n_us.sun_path,path,sizeof(n_us.sun_path)-1);       
+    strncpy(n_us.sun_path,path,sizeof(n_us.sun_path)-1);
 
-    if((ossock = socket(AF_UNIX, SOCK_DGRAM,0)) < 0)
+    if((ossock = socket(PF_UNIX, SOCK_DGRAM,0)) < 0)
         return(OS_SOCKTERR);
 
 
@@ -195,23 +240,33 @@ int OS_ConnectUnixDomain(char * path, int max_msg_size)
      * We can use "send" after that
      */
     if(connect(ossock,(struct sockaddr *)&n_us,SUN_LEN(&n_us)) < 0)
+    {
+        OS_CloseSocket(ossock);
         return(OS_SOCKTERR);
+    }
 
 
     /* Getting current maximum size */
     if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
+    {
+        OS_CloseSocket(ossock);
         return(OS_SOCKTERR);
+    }
 
 
     /* Setting maximum message size */
     if(len < max_msg_size)
     {
         len = max_msg_size;
-        setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen);
+        if(setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
     }
-    
-    
-    /* Returning the socket */ 
+
+
+    /* Returning the socket */
     return(ossock);
 }
 
@@ -224,46 +279,88 @@ int OS_getsocketsize(int ossock)
     /* Getting current maximum size */
     if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
         return(OS_SOCKTERR);
-    
-    return(len);    
+
+    return(len);
 }
 
 #endif
 
 /* OS_Connect v 0.1, 2004/07/21
- * Open a TCP/UDP client socket 
+ * Open a TCP/UDP client socket
  */
-int OS_Connect(unsigned int _port, unsigned int protocol, char *_ip)
+int OS_Connect(unsigned int _port, unsigned int protocol, char *_ip, int ipv6)
 {
     int ossock;
     struct sockaddr_in server;
 
+    #ifndef WIN32
+    struct sockaddr_in6 server6;
+    #else
+    ipv6 = 0;
+    #endif
+
     if(protocol == IPPROTO_TCP)
     {
-        if((ossock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
+        if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
             return(OS_SOCKTERR);
     }
     else if(protocol == IPPROTO_UDP)
     {
-        if((ossock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
+        if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
             return(OS_SOCKTERR);
     }
     else
         return(OS_INVALID);
 
-    _cl = sizeof(server);      
 
-    memset(&server, 0, _cl);
-    server.sin_family = AF_INET;
-    server.sin_port = htons( _port );
+
+    #ifdef HPUX
+    {
+    int flags;
+    flags = fcntl(ossock,F_GETFL,0);
+    fcntl(ossock, F_SETFL, flags | O_NONBLOCK);
+    }
+    #endif
+
+
 
     if((_ip == NULL)||(_ip[0] == '\0'))
-        return(OS_INVALID);        
+    {
+        OS_CloseSocket(ossock);
+        return(OS_INVALID);
+    }
 
-    server.sin_addr.s_addr = inet_addr(_ip);
 
-    if(connect(ossock,(struct sockaddr *)&server, _cl) < 0)
-        return(OS_SOCKTERR);
+    if(ipv6 == 1)
+    {
+        #ifndef WIN32
+        memset(&server6, 0, sizeof(server6));
+        server6.sin6_family = AF_INET6;
+        server6.sin6_port = htons( _port );
+        inet_pton(AF_INET6, _ip, &server6.sin6_addr.s6_addr);
+
+        if(connect(ossock,(struct sockaddr *)&server6, sizeof(server6)) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
+        #endif
+    }
+    else
+    {
+        memset(&server, 0, sizeof(server));
+        server.sin_family = AF_INET;
+        server.sin_port = htons( _port );
+        server.sin_addr.s_addr = inet_addr(_ip);
+
+
+        if(connect(ossock,(struct sockaddr *)&server, sizeof(server)) < 0)
+        {
+            OS_CloseSocket(ossock);
+            return(OS_SOCKTERR);
+        }
+    }
+
 
     return(ossock);
 }
@@ -272,18 +369,18 @@ int OS_Connect(unsigned int _port, unsigned int protocol, char *_ip)
 /* OS_ConnectTCP, v0.1
  * Open a TCP socket
  */
-int OS_ConnectTCP(unsigned int _port, char *_ip)
+int OS_ConnectTCP(unsigned int _port, char *_ip, int ipv6)
 {
-    return(OS_Connect(_port, IPPROTO_TCP,_ip));
+    return(OS_Connect(_port, IPPROTO_TCP, _ip, ipv6));
 }
 
 
 /* OS_ConnectUDP, v0.1
- * Open a UDP socket 
+ * Open a UDP socket
  */
-int OS_ConnectUDP(unsigned int _port, char *_ip)
+int OS_ConnectUDP(unsigned int _port, char *_ip, int ipv6)
 {
-    return(OS_Connect(_port, IPPROTO_UDP,_ip));
+    return(OS_Connect(_port, IPPROTO_UDP, _ip, ipv6));
 }
 
 /* OS_SendTCP v0.1, 2004/07/21
@@ -304,7 +401,7 @@ int OS_SendTCPbySize(int socket, int size, char *msg)
 {
     if((send(socket, msg, size, 0)) < size)
         return (OS_SOCKTERR);
-        
+
     return(0);
 }
 
@@ -324,11 +421,11 @@ int OS_SendUDPbySize(int socket, int size, char *msg)
             return(OS_SOCKTERR);
         }
 
-        i++;    
+        i++;
         merror("%s: INFO: Remote socket busy, waiting %d s.", __local_name, i);
-        sleep(i);    
+        sleep(i);
     }
-        
+
     return(0);
 }
 
@@ -342,13 +439,13 @@ int OS_AcceptTCP(int socket, char *srcip, int addrsize)
     int clientsocket;
     struct sockaddr_in _nc;
     socklen_t _ncl;
-    
+
     memset(&_nc, 0, sizeof(_nc));
     _ncl = sizeof(_nc);
 
     if((clientsocket = accept(socket, (struct sockaddr *) &_nc,
                     &_ncl)) < 0)
-        return(-1);    
+        return(-1);
 
     strncpy(srcip, inet_ntoa(_nc.sin_addr),addrsize -1);
     srcip[addrsize -1]='\0';
@@ -364,14 +461,15 @@ char *OS_RecvTCP(int socket, int sizet)
 {
     char *ret;
 
-    int retsize=0;
-
     ret = (char *) calloc((sizet), sizeof(char));
     if(ret == NULL)
         return(NULL);
-        
-    if((retsize = recv(socket, ret, sizet-1,0)) <= 0)
+
+    if(recv(socket, ret, sizet-1,0) <= 0)
+    {
+        free(ret);
         return(NULL);
+    }
 
     return(ret);
 }
@@ -382,17 +480,12 @@ char *OS_RecvTCP(int socket, int sizet)
  */
 int OS_RecvTCPBuffer(int socket, char *buffer, int sizet)
 {
-    int retsize = 0;
+    int retsize;
 
-    while(!retsize)
+    if((retsize = recv(socket, buffer, sizet -1, 0)) > 0)
     {
-        retsize = recv(socket, buffer, sizet -1, 0);
-        if(retsize > 0)
-        {
-            buffer[retsize] = '\0';
-            return(0);
-        }
-        return(-1);
+        buffer[retsize] = '\0';
+        return(0);
     }
     return(-1);
 }
@@ -406,13 +499,16 @@ int OS_RecvTCPBuffer(int socket, char *buffer, int sizet)
 char *OS_RecvUDP(int socket, int sizet)
 {
     char *ret;
-    
+
     ret = (char *) calloc((sizet), sizeof(char));
     if(ret == NULL)
         return(NULL);
 
-    if((recvfrom(socket,ret,sizet-1,0,(struct sockaddr *)&_c,&_cl))<0)
+    if((recv(socket,ret,sizet-1,0))<0)
+    {
+        free(ret);
         return(NULL);
+    }
 
     return(ret);
 }
@@ -428,8 +524,8 @@ int OS_RecvConnUDP(int socket, char *buffer, int buffer_size)
     recv_b = recv(socket, buffer, buffer_size, 0);
     if(recv_b < 0)
         return(0);
-    
-    return(recv_b);    
+
+    return(recv_b);
 }
 
 
@@ -440,7 +536,7 @@ int OS_RecvConnUDP(int socket, char *buffer, int buffer_size)
 int OS_RecvUnix(int socket, int sizet, char *ret)
 {
     ssize_t recvd;
-    if((recvd = recvfrom(socket, ret, sizet -1, 0, 
+    if((recvd = recvfrom(socket, ret, sizet -1, 0,
                          (struct sockaddr*)&n_us,&us_l)) < 0)
         return(0);
 
@@ -451,13 +547,13 @@ int OS_RecvUnix(int socket, int sizet, char *ret)
 
 /* OS_SendUnix, v0.1, 2004/07/29
  * Send a message using a Unix socket.
- * Returns the OS_SOCKETERR if it 
- */ 
+ * Returns the OS_SOCKETERR if it
+ */
 int OS_SendUnix(int socket, char * msg, int size)
 {
     if(size == 0)
         size = strlen(msg)+1;
-        
+
     if(send(socket, msg, size,0) < size)
     {
         if(errno == ENOBUFS)
@@ -465,7 +561,7 @@ int OS_SendUnix(int socket, char * msg, int size)
 
         return(OS_SOCKTERR);
     }
-    
+
     return(OS_SUCCESS);
 }
 #endif
@@ -478,13 +574,13 @@ char *OS_GetHost(char *host, int attempts)
 {
     int i = 0;
     int sz;
-    
+
     char *ip;
     struct hostent *h;
 
     if(host == NULL)
         return(NULL);
-    
+
     while(i <= attempts)
     {
         if((h = gethostbyname(host)) == NULL)
@@ -505,4 +601,13 @@ char *OS_GetHost(char *host, int attempts)
     return(NULL);
 }
 
+int OS_CloseSocket(int socket)
+{
+    #ifdef WIN32
+    return (closesocket(socket));
+    #else
+    return (close(socket));
+    #endif /* WIN32 */
+}
+
 /* EOF */