/* 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)
{
	char buf[FGETS_BUF_SIZE];
	int j, num_lines = 0;

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

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

	while(!feof(lf->fp) && fgets(buf, sizeof(buf)-1, lf->fp)) {
		char *ptr = buf;

		num_lines++;

		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;
	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;

			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;
			}

			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);
	if (!fgets(buf, sizeof(buf)-1, lf->fp))
		return -1;

	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) {
		fprintf(stderr, "out of memory\n");
		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) {
		perror(lf->path);
		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) {
			closedir(dir);
			return NULL;
		}

		/* fill in field structure */
		if (lnstat_scan_fields(lf) < 0) {
			closedir(dir);
			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:
	free(file);

	return ret;
}
