1 /*
2  *  ICMP MIB group implementation - icmp.c
3  */
4 
5 #include <net-snmp/net-snmp-config.h>
6 #include "mibII_common.h"
7 
8 #if HAVE_NETINET_IP_ICMP_H
9 #include <netinet/ip_icmp.h>
10 #endif
11 
12 #ifdef NETSNMP_ENABLE_IPV6
13 #if HAVE_NETINET_ICMP6_H
14 #include <netinet/icmp6.h>
15 #endif
16 #endif /* NETSNMP_ENABLE_IPV6 */
17 
18 #if HAVE_NETINET_ICMP_VAR_H
19 #include <netinet/icmp_var.h>
20 #endif
21 
22 #include <net-snmp/net-snmp-includes.h>
23 #include <net-snmp/agent/net-snmp-agent-includes.h>
24 #include <net-snmp/agent/auto_nlist.h>
25 
26 #include <net-snmp/agent/cache_handler.h>
27 #include <net-snmp/agent/scalar_group.h>
28 #include <net-snmp/agent/sysORTable.h>
29 
30 #include "util_funcs/MIB_STATS_CACHE_TIMEOUT.h"
31 #include "icmp.h"
32 #include "ip.h"
33 
34 #ifndef MIB_STATS_CACHE_TIMEOUT
35 #define MIB_STATS_CACHE_TIMEOUT	5
36 #endif
37 #ifndef ICMP_STATS_CACHE_TIMEOUT
38 #define ICMP_STATS_CACHE_TIMEOUT	MIB_STATS_CACHE_TIMEOUT
39 #endif
40 
41 /* redefine ICMP6 message types from glibc < 2.4 to newer names */
42 #ifndef MLD_LISTENER_QUERY
43 #define MLD_LISTENER_QUERY ICMP6_MEMBERSHIP_QUERY
44 #define MLD_LISTENER_REPORT ICMP6_MEMBERSHIP_REPORT
45 #define MLD_LISTENER_REDUCTION ICMP6_MEMBERSHIP_REDUCTION
46 #endif /* ICMP6_MEMBERSHIP_QUERY */
47 
48 
49 #if defined(HAVE_LIBPERFSTAT_H) && (defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) && !defined(FIRST_PROTOCOL)
50 #ifdef HAVE_SYS_PROTOSW_H
51 #include <sys/protosw.h>
52 #endif
53 #include <libperfstat.h>
54 #ifdef FIRST_PROTOCOL
55 perfstat_protocol_t ps_proto;
56 perfstat_id_t ps_name;
57 #define _USE_PERFSTAT_PROTOCOL 1
58 #endif
59 #endif
60 
61         /*********************
62 	 *
63 	 *  Kernel & interface information,
64 	 *   and internal forward declarations
65 	 *
66 	 *********************/
67 
68         /*********************
69 	 *
70 	 *  Initialisation & common implementation functions
71 	 *
72 	 *********************/
73 
74 
75 #ifdef hpux11
76 #define ICMP_STAT_STRUCTURE	int
77 #endif
78 
79 #ifdef linux
80 #define ICMP_STAT_STRUCTURE	struct icmp_mib
81 #define USES_SNMP_DESIGNED_ICMPSTAT
82 #undef ICMPSTAT_SYMBOL
83 #endif
84 
85 #ifdef solaris2
86 #define USES_SNMP_DESIGNED_ICMPSTAT
87 #define ICMP_STAT_STRUCTURE	mib2_icmp_t
88 #include "kernel_mib.h"
89 static int
90 solaris_read_icmp_stat(ICMP_STAT_STRUCTURE *);
91 static int
92 solaris_read_icmp_msg_stat(ICMP_STAT_STRUCTURE *, struct icmp4_msg_mib *, int *);
93 #ifdef NETSNMP_ENABLE_IPV6
94 static int
95 solaris_read_icmp6_stat(struct icmp6_mib *);
96 static int
97 solaris_read_icmp6_msg_stat(struct icmp6_mib *, struct icmp6_msg_mib *, int *);
98 #endif
99 #endif
100 
101 #ifdef NETBSD_STATS_VIA_SYSCTL
102 #define ICMP_STAT_STRUCTURE     struct icmp_mib
103 #define USES_SNMP_DESIGNED_ICMPSTAT
104 #undef ICMP_NSTATS
105 #endif
106 
107 #ifdef HAVE_IPHLPAPI_H
108 #include <iphlpapi.h>
109 #define ICMP_STAT_STRUCTURE MIB_ICMP
110 #endif
111 
112 #if (defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS))
113 #define ICMP_STAT_STRUCTURE	struct icmp_mib
114 #define USES_SNMP_DESIGNED_ICMPSTAT
115 #undef ICMPSTAT_SYMBOL
116 #endif
117 
118 #ifdef HAVE_SYS_ICMPIPSTATS_H
119 /* or #ifdef		HAVE_SYS_TCPIPSTATS_H  ??? */
120 #define ICMP_STAT_STRUCTURE	struct kna
121 #define USES_TRADITIONAL_ICMPSTAT
122 #endif
123 
124 #if !defined(ICMP_STAT_STRUCTURE)
125 #define ICMP_STAT_STRUCTURE	struct icmpstat
126 #define USES_TRADITIONAL_ICMPSTAT
127 #endif
128 
129 ICMP_STAT_STRUCTURE icmpstat;
130 #if defined(solaris2) && defined(NETSNMP_ENABLE_IPV6)
131 static struct icmp6_mib icmp6stat;
132 #endif
133 
134 /* If they just all agreed ... */
135 
136 #ifndef ICMP_DEST_UNREACH
137 #define ICMP_DEST_UNREACH ICMP_UNREACH
138 #endif
139 #ifndef ICMP_SOURCE_QUENCH
140 #define ICMP_SOURCE_QUENCH ICMP_SOURCEQUENCH
141 #endif
142 #ifndef ICMP_TIME_EXCEEDED
143 #define ICMP_TIME_EXCEEDED ICMP_TIMXCEED
144 #endif
145 #ifndef ICMP_PARAMETERPROB
146 #define ICMP_PARAMETERPROB ICMP_PARAMPROB
147 #endif
148 #ifndef ICMP_TIMESTAMP
149 #define ICMP_TIMESTAMP ICMP_TSTAMP
150 #endif
151 #ifndef ICMP_TIMESTAMPREPLY
152 #define ICMP_TIMESTAMPREPLY ICMP_TSTAMPREPLY
153 #endif
154 #ifndef ICMP_ADDRESS
155 #define ICMP_ADDRESS ICMP_MASKREQ
156 #endif
157 #ifndef ICMP_ADDRESSREPLY
158 #define ICMP_ADDRESSREPLY ICMP_MASKREPLY
159 #endif
160 #ifndef MLD_LISTENER_REDUCTION
161 #define MLD_LISTENER_REDUCTION MLD_LISTENER_DONE
162 #endif
163 
164 /*
165  * Define the OID pointer to the top of the mib tree that we're
166  * registering underneath
167  */
168 static const oid icmp_oid[] = { SNMP_OID_MIB2, 5 };
169 static const oid icmp_stats_tbl_oid[] = { SNMP_OID_MIB2, 5, 29 };
170 static const oid icmp_msg_stats_tbl_oid[] = { SNMP_OID_MIB2, 5, 30 };
171 
172 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
173 struct icmp_stats_table_entry {
174 	uint32_t ipVer;
175         uint32_t icmpStatsInMsgs;
176         uint32_t icmpStatsInErrors;
177         uint32_t icmpStatsOutMsgs;
178         uint32_t icmpStatsOutErrors;
179 };
180 
181 struct icmp_stats_table_entry icmp_stats_table[2];
182 
183 #define ICMP_MSG_STATS_HAS_IN 1
184 #define ICMP_MSG_STATS_HAS_OUT 2
185 
186 struct icmp_msg_stats_table_entry {
187         uint32_t ipVer;
188         uint32_t icmpMsgStatsType;
189         uint32_t icmpMsgStatsInPkts;
190         uint32_t icmpMsgStatsOutPkts;
191         int flags;
192 };
193 
194 #ifdef linux
195 /* Linux keeps track of all possible message types */
196 #define ICMP_MSG_STATS_IPV4_COUNT 256
197 #else
198 #define ICMP_MSG_STATS_IPV4_COUNT 11
199 #endif
200 
201 #ifdef NETSNMP_ENABLE_IPV6
202 #ifdef linux
203 /* Linux keeps track of all possible message types */
204 #define ICMP_MSG_STATS_IPV6_COUNT 256
205 #else
206 #define ICMP_MSG_STATS_IPV6_COUNT 14
207 #endif
208 #else
209 #define ICMP_MSG_STATS_IPV6_COUNT 0
210 #endif /* NETSNMP_ENABLE_IPV6 */
211 
212 struct icmp_msg_stats_table_entry icmp_msg_stats_table[ICMP_MSG_STATS_IPV4_COUNT + ICMP_MSG_STATS_IPV6_COUNT];
213 
214 int
icmp_stats_load(netsnmp_cache * cache,void * vmagic)215 icmp_stats_load(netsnmp_cache *cache, void *vmagic)
216 {
217 
218     /*
219      * note don't bother using the passed in cache
220      * and vmagic pointers.  They are useless as they
221      * currently point to the icmp system stats cache
222      * since I see little point in registering another
223      * cache for this table.  Its not really needed
224      */
225 
226     int i;
227     ICMP_STAT_STRUCTURE v4icmp;
228 #ifdef NETSNMP_ENABLE_IPV6
229     struct icmp6_mib v6icmp;
230 #endif
231     for(i = 0; i < 2; i++) {
232         switch(i) {
233         case 0:
234 #ifdef linux
235             linux_read_icmp_stat(&v4icmp);
236 #elif defined(NETBSD_STATS_VIA_SYSCTL)
237 	    netbsd_read_icmp_stat(&v4icmp);
238 #elif (defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS))
239 	    sysctl_read_icmp_stat(&v4icmp);
240 #elif defined(solaris2)
241 	    solaris_read_icmp_stat(&v4icmp);
242 #else
243 	    return -1;
244 #endif
245             icmp_stats_table[i].icmpStatsInMsgs = v4icmp.icmpInMsgs;
246             icmp_stats_table[i].icmpStatsInErrors = v4icmp.icmpInErrors;
247             icmp_stats_table[i].icmpStatsOutMsgs = v4icmp.icmpOutMsgs;
248             icmp_stats_table[i].icmpStatsOutErrors = v4icmp.icmpOutErrors;
249             break;
250         case 1:
251 #ifdef NETSNMP_ENABLE_IPV6
252             memset(&icmp_stats_table[i],0,
253                     sizeof(struct icmp_stats_table_entry));
254 #ifdef linux
255             linux_read_icmp6_stat(&v6icmp);
256 #elif defined(NETBSD_STATS_VIA_SYSCTL)
257 	    netbsd_read_icmp6_stat(&v6icmp);
258 #elif (defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS))
259 	    sysctl_read_icmp6_stat(&v6icmp);
260 #elif defined(solaris2)
261 	    solaris_read_icmp6_stat(&v6icmp);
262 #else
263 	    return -1;
264 #endif
265             icmp_stats_table[i].icmpStatsInMsgs = v6icmp.icmp6InMsgs;
266             icmp_stats_table[i].icmpStatsInErrors = v6icmp.icmp6InErrors;
267             icmp_stats_table[i].icmpStatsOutMsgs = v6icmp.icmp6OutMsgs;
268             icmp_stats_table[i].icmpStatsOutErrors =
269                         v6icmp.icmp6OutDestUnreachs +
270                         v6icmp.icmp6OutPktTooBigs +  v6icmp.icmp6OutTimeExcds +
271                         v6icmp.icmp6OutParmProblems;
272 #endif	/* NETSNMP_ENABLE_IPV6 */
273             break;
274         }
275         icmp_stats_table[i].ipVer = i + 1;
276     }
277 
278     return 0;
279 }
280 
281 int
icmp_msg_stats_load(netsnmp_cache * cache,void * vmagic)282 icmp_msg_stats_load(netsnmp_cache *cache, void *vmagic)
283 {
284     ICMP_STAT_STRUCTURE v4icmp;
285     struct icmp4_msg_mib v4icmpmsg;
286 #ifdef NETSNMP_ENABLE_IPV6
287     struct icmp6_mib v6icmp;
288     struct icmp6_msg_mib v6icmpmsg;
289 #endif
290     int i, k, flag, inc;
291 
292     memset(&icmp_msg_stats_table, 0, sizeof(icmp_msg_stats_table));
293 
294     i = 0;
295     flag = 0;
296     k = 0;
297     inc = 0;
298 #ifdef linux
299     linux_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag);
300 #elif defined(NETBSD_STATS_VIA_SYSCTL)
301     netbsd_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag);
302 #elif (defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS))
303     sysctl_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag);
304 #elif defined(solaris2)
305     solaris_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag);
306 #else
307     return -1;
308 #endif
309     if (flag) {
310         while (255 >= k) {
311             if (v4icmpmsg.vals[k].InType) {
312                 icmp_msg_stats_table[i].ipVer = 1;
313                 icmp_msg_stats_table[i].icmpMsgStatsType = k;
314                 icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmpmsg.vals[k].InType;
315                 icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_IN;
316                 inc = 1; /* Set this if we found a valid entry */
317             }
318             if (v4icmpmsg.vals[k].OutType) {
319                 icmp_msg_stats_table[i].ipVer = 1;
320                 icmp_msg_stats_table[i].icmpMsgStatsType = k;
321                 icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmpmsg.vals[k].OutType;
322                 icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_OUT;
323                 inc = 1; /* Set this if we found a valid entry */
324             }
325             if (inc) {
326                 i++;
327                 inc = 0;
328             }
329             k++;
330         }
331     } else {
332         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ECHOREPLY;
333         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInEchoReps;
334         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutEchoReps;
335         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
336         icmp_msg_stats_table[i].ipVer = 1;
337         i++;
338 
339         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_DEST_UNREACH;
340         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInDestUnreachs;
341         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutDestUnreachs;
342         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
343         icmp_msg_stats_table[i].ipVer = 1;
344         i++;
345 
346         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_SOURCE_QUENCH;
347         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInSrcQuenchs;
348         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutSrcQuenchs;
349         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
350         icmp_msg_stats_table[i].ipVer = 1;
351         i++;
352 
353         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_REDIRECT;
354         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInRedirects;
355         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutRedirects;
356         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
357         icmp_msg_stats_table[i].ipVer = 1;
358         i++;
359 
360         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ECHO;
361         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInEchos;
362         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutEchos;
363         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
364         icmp_msg_stats_table[i].ipVer = 1;
365         i++;
366 
367         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIME_EXCEEDED;
368         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimeExcds;
369         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimeExcds;
370         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
371         icmp_msg_stats_table[i].ipVer = 1;
372         i++;
373 
374         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_PARAMETERPROB;
375         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInParmProbs;
376         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutParmProbs;
377         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
378         icmp_msg_stats_table[i].ipVer = 1;
379         i++;
380 
381         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIMESTAMP;
382         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimestamps;
383         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimestamps;
384         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
385         icmp_msg_stats_table[i].ipVer = 1;
386         i++;
387 
388         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIMESTAMPREPLY;
389         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimestampReps;
390         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimestampReps;
391         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
392         icmp_msg_stats_table[i].ipVer = 1;
393         i++;
394 
395         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ADDRESS;
396         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInAddrMasks;
397         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutAddrMasks;
398         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
399         icmp_msg_stats_table[i].ipVer = 1;
400         i++;
401 
402         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ADDRESSREPLY;
403         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInAddrMaskReps;
404         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutAddrMaskReps;
405         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
406         icmp_msg_stats_table[i].ipVer = 1;
407         i++;
408     }
409 
410 #ifdef NETSNMP_ENABLE_IPV6
411     flag = 0;
412     k = 0;
413     inc = 0;
414 #ifdef linux
415     linux_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag);
416 #elif defined(NETBSD_STATS_VIA_SYSCTL)
417     netbsd_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag);
418 #elif (defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS))
419     sysctl_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag);
420 #elif defined(solaris2)
421     solaris_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag);
422 #else
423     return -1;
424 #endif
425     if (flag) {
426         while (255 >= k) {
427             if (v6icmpmsg.vals[k].InType) {
428                 icmp_msg_stats_table[i].ipVer = 2;
429                 icmp_msg_stats_table[i].icmpMsgStatsType = k;
430                 icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmpmsg.vals[k].InType;
431                 icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_IN;
432                 inc = 1; /* Set this if we found a valid entry */
433             }
434             if (v6icmpmsg.vals[k].OutType) {
435                 icmp_msg_stats_table[i].ipVer = 2;
436                 icmp_msg_stats_table[i].icmpMsgStatsType = k;
437                 icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmpmsg.vals[k].OutType;
438                 icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_OUT;
439                 inc = 1; /* Set this if we found a valid entry */
440             }
441             if (inc) {
442                 i++;
443                 inc = 0;
444             }
445             k++;
446         }
447     } else {
448         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_DST_UNREACH;
449         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InDestUnreachs;
450         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutDestUnreachs;
451         icmp_msg_stats_table[i].ipVer = 2;
452         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
453         i++;
454 
455         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_PACKET_TOO_BIG;
456         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InPktTooBigs;
457         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutPktTooBigs;
458         icmp_msg_stats_table[i].ipVer = 2;
459         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
460         i++;
461 
462         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_TIME_EXCEEDED;
463         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InTimeExcds;
464         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutTimeExcds;
465         icmp_msg_stats_table[i].ipVer = 2;
466         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
467         i++;
468 
469         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_PARAM_PROB;
470         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InParmProblems;
471         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutParmProblems;
472         icmp_msg_stats_table[i].ipVer = 2;
473         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
474         i++;
475 
476         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_ECHO_REQUEST;
477         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InEchos;
478         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutEchos;
479         icmp_msg_stats_table[i].ipVer = 2;
480         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
481         i++;
482 
483         icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_ECHO_REPLY;
484         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InEchoReplies;
485         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutEchoReplies;
486         icmp_msg_stats_table[i].ipVer = 2;
487         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
488         i++;
489 
490 #ifdef MLD_LISTENER_QUERY
491         icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_QUERY;
492         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembQueries;
493         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = 0;
494         icmp_msg_stats_table[i].ipVer = 2;
495         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN;
496         i++;
497 
498         icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_REPORT;
499         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembResponses;
500         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutGroupMembResponses;
501         icmp_msg_stats_table[i].ipVer = 2;
502         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
503         i++;
504 
505         icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_REDUCTION;
506         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembReductions;
507         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutGroupMembReductions;
508         icmp_msg_stats_table[i].ipVer = 2;
509         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
510         i++;
511 
512         icmp_msg_stats_table[i].icmpMsgStatsType = ND_ROUTER_SOLICIT;
513         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRouterSolicits;
514         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutRouterSolicits;
515         icmp_msg_stats_table[i].ipVer = 2;
516         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
517         i++;
518 
519         icmp_msg_stats_table[i].icmpMsgStatsType = ND_ROUTER_ADVERT;
520         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRouterAdvertisements;
521         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = 0;
522         icmp_msg_stats_table[i].ipVer = 2;
523         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN;
524         i++;
525 
526         icmp_msg_stats_table[i].icmpMsgStatsType = ND_NEIGHBOR_SOLICIT;
527         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InNeighborSolicits;
528         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutNeighborSolicits;
529         icmp_msg_stats_table[i].ipVer = 2;
530         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
531         i++;
532 
533         icmp_msg_stats_table[i].icmpMsgStatsType = ND_NEIGHBOR_ADVERT;
534         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InNeighborAdvertisements;
535         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutNeighborAdvertisements;
536         icmp_msg_stats_table[i].ipVer = 2;
537         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
538         i++;
539 
540         icmp_msg_stats_table[i].icmpMsgStatsType = ND_REDIRECT;
541         icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRedirects;
542         icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutRedirects;
543         icmp_msg_stats_table[i].ipVer = 2;
544         icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT;
545 #endif
546     }
547 #endif /* NETSNMP_ENABLE_IPV6 */
548     return 0;
549 }
550 
551 netsnmp_variable_list *
icmp_stats_next_entry(void ** loop_context,void ** data_context,netsnmp_variable_list * index,netsnmp_iterator_info * data)552 icmp_stats_next_entry( void **loop_context,
553                      void **data_context,
554                      netsnmp_variable_list *index,
555                      netsnmp_iterator_info *data)
556 {
557     int i = (int)(intptr_t)(*loop_context);
558     netsnmp_variable_list *idx = index;
559 
560     if(i > 1)
561         return NULL;
562 
563 
564     /*
565      *set IP version
566      */
567     snmp_set_var_typed_value(idx, ASN_INTEGER, (u_char *)&icmp_stats_table[i].ipVer,
568                             sizeof(uint32_t));
569     idx = idx->next_variable;
570 
571     *data_context = &icmp_stats_table[i];
572 
573     *loop_context = (void *)(intptr_t)(++i);
574 
575     return index;
576 }
577 
578 
579 netsnmp_variable_list *
icmp_stats_first_entry(void ** loop_context,void ** data_context,netsnmp_variable_list * index,netsnmp_iterator_info * data)580 icmp_stats_first_entry( void **loop_context,
581                      void **data_context,
582                      netsnmp_variable_list *index,
583                      netsnmp_iterator_info *data)
584 {
585     *loop_context = NULL;
586     *data_context = NULL;
587     return icmp_stats_next_entry(loop_context, data_context, index, data);
588 }
589 
590 netsnmp_variable_list *
icmp_msg_stats_next_entry(void ** loop_context,void ** data_context,netsnmp_variable_list * index,netsnmp_iterator_info * data)591 icmp_msg_stats_next_entry(void **loop_context,
592                           void **data_context,
593                           netsnmp_variable_list *index,
594                           netsnmp_iterator_info *data)
595 {
596     int i = (int)(intptr_t)(*loop_context);
597     netsnmp_variable_list *idx = index;
598 
599     if(i >= ICMP_MSG_STATS_IPV4_COUNT + ICMP_MSG_STATS_IPV6_COUNT)
600         return NULL;
601 
602     /* set IP version */
603     snmp_set_var_typed_value(idx, ASN_INTEGER,
604             (u_char *)&icmp_msg_stats_table[i].ipVer,
605             sizeof(uint32_t));
606 
607     /* set packet type */
608     idx = idx->next_variable;
609     snmp_set_var_typed_value(idx, ASN_INTEGER,
610             (u_char *)&icmp_msg_stats_table[i].icmpMsgStatsType,
611             sizeof(uint32_t));
612 
613     *data_context = &icmp_msg_stats_table[i];
614     *loop_context = (void *)(intptr_t)(++i);
615 
616     return index;
617 }
618 
619 
620 netsnmp_variable_list *
icmp_msg_stats_first_entry(void ** loop_context,void ** data_context,netsnmp_variable_list * index,netsnmp_iterator_info * data)621 icmp_msg_stats_first_entry(void **loop_context,
622                            void **data_context,
623                            netsnmp_variable_list *index,
624                            netsnmp_iterator_info *data)
625 {
626     *loop_context = NULL;
627     *data_context = NULL;
628     return icmp_msg_stats_next_entry(loop_context, data_context, index, data);
629 }
630 #endif
631 
632 void
init_icmp(void)633 init_icmp(void)
634 {
635 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
636     netsnmp_handler_registration *msg_stats_reginfo = NULL;
637     netsnmp_handler_registration *table_reginfo = NULL;
638     netsnmp_iterator_info *iinfo;
639     netsnmp_iterator_info *msg_stats_iinfo;
640     netsnmp_table_registration_info *table_info = NULL;
641     netsnmp_table_registration_info *msg_stats_table_info;
642 #endif
643     netsnmp_handler_registration *scalar_reginfo = NULL;
644     int                    rc;
645 
646     /*
647      * register ourselves with the agent as a group of scalars...
648      */
649     DEBUGMSGTL(("mibII/icmp", "Initialising ICMP group\n"));
650     scalar_reginfo = netsnmp_create_handler_registration("icmp", icmp_handler,
651 		    icmp_oid, OID_LENGTH(icmp_oid), HANDLER_CAN_RONLY);
652     rc = netsnmp_register_scalar_group(scalar_reginfo, ICMPINMSGS, ICMPOUTADDRMASKREPS);
653     if (rc != SNMPERR_SUCCESS)
654         return;
655     /*
656      * .... with a local cache
657      *    (except for HP-UX 11, which extracts objects individually)
658      */
659 #ifndef hpux11
660     rc = netsnmp_inject_handler( scalar_reginfo,
661 		    netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
662 			   		icmp_load, icmp_free,
663 					icmp_oid, OID_LENGTH(icmp_oid)));
664     if (rc != SNMPERR_SUCCESS)
665 	goto bail;
666 #endif
667 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
668 
669     /* register icmpStatsTable */
670     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
671     if (!table_info)
672         goto bail;
673     netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
674     table_info->min_column = ICMP_STAT_INMSG;
675     table_info->max_column = ICMP_STAT_OUTERR;
676 
677 
678     iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
679     if (!iinfo)
680         goto bail;
681     iinfo->get_first_data_point = icmp_stats_first_entry;
682     iinfo->get_next_data_point  = icmp_stats_next_entry;
683     iinfo->table_reginfo        = table_info;
684 
685     table_reginfo = netsnmp_create_handler_registration("icmpStatsTable",
686 		icmp_stats_table_handler, icmp_stats_tbl_oid,
687 		OID_LENGTH(icmp_stats_tbl_oid), HANDLER_CAN_RONLY);
688 
689     rc = netsnmp_register_table_iterator2(table_reginfo, iinfo);
690     if (rc != SNMPERR_SUCCESS) {
691         table_reginfo = NULL;
692         goto bail;
693     }
694     netsnmp_inject_handler( table_reginfo,
695             netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
696                         icmp_load, icmp_free,
697                         icmp_stats_tbl_oid, OID_LENGTH(icmp_stats_tbl_oid)));
698 
699     /* register icmpMsgStatsTable */
700     msg_stats_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
701     if (!msg_stats_table_info)
702         goto bail;
703     netsnmp_table_helper_add_indexes(msg_stats_table_info, ASN_INTEGER, ASN_INTEGER, 0);
704     msg_stats_table_info->min_column = ICMP_MSG_STAT_IN_PKTS;
705     msg_stats_table_info->max_column = ICMP_MSG_STAT_OUT_PKTS;
706 
707     msg_stats_iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
708     if (!msg_stats_iinfo)
709         goto bail;
710     msg_stats_iinfo->get_first_data_point = icmp_msg_stats_first_entry;
711     msg_stats_iinfo->get_next_data_point  = icmp_msg_stats_next_entry;
712     msg_stats_iinfo->table_reginfo        = msg_stats_table_info;
713 
714     msg_stats_reginfo = netsnmp_create_handler_registration("icmpMsgStatsTable",
715             icmp_msg_stats_table_handler, icmp_msg_stats_tbl_oid,
716             OID_LENGTH(icmp_msg_stats_tbl_oid), HANDLER_CAN_RONLY);
717 
718     rc = netsnmp_register_table_iterator2(msg_stats_reginfo, msg_stats_iinfo);
719     if (rc != SNMPERR_SUCCESS) {
720         msg_stats_reginfo = NULL;
721         goto bail;
722     }
723 
724     netsnmp_inject_handler( msg_stats_reginfo,
725             netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
726                 icmp_load, icmp_free,
727                 icmp_msg_stats_tbl_oid, OID_LENGTH(icmp_msg_stats_tbl_oid)));
728 #endif /* USES_SNMP_DESIGNED_ICMPSTAT */
729 
730 #ifdef USING_MIBII_IP_MODULE
731     if (++ip_module_count == 2)
732         REGISTER_SYSOR_TABLE(ip_module_oid, ip_module_oid_len,
733                              "The MIB module for managing IP and ICMP implementations");
734 #endif
735 
736 #if !defined(_USE_PERFSTAT_PROTOCOL)
737 #ifdef ICMPSTAT_SYMBOL
738     auto_nlist(ICMPSTAT_SYMBOL, 0, 0);
739 #endif
740 #ifdef solaris2
741     init_kernel_sunos5();
742 #endif
743 #endif
744     return;
745 
746 #ifndef hpux11
747 bail:
748 #endif
749 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
750     if (msg_stats_reginfo)
751         netsnmp_handler_registration_free(msg_stats_reginfo);
752     if (table_reginfo)
753         netsnmp_handler_registration_free(table_reginfo);
754 #endif
755     if (scalar_reginfo)
756         netsnmp_handler_registration_free(scalar_reginfo);
757 }
758 
759 
760         /*********************
761 	 *
762 	 *  System specific data formats
763 	 *
764 	 *********************/
765 
766         /*********************
767 	 *
768 	 *  System independent handler
769 	 *       (mostly!)
770 	 *
771 	 *********************/
772 
773 int
icmp_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)774 icmp_handler(netsnmp_mib_handler          *handler,
775              netsnmp_handler_registration *reginfo,
776              netsnmp_agent_request_info   *reqinfo,
777              netsnmp_request_info         *requests)
778 {
779     netsnmp_request_info  *request;
780     netsnmp_variable_list *requestvb;
781     long     ret_value;
782     oid      subid;
783 
784     /*
785      * The cached data should already have been loaded by the
786      *    cache handler, higher up the handler chain.
787      */
788 #if defined(_USE_PERFSTAT_PROTOCOL)
789     icmp_load(NULL, NULL);
790 #endif
791 
792 
793     /*
794      *
795      *
796      */
797     DEBUGMSGTL(("mibII/icmp", "Handler - mode %s\n",
798                     se_find_label_in_slist("agent_mode", reqinfo->mode)));
799     switch (reqinfo->mode) {
800     case MODE_GET:
801         for (request=requests; request; request=request->next) {
802             requestvb = request->requestvb;
803             subid = requestvb->name[OID_LENGTH(icmp_oid)];  /* XXX */
804             DEBUGMSGTL(( "mibII/icmp", "oid: "));
805             DEBUGMSGOID(("mibII/icmp", requestvb->name,
806                                        requestvb->name_length));
807             DEBUGMSG((   "mibII/icmp", "\n"));
808 
809             switch (subid) {
810 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
811     case ICMPINMSGS:
812         ret_value = icmpstat.icmpInMsgs;
813         break;
814     case ICMPINERRORS:
815         ret_value = icmpstat.icmpInErrors;
816         break;
817     case ICMPINDESTUNREACHS:
818         ret_value = icmpstat.icmpInDestUnreachs;
819         break;
820     case ICMPINTIMEEXCDS:
821         ret_value = icmpstat.icmpInTimeExcds;
822         break;
823     case ICMPINPARMPROBS:
824         ret_value = icmpstat.icmpInParmProbs;
825         break;
826     case ICMPINSRCQUENCHS:
827         ret_value = icmpstat.icmpInSrcQuenchs;
828         break;
829     case ICMPINREDIRECTS:
830         ret_value = icmpstat.icmpInRedirects;
831         break;
832     case ICMPINECHOS:
833         ret_value = icmpstat.icmpInEchos;
834         break;
835     case ICMPINECHOREPS:
836         ret_value = icmpstat.icmpInEchoReps;
837         break;
838     case ICMPINTIMESTAMPS:
839         ret_value = icmpstat.icmpInTimestamps;
840         break;
841     case ICMPINTIMESTAMPREPS:
842         ret_value = icmpstat.icmpInTimestampReps;
843         break;
844     case ICMPINADDRMASKS:
845         ret_value = icmpstat.icmpInAddrMasks;
846         break;
847     case ICMPINADDRMASKREPS:
848         ret_value = icmpstat.icmpInAddrMaskReps;
849         break;
850     case ICMPOUTMSGS:
851         ret_value = icmpstat.icmpOutMsgs;
852         break;
853     case ICMPOUTERRORS:
854         ret_value = icmpstat.icmpOutErrors;
855         break;
856     case ICMPOUTDESTUNREACHS:
857         ret_value = icmpstat.icmpOutDestUnreachs;
858         break;
859     case ICMPOUTTIMEEXCDS:
860         ret_value = icmpstat.icmpOutTimeExcds;
861         break;
862     case ICMPOUTPARMPROBS:
863         ret_value = icmpstat.icmpOutParmProbs;
864         break;
865     case ICMPOUTSRCQUENCHS:
866         ret_value = icmpstat.icmpOutSrcQuenchs;
867         break;
868     case ICMPOUTREDIRECTS:
869         ret_value = icmpstat.icmpOutRedirects;
870         break;
871     case ICMPOUTECHOS:
872         ret_value = icmpstat.icmpOutEchos;
873         break;
874     case ICMPOUTECHOREPS:
875         ret_value = icmpstat.icmpOutEchoReps;
876         break;
877     case ICMPOUTTIMESTAMPS:
878         ret_value = icmpstat.icmpOutTimestamps;
879         break;
880     case ICMPOUTTIMESTAMPREPS:
881         ret_value = icmpstat.icmpOutTimestampReps;
882         break;
883     case ICMPOUTADDRMASKS:
884         ret_value = icmpstat.icmpOutAddrMasks;
885         break;
886     case ICMPOUTADDRMASKREPS:
887         ret_value = icmpstat.icmpOutAddrMaskReps;
888         break;
889 #elif defined(USES_TRADITIONAL_ICMPSTAT) && !defined(_USE_PERFSTAT_PROTOCOL)
890     case ICMPINMSGS: {
891         int i;
892 
893         ret_value = icmpstat.icps_badcode +
894             icmpstat.icps_tooshort +
895             icmpstat.icps_checksum + icmpstat.icps_badlen;
896         for (i = 0; i <= ICMP_MAXTYPE; i++)
897             ret_value += icmpstat.icps_inhist[i];
898         break;
899     }
900     case ICMPINERRORS:
901         ret_value = icmpstat.icps_badcode +
902             icmpstat.icps_tooshort +
903             icmpstat.icps_checksum + icmpstat.icps_badlen;
904         break;
905     case ICMPINDESTUNREACHS:
906         ret_value = icmpstat.icps_inhist[ICMP_UNREACH];
907         break;
908     case ICMPINTIMEEXCDS:
909         ret_value = icmpstat.icps_inhist[ICMP_TIMXCEED];
910         break;
911     case ICMPINPARMPROBS:
912         ret_value = icmpstat.icps_inhist[ICMP_PARAMPROB];
913         break;
914     case ICMPINSRCQUENCHS:
915         ret_value = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];
916         break;
917     case ICMPINREDIRECTS:
918         ret_value = icmpstat.icps_inhist[ICMP_REDIRECT];
919         break;
920     case ICMPINECHOS:
921         ret_value = icmpstat.icps_inhist[ICMP_ECHO];
922         break;
923     case ICMPINECHOREPS:
924         ret_value = icmpstat.icps_inhist[ICMP_ECHOREPLY];
925         break;
926     case ICMPINTIMESTAMPS:
927         ret_value = icmpstat.icps_inhist[ICMP_TSTAMP];
928         break;
929     case ICMPINTIMESTAMPREPS:
930         ret_value = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];
931         break;
932     case ICMPINADDRMASKS:
933         ret_value = icmpstat.icps_inhist[ICMP_MASKREQ];
934         break;
935     case ICMPINADDRMASKREPS:
936         ret_value = icmpstat.icps_inhist[ICMP_MASKREPLY];
937         break;
938     case ICMPOUTMSGS: {
939         int i;
940 
941         ret_value = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
942         for (i = 0; i <= ICMP_MAXTYPE; i++)
943             ret_value += icmpstat.icps_outhist[i];
944         break;
945     }
946     case ICMPOUTERRORS:
947         ret_value = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
948         break;
949     case ICMPOUTDESTUNREACHS:
950         ret_value = icmpstat.icps_outhist[ICMP_UNREACH];
951         break;
952     case ICMPOUTTIMEEXCDS:
953         ret_value = icmpstat.icps_outhist[ICMP_TIMXCEED];
954         break;
955     case ICMPOUTPARMPROBS:
956         ret_value = icmpstat.icps_outhist[ICMP_PARAMPROB];
957         break;
958     case ICMPOUTSRCQUENCHS:
959         ret_value = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];
960         break;
961     case ICMPOUTREDIRECTS:
962         ret_value = icmpstat.icps_outhist[ICMP_REDIRECT];
963         break;
964     case ICMPOUTECHOS:
965         ret_value = icmpstat.icps_outhist[ICMP_ECHO];
966         break;
967     case ICMPOUTECHOREPS:
968         ret_value = icmpstat.icps_outhist[ICMP_ECHOREPLY];
969         break;
970     case ICMPOUTTIMESTAMPS:
971         ret_value = icmpstat.icps_outhist[ICMP_TSTAMP];
972         break;
973     case ICMPOUTTIMESTAMPREPS:
974         ret_value = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];
975         break;
976     case ICMPOUTADDRMASKS:
977         ret_value = icmpstat.icps_outhist[ICMP_MASKREQ];
978         break;
979     case ICMPOUTADDRMASKREPS:
980         ret_value = icmpstat.icps_outhist[ICMP_MASKREPLY];
981         break;
982 #elif defined(hpux11)
983     case ICMPINMSGS:
984     case ICMPINERRORS:
985     case ICMPINDESTUNREACHS:
986     case ICMPINTIMEEXCDS:
987     case ICMPINPARMPROBS:
988     case ICMPINSRCQUENCHS:
989     case ICMPINREDIRECTS:
990     case ICMPINECHOS:
991     case ICMPINECHOREPS:
992     case ICMPINTIMESTAMPS:
993     case ICMPINTIMESTAMPREPS:
994     case ICMPINADDRMASKS:
995     case ICMPINADDRMASKREPS:
996     case ICMPOUTMSGS:
997     case ICMPOUTERRORS:
998     case ICMPOUTDESTUNREACHS:
999     case ICMPOUTTIMEEXCDS:
1000     case ICMPOUTPARMPROBS:
1001     case ICMPOUTSRCQUENCHS:
1002     case ICMPOUTREDIRECTS:
1003     case ICMPOUTECHOS:
1004     case ICMPOUTECHOREPS:
1005     case ICMPOUTTIMESTAMPS:
1006     case ICMPOUTTIMESTAMPREPS:
1007     case ICMPOUTADDRMASKS:
1008     case ICMPOUTADDRMASKREPS:
1009 	/*
1010 	 * This is a bit of a hack, to shoehorn the HP-UX 11
1011 	 * single-object retrieval approach into the caching
1012 	 * architecture.
1013 	 */
1014 	if (icmp_load(NULL, (void*)subid) == -1 ) {
1015             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
1016             continue;
1017 	}
1018         ret_value = icmpstat;
1019         break;
1020 #elif defined (WIN32) || defined (cygwin)
1021     case ICMPINMSGS:
1022         ret_value = icmpstat.stats.icmpInStats.dwMsgs;
1023         break;
1024     case ICMPINERRORS:
1025         ret_value = icmpstat.stats.icmpInStats.dwErrors;
1026         break;
1027     case ICMPINDESTUNREACHS:
1028         ret_value = icmpstat.stats.icmpInStats.dwDestUnreachs;
1029         break;
1030     case ICMPINTIMEEXCDS:
1031         ret_value = icmpstat.stats.icmpInStats.dwTimeExcds;
1032         break;
1033     case ICMPINPARMPROBS:
1034         ret_value = icmpstat.stats.icmpInStats.dwParmProbs;
1035         break;
1036     case ICMPINSRCQUENCHS:
1037         ret_value = icmpstat.stats.icmpInStats.dwSrcQuenchs;
1038         break;
1039     case ICMPINREDIRECTS:
1040         ret_value = icmpstat.stats.icmpInStats.dwRedirects;
1041         break;
1042     case ICMPINECHOS:
1043         ret_value = icmpstat.stats.icmpInStats.dwEchos;
1044         break;
1045     case ICMPINECHOREPS:
1046         ret_value = icmpstat.stats.icmpInStats.dwEchoReps;
1047         break;
1048     case ICMPINTIMESTAMPS:
1049         ret_value = icmpstat.stats.icmpInStats.dwTimestamps;
1050         break;
1051     case ICMPINTIMESTAMPREPS:
1052         ret_value = icmpstat.stats.icmpInStats.dwTimestampReps;
1053         break;
1054     case ICMPINADDRMASKS:
1055         ret_value = icmpstat.stats.icmpInStats.dwAddrMasks;
1056         break;
1057     case ICMPINADDRMASKREPS:
1058         ret_value = icmpstat.stats.icmpInStats.dwAddrMaskReps;
1059         break;
1060     case ICMPOUTMSGS:
1061         ret_value = icmpstat.stats.icmpOutStats.dwMsgs;
1062         break;
1063     case ICMPOUTERRORS:
1064         ret_value = icmpstat.stats.icmpOutStats.dwErrors;
1065         break;
1066     case ICMPOUTDESTUNREACHS:
1067         ret_value = icmpstat.stats.icmpOutStats.dwDestUnreachs;
1068         break;
1069     case ICMPOUTTIMEEXCDS:
1070         ret_value = icmpstat.stats.icmpOutStats.dwTimeExcds;
1071         break;
1072     case ICMPOUTPARMPROBS:
1073         ret_value = icmpstat.stats.icmpOutStats.dwParmProbs;
1074         break;
1075     case ICMPOUTSRCQUENCHS:
1076         ret_value = icmpstat.stats.icmpOutStats.dwSrcQuenchs;
1077         break;
1078     case ICMPOUTREDIRECTS:
1079         ret_value = icmpstat.stats.icmpOutStats.dwRedirects;
1080         break;
1081     case ICMPOUTECHOS:
1082         ret_value = icmpstat.stats.icmpOutStats.dwEchos;
1083         break;
1084     case ICMPOUTECHOREPS:
1085         ret_value = icmpstat.stats.icmpOutStats.dwEchoReps;
1086         break;
1087     case ICMPOUTTIMESTAMPS:
1088         ret_value = icmpstat.stats.icmpOutStats.dwTimestamps;
1089         break;
1090     case ICMPOUTTIMESTAMPREPS:
1091         ret_value = icmpstat.stats.icmpOutStats.dwTimestampReps;
1092         break;
1093     case ICMPOUTADDRMASKS:
1094         ret_value = icmpstat.stats.icmpOutStats.dwAddrMasks;
1095         break;
1096     case ICMPOUTADDRMASKREPS:
1097         ret_value = icmpstat.stats.icmpOutStats.dwAddrMaskReps;
1098         break;
1099 #elif defined(_USE_PERFSTAT_PROTOCOL)
1100     case ICMPINMSGS:
1101         ret_value = ps_proto.u.icmp.received;
1102         break;
1103     case ICMPINERRORS:
1104         ret_value = ps_proto.u.icmp.errors;
1105         break;
1106     case ICMPINDESTUNREACHS:
1107     case ICMPINTIMEEXCDS:
1108     case ICMPINPARMPROBS:
1109     case ICMPINSRCQUENCHS:
1110     case ICMPINREDIRECTS:
1111     case ICMPINECHOS:
1112     case ICMPINECHOREPS:
1113     case ICMPINTIMESTAMPS:
1114     case ICMPINTIMESTAMPREPS:
1115     case ICMPINADDRMASKS:
1116     case ICMPINADDRMASKREPS:
1117         ret_value = 0;
1118         break;
1119     case ICMPOUTMSGS:
1120         ret_value = ps_proto.u.icmp.sent;
1121         break;
1122     case ICMPOUTERRORS:
1123         ret_value = ps_proto.u.icmp.errors;
1124         break;
1125     case ICMPOUTDESTUNREACHS:
1126     case ICMPOUTTIMEEXCDS:
1127     case ICMPOUTPARMPROBS:
1128     case ICMPOUTSRCQUENCHS:
1129     case ICMPOUTREDIRECTS:
1130     case ICMPOUTECHOS:
1131     case ICMPOUTECHOREPS:
1132     case ICMPOUTTIMESTAMPS:
1133     case ICMPOUTTIMESTAMPREPS:
1134     case ICMPOUTADDRMASKS:
1135     case ICMPOUTADDRMASKREPS:
1136         ret_value = 0;
1137         break;
1138 #endif                          /* USES_SNMP_DESIGNED_ICMPSTAT */
1139 	    }
1140 	    snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
1141 			             (u_char *)&ret_value, sizeof(ret_value));
1142 	}
1143         break;
1144 
1145     case MODE_GETNEXT:
1146     case MODE_GETBULK:
1147 #ifndef NETSNMP_NO_WRITE_SUPPORT
1148     case MODE_SET_RESERVE1:
1149     case MODE_SET_RESERVE2:
1150     case MODE_SET_ACTION:
1151     case MODE_SET_COMMIT:
1152     case MODE_SET_FREE:
1153     case MODE_SET_UNDO:
1154         snmp_log(LOG_WARNING, "mibII/icmp: Unsupported mode (%d)\n",
1155                                reqinfo->mode);
1156         break;
1157 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
1158     default:
1159         snmp_log(LOG_WARNING, "mibII/icmp: Unrecognised mode (%d)\n",
1160                                reqinfo->mode);
1161         break;
1162     }
1163 
1164     return SNMP_ERR_NOERROR;
1165 }
1166 
1167 
1168 #ifdef USES_SNMP_DESIGNED_ICMPSTAT
1169 int
icmp_stats_table_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)1170 icmp_stats_table_handler(netsnmp_mib_handler  *handler,
1171                  netsnmp_handler_registration *reginfo,
1172                  netsnmp_agent_request_info   *reqinfo,
1173                  netsnmp_request_info         *requests)
1174 {
1175 	netsnmp_request_info  *request;
1176 	netsnmp_variable_list *requestvb;
1177 	netsnmp_table_request_info *table_info;
1178 	struct icmp_stats_table_entry   *entry;
1179 	oid      subid;
1180 
1181 	switch (reqinfo->mode) {
1182 		case MODE_GET:
1183 			for (request=requests; request; request=request->next) {
1184 				requestvb = request->requestvb;
1185 				entry = (struct icmp_stats_table_entry *)netsnmp_extract_iterator_context(request);
1186 				if (!entry)
1187 					continue;
1188 				table_info = netsnmp_extract_table_info(request);
1189 				subid      = table_info->colnum;
1190 				DEBUGMSGTL(( "mibII/icmpStatsTable", "oid: " ));
1191 				DEBUGMSGOID(( "mibII/icmpStatsTable", request->requestvb->name,
1192 						 request->requestvb->name_length ));
1193 				DEBUGMSG(( "mibII/icmpStatsTable", " In %d InErr %d Out %d OutErr %d\n",
1194 					      entry->icmpStatsInMsgs, entry->icmpStatsInErrors,
1195 					      entry->icmpStatsOutMsgs, entry->icmpStatsOutErrors ));
1196 
1197 				switch (subid) {
1198 					case ICMP_STAT_INMSG:
1199 						snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1200 							(u_char *)&entry->icmpStatsInMsgs, sizeof(uint32_t));
1201 						break;
1202 					case ICMP_STAT_INERR:
1203 						snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1204 							(u_char *)&entry->icmpStatsInErrors, sizeof(uint32_t));
1205 						break;
1206 					case ICMP_STAT_OUTMSG:
1207 						snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1208 							(u_char *)&entry->icmpStatsOutMsgs, sizeof(uint32_t));
1209 						break;
1210 					case ICMP_STAT_OUTERR:
1211 						snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1212 							(u_char *)&entry->icmpStatsOutErrors, sizeof(uint32_t));
1213 						break;
1214 					default:
1215 						snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised column (%d)\n",(int)subid);
1216 				}
1217 			}
1218 			break;
1219 		case MODE_GETNEXT:
1220 		case MODE_GETBULK:
1221 #ifndef NETSNMP_NO_WRITE_SUPPORT
1222 		case MODE_SET_RESERVE1:
1223 		case MODE_SET_RESERVE2:
1224 		case MODE_SET_ACTION:
1225 		case MODE_SET_COMMIT:
1226 		case MODE_SET_FREE:
1227 		case MODE_SET_UNDO:
1228 			snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unsupported mode (%d)\n",
1229 				reqinfo->mode);
1230 			break;
1231 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
1232 		default:
1233 			snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised mode (%d)\n",
1234 				reqinfo->mode);
1235 			break;
1236 
1237 	}
1238 
1239 	return SNMP_ERR_NOERROR;
1240 }
1241 
1242 int
icmp_msg_stats_table_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)1243 icmp_msg_stats_table_handler(netsnmp_mib_handler          *handler,
1244                              netsnmp_handler_registration *reginfo,
1245                              netsnmp_agent_request_info   *reqinfo,
1246                              netsnmp_request_info         *requests)
1247 {
1248     netsnmp_request_info *request;
1249     netsnmp_variable_list *requestvb;
1250     netsnmp_table_request_info *table_info;
1251     struct icmp_msg_stats_table_entry *entry;
1252     oid subid;
1253 
1254     switch (reqinfo->mode) {
1255         case MODE_GET:
1256             for (request = requests; request; request = request->next) {
1257                 requestvb = request->requestvb;
1258                 entry = (struct icmp_msg_stats_table_entry *)netsnmp_extract_iterator_context(request);
1259                 if (!entry)
1260                     continue;
1261                 table_info = netsnmp_extract_table_info(request);
1262                 subid = table_info->colnum;
1263                 DEBUGMSGTL(( "mibII/icmpMsgStatsTable", "oid: " ));
1264                 DEBUGMSGOID(( "mibII/icmpMsgStatsTable", request->requestvb->name,
1265                                  request->requestvb->name_length ));
1266                 DEBUGMSG(( "mibII/icmpMsgStatsTable", " In %d Out %d Flags 0x%x\n",
1267                                  entry->icmpMsgStatsInPkts, entry->icmpMsgStatsOutPkts, entry->flags ));
1268 
1269                 switch (subid) {
1270                     case ICMP_MSG_STAT_IN_PKTS:
1271                         if (entry->flags & ICMP_MSG_STATS_HAS_IN) {
1272                             snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1273                                     (u_char *)&entry->icmpMsgStatsInPkts, sizeof(uint32_t));
1274                         } else {
1275                             requestvb->type = SNMP_NOSUCHINSTANCE;
1276                         }
1277                         break;
1278                     case ICMP_MSG_STAT_OUT_PKTS:
1279                         if (entry->flags & ICMP_MSG_STATS_HAS_OUT) {
1280                             snmp_set_var_typed_value(requestvb, ASN_COUNTER,
1281                                     (u_char *)&entry->icmpMsgStatsOutPkts, sizeof(uint32_t));
1282                         } else {
1283                             requestvb->type = SNMP_NOSUCHINSTANCE;
1284                         }
1285                         break;
1286                     default:
1287                         snmp_log(LOG_WARNING, "mibII/icmpMsgStatsTable: Unrecognised column (%d)\n",(int)subid);
1288                 }
1289             }
1290             break;
1291         case MODE_GETNEXT:
1292         case MODE_GETBULK:
1293 #ifndef NETSNMP_NO_WRITE_SUPPORT
1294         case MODE_SET_RESERVE1:
1295         case MODE_SET_RESERVE2:
1296         case MODE_SET_ACTION:
1297         case MODE_SET_COMMIT:
1298         case MODE_SET_FREE:
1299         case MODE_SET_UNDO:
1300             snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unsupported mode (%d)\n",
1301                     reqinfo->mode);
1302             break;
1303 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
1304         default:
1305             snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised mode (%d)\n",
1306                     reqinfo->mode);
1307             break;
1308 
1309     }
1310 
1311     return SNMP_ERR_NOERROR;
1312 }
1313 #endif		/* USES_SNMP_DESIGNED_ICMPSTAT */
1314 
1315         /*********************
1316 	 *
1317 	 *  Internal implementation functions
1318 	 *
1319 	 *********************/
1320 
1321 #ifdef hpux11
1322 int
icmp_load(netsnmp_cache * cache,void * vmagic)1323 icmp_load(netsnmp_cache *cache, void *vmagic)
1324 {
1325     int             fd;
1326     struct nmparms  p;
1327     unsigned int    ulen;
1328     int             ret;
1329     int             magic = (int) vmagic;
1330 
1331     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
1332         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP object %d (hpux11)\n", magic));
1333         return (-1);            /* error */
1334     }
1335 
1336     switch (magic) {
1337     case ICMPINMSGS:
1338         p.objid = ID_icmpInMsgs;
1339         break;
1340     case ICMPINERRORS:
1341         p.objid = ID_icmpInErrors;
1342         break;
1343     case ICMPINDESTUNREACHS:
1344         p.objid = ID_icmpInDestUnreachs;
1345         break;
1346     case ICMPINTIMEEXCDS:
1347         p.objid = ID_icmpInTimeExcds;
1348         break;
1349     case ICMPINPARMPROBS:
1350         p.objid = ID_icmpInParmProbs;
1351         break;
1352     case ICMPINSRCQUENCHS:
1353         p.objid = ID_icmpInSrcQuenchs;
1354         break;
1355     case ICMPINREDIRECTS:
1356         p.objid = ID_icmpInRedirects;
1357         break;
1358     case ICMPINECHOS:
1359         p.objid = ID_icmpInEchos;
1360         break;
1361     case ICMPINECHOREPS:
1362         p.objid = ID_icmpInEchoReps;
1363         break;
1364     case ICMPINTIMESTAMPS:
1365         p.objid = ID_icmpInTimestamps;
1366         break;
1367     case ICMPINTIMESTAMPREPS:
1368         p.objid = ID_icmpInTimestampReps;
1369         break;
1370     case ICMPINADDRMASKS:
1371         p.objid = ID_icmpInAddrMasks;
1372         break;
1373     case ICMPINADDRMASKREPS:
1374         p.objid = ID_icmpInAddrMaskReps;
1375         break;
1376     case ICMPOUTMSGS:
1377         p.objid = ID_icmpOutMsgs;
1378         break;
1379     case ICMPOUTERRORS:
1380         p.objid = ID_icmpOutErrors;
1381         break;
1382     case ICMPOUTDESTUNREACHS:
1383         p.objid = ID_icmpOutDestUnreachs;
1384         break;
1385     case ICMPOUTTIMEEXCDS:
1386         p.objid = ID_icmpOutTimeExcds;
1387         break;
1388     case ICMPOUTPARMPROBS:
1389         p.objid = ID_icmpOutParmProbs;
1390         break;
1391     case ICMPOUTSRCQUENCHS:
1392         p.objid = ID_icmpOutSrcQuenchs;
1393         break;
1394     case ICMPOUTREDIRECTS:
1395         p.objid = ID_icmpOutRedirects;
1396         break;
1397     case ICMPOUTECHOS:
1398         p.objid = ID_icmpOutEchos;
1399         break;
1400     case ICMPOUTECHOREPS:
1401         p.objid = ID_icmpOutEchoReps;
1402         break;
1403     case ICMPOUTTIMESTAMPS:
1404         p.objid = ID_icmpOutTimestamps;
1405         break;
1406     case ICMPOUTTIMESTAMPREPS:
1407         p.objid = ID_icmpOutTimestampReps;
1408         break;
1409     case ICMPOUTADDRMASKS:
1410         p.objid = ID_icmpOutAddrMasks;
1411         break;
1412     case ICMPOUTADDRMASKREPS:
1413         p.objid = ID_icmpOutAddrMaskReps;
1414         break;
1415     default:
1416         icmpstat = 0;
1417         close_mib(fd);
1418         return (0);
1419     }
1420 
1421     p.buffer = (void *)&icmpstat;
1422     ulen = sizeof(ICMP_STAT_STRUCTURE);
1423     p.len = &ulen;
1424     ret = get_mib_info(fd, &p);
1425     close_mib(fd);
1426 
1427     DEBUGMSGTL(("mibII/icmp", "%s ICMP object %d (hpux11)\n",
1428                (ret < 0 ? "Failed to load" : "Loaded"),  magic));
1429     return (ret);               /* 0: ok, < 0: error */
1430 }
1431 #elif defined(linux)
1432 int
icmp_load(netsnmp_cache * cache,void * vmagic)1433 icmp_load(netsnmp_cache *cache, void *vmagic)
1434 {
1435     long            ret_value = -1;
1436 
1437     ret_value = linux_read_icmp_stat(&icmpstat);
1438 
1439     if ( ret_value < 0 ) {
1440         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (linux)\n"));
1441     } else {
1442         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (linux)\n"));
1443     }
1444     icmp_stats_load(cache, vmagic);
1445     icmp_msg_stats_load(cache, vmagic);
1446     return ret_value;
1447 }
1448 #elif defined(solaris2)
1449 int
icmp_load(netsnmp_cache * cache,void * vmagic)1450 icmp_load(netsnmp_cache *cache, void *vmagic)
1451 {
1452     int ret_value = -1;
1453 #ifdef NETSNMP_ENABLE_IPV6
1454     mib2_ipv6IfIcmpEntry_t ifstat;
1455     int req = GET_FIRST;
1456 #endif
1457 
1458     ret_value =
1459         getMibstat(MIB_ICMP, &icmpstat, sizeof(mib2_icmp_t), GET_FIRST,
1460                    &Get_everything, NULL);
1461 
1462     if ( ret_value < 0 ) {
1463         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (solaris)\n"));
1464     } else {
1465         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (solaris)\n"));
1466     }
1467 
1468 #ifdef NETSNMP_ENABLE_IPV6
1469     memset(&icmp6stat, 0, sizeof(icmp6stat));
1470     while ((ret_value = getMibstat(MIB_ICMP6, &ifstat, sizeof(ifstat), req,
1471                    &Get_everything, NULL)) == 0) {
1472 	if ( ret_value < 0 ) {
1473 	    DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP6 Group (solaris)\n"));
1474 	} else {
1475 	    DEBUGMSGTL(("mibII/icmp", "Loaded ICMP6 Group (solaris)\n"));
1476 	}
1477 	icmp6stat.icmp6OutMsgs += ifstat.ipv6IfIcmpOutMsgs;
1478 	icmp6stat.icmp6InMsgs += ifstat.ipv6IfIcmpInMsgs;
1479 	icmp6stat.icmp6InErrors += ifstat.ipv6IfIcmpInErrors;
1480 	icmp6stat.icmp6OutDestUnreachs += ifstat.ipv6IfIcmpOutDestUnreachs;
1481 	icmp6stat.icmp6InDestUnreachs += ifstat.ipv6IfIcmpInDestUnreachs;
1482 	icmp6stat.icmp6OutPktTooBigs += ifstat.ipv6IfIcmpOutPktTooBigs;
1483 	icmp6stat.icmp6InPktTooBigs += ifstat.ipv6IfIcmpInPktTooBigs;
1484 	icmp6stat.icmp6OutTimeExcds += ifstat.ipv6IfIcmpOutTimeExcds;
1485 	icmp6stat.icmp6InTimeExcds += ifstat.ipv6IfIcmpInTimeExcds;
1486 	icmp6stat.icmp6OutParmProblems += ifstat.ipv6IfIcmpOutParmProblems;
1487 	icmp6stat.icmp6InParmProblems += ifstat.ipv6IfIcmpInParmProblems;
1488 	icmp6stat.icmp6OutEchos += ifstat.ipv6IfIcmpOutEchos;
1489 	icmp6stat.icmp6InEchos += ifstat.ipv6IfIcmpInEchos;
1490 	icmp6stat.icmp6OutEchoReplies += ifstat.ipv6IfIcmpOutEchoReplies;
1491 	icmp6stat.icmp6InEchoReplies += ifstat.ipv6IfIcmpInEchoReplies;
1492 	icmp6stat.icmp6OutRouterSolicits += ifstat.ipv6IfIcmpOutRouterSolicits;
1493 	icmp6stat.icmp6InRouterSolicits += ifstat.ipv6IfIcmpInRouterSolicits;
1494 	icmp6stat.icmp6OutNeighborAdvertisements += ifstat.ipv6IfIcmpOutNeighborAdvertisements;
1495 	icmp6stat.icmp6InNeighborAdvertisements += ifstat.ipv6IfIcmpInNeighborAdvertisements;
1496 	icmp6stat.icmp6OutNeighborSolicits += ifstat.ipv6IfIcmpOutNeighborSolicits;
1497 	icmp6stat.icmp6InNeighborSolicits += ifstat.ipv6IfIcmpInNeighborSolicits;
1498 	icmp6stat.icmp6OutRedirects += ifstat.ipv6IfIcmpOutRedirects;
1499 	icmp6stat.icmp6InRedirects += ifstat.ipv6IfIcmpInRedirects;
1500 	icmp6stat.icmp6InGroupMembQueries += ifstat.ipv6IfIcmpInGroupMembQueries;
1501 	icmp6stat.icmp6OutGroupMembResponses += ifstat.ipv6IfIcmpOutGroupMembResponses;
1502 	icmp6stat.icmp6InGroupMembResponses += ifstat.ipv6IfIcmpInGroupMembResponses;
1503 	icmp6stat.icmp6OutGroupMembReductions += ifstat.ipv6IfIcmpOutGroupMembReductions;
1504 	icmp6stat.icmp6InGroupMembReductions += ifstat.ipv6IfIcmpInGroupMembReductions;
1505 	req = GET_NEXT;
1506     }
1507 #endif
1508 
1509     icmp_stats_load(cache, vmagic);
1510     icmp_msg_stats_load(cache, vmagic);
1511     return ret_value;
1512 }
1513 
1514 static int
solaris_read_icmp_stat(ICMP_STAT_STRUCTURE * mib)1515 solaris_read_icmp_stat(ICMP_STAT_STRUCTURE *mib)
1516 {
1517     *mib = icmpstat;
1518     return 0;
1519 }
1520 
1521 static int
solaris_read_icmp_msg_stat(ICMP_STAT_STRUCTURE * mib,struct icmp4_msg_mib * msg_mib,int * flag)1522 solaris_read_icmp_msg_stat(ICMP_STAT_STRUCTURE *mib, struct icmp4_msg_mib *msg_mib, int *flag)
1523 {
1524     *mib = icmpstat;
1525     *flag = 0;
1526     return 0;
1527 }
1528 
1529 #ifdef NETSNMP_ENABLE_IPV6
1530 static int
solaris_read_icmp6_stat(struct icmp6_mib * mib)1531 solaris_read_icmp6_stat(struct icmp6_mib *mib)
1532 {
1533     *mib = icmp6stat;
1534     return 0;
1535 }
1536 
1537 static int
solaris_read_icmp6_msg_stat(struct icmp6_mib * mib,struct icmp6_msg_mib * msg_mib,int * flag)1538 solaris_read_icmp6_msg_stat(struct icmp6_mib *mib, struct icmp6_msg_mib *msg_mib, int *flag)
1539 {
1540     *mib = icmp6stat;
1541     *flag = 0;
1542     return 0;
1543 }
1544 #endif
1545 
1546 #elif defined(NETBSD_STATS_VIA_SYSCTL)
1547 int
icmp_load(netsnmp_cache * cache,void * vmagic)1548 icmp_load(netsnmp_cache *cache, void *vmagic)
1549 {
1550     long            ret_value =- -1;
1551 
1552     ret_value = netbsd_read_icmp_stat(&icmpstat);
1553 
1554     if ( ret_value < 0 ) {
1555 	DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (netbsd)\n"));
1556     } else {
1557 	DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (netbsd)\n"));
1558     }
1559     icmp_stats_load(cache, vmagic);
1560     icmp_msg_stats_load(cache, vmagic);
1561     return ret_value;
1562 }
1563 #elif defined (WIN32) || defined (cygwin)
1564 int
icmp_load(netsnmp_cache * cache,void * vmagic)1565 icmp_load(netsnmp_cache *cache, void *vmagic)
1566 {
1567     long            ret_value = -1;
1568 
1569     ret_value = GetIcmpStatistics(&icmpstat);
1570 
1571     if ( ret_value < 0 ) {
1572         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (win32)\n"));
1573     } else {
1574         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (win32)\n"));
1575     }
1576     return ret_value;
1577 }
1578 #elif defined(_USE_PERFSTAT_PROTOCOL)
1579 int
icmp_load(netsnmp_cache * cache,void * vmagic)1580 icmp_load(netsnmp_cache *cache, void *vmagic)
1581 {
1582     long            ret_value = -1;
1583 
1584     strcpy(ps_name.name, "icmp");
1585     ret_value = perfstat_protocol(&ps_name, &ps_proto, sizeof(ps_proto), 1);
1586 
1587     if ( ret_value < 0 ) {
1588         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (AIX)\n"));
1589     } else {
1590         ret_value = 0;
1591         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (AIX)\n"));
1592     }
1593     return ret_value;
1594 }
1595 #elif defined(NETSNMP_CAN_USE_SYSCTL) && defined(ICMPCTL_STATS)
1596 int
icmp_load(netsnmp_cache * cache,void * vmagic)1597 icmp_load(netsnmp_cache *cache, void *vmagic)
1598 {
1599     long            ret_value = -1;
1600 
1601     ret_value = sysctl_read_icmp_stat(&icmpstat);
1602 
1603     if ( ret_value < 0 ) {
1604 	DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (netbsd)\n"));
1605     } else {
1606 	DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (netbsd)\n"));
1607     }
1608     icmp_stats_load(cache, vmagic);
1609     icmp_msg_stats_load(cache, vmagic);
1610     return ret_value;
1611 }
1612 #elif defined(HAVE_SYS_TCPIPSTATS_H)
1613 int
icmp_load(netsnmp_cache * cache,void * vmagic)1614 icmp_load(netsnmp_cache *cache, void *vmagic)
1615 {
1616     long            ret_value = -1;
1617 
1618     ret_value =
1619         sysmp(MP_SAGET, MPSA_TCPIPSTATS, &icmpstat, sizeof icmpstat);
1620 
1621     if ( ret_value < 0 ) {
1622         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (tcpipstats)\n"));
1623     } else {
1624         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (tcpipstats)\n"));
1625     }
1626     return ret_value;
1627 }
1628 #elif defined(ICMPSTAT_SYMBOL)
1629 int
icmp_load(netsnmp_cache * cache,void * vmagic)1630 icmp_load(netsnmp_cache *cache, void *vmagic)
1631 {
1632     long            ret_value = -1;
1633 
1634     if (auto_nlist(ICMPSTAT_SYMBOL, (char *)&icmpstat, sizeof(icmpstat)))
1635         ret_value = 0;
1636 
1637     if ( ret_value < 0 ) {
1638         DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (icmpstat)\n"));
1639     } else {
1640         DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (icmpstat)\n"));
1641     }
1642     return ret_value;
1643 }
1644 #else		/* ICMPSTAT_SYMBOL */
1645 int
icmp_load(netsnmp_cache * cache,void * vmagic)1646 icmp_load(netsnmp_cache *cache, void *vmagic)
1647 {
1648     long            ret_value = -1;
1649 
1650     DEBUGMSGTL(("mibII/icmp", "Failed to load ICMP Group (null)\n"));
1651     return ret_value;
1652 }
1653 #endif		/* hpux11 */
1654 
1655 void
icmp_free(netsnmp_cache * cache,void * magic)1656 icmp_free(netsnmp_cache *cache, void *magic)
1657 {
1658 #if defined(_USE_PERFSTAT_PROTOCOL)
1659     memset(&ps_proto, 0, sizeof(ps_proto));
1660 #else
1661     memset(&icmpstat, 0, sizeof(icmpstat));
1662 #endif
1663 }
1664