/* SPDX-License-Identifier: GPL-2.0-or-later */
/* 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
 */

#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);
	buf[sizeof(buf) - 1] = '\0';

	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 = calloc(1, sizeof(*lf));
	if (!lf) {
		fprintf(stderr, "out of memory\n");
		return NULL;
	}

	/* initialize */
	snprintf(lf->basename, sizeof(lf->basename), "%s", file);
	snprintf(lf->path, sizeof(lf->path), "%s/%s", path, file);

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