dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / snmp / apps / snmpwalk.c
blob99e4d3305263e21f55cfdef76f211bd62a0956cf
1 /*
2 * snmpwalk.c - send snmp GETNEXT requests to a network entity, walking a
3 * subtree.
5 */
6 /**********************************************************************
7 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
9 All Rights Reserved
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
25 SOFTWARE.
26 ******************************************************************/
27 #include <net-snmp/net-snmp-config.h>
29 #if HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #if HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #if HAVE_STRING_H
36 #include <string.h>
37 #else
38 #include <strings.h>
39 #endif
40 #include <sys/types.h>
41 #if HAVE_NETINET_IN_H
42 # include <netinet/in.h>
43 #endif
44 #if TIME_WITH_SYS_TIME
45 # ifdef WIN32
46 # include <sys/timeb.h>
47 # else
48 # include <sys/time.h>
49 # endif
50 # include <time.h>
51 #else
52 # if HAVE_SYS_TIME_H
53 # include <sys/time.h>
54 # else
55 # include <time.h>
56 # endif
57 #endif
58 #if HAVE_SYS_SELECT_H
59 #include <sys/select.h>
60 #endif
61 #include <stdio.h>
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/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 };
79 int numprinted = 0;
81 void
82 usage(void)
84 fprintf(stderr, "USAGE: snmpwalk ");
85 snmp_parse_args_usage(stderr);
86 fprintf(stderr, " [OID]\n\n");
87 snmp_parse_args_descriptions(stderr);
88 fprintf(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");
92 fprintf(stderr,
93 "\t\t\t c: do not check returned OIDs are increasing\n");
96 void
97 snmp_get_and_print(netsnmp_session * ss, oid * theoid, size_t theoid_len)
99 netsnmp_pdu *pdu, *response;
100 netsnmp_variable_list *vars;
101 int status;
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) {
109 numprinted++;
110 print_variable(vars->name, vars->name_length, vars);
113 if (response) {
114 snmp_free_pdu(response);
118 static void
119 optProc(int argc, char *const *argv, int opt)
121 switch (opt) {
122 case 'C':
123 while (*optarg) {
124 switch (*optarg++) {
125 case 'i':
126 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
127 NETSNMP_DS_WALK_INCLUDE_REQUESTED);
128 break;
130 case 'p':
131 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
132 NETSNMP_DS_WALK_PRINT_STATISTICS);
133 break;
135 case 'c':
136 netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
137 NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
138 break;
139 default:
140 fprintf(stderr, "Unknown flag passed to -C: %c\n",
141 optarg[-1]);
142 exit(1);
145 break;
150 main(int argc, char *argv[])
152 netsnmp_session session, *ss;
153 netsnmp_pdu *pdu, *response;
154 netsnmp_variable_list *vars;
155 int arg;
156 oid name[MAX_OID_LEN];
157 size_t name_length;
158 oid root[MAX_OID_LEN];
159 size_t rootlen;
160 int count;
161 int running;
162 int status;
163 int check;
164 int exitval = 0;
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)) {
182 case -2:
183 exit(0);
184 case -1:
185 usage();
186 exit(1);
187 default:
188 break;
192 * get the initial object and subtree
194 if (arg < argc) {
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]);
201 exit(1);
203 } else {
205 * use default value
207 memmove(root, objid_mib, sizeof(objid_mib));
208 rootlen = sizeof(objid_mib) / sizeof(oid);
211 SOCK_STARTUP;
214 * open an SNMP session
216 ss = snmp_open(&session);
217 if (ss == NULL) {
219 * diagnose snmp_open errors with the input netsnmp_session pointer
221 snmp_sess_perror("snmpwalk", &session);
222 SOCK_CLEANUP;
223 exit(1);
227 * get first object to start walk
229 memmove(name, root, rootlen * sizeof(oid));
230 name_length = rootlen;
232 running = 1;
234 check =
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);
241 while (running) {
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);
249 * do the request
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))
261 != 0)) {
263 * not part of this subtree
265 running = 0;
266 continue;
268 numprinted++;
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
276 if (check
277 && snmp_oid_compare(name, name_length,
278 vars->name,
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,
284 vars->name_length);
285 fprintf(stderr, "\n");
286 running = 0;
287 exitval = 1;
289 memmove((char *) name, (char *) vars->name,
290 vars->name_length * sizeof(oid));
291 name_length = vars->name_length;
292 } else
294 * an exception value, so stop
296 running = 0;
298 } else {
300 * error in response, print it
302 running = 0;
303 if (response->errstat == SNMP_ERR_NOSUCHNAME) {
304 printf("End of MIB\n");
305 } else {
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++)
313 /*EMPTY*/;
314 if (vars)
315 fprint_objid(stderr, vars->name,
316 vars->name_length);
317 fprintf(stderr, "\n");
319 exitval = 2;
322 } else if (status == STAT_TIMEOUT) {
323 fprintf(stderr, "Timeout: No Response from %s\n",
324 session.peername);
325 running = 0;
326 exitval = 1;
327 } else { /* status == STAT_ERROR */
328 snmp_sess_perror("snmpwalk", ss);
329 running = 0;
330 exitval = 1;
332 if (response)
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
340 * for get measure.
342 snmp_get_and_print(ss, root, rootlen);
344 snmp_close(ss);
346 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_PRINT_STATISTICS)) {
347 printf("Variables found: %d\n", numprinted);
350 SOCK_CLEANUP;
351 return exitval;