/*
 * s2digilimit.cpp - Silencer Toolkit Example Application
 *
 * Written by Michael "Mr. Sump" Poppitz.
 *
 */

 /***************************************************************************
  *                                                                         *
  *   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 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
  ***************************************************************************/

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

#include "trx.h"
#include "call.h"
#include "packet.h"


bool check(Packet *pa, char *pattern, int limit) {	/* does the testing for our criteria */
	char info[0x100];
	regex_t regex;

	if (pa->getFrameType() != pa->FRAME_I)
		return (false);				/* we can only do tests on information frames */

	if (pa->getRepeaterCount() <= limit)
		return (false);				/* we dont care for up to limit repeated packets */

	pa->getInfo((unsigned char *)info);				/* get a copy of the packets data */
	regcomp(&regex, pattern, REG_ICASE);
	int result = regexec(&regex, info, 0, NULL, 0);
	regfree(&regex);				/* compile, execute and throw away regexp */
							/* (performance doesnt matter, so we can do it here) */
	if (result)
		return (false);				/* abort if pattern didn't match */

	return (true);					/* otherwise we successfully identified a violator */
}

void notify(Packet *pa) {				/* notify admin through stdout */
	Call *s = pa->getSourceCall();
	Call *d = pa->getDestinationCall();
	printf(
		"Match: %s -> %s via %i nodes\n",
		s->call, d->call, pa->getRepeaterCount()
	);
	delete d;
	delete s;
}

void attack(TRX *trx, Packet *pa) {			/* give the desired response */
	pa->reverseCalls();				/* form a response */
	pa->setFrameType(pa->FRAME_U, pa->UFRAME_DISC);	/* which in our case is a DISC */
	trx->tx(pa);					/* transmit */
}


int main(int argc, char **argv) {

	if (argc != 3) {
		printf("Usage: %s digilimit regexp\n\n", argv[0]);
		exit(EXIT_FAILURE);
	}						/* give instructions if args look bogus */

	char *pattern = argv[2];			/* since this is not an example on */
	int limit = argv[1][0] - 0x30;			/* user input validation this is sufficient ;) */
	printf(
		"Rule: If packet matches %s "
		"and uses more than %i repeater "
		"the connection will be terminated.\n",
		pattern, limit
	);						/* summarize information retrieved from argv */

	TRX *trx = new TRX();				/* get an trx, so we can listen for packets */
	if (trx->init() < 0) {
		perror("init"); 
		exit(EXIT_FAILURE);
	}

	while (Packet *pa = trx->rx()) {		/* keep listening until error occurs */
		if (check(pa, pattern, limit)) {	/* check if matches rules */
			notify(pa);			/* report violation */
			attack(trx, pa);		/* attack */
		}
		delete pa;				/* destroy packet */
	}

	return(EXIT_SUCCESS);
}
