2 * snmpwalk.c - send snmp GETNEXT requests to a network entity, walking a
6 /**********************************************************************
7 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
11 Permission to use, copy, modify, and distribute this software and its
12 documentation for any purpose and without fee is hereby granted,
13 provided that the above copyright notice appear in all copies and that
14 both that copyright notice and this permission notice appear in
15 supporting documentation, and that the name of CMU not be
16 used in advertising or publicity pertaining to distribution of the
17 software without specific, written prior permission.
19 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
20 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
21 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 ******************************************************************/
27 #include <net-snmp/net-snmp-config.h>
40 #include <sys/types.h>
42 # include <netinet/in.h>
44 #if TIME_WITH_SYS_TIME
46 # include <sys/timeb.h>
48 # include <sys/time.h>
53 # include <sys/time.h>
59 #include <sys/select.h>
69 #include <arpa/inet.h>
72 #include <net-snmp/net-snmp-includes.h>
74 #define NETSNMP_DS_WALK_INCLUDE_REQUESTED 1
75 #define NETSNMP_DS_WALK_PRINT_STATISTICS 2
76 #define NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC 3
78 oid objid_mib
[] = { 1, 3, 6, 1, 2, 1 };
84 fprintf(stderr
, "USAGE: snmpwalk ");
85 snmp_parse_args_usage(stderr
);
86 fprintf(stderr
, " [OID]\n\n");
87 snmp_parse_args_descriptions(stderr
);
89 " -C APPOPTS\t\tSet various application specific behaviours:\n");
90 fprintf(stderr
, "\t\t\t p: print the number of variables found\n");
91 fprintf(stderr
, "\t\t\t i: include given OID in the search range\n");
93 "\t\t\t c: do not check returned OIDs are increasing\n");
97 snmp_get_and_print(netsnmp_session
* ss
, oid
* theoid
, size_t theoid_len
)
99 netsnmp_pdu
*pdu
, *response
;
100 netsnmp_variable_list
*vars
;
103 pdu
= snmp_pdu_create(SNMP_MSG_GET
);
104 snmp_add_null_var(pdu
, theoid
, theoid_len
);
106 status
= snmp_synch_response(ss
, pdu
, &response
);
107 if (status
== STAT_SUCCESS
&& response
->errstat
== SNMP_ERR_NOERROR
) {
108 for (vars
= response
->variables
; vars
; vars
= vars
->next_variable
) {
110 print_variable(vars
->name
, vars
->name_length
, vars
);
114 snmp_free_pdu(response
);
119 optProc(int argc
, char *const *argv
, int opt
)
126 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID
,
127 NETSNMP_DS_WALK_INCLUDE_REQUESTED
);
131 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID
,
132 NETSNMP_DS_WALK_PRINT_STATISTICS
);
136 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID
,
137 NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC
);
140 fprintf(stderr
, "Unknown flag passed to -C: %c\n",
150 main(int argc
, char *argv
[])
152 netsnmp_session session
, *ss
;
153 netsnmp_pdu
*pdu
, *response
;
154 netsnmp_variable_list
*vars
;
156 oid name
[MAX_OID_LEN
];
158 oid root
[MAX_OID_LEN
];
166 netsnmp_ds_register_config(ASN_BOOLEAN
, "snmpwalk", "includeRequested",
167 NETSNMP_DS_APPLICATION_ID
,
168 NETSNMP_DS_WALK_INCLUDE_REQUESTED
);
170 netsnmp_ds_register_config(ASN_BOOLEAN
, "snmpwalk", "printStatistics",
171 NETSNMP_DS_APPLICATION_ID
,
172 NETSNMP_DS_WALK_PRINT_STATISTICS
);
174 netsnmp_ds_register_config(ASN_BOOLEAN
, "snmpwalk", "dontCheckOrdering",
175 NETSNMP_DS_APPLICATION_ID
,
176 NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC
);
179 * get the common command line arguments
181 switch (arg
= snmp_parse_args(argc
, argv
, &session
, "C:", optProc
)) {
192 * get the initial object and subtree
196 * specified on the command line
198 rootlen
= MAX_OID_LEN
;
199 if (snmp_parse_oid(argv
[arg
], root
, &rootlen
) == NULL
) {
200 snmp_perror(argv
[arg
]);
207 memmove(root
, objid_mib
, sizeof(objid_mib
));
208 rootlen
= sizeof(objid_mib
) / sizeof(oid
);
214 * open an SNMP session
216 ss
= snmp_open(&session
);
219 * diagnose snmp_open errors with the input netsnmp_session pointer
221 snmp_sess_perror("snmpwalk", &session
);
227 * get first object to start walk
229 memmove(name
, root
, rootlen
* sizeof(oid
));
230 name_length
= rootlen
;
235 !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID
,
236 NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC
);
237 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID
, NETSNMP_DS_WALK_INCLUDE_REQUESTED
)) {
238 snmp_get_and_print(ss
, root
, rootlen
);
243 * create PDU for GETNEXT request and add object name to request
245 pdu
= snmp_pdu_create(SNMP_MSG_GETNEXT
);
246 snmp_add_null_var(pdu
, name
, name_length
);
251 status
= snmp_synch_response(ss
, pdu
, &response
);
252 if (status
== STAT_SUCCESS
) {
253 if (response
->errstat
== SNMP_ERR_NOERROR
) {
255 * check resulting variables
257 for (vars
= response
->variables
; vars
;
258 vars
= vars
->next_variable
) {
259 if ((vars
->name_length
< rootlen
)
260 || (memcmp(root
, vars
->name
, rootlen
* sizeof(oid
))
263 * not part of this subtree
269 print_variable(vars
->name
, vars
->name_length
, vars
);
270 if ((vars
->type
!= SNMP_ENDOFMIBVIEW
) &&
271 (vars
->type
!= SNMP_NOSUCHOBJECT
) &&
272 (vars
->type
!= SNMP_NOSUCHINSTANCE
)) {
274 * not an exception value
277 && snmp_oid_compare(name
, name_length
,
279 vars
->name_length
) >= 0) {
280 fprintf(stderr
, "Error: OID not increasing: ");
281 fprint_objid(stderr
, name
, name_length
);
282 fprintf(stderr
, " >= ");
283 fprint_objid(stderr
, vars
->name
,
285 fprintf(stderr
, "\n");
289 memmove((char *) name
, (char *) vars
->name
,
290 vars
->name_length
* sizeof(oid
));
291 name_length
= vars
->name_length
;
294 * an exception value, so stop
300 * error in response, print it
303 if (response
->errstat
== SNMP_ERR_NOSUCHNAME
) {
304 printf("End of MIB\n");
306 fprintf(stderr
, "Error in packet.\nReason: %s\n",
307 snmp_errstring(response
->errstat
));
308 if (response
->errindex
!= 0) {
309 fprintf(stderr
, "Failed object: ");
310 for (count
= 1, vars
= response
->variables
;
311 vars
&& count
!= response
->errindex
;
312 vars
= vars
->next_variable
, count
++)
315 fprint_objid(stderr
, vars
->name
,
317 fprintf(stderr
, "\n");
322 } else if (status
== STAT_TIMEOUT
) {
323 fprintf(stderr
, "Timeout: No Response from %s\n",
327 } else { /* status == STAT_ERROR */
328 snmp_sess_perror("snmpwalk", ss
);
333 snmp_free_pdu(response
);
336 if (numprinted
== 0 && status
== STAT_SUCCESS
) {
338 * no printed successful results, which may mean we were
339 * pointed at an only existing instance. Attempt a GET, just
342 snmp_get_and_print(ss
, root
, rootlen
);
346 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID
, NETSNMP_DS_WALK_PRINT_STATISTICS
)) {
347 printf("Variables found: %d\n", numprinted
);