/*
 *   logtool - a logfile parsing/monitoring/manipulation utility
 *
 *   Copyright (C) Y2K (2000) A.L.Lambert
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2, or (at your option)
 *   any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Yee ole includes (I put this all in one file for my sanity) */
#include "includes.h"

/*
 * a module to process iptables messages into something sane to read with the naked eye
 */

/* a function to get the value blah where SOMETHING=blah in the event message		*/
int mip_parse_val(char *target, char *str) {

	char tmp_str[LSIZE];
	char *ptr;
	
	/* okie, we're going to jump to target	*/
	ptr = strstr(event.raw, str);
	/* if ptr == NULL, we didn't find anything	*/
	if(ptr == NULL) return -1;
	/* move forward to the = sign	*/
	ptr = strstr(ptr, "=");
	++ptr; /* and then to first char of our value	*/
	strcpy(tmp_str, ptr);	/* copy that to tmp_str	*/
	ptr = strstr(tmp_str, " ");	/* jump to the space after the value	*/
	ptr[0] = '\0';			/* null terminate it there		*/
	if(tmp_str[0] != '\0') {		/* if we got a value	*/
		strcpy(target, tmp_str);	/* put it into the target variable	*/
	} else {		/* otherwise, return an error				*/
		return 1;
	}
	/* if we made it this far, return no error		*/
	return 0;
}

/* a function to rip everything outside the syslog message into a variable we can parse	*/
int mip_parse_msg(char *msg) {
	
	char tmp_msg[LSIZE];
	char *ptr;
	
	sscanf(event.raw, "%*s %*s %*s %*s %[^\n]", tmp_msg);
	/* in == the start of iptables messages	*/
	ptr = strstr(tmp_msg, "IN=");
	/* if we found the beginning, then null byte it and copy it to *msg	*/
	if(ptr !=NULL) {
		ptr[0] = '\0';
		if(msg[0] != '\0') {
			strcat(msg, tmp_msg);
		}
	}
	return 0;
}

short int mip_build_sd(char *src, char *src_prt, char *dst, char *dst_prt, short int resolv) {
	char tmp_str[LSIZE];
	char *ptr;

	if(resolv == TRUE) {
		ptr = get_host(src);
		if(ptr != NULL) {
			strcpy(tmp_str, ptr);
			strcat(tmp_str, "(");
			strcat(tmp_str, src);
			strcat(tmp_str, ")");
			strcpy(src, tmp_str);
		}
		ptr = get_host(dst);
		if(ptr != NULL) {
			strcpy(tmp_str, ptr);
			strcat(tmp_str, "(");
			strcat(tmp_str, dst);
			strcat(tmp_str, ")");
			strcpy(dst, tmp_str);
			/* output snort-esque color formatting if we're in ANSI or HTML mode	*/
			if(cf.outfmt == OUTPUT_ANSI || cf.outfmt == OUTPUT_HTML) {
				lt_strep(src, 1024, "(", "\033e\033l(\033e\033w");
				lt_strep(src, 1024, ")", "\033e\033l)\033e");
				
				lt_strep(dst, 1024, "(", "\033e\033l(\033e\033w");
				lt_strep(dst, 1024, ")", "\033e\033l)\033e");

			}
		}

	}
	
	if(cf.outfmt == OUTPUT_ANSI || cf.outfmt == OUTPUT_HTML) {
		if(src_prt[0] != '\0') {
			sprintf(tmp_str, " \033W%s\033e\033l:\033e\033W%s \033l->\033e \033W%s\033e:\033W%s\033e", src, src_prt, dst, dst_prt);
		} else {
			sprintf(tmp_str, " \033W%s\033e \033l->\033e \033W%s", src, dst);
		}

	} else {
		if(src_prt[0] != '\0') {
			sprintf(tmp_str, " %s:%s -> %s:%s", src, src_prt, dst, dst_prt);
		} else {
			sprintf(tmp_str, " %s -> %s", src, dst);
		}
	}
	
	strcat(event.pmsg, tmp_str);	
	return 0;
}

short int ltm_iptables() {
	/* see mods.h for the iptables data struct */
	/* variables local to this guy	*/
	char msg[LSIZE];		/* user defined message (if any)	*/
	char tmp_str[LSIZE];	/* some place to stick data temp basis	*/
	short int resolv = FALSE;/* do we resolve IP addresses?		*/	

	resolv = mod_varcheck("modipt_resolvips");
	
	/* Figure out what color this message should be         */
	lt_set_event_color();

	/* because you most often don't get a 'program' field in one of these	*/
	strcpy(event.program, "iptables:");
	
	/* parse up the basics (date format's, prog/src, etc)  */
	mod_premsg_setup();
	
	/* see if user used any prefixing and put it in the output if so	*/
	strcpy(msg, "-j LOG: ");
	mip_parse_msg(msg);
	
	/* now we get to work on parsing the variables in order	*/
	strcpy(it.in_if, "");
	strcpy(it.ou_if, "");
	strcpy(it.src, "");
	strcpy(it.src_prt, "");
	strcpy(it.dst, "");
	strcpy(it.dst_prt, "");
	strcpy(it.plen, "");
	strcpy(it.tos, "");
	strcpy(it.prec, "");
	strcpy(it.ttl, "");
	strcpy(it.proto, "");
	mip_parse_val(it.in_if, "IN=");
	mip_parse_val(it.ou_if, "OUT=");
	mip_parse_val(it.src, "SRC=");
	mip_parse_val(it.src_prt, "SPT=");
	mip_parse_val(it.dst, "DST=");
	mip_parse_val(it.dst_prt, "DPT=");
	mip_parse_val(it.plen, "LEN=");
	mip_parse_val(it.tos, "TOS=");
	mip_parse_val(it.prec, "PREC=");
	mip_parse_val(it.ttl, "TTL=");
	mip_parse_val(it.proto, "PROTO=");
	
	/* okie, parsing done, start building event.pmsg	*/
	/* start with the msg (if any)				*/
	if(msg[0] != '\0') {
		sprintf(tmp_str, " %s%s%s", event.pcolor, msg, "\033e");
		strcpy(it.msg, msg);
		strcat(event.pmsg, tmp_str);
	}
	
	if(it.proto[0] != '\0') {
		strcpy(tmp_str, " \033e\033l{\033e\033C");
		strcat(tmp_str, it.proto);
		strcat(tmp_str, "\033e\033l}\033e");
		strcat(event.pmsg, tmp_str);
	}
	
	mip_build_sd(it.src, it.src_prt, it.dst, it.dst_prt, resolv);
	/* make a link from the event.module structure to our iptables data */
	event.m.iptables = &it;

	return 0;
}

/* 
Mar  5 02:48:09 kern@friday/1.1.1.1 Bad packet on pub int:IN=eth1 OUT= MAC=00:40:05:6c:f9:8b:00:02:3b:01:be:9d:08:00 SRC=61.14.66.78 DST=65.71.249.147 LEN=78 TOS=0x00 PREC=0x00 TTL=108 ID=11861 PROTO=UDP SPT=1028 DPT=137 LEN=58
*/
