/* lnstat.c:  Unified linux network statistics
 *
 * Copyright (C) 2004 by Harald Welte <laforge@gnumonks.org>
 *
 * Development of this code was funded by Astaro AG, http://www.astaro.com/
 *
 * Based on original concept and ideas from predecessor rtstat.c:
 *
 * Copyright 2001 by Robert Olsson <robert.olsson@its.uu.se>
 *                                 Uppsala University, Sweden
 *
 * 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 <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <time.h>

#include <sys/time.h>
#include <sys/types.h>

#include "lnstat.h"

/* size of temp buffer used to read lines from procfiles */
#define FGETS_BUF_SIZE 1024


#define RTSTAT_COMPAT_LINE "entries  in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src  out_hit out_slow_tot out_slow_mc  gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"

/* Read (and summarize for SMP) the different stats vars. */
static int scan_lines(struct lnstat_file *lf, int i)
{
	int j, num_lines = 0;

	for (j = 0; j < lf->num_fields; j++)
		lf->fields[j].values[i] = 0;

	while(!feof(lf->fp)) {
		char buf[FGETS_BUF_SIZE];
		char *ptr = buf;

		num_lines++;

		fgets(buf, sizeof(buf)-1, lf->fp); 
		gettimeofday(&lf->last_read, NULL);

		for (j = 0; j < lf->num_fields; j++) {
			unsigned long f = strtoul(ptr, &ptr, 16);
			if (j == 0) 
				lf->fields[j].values[i] += f;
			else
				lf->fields[j].values[i] += f;
		}
	}
	return num_lines;
}

static int time_after(struct timeval *last, 
		      struct timeval *tout, 
		      struct timeval *now)
{
	if (now->tv_sec > last->tv_sec + tout->tv_sec)
		return 1;

	if (now->tv_sec == last->tv_sec + tout->tv_sec) {
		if (now->tv_usec > last->tv_usec + tout->tv_usec)
			return 1;
	}

	return 0;
}

int lnstat_update(struct lnstat_file *lnstat_files)
{
	struct lnstat_file *lf;
	char buf[FGETS_BUF_SIZE];
	struct timeval tv;

	gettimeofday(&tv, NULL);

	for (lf = lnstat_files; lf; lf = lf->next) {
		if (time_after(&lf->last_read, &lf->interval, &tv)) {
			int i;
			struct lnstat_field *lfi;

			rewind(lf->fp);
			if (!lf->compat) {
				/* skip first line */
				fgets(buf, sizeof(buf)-1, lf->fp);
			}
			scan_lines(lf, 1);

			for (i = 0, lfi = &lf->fields[i]; 
			     i < lf->num_fields; i++, lfi = &lf->fields[i]) {
				if (i == 0)
					lfi->result = lfi->values[1];
				else
					lfi->result = (lfi->values[1]-lfi->values[0])
				    			/ lf->interval.tv_sec;
			}

			rewind(lf->fp);
			fgets(buf, sizeof(buf)-1, lf->fp);
			scan_lines(lf, 0);
		}
	}

	return 0;
}

/* scan first template line and fill in per-field data structures */
static int __lnstat_scan_fields(struct lnstat_file *lf, char *buf)
{
	char *tok;
	int i;

	tok = strtok(buf, " \t\n");
	for (i = 0; i < LNSTAT_MAX_FIELDS_PER_LINE; i++) {
		lf->fields[i].file = lf;
		strncpy(lf->fields[i].name, tok, LNSTAT_MAX_FIELD_NAME_LEN);
		/* has to be null-terminate since we initialize to zero
		 * and field size is NAME_LEN + 1 */
		tok = strtok(NULL, " \t\n");
		if (!tok) {
			lf->num_fields = i+1;
			return 0;
		}
	}
	return 0;
}

static int lnstat_scan_fields(struct lnstat_file *lf)
{
	char buf[FGETS_BUF_SIZE];

	rewind(lf->fp);
	fgets(buf, sizeof(buf)-1, lf->fp);

	return __lnstat_scan_fields(lf, buf);
}

/* fake function emulating lnstat_scan_fields() for old kernels */
static int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf)
{
	char buf[FGETS_BUF_SIZE];

	strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1);

	return __lnstat_scan_fields(lf, buf);
}

