1 /* @(#) $Id: os_net.c,v 1.34 2009/06/24 17:06:31 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
11 * License details at the LICENSE file included with OSSEC or
12 * online at: http://www.ossec.net/en/licensing.html
16 * APIs for many network operations.
26 struct sockaddr_in _c; /* Client socket */
27 socklen_t _cl; /* Client socket length */
30 /* Unix socket -- not for windows */
32 struct sockaddr_un n_us;
33 socklen_t us_l = sizeof(n_us);
37 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
38 + strlen ((ptr)->sun_path))
46 /* OS_Bindport v 0.2, 2005/02/11
47 * Bind a specific port
48 * v0.2: Added REUSEADDR.
50 int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip)
53 struct sockaddr_in server;
56 if(_proto == IPPROTO_UDP)
58 if((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
63 else if(_proto == IPPROTO_TCP)
66 if((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
68 return(int)(OS_SOCKTERR);
71 if(setsockopt(ossock, SOL_SOCKET, SO_REUSEADDR,
72 (char *)&flag, sizeof(flag)) < 0)
82 memset(&server, 0, sizeof(server));
83 server.sin_family = AF_INET;
84 server.sin_port = htons( _port );
86 if((_ip == NULL)||(_ip[0] == '\0'))
87 server.sin_addr.s_addr = htonl(INADDR_ANY);
89 server.sin_addr.s_addr = inet_addr(_ip);
91 if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0)
96 if(_proto == IPPROTO_TCP)
98 if(listen(ossock, 32) < 0)
110 /* OS_Bindporttcp v 0.1
111 * Bind a TCP port, using the OS_Bindport
113 int OS_Bindporttcp(unsigned int _port, char *_ip)
115 return(OS_Bindport(_port, IPPROTO_TCP, _ip));
119 /* OS_Bindportudp v 0.1
120 * Bind a UDP port, using the OS_Bindport
122 int OS_Bindportudp(unsigned int _port, char *_ip)
124 return(OS_Bindport(_port, IPPROTO_UDP, _ip));
128 /* OS_BindUnixDomain v0.1, 2004/07/29
129 * Bind to a Unix domain, using DGRAM sockets
131 int OS_BindUnixDomain(char * path, int mode, int max_msg_size)
135 socklen_t optlen = sizeof(len);
137 /* Making sure the path isn't there */
140 memset(&n_us, 0, sizeof(n_us));
141 n_us.sun_family = AF_UNIX;
142 strncpy(n_us.sun_path, path, sizeof(n_us.sun_path)-1);
144 if((ossock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
147 if(bind(ossock, (struct sockaddr *)&n_us, SUN_LEN(&n_us)) < 0)
153 /* Changing permissions */
157 /* Getting current maximum size */
158 if(getsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1)
162 /* Setting socket opt */
163 if(len < max_msg_size)
166 setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen);
172 /* OS_ConnectUnixDomain v0.1, 2004/07/29
173 * Open a client Unix domain socket
174 * ("/tmp/lala-socket",0666));
177 int OS_ConnectUnixDomain(char * path, int max_msg_size)
181 socklen_t optlen = sizeof(len);
183 memset(&n_us, 0, sizeof(n_us));
185 n_us.sun_family = AF_UNIX;
187 /* Setting up path */
188 strncpy(n_us.sun_path,path,sizeof(n_us.sun_path)-1);
190 if((ossock = socket(AF_UNIX, SOCK_DGRAM,0)) < 0)
194 /* Connecting to the UNIX domain.
195 * We can use "send" after that
197 if(connect(ossock,(struct sockaddr *)&n_us,SUN_LEN(&n_us)) < 0)
201 /* Getting current maximum size */
202 if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
206 /* Setting maximum message size */
207 if(len < max_msg_size)
210 setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen);
214 /* Returning the socket */
219 int OS_getsocketsize(int ossock)
222 socklen_t optlen = sizeof(len);
224 /* Getting current maximum size */
225 if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
233 /* OS_Connect v 0.1, 2004/07/21
234 * Open a TCP/UDP client socket
236 int OS_Connect(unsigned int _port, unsigned int protocol, char *_ip)
239 struct sockaddr_in server;
241 if(protocol == IPPROTO_TCP)
243 if((ossock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
246 else if(protocol == IPPROTO_UDP)
248 if((ossock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
254 _cl = sizeof(server);
256 memset(&server, 0, _cl);
257 server.sin_family = AF_INET;
258 server.sin_port = htons( _port );
260 if((_ip == NULL)||(_ip[0] == '\0'))
263 server.sin_addr.s_addr = inet_addr(_ip);
265 if(connect(ossock,(struct sockaddr *)&server, _cl) < 0)
272 /* OS_ConnectTCP, v0.1
275 int OS_ConnectTCP(unsigned int _port, char *_ip)
277 return(OS_Connect(_port, IPPROTO_TCP,_ip));
281 /* OS_ConnectUDP, v0.1
284 int OS_ConnectUDP(unsigned int _port, char *_ip)
286 return(OS_Connect(_port, IPPROTO_UDP,_ip));
289 /* OS_SendTCP v0.1, 2004/07/21
290 * Send a TCP packet (in a open socket)
292 int OS_SendTCP(int socket, char *msg)
294 if((send(socket, msg, strlen(msg),0)) <= 0)
295 return (OS_SOCKTERR);
300 /* OS_SendTCPbySize v0.1, 2004/07/21
301 * Send a TCP packet (in a open socket) of a specific size
303 int OS_SendTCPbySize(int socket, int size, char *msg)
305 if((send(socket, msg, size, 0)) < size)
306 return (OS_SOCKTERR);
312 /* OS_SendUDPbySize v0.1, 2004/07/21
313 * Send a UDP packet (in a open socket) of a specific size
315 int OS_SendUDPbySize(int socket, int size, char *msg)
319 /* Maximum attempts is 5 */
320 while((send(socket,msg,size,0)) < 0)
322 if((errno != ENOBUFS) || (i >= 5))
328 merror("%s: INFO: Remote socket busy, waiting %d s.", __local_name, i);
337 /* OS_AcceptTCP v0.1, 2005/01/28
338 * Accept a TCP connection
340 int OS_AcceptTCP(int socket, char *srcip, int addrsize)
343 struct sockaddr_in _nc;
346 memset(&_nc, 0, sizeof(_nc));
349 if((clientsocket = accept(socket, (struct sockaddr *) &_nc,
353 strncpy(srcip, inet_ntoa(_nc.sin_addr),addrsize -1);
354 srcip[addrsize -1]='\0';
356 return(clientsocket);
360 /* OS_RecvTCP v0.1, 2004/07/21
361 * Receive a TCP packet (in a open socket)
363 char *OS_RecvTCP(int socket, int sizet)
369 ret = (char *) calloc((sizet), sizeof(char));
373 if((retsize = recv(socket, ret, sizet-1,0)) <= 0)
380 /* OS_RecvTCPBuffer v0.1, 2004/07/21
381 * Receive a TCP packet (in a open socket)
383 int OS_RecvTCPBuffer(int socket, char *buffer, int sizet)
389 retsize = recv(socket, buffer, sizet -1, 0);
392 buffer[retsize] = '\0';
403 /* OS_RecvUDP v 0.1, 2004/07/20
404 * Receive a UDP packet
406 char *OS_RecvUDP(int socket, int sizet)
410 ret = (char *) calloc((sizet), sizeof(char));
414 if((recvfrom(socket,ret,sizet-1,0,(struct sockaddr *)&_c,&_cl))<0)
421 /* OS_RecvConnUDP v0.1
422 * Receives a message from a connected UDP socket
424 int OS_RecvConnUDP(int socket, char *buffer, int buffer_size)
428 recv_b = recv(socket, buffer, buffer_size, 0);
437 /* OS_RecvUnix, v0.1, 2004/07/29
438 * Receive a message using a Unix socket
440 int OS_RecvUnix(int socket, int sizet, char *ret)
443 if((recvd = recvfrom(socket, ret, sizet -1, 0,
444 (struct sockaddr*)&n_us,&us_l)) < 0)
452 /* OS_SendUnix, v0.1, 2004/07/29
453 * Send a message using a Unix socket.
454 * Returns the OS_SOCKETERR if it
456 int OS_SendUnix(int socket, char * msg, int size)
459 size = strlen(msg)+1;
461 if(send(socket, msg, size,0) < size)
474 /* OS_GetHost, v0.1, 2005/01/181
475 * Calls gethostbyname (tries x attempts)
477 char *OS_GetHost(char *host, int attempts)
490 if((h = gethostbyname(host)) == NULL)
496 sz = strlen(inet_ntoa(*((struct in_addr *)h->h_addr)))+1;
497 if((ip = (char *) calloc(sz, sizeof(char))) == NULL)
500 strncpy(ip,inet_ntoa(*((struct in_addr *)h->h_addr)), sz-1);