dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / snmp / apps / snmpstatus.c
blob72dc82df50a9cd1453465ebc7593a293b23ffd70
1 /*
2 * snmpstatus.c - send snmp GET requests to a network entity.
4 */
5 /***********************************************************************
6 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
8 All Rights Reserved
10 Permission to use, copy, modify, and distribute this software and its
11 documentation for any purpose and without fee is hereby granted,
12 provided that the above copyright notice appear in all copies and that
13 both that copyright notice and this permission notice appear in
14 supporting documentation, and that the name of CMU not be
15 used in advertising or publicity pertaining to distribution of the
16 software without specific, written prior permission.
18 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 SOFTWARE.
25 ******************************************************************/
26 #include <net-snmp/net-snmp-config.h>
28 #if HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #if HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #if HAVE_STRING_H
35 #include <string.h>
36 #else
37 #include <strings.h>
38 #endif
39 #include <sys/types.h>
40 #if HAVE_NETINET_IN_H
41 #include <netinet/in.h>
42 #endif
43 #include <stdio.h>
44 #include <ctype.h>
45 #if TIME_WITH_SYS_TIME
46 # ifdef WIN32
47 # include <sys/timeb.h>
48 # else
49 # include <sys/time.h>
50 # endif
51 # include <time.h>
52 #else
53 # if HAVE_SYS_TIME_H
54 # include <sys/time.h>
55 # else
56 # include <time.h>
57 # endif
58 #endif
59 #if HAVE_SYS_SELECT_H
60 #include <sys/select.h>
61 #endif
62 #if HAVE_WINSOCK_H
63 #include <winsock.h>
64 #endif
65 #if HAVE_NETDB_H
66 #include <netdb.h>
67 #endif
68 #if HAVE_ARPA_INET_H
69 #include <arpa/inet.h>
70 #endif
72 #include <net-snmp/utilities.h>
74 #include <net-snmp/net-snmp-includes.h>
76 oid objid_sysDescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
77 size_t length_sysDescr = sizeof(objid_sysDescr) / sizeof(oid);
78 oid objid_sysUpTime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
79 size_t length_sysUpTime = sizeof(objid_sysUpTime) / sizeof(oid);
80 oid objid_ifOperStatus[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 8 };
81 size_t length_ifOperStatus =
82 sizeof(objid_ifOperStatus) / sizeof(oid);
83 oid objid_ifInUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 11 };
84 size_t length_ifInUCastPkts =
85 sizeof(objid_ifInUCastPkts) / sizeof(oid);
86 oid objid_ifInNUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 12 };
87 size_t length_ifInNUCastPkts =
88 sizeof(objid_ifInNUCastPkts) / sizeof(oid);
89 oid objid_ifOutUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 17 };
90 size_t length_ifOutUCastPkts =
91 sizeof(objid_ifOutUCastPkts) / sizeof(oid);
92 oid objid_ifOutNUCastPkts[] =
93 { 1, 3, 6, 1, 2, 1, 2, 2, 1, 18 };
94 size_t length_ifOutNUCastPkts =
95 sizeof(objid_ifOutNUCastPkts) / sizeof(oid);
96 oid objid_ipInReceives[] = { 1, 3, 6, 1, 2, 1, 4, 3, 0 };
97 size_t length_ipInReceives =
98 sizeof(objid_ipInReceives) / sizeof(oid);
99 oid objid_ipOutRequests[] = { 1, 3, 6, 1, 2, 1, 4, 10, 0 };
100 size_t length_ipOutRequests =
101 sizeof(objid_ipOutRequests) / sizeof(oid);
103 #define NETSNMP_DS_APP_DONT_FIX_PDUS 0
105 static void
106 optProc(int argc, char *const *argv, int opt)
108 switch (opt) {
109 case 'C':
110 while (*optarg) {
111 switch (*optarg++) {
112 case 'f':
113 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
114 NETSNMP_DS_APP_DONT_FIX_PDUS);
115 break;
116 default:
117 fprintf(stderr, "Unknown flag passed to -C: %c\n",
118 optarg[-1]);
119 exit(1);
122 break;
126 void
127 usage(void)
129 fprintf(stderr, "USAGE: snmpstatus ");
130 snmp_parse_args_usage(stderr);
131 fprintf(stderr, "\n\n");
132 snmp_parse_args_descriptions(stderr);
133 fprintf(stderr,
134 " -C APPOPTS\t\tSet various application specific behaviours:\n");
135 fprintf(stderr,
136 "\t\t\t f: do not fix errors and retry the request\n");
141 main(int argc, char *argv[])
143 netsnmp_session session, *ss;
144 netsnmp_pdu *pdu, *response;
145 netsnmp_variable_list *vars;
146 netsnmp_transport *transport = NULL;
147 char *sysdescr = NULL;
148 u_long uptime = 0;
149 int status;
150 int ipin = 0, ipout = 0, ipackets = 0, opackets = 0;
151 int good_var;
152 int down_interfaces = 0;
153 char buf[40];
154 int interfaces;
155 int count;
156 int exitval = 0;
159 * get the common command line arguments
161 switch (snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
162 case -2:
163 exit(0);
164 case -1:
165 usage();
166 exit(1);
167 default:
168 break;
171 SOCK_STARTUP;
174 * open an SNMP session
176 ss = snmp_open(&session);
177 if (ss == NULL) {
179 * diagnose snmp_open errors with the input netsnmp_session pointer
181 snmp_sess_perror("snmpstatus", &session);
182 SOCK_CLEANUP;
183 exit(1);
187 * create PDU for GET request and add object names to request
189 pdu = snmp_pdu_create(SNMP_MSG_GET);
190 snmp_add_null_var(pdu, objid_sysDescr, length_sysDescr);
191 snmp_add_null_var(pdu, objid_sysUpTime, length_sysUpTime);
192 snmp_add_null_var(pdu, objid_ipInReceives, length_ipInReceives);
193 snmp_add_null_var(pdu, objid_ipOutRequests, length_ipOutRequests);
196 * do the request
198 retry:
199 status = snmp_synch_response(ss, pdu, &response);
200 if (status == STAT_SUCCESS) {
201 if (response->errstat == SNMP_ERR_NOERROR) {
202 for (vars = response->variables; vars;
203 vars = vars->next_variable) {
204 if (vars->name_length == length_sysDescr
205 && !memcmp(objid_sysDescr, vars->name,
206 sizeof(objid_sysDescr))) {
207 sysdescr = (char *) malloc(vars->val_len + 1);
208 memcpy(sysdescr, vars->val.string, vars->val_len);
209 sysdescr[vars->val_len] = '\0';
211 if (vars->name_length == length_sysUpTime &&
212 !memcmp(objid_sysUpTime, vars->name,
213 sizeof(objid_sysUpTime))) {
214 uptime = *vars->val.integer;
216 if (vars->name_length == length_ipInReceives &&
217 !memcmp(objid_ipInReceives, vars->name,
218 sizeof(objid_ipInReceives))) {
219 ipin = *vars->val.integer;
221 if (vars->name_length == length_ipOutRequests &&
222 !memcmp(objid_ipOutRequests, vars->name,
223 sizeof(objid_ipOutRequests))) {
224 ipout = *vars->val.integer;
227 } else {
228 fprintf(stderr, "Error in packet.\nReason: %s\n",
229 snmp_errstring(response->errstat));
230 if (response->errindex != 0) {
231 fprintf(stderr, "Failed object: ");
232 for (count = 1, vars = response->variables;
233 vars && count != response->errindex;
234 vars = vars->next_variable, count++);
235 if (vars)
236 fprint_objid(stderr, vars->name, vars->name_length);
237 fprintf(stderr, "\n");
241 * retry if the errored variable was successfully removed
243 if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
244 NETSNMP_DS_APP_DONT_FIX_PDUS)) {
245 pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
246 snmp_free_pdu(response);
247 response = NULL;
248 if (pdu != NULL)
249 goto retry;
252 } else if (status == STAT_TIMEOUT) {
253 fprintf(stderr, "Timeout: No Response from %s\n",
254 session.peername);
255 SOCK_CLEANUP;
256 exit(1);
257 } else { /* status == STAT_ERROR */
258 snmp_sess_perror("snmpstatus", ss);
259 SOCK_CLEANUP;
260 exit(2);
263 transport = snmp_sess_transport(snmp_sess_pointer(ss));
264 if (transport != NULL && transport->f_fmtaddr != NULL) {
265 char *s = transport->f_fmtaddr(transport,
266 response->transport_data,
267 response->
268 transport_data_length);
269 printf("[%s]=>[%s] Up: %s\n", s, sysdescr,
270 uptime_string(uptime, buf));
271 } else {
272 printf("[<UNKNOWN>]=>[%s] Up: %s\n", sysdescr,
273 uptime_string(uptime, buf));
276 if (response)
277 snmp_free_pdu(response);
280 * create PDU for GET request and add object names to request
282 pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
283 snmp_add_null_var(pdu, objid_ifOperStatus, length_ifOperStatus);
284 snmp_add_null_var(pdu, objid_ifInUCastPkts, length_ifInUCastPkts);
285 snmp_add_null_var(pdu, objid_ifInNUCastPkts, length_ifInNUCastPkts);
286 snmp_add_null_var(pdu, objid_ifOutUCastPkts, length_ifOutUCastPkts);
287 snmp_add_null_var(pdu, objid_ifOutNUCastPkts, length_ifOutNUCastPkts);
290 * ?? note: this code is not quite complete
292 good_var = 5;
293 interfaces = 0;
294 while (good_var == 5) {
295 good_var = 0;
296 status = snmp_synch_response(ss, pdu, &response);
297 if (status == STAT_SUCCESS) {
298 if (response->errstat == SNMP_ERR_NOERROR) {
299 pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
300 for (vars = response->variables; vars;
301 vars = vars->next_variable) {
302 if (vars->name_length >= length_ifOperStatus
303 && !memcmp(objid_ifOperStatus, vars->name,
304 sizeof(objid_ifOperStatus))) {
305 if (*vars->val.integer != MIB_IFSTATUS_UP)
306 down_interfaces++;
307 snmp_add_null_var(pdu, vars->name,
308 vars->name_length);
309 good_var++;
310 } else if (vars->name_length >= length_ifInUCastPkts &&
311 !memcmp(objid_ifInUCastPkts, vars->name,
312 sizeof(objid_ifInUCastPkts))) {
313 ipackets += *vars->val.integer;
314 snmp_add_null_var(pdu, vars->name,
315 vars->name_length);
316 good_var++;
317 } else if (vars->name_length >= length_ifInNUCastPkts
318 && !memcmp(objid_ifInNUCastPkts, vars->name,
319 sizeof(objid_ifInNUCastPkts))) {
320 ipackets += *vars->val.integer;
321 snmp_add_null_var(pdu, vars->name,
322 vars->name_length);
323 good_var++;
324 } else if (vars->name_length >= length_ifOutUCastPkts
325 && !memcmp(objid_ifOutUCastPkts, vars->name,
326 sizeof(objid_ifOutUCastPkts))) {
327 opackets += *vars->val.integer;
328 snmp_add_null_var(pdu, vars->name,
329 vars->name_length);
330 good_var++;
331 } else if (vars->name_length >= length_ifOutNUCastPkts
332 && !memcmp(objid_ifOutNUCastPkts,
333 vars->name,
334 sizeof(objid_ifOutNUCastPkts))) {
335 opackets += *vars->val.integer;
336 snmp_add_null_var(pdu, vars->name,
337 vars->name_length);
338 good_var++;
341 if (good_var == 5)
342 interfaces++;
343 } else {
344 fprintf(stderr, "Error in packet.\nReason: %s\n",
345 snmp_errstring(response->errstat));
346 if (response->errindex != 0) {
347 fprintf(stderr, "Failed object: ");
348 for (count = 1, vars = response->variables;
349 vars && count != response->errindex;
350 vars = vars->next_variable, count++);
351 if (vars)
352 fprint_objid(stderr, vars->name,
353 vars->name_length);
354 fprintf(stderr, "\n");
356 exitval = 2;
358 } else if (status == STAT_TIMEOUT) {
359 fprintf(stderr, "Timeout: No Response from %s\n",
360 session.peername);
361 exitval = 1;
362 } else { /* status == STAT_ERROR */
363 snmp_sess_perror("snmpstatus", ss);
364 exitval = 1;
367 if (response)
368 snmp_free_pdu(response);
370 printf("Interfaces: %d, Recv/Trans packets: %d/%d | IP: %d/%d\n",
371 interfaces, ipackets, opackets, ipin, ipout);
372 if (down_interfaces > 0) {
373 printf("%d interface%s down!\n",
374 down_interfaces, down_interfaces > 1 ? "s are" : " is");
377 snmp_close(ss);
378 SOCK_CLEANUP;
379 return exitval;