/*
 * Program to read the access_log from the Harvest cache (v1.2) on stdin,
 * and dump to stdout the records with the IP addresses transformed using a
 * trapdoor encryption function so that the uniqueness/correlation between
 * addresses is the same, but the original addresses are not given out.
 * Useful for sharing your logs with other people who want them (e.g., for
 * trace-driven simulations) without violating cache users' privacy.
 * 
 * Program written by Terry Stowers (tstowers@science.gmu.edu) and Mike
 * Schwartz (schwartz@cs.colorado.edu) March 1995, using IP address
 * encryption function written by Dan Muntz (dmuntz@citi.umich.edu).
 *
 * Note: this program does no sanity checking on input format, and will seg
 * fault for earlier versions of the Harvest chace log file format (which
 * didn't include IP addresses).
 * 
 */

/* call char *munge_ip(char *) to disguise an ip address */

#include <stdio.h>

#define MAXLIN 256

#define MAXINT 2147483647

/* GLOBALS */
int A[128], B[64], C[64];

char *munge_ip(s)
char *s;
{
	int i;
	int oldn[4], newn[4];
	char newc[4];
	char *result;

	result = (char *) malloc(40);
	sscanf(s, "%d.%d.%d.%d", &oldn[0], &oldn[1], &oldn[2], &oldn[3]);
	for (i = 0; i < 4; i++)
		if (oldn[i] < 128) {
			newc[i] = 'A';
			newn[i] = A[oldn[i]];
		} else if (oldn[i] < 192) {
			newc[i] = 'B';
			newn[i] = B[oldn[i] - 128];
		} else {
			newc[i] = 'C';
			newn[i] = C[oldn[i] - 192];
		}
	sprintf(result, "%c%d.%c%d.%c%d.%c%d", newc[0], newn[0], newc[1], newn[1], newc[2], newn[2], newc[3], newn[3]);
	return result;
}


init_ip()
{
	int i, temp, temp2;

	srand(time(NULL));

	for (i = 0; i < 128; i++)
		A[i] = i;
	for (i = 0; i < 64; i++)
		B[i] = C[i] = i;
	for (i = 0; i < 128; i++) {
		temp = rand() / (MAXINT / 128);
		temp2 = A[i];
		A[i] = A[temp];
		A[temp] = temp2;
	}
	for (i = 0; i < 64; i++) {
		temp = rand() / (MAXINT / 64);
		temp2 = B[i];
		B[i] = B[temp];
		B[temp] = temp2;
	}
	for (i = 0; i < 64; i++) {
		temp = rand() / (MAXINT / 64);
		temp2 = C[i];
		C[i] = C[temp];
		C[temp] = temp2;
	}
}


int main()
{
	char str[MAXLIN];
	char stamp[MAXLIN];
	char url[MAXLIN];
	char ipstr[MAXLIN];
	char size[MAXLIN];
	char status[MAXLIN];
	char *mung;

	/*
	   FILE *fp1, *fp2;

	   printf("\nTrace conversion of IP addrs\n\n");
	   fp1 = fopen("http.log","r");
	 */

	/* call init_ip() once at start to set up conversion tables */
	init_ip();

	/*
	   while ( fgets(str, MAXLIN, fp1) != NULL)
	 */

	while (gets(str) != NULL) {
#ifdef OLD_CACHE_LOG_FORMAT
		sscanf(str, "%s%s%s%s%s", stamp, url, ipstr, size, status);
#else
		sscanf(str, "%s - - [%[^]]] \"%[^\"]\" %s%s",
			ipstr,stamp,url,status,size);
#endif
		mung = munge_ip(ipstr);

#ifdef OLD_CACHE_LOG_FORMAT
		printf("%s %s %s %s %s\n", stamp, url, mung, size, status);
#else
		printf("%s - - [%s] \"%s\" %s %s\n",
			mung,stamp,url,status,size);
#endif

	}
	/*
	   fclose( fp1);    
	   printf("\nConversion complete\n");
	 */
}
