///////////////////////////////////////////////////////////////////////////////
//
//  nmapgrep v0.1 by blh@sr-71.nu 20030530
//
//  nmapgrep is a program that searches for patterns in nmap log files and
//  outputs the matching ip if the port is flagged as open.
//
//  in example, searching for hosts that has port 80 open:
//  # nmapgrep ^80/tcp logfile.txt
//
//  compile:
//    in win32 using visual studio:
//      cl nmapgrep.c
//
//    in any unix or with cygwin:
//      gcc -Wall -O2 -DHAVE_REGEX -o nmapgrep nmapgrep.c
//
//  use -DHAVE_REGEX only if you know that you have regex.h
//
//  feel free to use the code at your own disposal
//
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_REGEX
#include <sys/types.h>
#include <regex.h>
#endif
#include <errno.h>

int
main(int argc, char **argv)
{
	FILE *fp = stdin;

	char buf[1024];
	char hoststr[64];

	char *ptr1 = NULL;
	char *ptr2 = NULL;

	int i = 1;
	int val = 0;

#ifdef HAVE_REGEX
	int nmatch = 0;
	regmatch_t pmatch;
	regex_t preg;
#endif

	if(argc < 2)
		fprintf(stderr, "nmapgrep v0.1 by blh@sr-71.nu 20030530\n"
		                "syntax: %s pattern [nmaplogfile]\n"
#ifdef HAVE_REGEX
		                "\t- regular expressions supported\n"
#endif
		                , argv[0]), exit(1);

	if(argc > 2)
		{
			if((fp = fopen(argv[2], "r")) == NULL)
				perror("fopen"), exit(1);
		}

	fgets(buf, 1024, fp);
	if(strncmp(buf, "# nmap", 6))
		fprintf(stderr, "unknown log format.\n"), exit(1);

#ifdef HAVE_REGEX
	if((regcomp(&preg, argv[1], REG_EXTENDED)) != 0)
		perror("expression"), exit(1);
#endif

	while((fgets(buf, 1024, fp)) != NULL)
		{
			if(!strncmp(buf, "Interesting", 11))
				{
					if(val != 0)
						fprintf(stdout, "%s\n", hoststr);

					val = 0;

					if(((ptr1 = strchr(buf, '(')) == NULL) ||
					   ((ptr2 = strchr(ptr1, ')')) == NULL))
						fprintf(stderr, "error parsing line %d\n", i), exit(1);

					ptr1[0] = 0;
					ptr2[0] = 0;

					ptr1++;

					strncpy(hoststr, ptr1, 64);
				}
#ifdef HAVE_REGEX
			else if((regexec(&preg, buf, nmatch, &pmatch, REG_NOTBOL)) != REG_NOMATCH)
#else
			else if(strstr(buf, argv[1]))
#endif
				{
					if(strstr(buf, "open"))
						val++;
				}

			i++;
		}

	if(val != 0)
		fprintf(stdout, "%s\n", hoststr);

	fclose(fp);

	exit(0);
}
