# BRCM_VERSION=3
[bcm963xx.git] / userapps / opensource / net-snmp / apps / snmpstatus.c
1 /*
2  * snmpstatus.c - send snmp GET requests to a network entity.
3  *
4  */
5 /***********************************************************************
6         Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
7
8                       All Rights Reserved
9
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.  
17
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>
27
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
71
72 #include <net-snmp/utilities.h>
73
74 #include <net-snmp/net-snmp-includes.h>
75
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);
102
103 #define NETSNMP_DS_APP_DONT_FIX_PDUS 0
104
105 static void
106 optProc(int argc, char *const *argv, int opt)
107 {
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);
120             }
121         }
122         break;
123     }
124 }
125
126 void
127 usage(void)
128 {
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");
137 }
138
139
140 int
141 main(int argc, char *argv[])
142 {
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;
157
158     /*
159      * get the common command line arguments 
160      */
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;
169     }
170
171     SOCK_STARTUP;
172
173     /*
174      * open an SNMP session 
175      */
176     ss = snmp_open(&session);
177     if (ss == NULL) {
178         /*
179          * diagnose snmp_open errors with the input netsnmp_session pointer 
180          */
181         snmp_sess_perror("snmpstatus", &session);
182         SOCK_CLEANUP;
183         exit(1);
184     }
185
186     /*
187      * create PDU for GET request and add object names to request 
188      */
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);
194
195     /*
196      * do the request 
197      */
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';
210                 }
211                 if (vars->name_length == length_sysUpTime &&
212                     !memcmp(objid_sysUpTime, vars->name,
213                             sizeof(objid_sysUpTime))) {
214                     uptime = *vars->val.integer;
215                 }
216                 if (vars->name_length == length_ipInReceives &&
217                     !memcmp(objid_ipInReceives, vars->name,
218                             sizeof(objid_ipInReceives))) {
219                     ipin = *vars->val.integer;
220                 }
221                 if (vars->name_length == length_ipOutRequests &&
222                     !memcmp(objid_ipOutRequests, vars->name,
223                             sizeof(objid_ipOutRequests))) {
224                     ipout = *vars->val.integer;
225                 }
226             }
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");
238             }
239
240             /*
241              * retry if the errored variable was successfully removed 
242              */
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;
250             }
251         }
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);
261     }
262
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));
274     }
275
276     if (response)
277         snmp_free_pdu(response);
278
279     /*
280      * create PDU for GET request and add object names to request 
281      */
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);
288
289     /*
290      * ?? note: this code is not quite complete 
291      */
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++;
339                     }
340                 }
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");
355                 }
356                 exitval = 2;
357             }
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;
365         }
366
367         if (response)
368             snmp_free_pdu(response);
369     }
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");
375     }
376
377     snmp_close(ss);
378     SOCK_CLEANUP;
379     return exitval;
380 }