-/* @(#) $Id$ */
+/* @(#) $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 2) 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 */
+ strlen ((ptr)->sun_path))
#endif /* Sun_LEN */
-#else
-int ENOBUFS = 0;
+#else /* WIN32 */
+/*int ENOBUFS = 0;*/
+# ifndef ENOBUFS
+# define ENOBUFS 0
+# endif
+
#endif /* WIN32*/
* 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;
}
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);
}
}
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);
}
/* 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
/* 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);
}
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);
* 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);
}
/* 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);
}
/* 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
{
if((send(socket, msg, size, 0)) < size)
return (OS_SOCKTERR);
-
+
return(0);
}
return(OS_SOCKTERR);
}
- i++;
+ i++;
merror("%s: INFO: Remote socket busy, waiting %d s.", __local_name, i);
- sleep(i);
+ sleep(i);
}
-
+
return(0);
}
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';
{
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);
}
*/
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);
}
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);
}
recv_b = recv(socket, buffer, buffer_size, 0);
if(recv_b < 0)
return(0);
-
- return(recv_b);
+
+ return(recv_b);
}
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);
/* 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)
return(OS_SOCKTERR);
}
-
+
return(OS_SUCCESS);
}
#endif
{
int i = 0;
int sz;
-
+
char *ip;
struct hostent *h;
if(host == NULL)
return(NULL);
-
+
while(i <= attempts)
{
if((h = gethostbyname(host)) == NULL)
return(NULL);
}
+int OS_CloseSocket(int socket)
+{
+ #ifdef WIN32
+ return (closesocket(socket));
+ #else
+ return (close(socket));
+ #endif /* WIN32 */
+}
+
/* EOF */