/************************************************/
/* This checks open network ports.		*/
/* This module checks for open network ports on */
/* the system by means of a netstat -an.	*/
/* the output is stripped for LISTEN lines and  */
/* that is checked against /etc/services in     */
/* order to print out a "guess" at what is 	*/
/* running on that port. I could have used nmap */
/* or something else, but I wanted to just have */
/* a quick check without having to install 	*/
/* yet another program (YAP).			*/
/*						*/
/* See lsatmain.c for more details...		*/
/************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checknet(filename, verbose)
const char *const filename;
int verbose;
{

	char *ptr;
	char line[1024];      /* temp line for reading		*/
	char tempstring[50];  /* tempstring for entries		*/
	int field;  			 /* some vars...	*/
	int i;					 /* counter	*/
	FILE *infile;  		 /* tempfile file pointer   	*/
	FILE *outfile; 		 /* output file pointer     	*/

	if (verbose == 1)
	{
		printf("In checknet module...\n");
	}


	/* open the output file for append. */
	outfile = fopen(filename, "a");
	if (outfile == NULL)
	{
		perror("Error opening outfile.\n");
		perror("Check perms perhaps?\n");
		return(-1);
	}

	if (verbose == 1)
	{
		printf("Checking for open/running network services...\n");
	}

	/* print some header info... */
	fprintf(outfile, "****************************************\n");
	fprintf(outfile, "Ports listening on this system:\n\n");
	fprintf(outfile, "\n");
	fprintf(outfile, "Protocol\t  Port\n");

	if (system("netstat -an |grep LISTEN |grep 0.0.0.0 1>/dev/null 2>/dev/null > /tmp/greplist.txt") == 2)
	{
		perror("Problem executing netstat in checknet.\n");
		return(-1);
	}

	/* ok, open the file we just made for read */
	infile = fopen("/tmp/greplist.txt", "r");
	if (infile == NULL)
	{
		perror("Error opening tmp file.\n");
		return(-1);
	}

	/* ok, the file should look something like: 			*/
	/* protocol	n	n	<ip>:<port>      <ip>:<port> LISTEN 	*/
	/* so we want the port on the 1st <ip>:<port> pair.		*/
	/* we then want to look that port up in /etc/services    */
	/* and print out that line to the outfile...			*/

	i = 0; /* counter for our array */
	while (fgets(line, sizeof(line), infile) != NULL)
	{
		field=0;
		/* if we say a token is a ' ' or :, then we need to 	*/
		/* grab the 5th field of each line of the file.		*/
		/* note here we will also print out the 1st field,	*/
		/* although AFAIK they will all be tcp.			*/
		ptr = strtok(line, ", :\n");
		while (ptr != NULL)
		{
			if (sscanf(ptr, "%s", &tempstring) < 1)
			{
				perror("sccanf bit the dust");
				return(-1);
			}
			/* get the 1st field...*/
			if (field == 0)
			{
				fprintf(outfile, "%s", tempstring);
			}
			/* get the 5th field... */
			if (field == 4)
			{
				fprintf(outfile, "\t\t%s\n", tempstring);
			}
			ptr = strtok(NULL, ", :\n");
			if (ptr == NULL)
			{
				/* freak out */
				break;
			}
			field++;
		} /* end while (ptr!=NULL) */
	} /* end while(fgets...) */

	/* close files in use, but not outfile  */
	fclose(infile);
	if ((system("rm -f /tmp/greplist.txt")) < 0)
	{
		/* rhut-rho... problems.. */
		perror("Can't rm tempfile...\n");
		perror("Permissions problem??\n");
		return(-1);
	}

	/* print some footer information */
	fprintf(outfile, "\n");
	fprintf(outfile, "Check the above ports in /etc/services\n");
	fprintf(outfile, "to see what they are. Consider closing off\n");
	fprintf(outfile, "services you do not need.\n");
	fprintf(outfile, "****************************************\n");


	/* now we close the outfile... */
	fclose(outfile);

	if (verbose == 1)
	{
		printf("Finished module checknet.\n");
	}
	return(0);
}
