/* 
	Simple TCPport monitor
	
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <stdlib.h>
#ifndef __FreeBSD__
#include <malloc.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include "config.h"
#include "wmnetmon.h"
#include "pinger.h"


int tcp_isalive(pinger_host *h)
{
	int ret;
	
	h->tcpsock=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
	if (!h->tcpsock) {
		perror("malloc");
		return -1;
	}
	h->tcpsock->sin_family = AF_INET;
	h->tcpsock->sin_port = htons(h->tcpport);
	h->tcpsock->sin_addr = h->sock->sin_addr;
	
	h->lastping = time(0);
	
	h->tcp_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (!h->tcp_socket) {
		perror("socket (tcp)");
		return -1;
	}
	/* POSIX nonblocking */
	
	if (fcntl (h->tcp_socket, F_SETFL , fcntl(h->tcp_socket, F_GETFL,0) | O_NONBLOCK )<0) {
		perror("fcntl setting nonblocking for tcp socket");
		close(h->tcp_socket);
		return -2;
	}
		
	if (debug)
	fprintf(stderr,"trying to connect (tcp) to port %d at %s...\n", h->tcpport,
	    inet_ntoa(h->tcpsock->sin_addr));
	if (connect(h->tcp_socket, (struct sockaddr*)h->tcpsock, 
	        sizeof(struct sockaddr_in))<0) 
	   switch(errno) {
		case EISCONN: /* Common.. reported by lots of users 
				 just close the socket and return...*/
			close(h->tcp_socket);
			break;
		case EINPROGRESS:
		case EALREADY:
			break;
		default:
			if (debug) perror("tcpmonitor.c:tcp_isalive() : connect");
	}
	return 0;
}

/* UDPmonitor goes here too :) */

int udp_isalive(pinger_host *h)
{
	int udp_socket,ret;
	char buf=0;
	struct sockaddr_in sock;
#ifdef HAVE_STRUCT_UDP 
	struct udp *uhdr;
#else
	struct udphdr *uhdr;
#endif
	
	sock.sin_family=AF_INET;
	sock.sin_port = htons(h->udpport);
	sock.sin_addr = h->sock->sin_addr;
	
/*	h->lastping=time(0); */
	               
	udp_socket = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (!udp_socket)
		return -1;
	if (debug)
	        fprintf(stderr,"trying to UDPconnect to port %d at %s...", h->udpport,
		inet_ntoa(sock.sin_addr));
	ret = sendto(udp_socket, &buf, 1, 0x0, (struct sockaddr*)&sock, 
	      sizeof(struct sockaddr_in));
	if (debug) perror("sendto");
	if (ret<0) h->udpstatus=1;
	else h->udpstatus=0;
	close(udp_socket);
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1