lnstat_util.c revision f5f1a6c5836a405381fb9d4be74d5ddf98404db1
14677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* lnstat.c: Unified linux network statistics 24677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 34677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * Copyright (C) 2004 by Harald Welte <laforge@gnumonks.org> 44677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 54677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * Development of this code was funded by Astaro AG, http://www.astaro.com/ 64677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 74677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * Based on original concept and ideas from predecessor rtstat.c: 84677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 94677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * Copyright 2001 by Robert Olsson <robert.olsson@its.uu.se> 104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * Uppsala University, Sweden 114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * This program is free software; you can redistribute it and/or modify 134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * it under the terms of the GNU General Public License as published by 144677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * the Free Software Foundation; either version 2 of the License, or 154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * (at your option) any later version. 164677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * 174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger */ 184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <unistd.h> 204677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <stdio.h> 214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <stdlib.h> 224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <string.h> 234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <dirent.h> 244677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <limits.h> 254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <time.h> 264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <sys/time.h> 284677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include <sys/types.h> 294677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 304677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#include "lnstat.h" 314677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 324677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* size of temp buffer used to read lines from procfiles */ 334677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#define FGETS_BUF_SIZE 1024 344677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 354677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 364677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger#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" 374677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 384677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* Read (and summarize for SMP) the different stats vars. */ 394677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int scan_lines(struct lnstat_file *lf, int i) 404677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 414677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int j, num_lines = 0; 424677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 434677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (j = 0; j < lf->num_fields; j++) 444677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fields[j].values[i] = 0; 454677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 464677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger while(!feof(lf->fp)) { 474677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 484677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *ptr = buf; 494677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 504677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger num_lines++; 514677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 524677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fgets(buf, sizeof(buf)-1, lf->fp); 534677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger gettimeofday(&lf->last_read, NULL); 544677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 55f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger for (j = 0; j < lf->num_fields; j++) { 56f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger unsigned long f = strtoul(ptr, &ptr, 16); 57f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger if (j == 0) 58f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger lf->fields[j].values[i] += f; 59f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger else 60f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger lf->fields[j].values[i] += f; 61f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger } 624677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 634677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return num_lines; 644677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 654677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 664677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int time_after(struct timeval *last, 674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct timeval *tout, 684677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct timeval *now) 694677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 704677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_sec > last->tv_sec + tout->tv_sec) 714677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 724677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_sec == last->tv_sec + tout->tv_sec) { 744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_usec > last->tv_usec + tout->tv_usec) 754677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 764677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 784677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 814677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerint lnstat_update(struct lnstat_file *lnstat_files) 824677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 854677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct timeval tv; 864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger gettimeofday(&tv, NULL); 884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (time_after(&lf->last_read, &lf->interval, &tv)) { 914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_field *lfi; 934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 944677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger rewind(lf->fp); 954677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf->compat) { 964677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* skip first line */ 974677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fgets(buf, sizeof(buf)-1, lf->fp); 984677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 994677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger scan_lines(lf, 1); 1004677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1014677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0, lfi = &lf->fields[i]; 1024677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger i < lf->num_fields; i++, lfi = &lf->fields[i]) { 1034677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (i == 0) 1044677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lfi->result = lfi->values[1]; 1054677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger else 1064677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lfi->result = (lfi->values[1]-lfi->values[0]) 1074677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger / lf->interval.tv_sec; 1084677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1094677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger rewind(lf->fp); 1114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fgets(buf, sizeof(buf)-1, lf->fp); 1124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger scan_lines(lf, 0); 1134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1144677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1164677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* scan first template line and fill in per-field data structures */ 1204677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int __lnstat_scan_fields(struct lnstat_file *lf, char *buf) 1214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *tok; 1234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 1244677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger tok = strtok(buf, " \t\n"); 1264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < LNSTAT_MAX_FIELDS_PER_LINE; i++) { 1274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fields[i].file = lf; 1284677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strncpy(lf->fields[i].name, tok, LNSTAT_MAX_FIELD_NAME_LEN); 1294677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* has to be null-terminate since we initialize to zero 1304677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * and field size is NAME_LEN + 1 */ 1314677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger tok = strtok(NULL, " \t\n"); 1324677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!tok) { 1334677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->num_fields = i+1; 1344677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1354677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1364677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1374677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1384677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1394677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1404677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int lnstat_scan_fields(struct lnstat_file *lf) 1414677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1424677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 1434677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1444677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger rewind(lf->fp); 1454677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fgets(buf, sizeof(buf)-1, lf->fp); 1464677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1474677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return __lnstat_scan_fields(lf, buf); 1484677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1494677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1504677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* fake function emulating lnstat_scan_fields() for old kernels */ 1514677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf) 1524677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1534677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 1544677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1554677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1); 1564677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1574677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return __lnstat_scan_fields(lf, buf); 1584677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1594677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1604677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* find out whether string 'name; is in given string array */ 1614677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int name_in_array(const int num, const char **arr, const char *name) 1624677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1634677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 1644677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < num; i++) { 1654677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!strcmp(arr[i], name)) 1664677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 1674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1684677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1694677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1704677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1714677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* allocate lnstat_file and open given file */ 1724677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic struct lnstat_file *alloc_and_open(const char *path, const char *file) 1734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 1754677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1764677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* allocate */ 1774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf = malloc(sizeof(*lf)); 1784677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf) 1794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 1804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1814677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* initialize */ 1824677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger memset(lf, 0, sizeof(*lf)); 1834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* de->d_name is guaranteed to be <= NAME_MAX */ 1854677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcpy(lf->basename, file); 1864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcpy(lf->path, path); 1874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcat(lf->path, "/"); 1884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcat(lf->path, lf->basename); 1894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* initialize to default */ 1914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->interval.tv_sec = 1; 1924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* open */ 1944677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fp = fopen(lf->path, "r"); 1954677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf->fp) { 1964677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger free(lf); 1974677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 1984677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1994677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2004677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return lf; 2014677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 2024677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2034677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2044677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* lnstat_scan_dir - find and parse all available statistics files/fields */ 2054677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstruct lnstat_file *lnstat_scan_dir(const char *path, const int num_req_files, 2064677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char **req_files) 2074677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 2084677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger DIR *dir; 2094677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lnstat_files = NULL; 2104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct dirent *de; 2114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!path) 2134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger path = PROC_NET_STAT; 2144677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger dir = opendir(path); 2164677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!dir) { 2174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 2184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* Old kernel, before /proc/net/stat was introduced */ 2194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(stderr, "Your kernel doesn't have lnstat support. "); 2204677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* we only support rtstat, not multiple files */ 2224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (num_req_files >= 2) { 2234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fputc('\n', stderr); 2244677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* we really only accept rt_cache */ 2284677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (num_req_files && !name_in_array(num_req_files, 2294677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger req_files, "rt_cache")) { 2304677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fputc('\n', stderr); 2314677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2324677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2334677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2344677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(stderr, "Fallback to old rtstat-only operation\n"); 2354677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2364677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf = alloc_and_open("/proc/net", "rt_cache_stat"); 2374677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf) 2384677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2394677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->compat = 1; 2404677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strncpy(lf->basename, "rt_cache", sizeof(lf->basename)); 2414677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2424677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* FIXME: support for old files */ 2434677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (lnstat_scan_compat_rtstat_fields(lf) < 0) 2444677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2454677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2464677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->next = lnstat_files; 2474677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lnstat_files = lf; 2484677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return lnstat_files; 2494677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2504677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2514677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger while ((de = readdir(dir))) { 2524677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 2534677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2544677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (de->d_type != DT_REG) 2554677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger continue; 2564677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2574677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (num_req_files && !name_in_array(num_req_files, 2584677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger req_files, de->d_name)) 2594677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger continue; 2604677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2614677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf = alloc_and_open(path, de->d_name); 2624677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf) 2634677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2644677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2654677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* fill in field structure */ 2664677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (lnstat_scan_fields(lf) < 0) 2674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 2684677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2694677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* prepend to global list */ 2704677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->next = lnstat_files; 2714677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lnstat_files = lf; 2724677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger closedir(dir); 2744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2754677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return lnstat_files; 2764677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 2774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2784677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerint lnstat_dump(FILE *outfd, struct lnstat_file *lnstat_files) 2794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 2804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 2814677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2824677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 2834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 2844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2854677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(outfd, "%s:\n", lf->path); 2864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < lf->num_fields; i++) 2884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(outfd, "\t%2u: %s\n", i+1, lf->fields[i].name); 2894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 2924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 2934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2944677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstruct lnstat_field *lnstat_find_field(struct lnstat_file *lnstat_files, 2954677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *name) 2964677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 2974677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 2984677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_field *ret = NULL; 2994677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *colon = strchr(name, ':'); 3004677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *file; 3014677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *field; 3024677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3034677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (colon) { 3044677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger file = strndup(name, colon-name); 3054677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger field = colon+1; 3064677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } else { 3074677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger file = NULL; 3084677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger field = name; 3094677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 3124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 3134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3144677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (file && strcmp(file, lf->basename)) 3154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger continue; 3164677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < lf->num_fields; i++) { 3184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!strcmp(field, lf->fields[i].name)) { 3194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger ret = &lf->fields[i]; 3204677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger goto out; 3214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3244677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerout: 3254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (file) 3264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger free(file); 3274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3284677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return ret; 3294677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 330