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{ 41db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter char buf[FGETS_BUF_SIZE]; 424677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int j, num_lines = 0; 434677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 444677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (j = 0; j < lf->num_fields; j++) 454677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fields[j].values[i] = 0; 464677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 47db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter rewind(lf->fp); 48db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter /* skip first line */ 49db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter if (!lf->compat && !fgets(buf, sizeof(buf)-1, lf->fp)) 50db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter return -1; 51db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter 52db3ef44c5433aa50bae6f88736ad350fb14fc2cfPhil Sutter while(!feof(lf->fp) && fgets(buf, sizeof(buf)-1, lf->fp)) { 534677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *ptr = buf; 544677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 554677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger num_lines++; 564677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 574677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger gettimeofday(&lf->last_read, NULL); 584677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 59f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger for (j = 0; j < lf->num_fields; j++) { 60f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger unsigned long f = strtoul(ptr, &ptr, 16); 61ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (j == 0) 627339c0bb74e7e55ad70c29ced5628f26dd821900shemminger lf->fields[j].values[i] = f; 63f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger else 64f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger lf->fields[j].values[i] += f; 65f5f1a6c5836a405381fb9d4be74d5ddf98404db1osdl.net!shemminger } 664677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return num_lines; 684677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 694677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 70ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int time_after(struct timeval *last, 71ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger struct timeval *tout, 724677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct timeval *now) 734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_sec > last->tv_sec + tout->tv_sec) 754677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 764677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_sec == last->tv_sec + tout->tv_sec) { 784677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (now->tv_usec > last->tv_usec + tout->tv_usec) 794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 814677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 824677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 854677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerint lnstat_update(struct lnstat_file *lnstat_files) 864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct timeval tv; 894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger gettimeofday(&tv, NULL); 914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (time_after(&lf->last_read, &lf->interval, &tv)) { 944677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 954677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_field *lfi; 964677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 974677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger scan_lines(lf, 1); 984677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 99ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger for (i = 0, lfi = &lf->fields[i]; 1004677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger i < lf->num_fields; i++, lfi = &lf->fields[i]) { 1014677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (i == 0) 1024677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lfi->result = lfi->values[1]; 1034677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger else 1044677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lfi->result = (lfi->values[1]-lfi->values[0]) 1054677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger / lf->interval.tv_sec; 1064677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1074677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1084677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger scan_lines(lf, 0); 1094677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1144677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* scan first template line and fill in per-field data structures */ 1164677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int __lnstat_scan_fields(struct lnstat_file *lf, char *buf) 1174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *tok; 1194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 1204677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger tok = strtok(buf, " \t\n"); 1224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < LNSTAT_MAX_FIELDS_PER_LINE; i++) { 1234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fields[i].file = lf; 1244677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strncpy(lf->fields[i].name, tok, LNSTAT_MAX_FIELD_NAME_LEN); 1254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* has to be null-terminate since we initialize to zero 1264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger * and field size is NAME_LEN + 1 */ 1274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger tok = strtok(NULL, " \t\n"); 1284677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!tok) { 1294677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->num_fields = i+1; 1304677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1314677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1324677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1334677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1344677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1354677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1364677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int lnstat_scan_fields(struct lnstat_file *lf) 1374677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1384677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 1394677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1404677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger rewind(lf->fp); 141d572ed4d0af79eb597469d3f1a84456782c64f24Phil Sutter if (!fgets(buf, sizeof(buf)-1, lf->fp)) 142d572ed4d0af79eb597469d3f1a84456782c64f24Phil Sutter return -1; 1434677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1444677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return __lnstat_scan_fields(lf, buf); 1454677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1464677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1474677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* fake function emulating lnstat_scan_fields() for old kernels */ 1484677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf) 1494677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1504677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char buf[FGETS_BUF_SIZE]; 1514677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1524677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1); 1534677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1544677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return __lnstat_scan_fields(lf, buf); 1554677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1564677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1574677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* find out whether string 'name; is in given string array */ 1584677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic int name_in_array(const int num, const char **arr, const char *name) 1594677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1604677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 1614677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < num; i++) { 1624677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!strcmp(arr[i], name)) 1634677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 1; 1644677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 1654677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 1664677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 1674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1684677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger/* allocate lnstat_file and open given file */ 1694677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstatic struct lnstat_file *alloc_and_open(const char *path, const char *file) 1704677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 1714677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 1724677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* allocate */ 1744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf = malloc(sizeof(*lf)); 175b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger if (!lf) { 176b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger fprintf(stderr, "out of memory\n"); 1774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 178b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger } 1794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* initialize */ 1814677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger memset(lf, 0, sizeof(*lf)); 1824677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* de->d_name is guaranteed to be <= NAME_MAX */ 1844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcpy(lf->basename, file); 1854677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcpy(lf->path, path); 1864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcat(lf->path, "/"); 1874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger strcat(lf->path, lf->basename); 1884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* initialize to default */ 1904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->interval.tv_sec = 1; 1914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 1924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* open */ 1934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->fp = fopen(lf->path, "r"); 1944677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!lf->fp) { 195b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger perror(lf->path); 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; 214ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 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); 262b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger if (!lf) { 263b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger closedir(dir); 2644677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 265b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger } 2664677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2674677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* fill in field structure */ 268b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger if (lnstat_scan_fields(lf) < 0) { 269b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger closedir(dir); 2704677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return NULL; 271b90b773ca6aa1b1a39d76186d1a7639a13f5c916Stephen Hemminger } 2724677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2734677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger /* prepend to global list */ 2744677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lf->next = lnstat_files; 2754677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger lnstat_files = lf; 2764677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2774677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger closedir(dir); 2784677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2794677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return lnstat_files; 2804677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 2814677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2824677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerint lnstat_dump(FILE *outfd, struct lnstat_file *lnstat_files) 2834677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 2844677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 2854677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2864677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 2874677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 2884677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2894677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(outfd, "%s:\n", lf->path); 2904677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2914677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < lf->num_fields; i++) 2924677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger fprintf(outfd, "\t%2u: %s\n", i+1, lf->fields[i].name); 2934677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2944677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 2954677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return 0; 2964677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 2974677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 2984677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerstruct lnstat_field *lnstat_find_field(struct lnstat_file *lnstat_files, 2994677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *name) 3004677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger{ 3014677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_file *lf; 3024677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger struct lnstat_field *ret = NULL; 3034677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *colon = strchr(name, ':'); 3044677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger char *file; 3054677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger const char *field; 3064677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3074677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (colon) { 3084677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger file = strndup(name, colon-name); 3094677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger field = colon+1; 3104677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } else { 3114677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger file = NULL; 3124677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger field = name; 3134677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 314ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 3154677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (lf = lnstat_files; lf; lf = lf->next) { 3164677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger int i; 3174677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3184677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (file && strcmp(file, lf->basename)) 3194677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger continue; 3204677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3214677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger for (i = 0; i < lf->num_fields; i++) { 3224677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger if (!strcmp(field, lf->fields[i].name)) { 3234677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger ret = &lf->fields[i]; 3244677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger goto out; 3254677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3264677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3274677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger } 3284677a549831336400e16210e6f12251dc07d5232osdl.net!shemmingerout: 32992de1c2c820816801681d76f5de7137a2b5996dfStephen Hemminger free(file); 3304677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger 3314677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger return ret; 3324677a549831336400e16210e6f12251dc07d5232osdl.net!shemminger} 333