1 /* @(#) $Id: ./src/os_net/os_net.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
12 * License details at the LICENSE file included with OSSEC or
13 * online at: http://www.ossec.net/en/licensing.html
17 * APIs for many network operations.
29 /* Unix socket -- not for windows */
31 struct sockaddr_un n_us;
32 socklen_t us_l = sizeof(n_us);
36 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
37 + strlen ((ptr)->sun_path))
49 /* OS_Bindport v 0.2, 2005/02/11
50 * Bind a specific port
51 * v0.2: Added REUSEADDR.
53 int OS_Bindport(unsigned int _port, unsigned int _proto, char *_ip, int ipv6)
56 struct sockaddr_in server;
59 struct sockaddr_in6 server6;
65 if(_proto == IPPROTO_UDP)
67 if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
72 else if(_proto == IPPROTO_TCP)
75 if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
77 return(int)(OS_SOCKTERR);
80 if(setsockopt(ossock, SOL_SOCKET, SO_REUSEADDR,
81 (char *)&flag, sizeof(flag)) < 0)
83 OS_CloseSocket(ossock);
95 memset(&server6, 0, sizeof(server6));
96 server6.sin6_family = AF_INET6;
97 server6.sin6_port = htons( _port );
98 server6.sin6_addr = in6addr_any;
101 if(bind(ossock, (struct sockaddr *) &server6, sizeof(server6)) < 0)
103 OS_CloseSocket(ossock);
110 memset(&server, 0, sizeof(server));
111 server.sin_family = AF_INET;
112 server.sin_port = htons( _port );
115 if((_ip == NULL)||(_ip[0] == '\0'))
116 server.sin_addr.s_addr = htonl(INADDR_ANY);
118 server.sin_addr.s_addr = inet_addr(_ip);
121 if(bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0)
123 OS_CloseSocket(ossock);
130 if(_proto == IPPROTO_TCP)
132 if(listen(ossock, 32) < 0)
134 OS_CloseSocket(ossock);
144 /* OS_Bindporttcp v 0.1
145 * Bind a TCP port, using the OS_Bindport
147 int OS_Bindporttcp(unsigned int _port, char *_ip, int ipv6)
149 return(OS_Bindport(_port, IPPROTO_TCP, _ip, ipv6));
153 /* OS_Bindportudp v 0.1
154 * Bind a UDP port, using the OS_Bindport
156 int OS_Bindportudp(unsigned int _port, char *_ip, int ipv6)
158 return(OS_Bindport(_port, IPPROTO_UDP, _ip, ipv6));
162 /* OS_BindUnixDomain v0.1, 2004/07/29
163 * Bind to a Unix domain, using DGRAM sockets
165 int OS_BindUnixDomain(char * path, int mode, int max_msg_size)
169 socklen_t optlen = sizeof(len);
171 /* Making sure the path isn't there */
174 memset(&n_us, 0, sizeof(n_us));
175 n_us.sun_family = AF_UNIX;
176 strncpy(n_us.sun_path, path, sizeof(n_us.sun_path)-1);
178 if((ossock = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0)
181 if(bind(ossock, (struct sockaddr *)&n_us, SUN_LEN(&n_us)) < 0)
183 OS_CloseSocket(ossock);
187 /* Changing permissions */
188 if(chmod(path,mode) < 0)
190 OS_CloseSocket(ossock);
195 /* Getting current maximum size */
196 if(getsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1)
198 OS_CloseSocket(ossock);
203 /* Setting socket opt */
204 if(len < max_msg_size)
207 if(setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen) < 0)
209 OS_CloseSocket(ossock);
217 /* OS_ConnectUnixDomain v0.1, 2004/07/29
218 * Open a client Unix domain socket
219 * ("/tmp/lala-socket",0666));
222 int OS_ConnectUnixDomain(char * path, int max_msg_size)
226 socklen_t optlen = sizeof(len);
228 memset(&n_us, 0, sizeof(n_us));
230 n_us.sun_family = AF_UNIX;
232 /* Setting up path */
233 strncpy(n_us.sun_path,path,sizeof(n_us.sun_path)-1);
235 if((ossock = socket(PF_UNIX, SOCK_DGRAM,0)) < 0)
239 /* Connecting to the UNIX domain.
240 * We can use "send" after that
242 if(connect(ossock,(struct sockaddr *)&n_us,SUN_LEN(&n_us)) < 0)
244 OS_CloseSocket(ossock);
249 /* Getting current maximum size */
250 if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
252 OS_CloseSocket(ossock);
257 /* Setting maximum message size */
258 if(len < max_msg_size)
261 if(setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen) < 0)
263 OS_CloseSocket(ossock);
269 /* Returning the socket */
274 int OS_getsocketsize(int ossock)
277 socklen_t optlen = sizeof(len);
279 /* Getting current maximum size */
280 if(getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1)
288 /* OS_Connect v 0.1, 2004/07/21
289 * Open a TCP/UDP client socket
291 int OS_Connect(unsigned int _port, unsigned int protocol, char *_ip, int ipv6)
294 struct sockaddr_in server;
297 struct sockaddr_in6 server6;
302 if(protocol == IPPROTO_TCP)
304 if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
307 else if(protocol == IPPROTO_UDP)
309 if((ossock = socket(ipv6 == 1?PF_INET6:PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
320 flags = fcntl(ossock,F_GETFL,0);
321 fcntl(ossock, F_SETFL, flags | O_NONBLOCK);
327 if((_ip == NULL)||(_ip[0] == '\0'))
329 OS_CloseSocket(ossock);
337 memset(&server6, 0, sizeof(server6));
338 server6.sin6_family = AF_INET6;
339 server6.sin6_port = htons( _port );
340 inet_pton(AF_INET6, _ip, &server6.sin6_addr.s6_addr);
342 if(connect(ossock,(struct sockaddr *)&server6, sizeof(server6)) < 0)
344 OS_CloseSocket(ossock);
351 memset(&server, 0, sizeof(server));
352 server.sin_family = AF_INET;
353 server.sin_port = htons( _port );
354 server.sin_addr.s_addr = inet_addr(_ip);
357 if(connect(ossock,(struct sockaddr *)&server, sizeof(server)) < 0)
359 OS_CloseSocket(ossock);
369 /* OS_ConnectTCP, v0.1
372 int OS_ConnectTCP(unsigned int _port, char *_ip, int ipv6)
374 return(OS_Connect(_port, IPPROTO_TCP, _ip, ipv6));
378 /* OS_ConnectUDP, v0.1
381 int OS_ConnectUDP(unsigned int _port, char *_ip, int ipv6)
383 return(OS_Connect(_port, IPPROTO_UDP, _ip, ipv6));
386 /* OS_SendTCP v0.1, 2004/07/21
387 * Send a TCP packet (in a open socket)
389 int OS_SendTCP(int socket, char *msg)
391 if((send(socket, msg, strlen(msg),0)) <= 0)
392 return (OS_SOCKTERR);
397 /* OS_SendTCPbySize v0.1, 2004/07/21
398 * Send a TCP packet (in a open socket) of a specific size
400 int OS_SendTCPbySize(int socket, int size, char *msg)
402 if((send(socket, msg, size, 0)) < size)
403 return (OS_SOCKTERR);
409 /* OS_SendUDPbySize v0.1, 2004/07/21
410 * Send a UDP packet (in a open socket) of a specific size
412 int OS_SendUDPbySize(int socket, int size, char *msg)
416 /* Maximum attempts is 5 */
417 while((send(socket,msg,size,0)) < 0)
419 if((errno != ENOBUFS) || (i >= 5))
425 merror("%s: INFO: Remote socket busy, waiting %d s.", __local_name, i);
434 /* OS_AcceptTCP v0.1, 2005/01/28
435 * Accept a TCP connection
437 int OS_AcceptTCP(int socket, char *srcip, int addrsize)
440 struct sockaddr_in _nc;
443 memset(&_nc, 0, sizeof(_nc));
446 if((clientsocket = accept(socket, (struct sockaddr *) &_nc,
450 strncpy(srcip, inet_ntoa(_nc.sin_addr),addrsize -1);
451 srcip[addrsize -1]='\0';
453 return(clientsocket);
457 /* OS_RecvTCP v0.1, 2004/07/21
458 * Receive a TCP packet (in a open socket)
460 char *OS_RecvTCP(int socket, int sizet)
464 ret = (char *) calloc((sizet), sizeof(char));
468 if(recv(socket, ret, sizet-1,0) <= 0)
478 /* OS_RecvTCPBuffer v0.1, 2004/07/21
479 * Receive a TCP packet (in a open socket)
481 int OS_RecvTCPBuffer(int socket, char *buffer, int sizet)
485 if((retsize = recv(socket, buffer, sizet -1, 0)) > 0)
487 buffer[retsize] = '\0';
496 /* OS_RecvUDP v 0.1, 2004/07/20
497 * Receive a UDP packet
499 char *OS_RecvUDP(int socket, int sizet)
503 ret = (char *) calloc((sizet), sizeof(char));
507 if((recv(socket,ret,sizet-1,0))<0)
517 /* OS_RecvConnUDP v0.1
518 * Receives a message from a connected UDP socket
520 int OS_RecvConnUDP(int socket, char *buffer, int buffer_size)
524 recv_b = recv(socket, buffer, buffer_size, 0);
533 /* OS_RecvUnix, v0.1, 2004/07/29
534 * Receive a message using a Unix socket
536 int OS_RecvUnix(int socket, int sizet, char *ret)
539 if((recvd = recvfrom(socket, ret, sizet -1, 0,
540 (struct sockaddr*)&n_us,&us_l)) < 0)
548 /* OS_SendUnix, v0.1, 2004/07/29
549 * Send a message using a Unix socket.
550 * Returns the OS_SOCKETERR if it
552 int OS_SendUnix(int socket, char * msg, int size)
555 size = strlen(msg)+1;
557 if(send(socket, msg, size,0) < size)
570 /* OS_GetHost, v0.1, 2005/01/181
571 * Calls gethostbyname (tries x attempts)
573 char *OS_GetHost(char *host, int attempts)
586 if((h = gethostbyname(host)) == NULL)
592 sz = strlen(inet_ntoa(*((struct in_addr *)h->h_addr)))+1;
593 if((ip = (char *) calloc(sz, sizeof(char))) == NULL)
596 strncpy(ip,inet_ntoa(*((struct in_addr *)h->h_addr)), sz-1);
604 int OS_CloseSocket(int socket)
607 return (closesocket(socket));
609 return (close(socket));