1 /*
2  * sysctl interface for icmp stats for others than NetBSD
3  */
4 
5 #include <sys/param.h>
6 #include <sys/sysctl.h>
7 #include <sys/protosw.h>
8 
9 #include <netinet/in.h>
10 #include <netinet/in_systm.h>
11 #include <netinet/ip.h>
12 #include <netinet/ip_icmp.h>
13 #include <netinet/ip_var.h>
14 #include <netinet/icmp_var.h>
15 #include <netinet/icmp6.h>
16 
17 #include <net-snmp/net-snmp-config.h>
18 #include <net-snmp/net-snmp-includes.h>
19 #include <net-snmp/agent/net-snmp-agent-includes.h>
20 
21 #include "kernel_sysctl.h"
22 
23 #if defined(NETSNMP_CAN_USE_SYSCTL)
24 
25 int
sysctl_read_icmp_stat(struct icmp_mib * mib)26 sysctl_read_icmp_stat(struct icmp_mib *mib)
27 {
28     struct icmpstat icmpstat;
29     size_t   size = sizeof(icmpstat);
30     int      i;
31     static int      sname[4] =
32         { CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
33 
34     (void)memset(mib, 0, sizeof(*mib));
35 
36     if (-1 == sysctl(sname, 4, &icmpstat, &size, NULL, 0)) {
37 	snmp_perror("sysctl_read_icmp_stat: net.inet.icmp.stats");
38         return -1;
39     }
40 
41     mib->icmpInMsgs = icmpstat.icps_badcode
42         + icmpstat.icps_tooshort
43         + icmpstat.icps_checksum
44         + icmpstat.icps_badlen;
45     mib->icmpInErrors = mib->icmpInMsgs;
46     for (i = 0; i <= ICMP_MAXTYPE; i++)
47         mib->icmpInMsgs  += icmpstat.icps_inhist[i];
48     mib->icmpInDestUnreachs = icmpstat.icps_inhist[ICMP_UNREACH];
49     mib->icmpInTimeExcds = icmpstat.icps_inhist[ICMP_TIMXCEED];
50     mib->icmpInParmProbs = icmpstat.icps_inhist[ICMP_PARAMPROB];
51     mib->icmpInSrcQuenchs = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];
52     mib->icmpInRedirects = icmpstat.icps_inhist[ICMP_REDIRECT];
53     mib->icmpInEchos = icmpstat.icps_inhist[ICMP_ECHO];
54     mib->icmpInEchoReps = icmpstat.icps_inhist[ICMP_ECHOREPLY];
55     mib->icmpInTimestamps = icmpstat.icps_inhist[ICMP_TSTAMP];
56     mib->icmpInTimestampReps = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];
57     mib->icmpInAddrMasks = icmpstat.icps_inhist[ICMP_MASKREQ];
58     mib->icmpInAddrMaskReps = icmpstat.icps_inhist[ICMP_MASKREPLY];
59     mib->icmpOutMsgs = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
60     for (i = 0; i <= ICMP_MAXTYPE; i++)
61         mib->icmpOutMsgs += icmpstat.icps_outhist[i];
62     mib->icmpOutErrors = icmpstat.icps_oldshort + icmpstat.icps_oldicmp;
63     mib->icmpOutDestUnreachs = icmpstat.icps_outhist[ICMP_UNREACH];
64     mib->icmpOutTimeExcds = icmpstat.icps_outhist[ICMP_TIMXCEED];
65     mib->icmpOutParmProbs = icmpstat.icps_outhist[ICMP_PARAMPROB];
66     mib->icmpOutSrcQuenchs = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];
67     mib->icmpOutRedirects = icmpstat.icps_outhist[ICMP_REDIRECT];
68     mib->icmpOutEchos = icmpstat.icps_outhist[ICMP_ECHO];
69     mib->icmpOutEchoReps = icmpstat.icps_outhist[ICMP_ECHOREPLY];
70     mib->icmpOutTimestamps = icmpstat.icps_outhist[ICMP_TSTAMP];
71     mib->icmpOutTimestampReps = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];
72     mib->icmpOutAddrMasks = icmpstat.icps_outhist[ICMP_MASKREQ];
73     mib->icmpOutAddrMaskReps = icmpstat.icps_outhist[ICMP_MASKREPLY];
74 
75     return 0;
76 }
77 
78 
79 int
sysctl_read_icmp6_stat(struct icmp6_mib * mib)80 sysctl_read_icmp6_stat(struct icmp6_mib *mib)
81 {
82     struct icmp6stat icmpstat;
83     size_t   size = sizeof(icmpstat);
84     int      i;
85     static int      sname[4] =
86         { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_STATS };
87 
88     (void)memset(mib, 0, sizeof(*mib));
89 
90     if (-1 == sysctl(sname, 4, &icmpstat, &size, NULL, 0)) {
91 	snmp_perror("sysctl_read_icmp6_stat: net.inet6.icmp6.stats");
92         return -1;
93     }
94 
95     mib->icmp6InMsgs = icmpstat.icp6s_badcode
96             + icmpstat.icp6s_tooshort
97 	    + icmpstat.icp6s_checksum
98             + icmpstat.icp6s_badlen;
99     mib->icmp6InErrors = mib->icmp6InMsgs;
100     for (i = 0; i <= ICMP6_MAXTYPE; i++)
101         mib->icmp6InMsgs  += icmpstat.icp6s_inhist[i];
102     mib->icmp6InDestUnreachs = icmpstat.icp6s_inhist[ICMP6_DST_UNREACH];
103     mib->icmp6InPktTooBigs = icmpstat.icp6s_inhist[ICMP6_PACKET_TOO_BIG];
104     mib->icmp6InTimeExcds = icmpstat.icp6s_inhist[ICMP6_TIME_EXCEEDED];
105     mib->icmp6InParmProblems = icmpstat.icp6s_inhist[ICMP6_PARAM_PROB];
106     mib->icmp6InEchos = icmpstat.icp6s_inhist[ICMP6_ECHO_REQUEST];
107     mib->icmp6InEchoReplies = icmpstat.icp6s_inhist[ICMP6_ECHO_REPLY];
108     mib->icmp6InGroupMembQueries = icmpstat.icp6s_inhist[MLD_LISTENER_QUERY];
109     mib->icmp6InGroupMembResponses = icmpstat.icp6s_inhist[MLD_LISTENER_REPORT];
110     mib->icmp6InRouterSolicits = icmpstat.icp6s_inhist[ND_ROUTER_SOLICIT];
111     mib->icmp6InRouterAdvertisements = icmpstat.icp6s_inhist[ND_ROUTER_ADVERT];
112     mib->icmp6InNeighborSolicits = icmpstat.icp6s_inhist[ND_NEIGHBOR_SOLICIT];
113     mib->icmp6InNeighborAdvertisements = icmpstat.icp6s_inhist[ND_NEIGHBOR_ADVERT];
114     mib->icmp6InRedirects = icmpstat.icp6s_inhist[ND_REDIRECT];
115 
116     mib->icmp6OutMsgs = icmpstat.icp6s_canterror
117         + icmpstat.icp6s_toofreq;
118     for (i = 0; i <= ICMP6_MAXTYPE; i++)
119         mib->icmp6OutMsgs += icmpstat.icp6s_outhist[i];
120     mib->icmp6OutDestUnreachs = icmpstat.icp6s_outhist[ICMP6_DST_UNREACH];
121     mib->icmp6OutPktTooBigs =  icmpstat.icp6s_outhist[ICMP6_PACKET_TOO_BIG];
122     mib->icmp6OutTimeExcds = icmpstat.icp6s_outhist[ICMP6_TIME_EXCEEDED];
123     mib->icmp6OutParmProblems = icmpstat.icp6s_outhist[ICMP6_PARAM_PROB];
124     mib->icmp6OutEchos = icmpstat.icp6s_outhist[ICMP6_ECHO_REQUEST];
125     mib->icmp6OutEchoReplies = icmpstat.icp6s_outhist[ICMP6_ECHO_REPLY];
126     mib->icmp6OutRouterSolicits =  icmpstat.icp6s_outhist[ND_ROUTER_SOLICIT];
127     mib->icmp6OutNeighborSolicits =  icmpstat.icp6s_outhist[ND_NEIGHBOR_SOLICIT];
128     mib->icmp6OutNeighborAdvertisements =  icmpstat.icp6s_outhist[ND_NEIGHBOR_ADVERT];
129     mib->icmp6OutRedirects = icmpstat.icp6s_outhist[ND_REDIRECT];
130     mib->icmp6OutGroupMembResponses =  icmpstat.icp6s_outhist[MLD_LISTENER_REPORT];
131     mib->icmp6OutGroupMembReductions =  icmpstat.icp6s_outhist[MLD_LISTENER_DONE];
132 
133     return 0;
134 }
135 
136 
137 int
sysctl_read_icmp_msg_stat(struct icmp_mib * mib,struct icmp4_msg_mib * msgmib,int * flag)138 sysctl_read_icmp_msg_stat(struct icmp_mib *mib,
139                           struct icmp4_msg_mib *msgmib,
140 			  int *flag)
141 {
142     sysctl_read_icmp_stat(mib);
143     *flag = 0;
144     return 0;
145 }
146 
147 
148 int
sysctl_read_icmp6_msg_stat(struct icmp6_mib * mib,struct icmp6_msg_mib * msgmib,int * support)149 sysctl_read_icmp6_msg_stat(struct icmp6_mib *mib,
150                            struct icmp6_msg_mib *msgmib,
151 			   int *support)
152 {
153     struct icmp6stat icmpstat;
154     size_t   size = sizeof(icmpstat);
155     int      i;
156     static int      sname[4] =
157         { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_STATS };
158 
159     sysctl_read_icmp6_stat(mib);
160 
161     if (-1 == sysctl(sname, 4, &icmpstat, &size, NULL, 0)) {
162 	snmp_perror("sysctl_read_icmp6_stat: net.inet6.icmp6.stats");
163         return -1;
164     }
165 
166     for (i = 0; i < 256; i++) {
167 	msgmib->vals[i].InType = icmpstat.icp6s_inhist[i];
168 	msgmib->vals[i].OutType = icmpstat.icp6s_outhist[i];
169     }
170     *support = 1;
171     return 0;
172 }
173 
174 
175 #endif
176