-/* @(#) $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 "shared.h"
#include "os_net.h"
-struct sockaddr_in _c; /* Client socket */
-socklen_t _cl; /* Client socket length */
/* Unix socket -- not for windows */
* 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)
{
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)
+ {
+ 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)
+ {
+ return(OS_SOCKTERR);
+ }
}
+
+
if(_proto == IPPROTO_TCP)
{
if(listen(ossock, 32) < 0)
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);
close(ossock);
return(OS_SOCKTERR);
}
-
+
/* Changing permissions */
chmod(path,mode);
-
-
+
+
/* Getting current maximum size */
if(getsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1)
return(OS_SOCKTERR);
-
-
+
+
/* Setting socket opt */
if(len < max_msg_size)
{
len = max_msg_size;
setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen);
}
-
+
return(ossock);
}
len = max_msg_size;
setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen);
}
-
-
+
+
/* 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);
+ 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)
+ 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)
+ 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);
ret = (char *) calloc((sizet), sizeof(char));
if(ret == NULL)
return(NULL);
-
+
if((retsize = recv(socket, ret, sizet-1,0)) <= 0)
return(NULL);
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)
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)