1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * nstat.c	handy utility to read counters /proc/net/netstat and snmp
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <time.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/time.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fnmatch.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/file.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/un.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/poll.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/wait.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/stat.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <signal.h>
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <math.h>
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <SNAPSHOT.h>
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint dump_zeros = 0;
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint reset_history = 0;
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint ignore_history = 0;
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint no_output = 0;
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint no_update = 0;
37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint scan_interval = 0;
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint time_constant = 0;
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerdouble W;
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar **patterns;
41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint npatterns;
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar info_source[128];
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint source_mismatch;
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
464ffc44ca7c1ec7adb980b67ae1e1c8fa772777f1Yu Zhiguostatic int generic_proc_open(const char *env, char *name)
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char store[128];
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *p = getenv(env);
50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!p) {
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p = getenv("PROC_ROOT") ? : "/proc";
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		snprintf(store, sizeof(store)-1, "%s/%s", p, name);
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p = store;
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
554ffc44ca7c1ec7adb980b67ae1e1c8fa772777f1Yu Zhiguo	return open(p, O_RDONLY);
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint net_netstat_open(void)
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return generic_proc_open("PROC_NET_NETSTAT", "net/netstat");
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint net_snmp_open(void)
64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return generic_proc_open("PROC_NET_SNMP", "net/snmp");
66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint net_snmp6_open(void)
69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return generic_proc_open("PROC_NET_SNMP6", "net/snmp6");
71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct nstat_ent
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *next;
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char		 *id;
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long long val;
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long	   ival;
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	double		   rate;
80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger};
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct nstat_ent *kern_db;
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct nstat_ent *hist_db;
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar *useless_numbers[] = {
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger"IpForwarding", "IpDefaultTTL",
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger"TcpRtoAlgorithm", "TcpRtoMin", "TcpRtoMax",
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger"TcpMaxConn", "TcpCurrEstab"
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger};
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint useless_number(char *id)
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int i;
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (i=0; i<sizeof(useless_numbers)/sizeof(*useless_numbers); i++)
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(id, useless_numbers[i]) == 0)
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return 1;
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint match(char *id)
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int i;
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (npatterns == 0)
105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 1;
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (i=0; i<npatterns; i++) {
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!fnmatch(patterns[i], id, 0))
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return 1;
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_good_table(FILE *fp)
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[4096];
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *db = NULL;
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *n;
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (fgets(buf, sizeof(buf), fp) != NULL) {
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int nr;
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		unsigned long long val;
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		double rate;
124b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		char idbuf[sizeof(buf)];
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (buf[0] == '#') {
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			buf[strlen(buf)-1] = 0;
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (info_source[0] && strcmp(info_source, buf+1))
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				source_mismatch = 1;
129b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger			info_source[0] = 0;
130b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger			strncat(info_source, buf+1, sizeof(info_source)-1);
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
133b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		/* idbuf is as big as buf, so this is safe */
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		nr = sscanf(buf, "%s%llu%lg", idbuf, &val, &rate);
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (nr < 2)
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			abort();
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (nr < 3)
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			rate = 0;
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (useless_number(idbuf))
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((n = malloc(sizeof(*n))) == NULL)
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			abort();
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->id = strdup(idbuf);
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->ival = (unsigned long)val;
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->val = val;
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->rate = rate;
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->next = db;
148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		db = n;
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (db) {
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n = db;
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		db = db->next;
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->next = kern_db;
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		kern_db = n;
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_ugly_table(FILE *fp)
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[4096];
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *db = NULL;
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *n;
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (fgets(buf, sizeof(buf), fp) != NULL) {
167b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		char idbuf[sizeof(buf)];
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int  off;
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char *p;
170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p = strchr(buf, ':');
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!p)
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			abort();
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		*p = 0;
175b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		idbuf[0] = 0;
176b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		strncat(idbuf, buf, sizeof(idbuf) - 1);
177b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger		off = p - buf;
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		p += 2;
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		while (*p) {
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			char *next;
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if ((next = strchr(p, ' ')) != NULL)
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				*next++ = 0;
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			else if ((next = strchr(p, '\n')) != NULL)
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				*next++ = 0;
186b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger			if (off < sizeof(idbuf)) {
187b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger				idbuf[off] = 0;
188b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger				strncat(idbuf, p, sizeof(idbuf) - off - 1);
189b482ffa6a64b7d477306dda139432afe6d2ece48net[shemminger]!shemminger			}
190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n = malloc(sizeof(*n));
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (!n)
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				abort();
193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->id = strdup(idbuf);
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->rate = 0;
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->next = db;
196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			db = n;
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p = next;
198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n = db;
200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fgets(buf, sizeof(buf), fp) == NULL)
201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			abort();
202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		do {
203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			p = strrchr(buf, ' ');
204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (!p)
205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				abort();
206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			*p = 0;
207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (sscanf(p+1, "%lu", &n->ival) != 1)
208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				abort();
209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->val = n->ival;
210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			/* Trick to skip "dummy" trailing ICMP MIB in 2.4 */
211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(idbuf, "IcmpOutAddrMaskReps") == 0)
212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				idbuf[5] = 0;
213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			else
214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				n = n->next;
215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} while (p > buf + off + 2);
216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (db) {
219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n = db;
220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		db = db->next;
221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (useless_number(n->id)) {
222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			free(n->id);
223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			free(n);
224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->next = kern_db;
226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			kern_db = n;
227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_snmp(void)
232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fdopen(net_snmp_open(), "r");
234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp) {
235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_ugly_table(fp);
236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(fp);
237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_snmp6(void)
241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fdopen(net_snmp6_open(), "r");
243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp) {
244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_good_table(fp);
245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(fp);
246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_netstat(void)
250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = fdopen(net_netstat_open(), "r");
252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp) {
253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_ugly_table(fp);
254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(fp);
255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid dump_kern_db(FILE *fp, int to_hist)
259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *n, *h;
261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	h = hist_db;
262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(fp, "#%s\n", info_source);
263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (n=kern_db; n; n=n->next) {
264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		unsigned long long val = n->val;
265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!dump_zeros && !val && !n->rate)
266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!match(n->id)) {
268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			struct nstat_ent *h1;
269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (!to_hist)
270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				continue;
271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			for (h1 = h; h1; h1 = h1->next) {
272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (strcmp(h1->id, n->id) == 0) {
273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					val = h1->val;
274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					h = h1->next;
275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					break;
276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "%-32s%-16llu%6.1f\n", n->id, val, n->rate);
280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid dump_incr_db(FILE *fp)
284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *n, *h;
286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	h = hist_db;
287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(fp, "#%s\n", info_source);
288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (n=kern_db; n; n=n->next) {
289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int ovfl = 0;
290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		unsigned long long val = n->val;
291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct nstat_ent *h1;
292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		for (h1 = h; h1; h1 = h1->next) {
293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(h1->id, n->id) == 0) {
294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (val < h1->val) {
295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					ovfl = 1;
296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					val = h1->val;
297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				val -= h1->val;
299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				h = h1->next;
300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				break;
301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!dump_zeros && !val && !n->rate)
304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!match(n->id))
306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			continue;
307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "%-32s%-16llu%6.1f%s\n", n->id, val,
308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->rate, ovfl?" (overflow)":"");
309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int children;
313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid sigchild(int signo)
315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid update_db(int interval)
319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct nstat_ent *n, *h;
321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n = kern_db;
323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	kern_db = NULL;
324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_netstat();
326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_snmp6();
327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_snmp();
328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
329aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	h = kern_db;
330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	kern_db = n;
331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (n = kern_db; n; n = n->next) {
333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct nstat_ent *h1;
334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		for (h1 = h; h1; h1 = h1->next) {
335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(h1->id, n->id) == 0) {
336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				double sample;
337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				unsigned long incr = h1->ival - n->ival;
338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				n->val += incr;
339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				n->ival = h1->ival;
340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				sample = (double)(incr*1000)/interval;
341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (interval >= scan_interval) {
342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					n->rate += W*(sample-n->rate);
343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				} else if (interval >= 1000) {
344aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					if (interval >= time_constant) {
345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						n->rate = sample;
346aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					} else {
347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						double w = W*(double)interval/scan_interval;
348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						n->rate += w*(sample-n->rate);
349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					}
350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				while (h != h1) {
353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					struct nstat_ent *tmp = h;
354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					h = h->next;
355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					free(tmp->id);
356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					free(tmp);
357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				};
358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				h = h1->next;
359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				free(h1->id);
360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				free(h1);
361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				break;
362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define T_DIFF(a,b) (((a).tv_sec-(b).tv_sec)*1000 + ((a).tv_usec-(b).tv_usec)/1000)
368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid server_loop(int fd)
371aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
372737f15f6da0ed7512220f6fa5244a39777de4e0dshemminger	struct timeval snaptime = { 0 };
373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct pollfd p;
374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	p.fd = fd;
375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	p.events = p.revents = POLLIN;
376ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	sprintf(info_source, "%d.%lu sampling_interval=%d time_const=%d",
378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		getpid(), (unsigned long)random(), scan_interval/1000, time_constant/1000);
379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_netstat();
381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_snmp6();
382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	load_snmp();
383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (;;) {
385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int status;
386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		int tdiff;
387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct timeval now;
388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		gettimeofday(&now, NULL);
389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		tdiff = T_DIFF(now, snaptime);
390aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (tdiff >= scan_interval) {
391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			update_db(tdiff);
392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			snaptime = now;
393aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			tdiff = 0;
394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (poll(&p, 1, tdiff + scan_interval) > 0
396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    && (p.revents&POLLIN)) {
397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			int clnt = accept(fd, NULL, NULL);
398aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (clnt >= 0) {
399aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				pid_t pid;
400aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (children >= 5) {
401aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					close(clnt);
402aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				} else if ((pid = fork()) != 0) {
403aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					if (pid>0)
404aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						children++;
405aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					close(clnt);
406aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				} else {
407aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					FILE *fp = fdopen(clnt, "w");
408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					if (fp) {
409aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						if (tdiff > 0)
410aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger							update_db(tdiff);
411aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger						dump_kern_db(fp, 0);
412aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					}
413aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					exit(0);
414aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				}
415aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
416aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
417aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		while (children && waitpid(-1, &status, WNOHANG) > 0)
418aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			children--;
419aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
420aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
421aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
422aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint verify_forging(int fd)
423aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
424aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ucred cred;
425737f15f6da0ed7512220f6fa5244a39777de4e0dshemminger	socklen_t olen = sizeof(cred);
426737f15f6da0ed7512220f6fa5244a39777de4e0dshemminger
427aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, (void*)&cred, &olen) ||
428aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    olen < sizeof(cred))
429aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
430aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (cred.uid == getuid() || cred.uid == 0)
431aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
432aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return -1;
433aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
434aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
435aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn));
436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
437aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
438aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr,
440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger"Usage: nstat [ -h?vVzrnasd:t: ] [ PATTERN [ PATTERN ] ]\n"
441aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		);
442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint main(int argc, char *argv[])
447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
448896ebd6c705651abe0a6eedc9c6158a5db6e38d3Stephen Hemminger	char *hist_name;
449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct sockaddr_un sun;
450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *hist_fp = NULL;
451aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int ch;
452aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int fd;
453aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
454aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while ((ch = getopt(argc, argv, "h?vVzrnasd:t:")) != EOF) {
455aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		switch(ch) {
456aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'z':
457aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dump_zeros = 1;
458aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
459aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'r':
460aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			reset_history = 1;
461aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
462aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'a':
463aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			ignore_history = 1;
464aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
465aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 's':
466aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			no_update = 1;
467aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
468aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'n':
469aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			no_output = 1;
470aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'd':
472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			scan_interval = 1000*atoi(optarg);
473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 't':
475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (sscanf(optarg, "%d", &time_constant) != 1 ||
476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			    time_constant <= 0) {
477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "nstat: invalid time constant divisor\n");
478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				exit(-1);
479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'v':
482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'V':
483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("nstat utility, iproute2-ss%s\n", SNAPSHOT);
484aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(0);
485aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case 'h':
486aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		case '?':
487aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		default:
488aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
489aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
490aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
491aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
492aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	argc -= optind;
493aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	argv += optind;
494aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
495aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	sun.sun_family = AF_UNIX;
496aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	sun.sun_path[0] = 0;
497aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	sprintf(sun.sun_path+1, "nstat%d", getuid());
498aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
499aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (scan_interval > 0) {
500aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (time_constant == 0)
501aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			time_constant = 60;
502aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		time_constant *= 1000;
503aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant);
504aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
505aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: socket");
506aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
507aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
508aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (bind(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) < 0) {
509aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: bind");
510aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
512aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (listen(fd, 5) < 0) {
513aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: listen");
514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
515aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
516a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger		if (daemon(0, 0)) {
517a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger			perror("nstat: daemon");
518a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger			exit(-1);
519a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger		}
520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		signal(SIGPIPE, SIG_IGN);
521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		signal(SIGCHLD, sigchild);
522aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		server_loop(fd);
523aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(0);
524aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
525aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
526aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	patterns = argv;
527aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	npatterns = argc;
528aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
529896ebd6c705651abe0a6eedc9c6158a5db6e38d3Stephen Hemminger	if ((hist_name = getenv("NSTAT_HISTORY")) == NULL) {
530896ebd6c705651abe0a6eedc9c6158a5db6e38d3Stephen Hemminger		hist_name = malloc(128);
531aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		sprintf(hist_name, "/tmp/.nstat.u%d", getuid());
532896ebd6c705651abe0a6eedc9c6158a5db6e38d3Stephen Hemminger	}
533aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
534aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (reset_history)
535aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		unlink(hist_name);
536aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
537aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!ignore_history || !no_update) {
538aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct stat stb;
539aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
540aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fd = open(hist_name, O_RDWR|O_CREAT|O_NOFOLLOW, 0600);
541aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fd < 0) {
542aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: open history file");
543aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
544aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((hist_fp = fdopen(fd, "r+")) == NULL) {
546aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: fdopen history file");
547aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
548aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
549aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (flock(fileno(hist_fp), LOCK_EX)) {
550aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: flock history file");
551aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fstat(fileno(hist_fp), &stb) != 0) {
554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("nstat: fstat history file");
555aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
556aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
557aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (stb.st_nlink != 1 || stb.st_uid != getuid()) {
558aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "nstat: something is so wrong with history file, that I prefer not to proceed.\n");
559aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
560aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
561aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!ignore_history) {
562aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			FILE *tfp;
5639a230771c0a0b27e2f26bbbc29a93ad1ad591ce9Dan McGee			long uptime = -1;
564aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if ((tfp = fopen("/proc/uptime", "r")) != NULL) {
565aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				if (fscanf(tfp, "%ld", &uptime) != 1)
566aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger					uptime = -1;
567aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fclose(tfp);
568aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
569aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) {
570aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				fprintf(stderr, "nstat: history is aged out, resetting\n");
571aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				ftruncate(fileno(hist_fp), 0);
572aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
573aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
574aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
575aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_good_table(hist_fp);
576aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
577aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		hist_db = kern_db;
578aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		kern_db = NULL;
579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    (connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0
583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	     || (strcpy(sun.sun_path+1, "nstat0"),
584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		 connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0))
585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    && verify_forging(fd) == 0) {
586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		FILE *sfp = fdopen(fd, "r");
587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_good_table(sfp);
588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (hist_db && source_mismatch) {
589aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "nstat: history is stale, ignoring it.\n");
590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			hist_db = NULL;
591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(sfp);
593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	} else {
594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fd >= 0)
595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			close(fd);
596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (hist_db && info_source[0] && strcmp(info_source, "kernel")) {
597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "nstat: history is stale, ignoring it.\n");
598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			hist_db = NULL;
599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			info_source[0] = 0;
600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_netstat();
602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_snmp6();
603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		load_snmp();
604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (info_source[0] == 0)
605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			strcpy(info_source, "kernel");
606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!no_output) {
609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (ignore_history || hist_db == NULL)
610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dump_kern_db(stdout, 0);
611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		else
612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dump_incr_db(stdout);
613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!no_update) {
615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ftruncate(fileno(hist_fp), 0);
616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		rewind(hist_fp);
617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dump_kern_db(hist_fp, 1);
618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fflush(hist_fp);
619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(0);
621aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
622