1*de1e4e89SAndroid Build Coastguard Worker /* lnstat - Unified linux network statistics
2*de1e4e89SAndroid Build Coastguard Worker *
3*de1e4e89SAndroid Build Coastguard Worker * Copyright (C) 2004 by Harald Welte <[email protected]>
4*de1e4e89SAndroid Build Coastguard Worker *
5*de1e4e89SAndroid Build Coastguard Worker * Development of this code was funded by Astaro AG, http://www.astaro.com/
6*de1e4e89SAndroid Build Coastguard Worker *
7*de1e4e89SAndroid Build Coastguard Worker * Based on original concept and ideas from predecessor rtstat.c:
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Copyright 2001 by Robert Olsson <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker * Uppsala University, Sweden
11*de1e4e89SAndroid Build Coastguard Worker *
12*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
13*de1e4e89SAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
14*de1e4e89SAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
15*de1e4e89SAndroid Build Coastguard Worker * (at your option) any later version.
16*de1e4e89SAndroid Build Coastguard Worker *
17*de1e4e89SAndroid Build Coastguard Worker */
18*de1e4e89SAndroid Build Coastguard Worker
19*de1e4e89SAndroid Build Coastguard Worker /* Maximum number of fields that can be displayed */
20*de1e4e89SAndroid Build Coastguard Worker #define MAX_FIELDS 128
21*de1e4e89SAndroid Build Coastguard Worker
22*de1e4e89SAndroid Build Coastguard Worker /* Maximum number of header lines */
23*de1e4e89SAndroid Build Coastguard Worker #define HDR_LINES 10
24*de1e4e89SAndroid Build Coastguard Worker
25*de1e4e89SAndroid Build Coastguard Worker /* default field width if none specified */
26*de1e4e89SAndroid Build Coastguard Worker #define FIELD_WIDTH_DEFAULT 8
27*de1e4e89SAndroid Build Coastguard Worker #define FIELD_WIDTH_MAX 20
28*de1e4e89SAndroid Build Coastguard Worker
29*de1e4e89SAndroid Build Coastguard Worker #define DEFAULT_INTERVAL 2
30*de1e4e89SAndroid Build Coastguard Worker
31*de1e4e89SAndroid Build Coastguard Worker #define HDR_LINE_LENGTH (MAX_FIELDS*FIELD_WIDTH_MAX)
32*de1e4e89SAndroid Build Coastguard Worker
33*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
34*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
35*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
36*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
37*de1e4e89SAndroid Build Coastguard Worker #include <getopt.h>
38*de1e4e89SAndroid Build Coastguard Worker
39*de1e4e89SAndroid Build Coastguard Worker #include <json_writer.h>
40*de1e4e89SAndroid Build Coastguard Worker #include "lnstat.h"
41*de1e4e89SAndroid Build Coastguard Worker
42*de1e4e89SAndroid Build Coastguard Worker static struct option opts[] = {
43*de1e4e89SAndroid Build Coastguard Worker { "version", 0, NULL, 'V' },
44*de1e4e89SAndroid Build Coastguard Worker { "count", 1, NULL, 'c' },
45*de1e4e89SAndroid Build Coastguard Worker { "dump", 0, NULL, 'd' },
46*de1e4e89SAndroid Build Coastguard Worker { "json", 0, NULL, 'j' },
47*de1e4e89SAndroid Build Coastguard Worker { "file", 1, NULL, 'f' },
48*de1e4e89SAndroid Build Coastguard Worker { "help", 0, NULL, 'h' },
49*de1e4e89SAndroid Build Coastguard Worker { "interval", 1, NULL, 'i' },
50*de1e4e89SAndroid Build Coastguard Worker { "keys", 1, NULL, 'k' },
51*de1e4e89SAndroid Build Coastguard Worker { "subject", 1, NULL, 's' },
52*de1e4e89SAndroid Build Coastguard Worker { "width", 1, NULL, 'w' },
53*de1e4e89SAndroid Build Coastguard Worker { "oneline", 0, NULL, 0 },
54*de1e4e89SAndroid Build Coastguard Worker };
55*de1e4e89SAndroid Build Coastguard Worker
usage(char * name,int exit_code)56*de1e4e89SAndroid Build Coastguard Worker static int usage(char *name, int exit_code)
57*de1e4e89SAndroid Build Coastguard Worker {
58*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "%s Version %s\n", name, LNSTAT_VERSION);
59*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Copyright (C) 2004 by Harald Welte <[email protected]>\n");
60*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "This program is free software licensed under GNU GPLv2\nwith ABSOLUTELY NO WARRANTY.\n\n");
61*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Parameters:\n");
62*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-V --version\t\tPrint Version of Program\n");
63*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-c --count <count>\t"
64*de1e4e89SAndroid Build Coastguard Worker "Print <count> number of intervals\n");
65*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-d --dump\t\t"
66*de1e4e89SAndroid Build Coastguard Worker "Dump list of available files/keys\n");
67*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-j --json\t\t"
68*de1e4e89SAndroid Build Coastguard Worker "Display in JSON format\n");
69*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-f --file <file>\tStatistics file to use\n");
70*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-h --help\t\tThis help message\n");
71*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-i --interval <intv>\t"
72*de1e4e89SAndroid Build Coastguard Worker "Set interval to 'intv' seconds\n");
73*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-k --keys k,k,k,...\tDisplay only keys specified\n");
74*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-s --subject [0-2]\tControl header printing:\n");
75*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t\t\t\t0 = never\n");
76*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t\t\t\t1 = once\n");
77*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t\t\t\t2 = every 20 lines (default))\n");
78*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\t-w --width n,n,n,...\tWidth for each field\n");
79*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\n");
80*de1e4e89SAndroid Build Coastguard Worker
81*de1e4e89SAndroid Build Coastguard Worker exit(exit_code);
82*de1e4e89SAndroid Build Coastguard Worker }
83*de1e4e89SAndroid Build Coastguard Worker
84*de1e4e89SAndroid Build Coastguard Worker struct field_param {
85*de1e4e89SAndroid Build Coastguard Worker const char *name;
86*de1e4e89SAndroid Build Coastguard Worker struct lnstat_field *lf;
87*de1e4e89SAndroid Build Coastguard Worker struct {
88*de1e4e89SAndroid Build Coastguard Worker unsigned int width;
89*de1e4e89SAndroid Build Coastguard Worker } print;
90*de1e4e89SAndroid Build Coastguard Worker };
91*de1e4e89SAndroid Build Coastguard Worker
92*de1e4e89SAndroid Build Coastguard Worker struct field_params {
93*de1e4e89SAndroid Build Coastguard Worker unsigned int num;
94*de1e4e89SAndroid Build Coastguard Worker struct field_param params[MAX_FIELDS];
95*de1e4e89SAndroid Build Coastguard Worker };
96*de1e4e89SAndroid Build Coastguard Worker
print_line(FILE * of,const struct lnstat_file * lnstat_files,const struct field_params * fp)97*de1e4e89SAndroid Build Coastguard Worker static void print_line(FILE *of, const struct lnstat_file *lnstat_files,
98*de1e4e89SAndroid Build Coastguard Worker const struct field_params *fp)
99*de1e4e89SAndroid Build Coastguard Worker {
100*de1e4e89SAndroid Build Coastguard Worker int i;
101*de1e4e89SAndroid Build Coastguard Worker
102*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < fp->num; i++) {
103*de1e4e89SAndroid Build Coastguard Worker const struct lnstat_field *lf = fp->params[i].lf;
104*de1e4e89SAndroid Build Coastguard Worker
105*de1e4e89SAndroid Build Coastguard Worker fprintf(of, "%*lu|", fp->params[i].print.width, lf->result);
106*de1e4e89SAndroid Build Coastguard Worker }
107*de1e4e89SAndroid Build Coastguard Worker fputc('\n', of);
108*de1e4e89SAndroid Build Coastguard Worker }
109*de1e4e89SAndroid Build Coastguard Worker
print_json(FILE * of,const struct lnstat_file * lnstat_files,const struct field_params * fp)110*de1e4e89SAndroid Build Coastguard Worker static void print_json(FILE *of, const struct lnstat_file *lnstat_files,
111*de1e4e89SAndroid Build Coastguard Worker const struct field_params *fp)
112*de1e4e89SAndroid Build Coastguard Worker {
113*de1e4e89SAndroid Build Coastguard Worker json_writer_t *jw = jsonw_new(of);
114*de1e4e89SAndroid Build Coastguard Worker int i;
115*de1e4e89SAndroid Build Coastguard Worker
116*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(jw);
117*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < fp->num; i++) {
118*de1e4e89SAndroid Build Coastguard Worker const struct lnstat_field *lf = fp->params[i].lf;
119*de1e4e89SAndroid Build Coastguard Worker
120*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(jw, lf->name, lf->result);
121*de1e4e89SAndroid Build Coastguard Worker }
122*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(jw);
123*de1e4e89SAndroid Build Coastguard Worker jsonw_destroy(&jw);
124*de1e4e89SAndroid Build Coastguard Worker }
125*de1e4e89SAndroid Build Coastguard Worker
126*de1e4e89SAndroid Build Coastguard Worker /* find lnstat_field according to user specification */
map_field_params(struct lnstat_file * lnstat_files,struct field_params * fps,int interval)127*de1e4e89SAndroid Build Coastguard Worker static int map_field_params(struct lnstat_file *lnstat_files,
128*de1e4e89SAndroid Build Coastguard Worker struct field_params *fps, int interval)
129*de1e4e89SAndroid Build Coastguard Worker {
130*de1e4e89SAndroid Build Coastguard Worker int i, j = 0;
131*de1e4e89SAndroid Build Coastguard Worker struct lnstat_file *lf;
132*de1e4e89SAndroid Build Coastguard Worker
133*de1e4e89SAndroid Build Coastguard Worker /* no field specification on commandline, need to build default */
134*de1e4e89SAndroid Build Coastguard Worker if (!fps->num) {
135*de1e4e89SAndroid Build Coastguard Worker for (lf = lnstat_files; lf; lf = lf->next) {
136*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < lf->num_fields; i++) {
137*de1e4e89SAndroid Build Coastguard Worker fps->params[j].lf = &lf->fields[i];
138*de1e4e89SAndroid Build Coastguard Worker fps->params[j].lf->file->interval.tv_sec =
139*de1e4e89SAndroid Build Coastguard Worker interval;
140*de1e4e89SAndroid Build Coastguard Worker if (!fps->params[j].print.width)
141*de1e4e89SAndroid Build Coastguard Worker fps->params[j].print.width =
142*de1e4e89SAndroid Build Coastguard Worker FIELD_WIDTH_DEFAULT;
143*de1e4e89SAndroid Build Coastguard Worker
144*de1e4e89SAndroid Build Coastguard Worker if (++j >= MAX_FIELDS - 1) {
145*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
146*de1e4e89SAndroid Build Coastguard Worker "WARN: MAX_FIELDS (%d) reached, truncating number of keys\n",
147*de1e4e89SAndroid Build Coastguard Worker MAX_FIELDS);
148*de1e4e89SAndroid Build Coastguard Worker goto full;
149*de1e4e89SAndroid Build Coastguard Worker }
150*de1e4e89SAndroid Build Coastguard Worker }
151*de1e4e89SAndroid Build Coastguard Worker }
152*de1e4e89SAndroid Build Coastguard Worker full:
153*de1e4e89SAndroid Build Coastguard Worker fps->num = j;
154*de1e4e89SAndroid Build Coastguard Worker return 1;
155*de1e4e89SAndroid Build Coastguard Worker }
156*de1e4e89SAndroid Build Coastguard Worker
157*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < fps->num; i++) {
158*de1e4e89SAndroid Build Coastguard Worker fps->params[i].lf = lnstat_find_field(lnstat_files,
159*de1e4e89SAndroid Build Coastguard Worker fps->params[i].name);
160*de1e4e89SAndroid Build Coastguard Worker if (!fps->params[i].lf) {
161*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Field `%s' unknown\n",
162*de1e4e89SAndroid Build Coastguard Worker fps->params[i].name);
163*de1e4e89SAndroid Build Coastguard Worker return 0;
164*de1e4e89SAndroid Build Coastguard Worker }
165*de1e4e89SAndroid Build Coastguard Worker fps->params[i].lf->file->interval.tv_sec = interval;
166*de1e4e89SAndroid Build Coastguard Worker if (!fps->params[i].print.width)
167*de1e4e89SAndroid Build Coastguard Worker fps->params[i].print.width = FIELD_WIDTH_DEFAULT;
168*de1e4e89SAndroid Build Coastguard Worker }
169*de1e4e89SAndroid Build Coastguard Worker return 1;
170*de1e4e89SAndroid Build Coastguard Worker }
171*de1e4e89SAndroid Build Coastguard Worker
172*de1e4e89SAndroid Build Coastguard Worker struct table_hdr {
173*de1e4e89SAndroid Build Coastguard Worker int num_lines;
174*de1e4e89SAndroid Build Coastguard Worker char *hdr[HDR_LINES];
175*de1e4e89SAndroid Build Coastguard Worker };
176*de1e4e89SAndroid Build Coastguard Worker
build_hdr_string(struct lnstat_file * lnstat_files,struct field_params * fps,int linewidth)177*de1e4e89SAndroid Build Coastguard Worker static struct table_hdr *build_hdr_string(struct lnstat_file *lnstat_files,
178*de1e4e89SAndroid Build Coastguard Worker struct field_params *fps,
179*de1e4e89SAndroid Build Coastguard Worker int linewidth)
180*de1e4e89SAndroid Build Coastguard Worker {
181*de1e4e89SAndroid Build Coastguard Worker int h, i;
182*de1e4e89SAndroid Build Coastguard Worker static struct table_hdr th;
183*de1e4e89SAndroid Build Coastguard Worker int ofs = 0;
184*de1e4e89SAndroid Build Coastguard Worker
185*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < HDR_LINES; i++)
186*de1e4e89SAndroid Build Coastguard Worker th.hdr[i] = calloc(1, HDR_LINE_LENGTH);
187*de1e4e89SAndroid Build Coastguard Worker
188*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < fps->num; i++) {
189*de1e4e89SAndroid Build Coastguard Worker char *cname, *fname = fps->params[i].lf->name;
190*de1e4e89SAndroid Build Coastguard Worker unsigned int width = fps->params[i].print.width;
191*de1e4e89SAndroid Build Coastguard Worker
192*de1e4e89SAndroid Build Coastguard Worker snprintf(th.hdr[0]+ofs, width+2, "%*.*s|", width, width,
193*de1e4e89SAndroid Build Coastguard Worker fps->params[i].lf->file->basename);
194*de1e4e89SAndroid Build Coastguard Worker
195*de1e4e89SAndroid Build Coastguard Worker cname = fname;
196*de1e4e89SAndroid Build Coastguard Worker for (h = 1; h < HDR_LINES; h++) {
197*de1e4e89SAndroid Build Coastguard Worker if (cname - fname >= strlen(fname))
198*de1e4e89SAndroid Build Coastguard Worker snprintf(th.hdr[h]+ofs, width+2,
199*de1e4e89SAndroid Build Coastguard Worker "%*.*s|", width, width, "");
200*de1e4e89SAndroid Build Coastguard Worker else {
201*de1e4e89SAndroid Build Coastguard Worker th.num_lines = h+1;
202*de1e4e89SAndroid Build Coastguard Worker snprintf(th.hdr[h]+ofs, width+2,
203*de1e4e89SAndroid Build Coastguard Worker "%*.*s|", width, width, cname);
204*de1e4e89SAndroid Build Coastguard Worker }
205*de1e4e89SAndroid Build Coastguard Worker cname += width;
206*de1e4e89SAndroid Build Coastguard Worker }
207*de1e4e89SAndroid Build Coastguard Worker ofs += width+1;
208*de1e4e89SAndroid Build Coastguard Worker }
209*de1e4e89SAndroid Build Coastguard Worker /* fill in spaces */
210*de1e4e89SAndroid Build Coastguard Worker for (h = 1; h <= th.num_lines; h++) {
211*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < ofs; i++) {
212*de1e4e89SAndroid Build Coastguard Worker if (th.hdr[h][i] == '\0')
213*de1e4e89SAndroid Build Coastguard Worker th.hdr[h][i] = ' ';
214*de1e4e89SAndroid Build Coastguard Worker }
215*de1e4e89SAndroid Build Coastguard Worker }
216*de1e4e89SAndroid Build Coastguard Worker
217*de1e4e89SAndroid Build Coastguard Worker return &th;
218*de1e4e89SAndroid Build Coastguard Worker }
219*de1e4e89SAndroid Build Coastguard Worker
print_hdr(FILE * of,struct table_hdr * th)220*de1e4e89SAndroid Build Coastguard Worker static int print_hdr(FILE *of, struct table_hdr *th)
221*de1e4e89SAndroid Build Coastguard Worker {
222*de1e4e89SAndroid Build Coastguard Worker int i;
223*de1e4e89SAndroid Build Coastguard Worker
224*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < th->num_lines; i++) {
225*de1e4e89SAndroid Build Coastguard Worker fputs(th->hdr[i], of);
226*de1e4e89SAndroid Build Coastguard Worker fputc('\n', of);
227*de1e4e89SAndroid Build Coastguard Worker }
228*de1e4e89SAndroid Build Coastguard Worker return 0;
229*de1e4e89SAndroid Build Coastguard Worker }
230*de1e4e89SAndroid Build Coastguard Worker
231*de1e4e89SAndroid Build Coastguard Worker
main(int argc,char ** argv)232*de1e4e89SAndroid Build Coastguard Worker int main(int argc, char **argv)
233*de1e4e89SAndroid Build Coastguard Worker {
234*de1e4e89SAndroid Build Coastguard Worker struct lnstat_file *lnstat_files;
235*de1e4e89SAndroid Build Coastguard Worker const char *basename;
236*de1e4e89SAndroid Build Coastguard Worker int i, c;
237*de1e4e89SAndroid Build Coastguard Worker int interval = DEFAULT_INTERVAL;
238*de1e4e89SAndroid Build Coastguard Worker int hdr = 2;
239*de1e4e89SAndroid Build Coastguard Worker enum {
240*de1e4e89SAndroid Build Coastguard Worker MODE_DUMP,
241*de1e4e89SAndroid Build Coastguard Worker MODE_JSON,
242*de1e4e89SAndroid Build Coastguard Worker MODE_NORMAL,
243*de1e4e89SAndroid Build Coastguard Worker } mode = MODE_NORMAL;
244*de1e4e89SAndroid Build Coastguard Worker unsigned long count = 0;
245*de1e4e89SAndroid Build Coastguard Worker struct table_hdr *header;
246*de1e4e89SAndroid Build Coastguard Worker static struct field_params fp;
247*de1e4e89SAndroid Build Coastguard Worker int num_req_files = 0;
248*de1e4e89SAndroid Build Coastguard Worker char *req_files[LNSTAT_MAX_FILES];
249*de1e4e89SAndroid Build Coastguard Worker
250*de1e4e89SAndroid Build Coastguard Worker /* backwards compatibility mode for old tools */
251*de1e4e89SAndroid Build Coastguard Worker basename = strrchr(argv[0], '/');
252*de1e4e89SAndroid Build Coastguard Worker if (basename)
253*de1e4e89SAndroid Build Coastguard Worker basename += 1; /* name after slash */
254*de1e4e89SAndroid Build Coastguard Worker else
255*de1e4e89SAndroid Build Coastguard Worker basename = argv[0]; /* no slash */
256*de1e4e89SAndroid Build Coastguard Worker
257*de1e4e89SAndroid Build Coastguard Worker if (!strcmp(basename, "rtstat")) {
258*de1e4e89SAndroid Build Coastguard Worker /* rtstat compatibility mode */
259*de1e4e89SAndroid Build Coastguard Worker req_files[0] = "rt_cache";
260*de1e4e89SAndroid Build Coastguard Worker num_req_files = 1;
261*de1e4e89SAndroid Build Coastguard Worker } else if (!strcmp(basename, "ctstat")) {
262*de1e4e89SAndroid Build Coastguard Worker /* ctstat compatibility mode */
263*de1e4e89SAndroid Build Coastguard Worker req_files[0] = "ip_conntrack";
264*de1e4e89SAndroid Build Coastguard Worker num_req_files = 1;
265*de1e4e89SAndroid Build Coastguard Worker }
266*de1e4e89SAndroid Build Coastguard Worker
267*de1e4e89SAndroid Build Coastguard Worker while ((c = getopt_long(argc, argv, "Vc:djpf:h?i:k:s:w:",
268*de1e4e89SAndroid Build Coastguard Worker opts, NULL)) != -1) {
269*de1e4e89SAndroid Build Coastguard Worker int len = 0;
270*de1e4e89SAndroid Build Coastguard Worker char *tmp, *tok;
271*de1e4e89SAndroid Build Coastguard Worker
272*de1e4e89SAndroid Build Coastguard Worker switch (c) {
273*de1e4e89SAndroid Build Coastguard Worker case 'c':
274*de1e4e89SAndroid Build Coastguard Worker count = strtoul(optarg, NULL, 0);
275*de1e4e89SAndroid Build Coastguard Worker break;
276*de1e4e89SAndroid Build Coastguard Worker case 'd':
277*de1e4e89SAndroid Build Coastguard Worker mode = MODE_DUMP;
278*de1e4e89SAndroid Build Coastguard Worker break;
279*de1e4e89SAndroid Build Coastguard Worker case 'j':
280*de1e4e89SAndroid Build Coastguard Worker mode = MODE_JSON;
281*de1e4e89SAndroid Build Coastguard Worker break;
282*de1e4e89SAndroid Build Coastguard Worker case 'f':
283*de1e4e89SAndroid Build Coastguard Worker req_files[num_req_files++] = strdup(optarg);
284*de1e4e89SAndroid Build Coastguard Worker break;
285*de1e4e89SAndroid Build Coastguard Worker case '?':
286*de1e4e89SAndroid Build Coastguard Worker case 'h':
287*de1e4e89SAndroid Build Coastguard Worker usage(argv[0], 0);
288*de1e4e89SAndroid Build Coastguard Worker break;
289*de1e4e89SAndroid Build Coastguard Worker case 'i':
290*de1e4e89SAndroid Build Coastguard Worker sscanf(optarg, "%u", &interval);
291*de1e4e89SAndroid Build Coastguard Worker break;
292*de1e4e89SAndroid Build Coastguard Worker case 'k':
293*de1e4e89SAndroid Build Coastguard Worker tmp = strdup(optarg);
294*de1e4e89SAndroid Build Coastguard Worker if (!tmp)
295*de1e4e89SAndroid Build Coastguard Worker break;
296*de1e4e89SAndroid Build Coastguard Worker for (tok = strtok(tmp, ",");
297*de1e4e89SAndroid Build Coastguard Worker tok;
298*de1e4e89SAndroid Build Coastguard Worker tok = strtok(NULL, ",")) {
299*de1e4e89SAndroid Build Coastguard Worker if (fp.num >= MAX_FIELDS) {
300*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
301*de1e4e89SAndroid Build Coastguard Worker "WARN: too many keys requested: (%d max)\n",
302*de1e4e89SAndroid Build Coastguard Worker MAX_FIELDS);
303*de1e4e89SAndroid Build Coastguard Worker break;
304*de1e4e89SAndroid Build Coastguard Worker }
305*de1e4e89SAndroid Build Coastguard Worker fp.params[fp.num++].name = tok;
306*de1e4e89SAndroid Build Coastguard Worker }
307*de1e4e89SAndroid Build Coastguard Worker break;
308*de1e4e89SAndroid Build Coastguard Worker case 's':
309*de1e4e89SAndroid Build Coastguard Worker sscanf(optarg, "%u", &hdr);
310*de1e4e89SAndroid Build Coastguard Worker break;
311*de1e4e89SAndroid Build Coastguard Worker case 'w':
312*de1e4e89SAndroid Build Coastguard Worker tmp = strdup(optarg);
313*de1e4e89SAndroid Build Coastguard Worker if (!tmp)
314*de1e4e89SAndroid Build Coastguard Worker break;
315*de1e4e89SAndroid Build Coastguard Worker i = 0;
316*de1e4e89SAndroid Build Coastguard Worker for (tok = strtok(tmp, ",");
317*de1e4e89SAndroid Build Coastguard Worker tok;
318*de1e4e89SAndroid Build Coastguard Worker tok = strtok(NULL, ",")) {
319*de1e4e89SAndroid Build Coastguard Worker len = strtoul(tok, NULL, 0);
320*de1e4e89SAndroid Build Coastguard Worker if (len > FIELD_WIDTH_MAX)
321*de1e4e89SAndroid Build Coastguard Worker len = FIELD_WIDTH_MAX;
322*de1e4e89SAndroid Build Coastguard Worker fp.params[i].print.width = len;
323*de1e4e89SAndroid Build Coastguard Worker i++;
324*de1e4e89SAndroid Build Coastguard Worker }
325*de1e4e89SAndroid Build Coastguard Worker if (i == 1) {
326*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < MAX_FIELDS; i++)
327*de1e4e89SAndroid Build Coastguard Worker fp.params[i].print.width = len;
328*de1e4e89SAndroid Build Coastguard Worker }
329*de1e4e89SAndroid Build Coastguard Worker break;
330*de1e4e89SAndroid Build Coastguard Worker default:
331*de1e4e89SAndroid Build Coastguard Worker usage(argv[0], 1);
332*de1e4e89SAndroid Build Coastguard Worker break;
333*de1e4e89SAndroid Build Coastguard Worker }
334*de1e4e89SAndroid Build Coastguard Worker }
335*de1e4e89SAndroid Build Coastguard Worker
336*de1e4e89SAndroid Build Coastguard Worker lnstat_files = lnstat_scan_dir(PROC_NET_STAT, num_req_files,
337*de1e4e89SAndroid Build Coastguard Worker (const char **) req_files);
338*de1e4e89SAndroid Build Coastguard Worker
339*de1e4e89SAndroid Build Coastguard Worker switch (mode) {
340*de1e4e89SAndroid Build Coastguard Worker case MODE_DUMP:
341*de1e4e89SAndroid Build Coastguard Worker lnstat_dump(stdout, lnstat_files);
342*de1e4e89SAndroid Build Coastguard Worker break;
343*de1e4e89SAndroid Build Coastguard Worker
344*de1e4e89SAndroid Build Coastguard Worker case MODE_NORMAL:
345*de1e4e89SAndroid Build Coastguard Worker case MODE_JSON:
346*de1e4e89SAndroid Build Coastguard Worker if (!map_field_params(lnstat_files, &fp, interval))
347*de1e4e89SAndroid Build Coastguard Worker exit(1);
348*de1e4e89SAndroid Build Coastguard Worker
349*de1e4e89SAndroid Build Coastguard Worker header = build_hdr_string(lnstat_files, &fp, 80);
350*de1e4e89SAndroid Build Coastguard Worker if (!header)
351*de1e4e89SAndroid Build Coastguard Worker exit(1);
352*de1e4e89SAndroid Build Coastguard Worker
353*de1e4e89SAndroid Build Coastguard Worker if (interval < 1)
354*de1e4e89SAndroid Build Coastguard Worker interval = 1;
355*de1e4e89SAndroid Build Coastguard Worker
356*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < count || !count; i++) {
357*de1e4e89SAndroid Build Coastguard Worker lnstat_update(lnstat_files);
358*de1e4e89SAndroid Build Coastguard Worker if (mode == MODE_JSON)
359*de1e4e89SAndroid Build Coastguard Worker print_json(stdout, lnstat_files, &fp);
360*de1e4e89SAndroid Build Coastguard Worker else {
361*de1e4e89SAndroid Build Coastguard Worker if ((hdr > 1 && !(i % 20)) ||
362*de1e4e89SAndroid Build Coastguard Worker (hdr == 1 && i == 0))
363*de1e4e89SAndroid Build Coastguard Worker print_hdr(stdout, header);
364*de1e4e89SAndroid Build Coastguard Worker print_line(stdout, lnstat_files, &fp);
365*de1e4e89SAndroid Build Coastguard Worker }
366*de1e4e89SAndroid Build Coastguard Worker fflush(stdout);
367*de1e4e89SAndroid Build Coastguard Worker if (i < count - 1 || !count)
368*de1e4e89SAndroid Build Coastguard Worker sleep(interval);
369*de1e4e89SAndroid Build Coastguard Worker }
370*de1e4e89SAndroid Build Coastguard Worker break;
371*de1e4e89SAndroid Build Coastguard Worker }
372*de1e4e89SAndroid Build Coastguard Worker
373*de1e4e89SAndroid Build Coastguard Worker return 1;
374*de1e4e89SAndroid Build Coastguard Worker }
375