mirror of
https://github.com/ntop/ntopng.git
synced 2026-07-13 18:02:02 +00:00
151 lines
3.2 KiB
C
151 lines
3.2 KiB
C
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#ifndef WIN32
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <errno.h>
|
|
#endif
|
|
|
|
#ifndef __USE_GNU
|
|
#define __USE_GNU
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#define gethostbyname2(a, b) gethostbyname(a)
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#define BUFLEN 65535
|
|
|
|
void diep(char *s)
|
|
{
|
|
perror(s);
|
|
exit(1);
|
|
}
|
|
|
|
int split_host_port(char *input, int default_port, char **host, int *port)
|
|
{
|
|
char *p;
|
|
|
|
*host = strdup(input);
|
|
|
|
if ((p = strchr(*host, ':')))
|
|
{
|
|
*port = strtol(p+1, NULL, 0);
|
|
*p = 0;
|
|
}
|
|
else
|
|
{
|
|
*port = default_port;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int open_udp_socket(int port)
|
|
{
|
|
struct sockaddr_in si_me;
|
|
int s;
|
|
int reuse = 1;
|
|
|
|
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
|
return(-1); // diep("socket");
|
|
|
|
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) != 0)
|
|
return(-1); //diep("setsockaopt");
|
|
|
|
memset((char *) &si_me, 0, sizeof(si_me));
|
|
si_me.sin_family = AF_INET;
|
|
si_me.sin_port = htons(port);
|
|
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
if (::bind(s, (struct sockaddr *) &si_me, sizeof(si_me)) != 0)
|
|
return(-1); //diep("bind");
|
|
|
|
return s;
|
|
}
|
|
|
|
void send_udp_datagram(void *buf, int len, int socket, char *target_host, int target_port)
|
|
{
|
|
struct sockaddr_in target_si;
|
|
|
|
struct addrinfo hints, *res = NULL, *p;
|
|
int errcode;
|
|
|
|
memset(&target_si, 0, sizeof(target_si));
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET; /* IPv4 */
|
|
// hints.ai_socktype = SOCK_STREAM;
|
|
// hints.ai_flags |= AI_CANONNAME;
|
|
|
|
if((errcode = getaddrinfo(target_host, NULL, &hints, &res))
|
|
|| !res)
|
|
return;
|
|
|
|
for (p = res; p != NULL; p = p->ai_next) {
|
|
memcpy(&target_si, res->ai_addr, res->ai_addrlen);
|
|
break;
|
|
}
|
|
|
|
freeaddrinfo(res);
|
|
|
|
target_si.sin_port = htons(target_port);
|
|
|
|
if (sendto(socket, (const char*)buf, len, 0, (struct sockaddr *) &target_si, sizeof(target_si)) == -1)
|
|
return; //diep("sendto");
|
|
}
|
|
|
|
int receive_udp_datagram(void *buf, int max, int socket, char **sender_host, int *sender_port)
|
|
{
|
|
struct sockaddr_in sender_si;
|
|
int slen = sizeof(sender_si);
|
|
int nr;
|
|
|
|
nr = recvfrom(socket, (char*)buf, BUFLEN,
|
|
#ifdef WIN32
|
|
0,
|
|
#else
|
|
MSG_DONTWAIT, // TODO: add select() to avoid waiting forever
|
|
#endif
|
|
(struct sockaddr *) &sender_si, (socklen_t*)&slen);
|
|
if (nr == -1)
|
|
{
|
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
return 0;
|
|
|
|
return(-1); //diep("recvfrom");
|
|
}
|
|
|
|
if (sender_host)
|
|
*sender_host = inet_ntoa(sender_si.sin_addr);
|
|
|
|
if (sender_port)
|
|
*sender_port = ntohs(sender_si.sin_port);
|
|
|
|
return nr;
|
|
}
|
|
|
|
/* Borrowed from the GNU libc manual. */
|
|
int input_timeout(int filedes, unsigned int seconds)
|
|
{
|
|
fd_set set;
|
|
struct timeval timeout;
|
|
|
|
/* Initialize the file descriptor set. */
|
|
FD_ZERO(&set);
|
|
FD_SET(filedes, &set);
|
|
|
|
/* Initialize the timeout data structure. */
|
|
timeout.tv_sec = seconds;
|
|
timeout.tv_usec = 0;
|
|
|
|
/* `select' returns 0 if timeout, 1 if input available, -1 if error. */
|
|
return /* TEMP_FAILURE_RETRY*/(select(FD_SETSIZE,
|
|
&set, NULL, NULL,
|
|
&timeout));
|
|
}
|