/* find out whether string 'name; is in given string array */
static int name_in_array(const int num, const char **arr, const char *name)
{
	int i;
	for (i = 0; i < num; i++) {
		if (!strcmp(arr[i], name))
			return 1;
	}
	return 0;
}

/* allocate lnstat_file and open given file */
static struct lnstat_file *alloc_and_open(const char *path, const char *file)
{
	struct lnstat_file *lf;

	/* allocate */
	lf = malloc(sizeof(*lf));
	if (!lf)
		return NULL;

	/* initialize */
	memset(lf, 0, sizeof(*lf));

	/* de->d_name is guaranteed to be <= NAME_MAX */
	strcpy(lf->basename, file);
	strcpy(lf->path, path);
	strcat(lf->path, "/");
	strcat(lf->path, lf->basename);

	/* initialize to default */
	lf->interval.tv_sec = 1;

	/* open */
	lf->fp = fopen(lf->path, "r");
	if (!lf->fp) {
		free(lf);
		return NULL;
	}

	return lf;
}


/* lnstat_scan_dir - find and parse all available statistics files/fields */
struct lnstat_file *lnstat_scan_dir(const char *path, const int num_req_files,
				    const char **req_files)
{
	DIR *dir;
	struct lnstat_file *lnstat_files = NULL;
	struct dirent *de;

	if (!path)
		path = PROC_NET_STAT;
	
	dir = opendir(path);
	if (!dir) {
		struct lnstat_file *lf;
		/* Old kernel, before /proc/net/stat was introduced */
		fprintf(stderr, "Your kernel doesn't have lnstat support. ");

		/* we only support rtstat, not multiple files */
		if (num_req_files >= 2) {
			fputc('\n', stderr);
			return NULL;
		}

		/* we really only accept rt_cache */
		if (num_req_files && !name_in_array(num_req_files,
						    req_files, "rt_cache")) {
			fputc('\n', stderr);
			return NULL;
		}

		fprintf(stderr, "Fallback to old rtstat-only operation\n");

		lf = alloc_and_open("/proc/net", "rt_cache_stat");
		if (!lf)
			return NULL;
		lf->compat = 1;
		strncpy(lf->basename, "rt_cache", sizeof(lf->basename));

		/* FIXME: support for old files */
		if (lnstat_scan_compat_rtstat_fields(lf) < 0)
			return NULL;

		lf->next = lnstat_files;
		lnstat_files = lf;
		return lnstat_files;
	}

	while ((de = readdir(dir))) {
		struct lnstat_file *lf;

		if (de->d_type != DT_REG)
			continue;

		if (num_req_files && !name_in_array(num_req_files,
						    req_files, de->d_name))
			continue;

		lf = alloc_and_open(path, de->d_name);
		if (!lf)
			return NULL;

		/* fill in field structure */
		if (lnstat_scan_fields(lf) < 0)
			return NULL;

		/* prepend to global list */
		lf->next = lnstat_files;
		lnstat_files = lf;
	}
	closedir(dir);

	return lnstat_files;
}

int lnstat_dump(FILE *outfd, struct lnstat_file *lnstat_files)
{
	struct lnstat_file *lf;

	for (lf = lnstat_files; lf; lf = lf->next) {
		int i;

		fprintf(outfd, "%s:\n", lf->path);

		for (i = 0; i < lf->num_fields; i++)
			fprintf(outfd, "\t%2u: %s\n", i+1, lf->fields[i].name);

	}
	return 0;
}

struct lnstat_field *lnstat_find_field(struct lnstat_file *lnstat_files,
				       const char *name)
{
	struct lnstat_file *lf;
	struct lnstat_field *ret = NULL;
	const char *colon = strchr(name, ':');
	char *file;
	const char *field;

	if (colon) {
		file = strndup(name, colon-name);
		field = colon+1;
	} else {
		file = NULL;
		field = name;
	}
		
	for (lf = lnstat_files; lf; lf = lf->next) {
		int i;

		if (file && strcmp(file, lf->basename))
			continue;

		for (i = 0; i < lf->num_fields; i++) {
			if (!strcmp(field, lf->fields[i].name)) {
				ret = &lf->fields[i];
				goto out;
			}
		}
	}
out:
	if (file)
		free(file);

	return ret;
}
