2 * snmpstatus.c - send snmp GET requests to a network entity.
5 /***********************************************************************
6 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
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
25 ******************************************************************/
26 #include <net-snmp/net-snmp-config.h>
39 #include <sys/types.h>
41 #include <netinet/in.h>
45 #if TIME_WITH_SYS_TIME
47 # include <sys/timeb.h>
49 # include <sys/time.h>
54 # include <sys/time.h>
60 #include <sys/select.h>
69 #include <arpa/inet.h>
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
106 optProc(int argc
, char *const *argv
, int opt
)
113 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID
,
114 NETSNMP_DS_APP_DONT_FIX_PDUS
);
117 fprintf(stderr
, "Unknown flag passed to -C: %c\n",
129 fprintf(stderr
, "USAGE: snmpstatus ");
130 snmp_parse_args_usage(stderr
);
131 fprintf(stderr
, "\n\n");
132 snmp_parse_args_descriptions(stderr
);
134 " -C APPOPTS\t\tSet various application specific behaviours:\n");
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
;
150 int ipin
= 0, ipout
= 0, ipackets
= 0, opackets
= 0;
152 int down_interfaces
= 0;
159 * get the common command line arguments
161 switch (snmp_parse_args(argc
, argv
, &session
, "C:", &optProc
)) {
174 * open an SNMP session
176 ss
= snmp_open(&session
);
179 * diagnose snmp_open errors with the input netsnmp_session pointer
181 snmp_sess_perror("snmpstatus", &session
);
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
);
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
;
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
++);
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
);
252 } else if (status
== STAT_TIMEOUT
) {
253 fprintf(stderr
, "Timeout: No Response from %s\n",
257 } else { /* status == STAT_ERROR */
258 snmp_sess_perror("snmpstatus", ss
);
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
,
268 transport_data_length
);
269 printf("[%s]=>[%s] Up: %s\n", s
, sysdescr
,
270 uptime_string(uptime
, buf
));
272 printf("[<UNKNOWN>]=>[%s] Up: %s\n", sysdescr
,
273 uptime_string(uptime
, buf
));
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
294 while (good_var
== 5) {
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
)
307 snmp_add_null_var(pdu
, vars
->name
,
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
,
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
,
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
,
331 } else if (vars
->name_length
>= length_ifOutNUCastPkts
332 && !memcmp(objid_ifOutNUCastPkts
,
334 sizeof(objid_ifOutNUCastPkts
))) {
335 opackets
+= *vars
->val
.integer
;
336 snmp_add_null_var(pdu
, vars
->name
,
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
++);
352 fprint_objid(stderr
, vars
->name
,
354 fprintf(stderr
, "\n");
358 } else if (status
== STAT_TIMEOUT
) {
359 fprintf(stderr
, "Timeout: No Response from %s\n",
362 } else { /* status == STAT_ERROR */
363 snmp_sess_perror("snmpstatus", ss
);
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");