www.usr.com/support/gpl/USR9113_release1.0.tar.gz
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / mibII / ip.c
1 #ifdef SNMP_IP_MIB
2 /*
3  *  IP MIB group implementation - ip.c
4  *
5  */
6
7 #include <net-snmp/net-snmp-config.h>
8
9 #if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL)
10 #define _KERNEL 1
11 #define _I_DEFINED_KERNEL
12 #endif
13 #if HAVE_SYS_PARAM_H
14 #include <sys/param.h>
15 #endif
16 #if HAVE_SYS_SOCKET_H
17 #include <sys/socket.h>
18 #endif
19
20 #if HAVE_STRING_H
21 #include <string.h>
22 #else
23 #include <strings.h>
24 #endif
25 #if HAVE_WINSOCK_H
26 #include <winsock.h>
27 #endif
28 #if HAVE_SYS_SYSCTL_H
29 #ifdef _I_DEFINED_KERNEL
30 #undef _KERNEL
31 #endif
32 #include <sys/sysctl.h>
33 #ifdef _I_DEFINED_KERNEL
34 #define _KERNEL 1
35 #endif
36 #endif
37 #if HAVE_SYS_SYSMP_H
38 #include <sys/sysmp.h>
39 #endif
40 #if HAVE_SYS_TCPIPSTATS_H
41 #include <sys/tcpipstats.h>
42 #endif
43 #if HAVE_NET_IF_H
44 #include <net/if.h>
45 #endif
46 #if HAVE_NET_IF_VAR_H
47 #include <net/if_var.h>
48 #endif
49 #ifdef _I_DEFINED_KERNEL
50 #undef _KERNEL
51 #endif
52 #if HAVE_NETINET_IN_H
53 #include <netinet/in.h>
54 #endif
55 #if HAVE_NETINET_IN_SYSTM_H
56 #include <netinet/in_systm.h>
57 #endif
58 #if HAVE_SYS_HASHING_H
59 #include <sys/hashing.h>
60 #endif
61 #if HAVE_NETINET_IN_VAR_H
62 #include <netinet/in_var.h>
63 #endif
64 #if HAVE_NETINET_IP_H
65 #include <netinet/ip.h>
66 #endif
67 #if HAVE_NETINET_IP_VAR_H
68 #include <netinet/ip_var.h>
69 #endif
70 #if HAVE_INET_MIB2_H
71 #include <inet/mib2.h>
72 #endif
73 #if HAVE_SYS_STREAM_H
74 #include <sys/stream.h>
75 #endif
76 #if HAVE_NET_ROUTE_H
77 #include <net/route.h>
78 #endif
79 #if HAVE_SYSLOG_H
80 #include <syslog.h>
81 #endif
82
83 #include <net-snmp/net-snmp-includes.h>
84 #include <net-snmp/agent/net-snmp-agent-includes.h>
85 #include <net-snmp/agent/auto_nlist.h>
86
87 #ifdef solaris2
88 #include "kernel_sunos5.h"
89 #else
90 #include "kernel.h"
91 #endif
92 #ifdef linux
93 #include "kernel_linux.h"
94 #endif
95
96 #if defined(MIB_IPCOUNTER_SYMBOL) || defined(hpux11)
97 #include <sys/mib.h>
98 #include <netinet/mib_kern.h>
99 #endif                          /* MIB_IPCOUNTER_SYMBOL || hpux11 */
100
101 #include "util_funcs.h"
102 #include "ip.h"
103 #include "ipAddr.h"
104 #include "interfaces.h"
105 #include "sysORTable.h"
106
107 #ifdef cygwin
108 #define WIN32
109 #include <windows.h>
110 #endif
111
112 #ifndef MIB_STATS_CACHE_TIMEOUT
113 #define MIB_STATS_CACHE_TIMEOUT 5
114 #endif
115 #ifndef IP_STATS_CACHE_TIMEOUT
116 #define IP_STATS_CACHE_TIMEOUT  MIB_STATS_CACHE_TIMEOUT
117 #endif
118 marker_t        ip_stats_cache_marker = NULL;
119
120         /*********************
121          *
122          *  Kernel & interface information,
123          *   and internal forward declarations
124          *
125          *********************/
126
127
128         /*********************
129          *
130          *  Initialisation & common implementation functions
131          *
132          *********************/
133
134 extern void     init_routes(void);
135
136
137 /*
138  * define the structure we're going to ask the agent to register our
139  * information at 
140  */
141 struct variable3 ip_variables[] = {
142 #ifdef WIN32
143     {IPFORWARDING, ASN_INTEGER, RWRITE, var_ip, 1, {1}},
144     {IPDEFAULTTTL, ASN_INTEGER, RWRITE, var_ip, 1, {2}},
145 #else
146     {IPFORWARDING, ASN_INTEGER, RONLY, var_ip, 1, {1}},
147     {IPDEFAULTTTL, ASN_INTEGER, RONLY, var_ip, 1, {2}},
148 #endif
149 #ifndef sunV3
150     {IPINRECEIVES, ASN_COUNTER, RONLY, var_ip, 1, {3}},
151 #endif
152     {IPINHDRERRORS, ASN_COUNTER, RONLY, var_ip, 1, {4}},
153 #ifndef sunV3
154     {IPINADDRERRORS, ASN_COUNTER, RONLY, var_ip, 1, {5}},
155     {IPFORWDATAGRAMS, ASN_COUNTER, RONLY, var_ip, 1, {6}},
156 #endif
157     {IPINUNKNOWNPROTOS, ASN_COUNTER, RONLY, var_ip, 1, {7}},
158 #ifndef sunV3
159     {IPINDISCARDS, ASN_COUNTER, RONLY, var_ip, 1, {8}},
160     {IPINDELIVERS, ASN_COUNTER, RONLY, var_ip, 1, {9}},
161 #endif
162     {IPOUTREQUESTS, ASN_COUNTER, RONLY, var_ip, 1, {10}},
163     {IPOUTDISCARDS, ASN_COUNTER, RONLY, var_ip, 1, {11}},
164     {IPOUTNOROUTES, ASN_COUNTER, RONLY, var_ip, 1, {12}},
165     {IPREASMTIMEOUT, ASN_INTEGER, RONLY, var_ip, 1, {13}},
166 #ifndef sunV3
167     {IPREASMREQDS, ASN_COUNTER, RONLY, var_ip, 1, {14}},
168     {IPREASMOKS, ASN_COUNTER, RONLY, var_ip, 1, {15}},
169     {IPREASMFAILS, ASN_COUNTER, RONLY, var_ip, 1, {16}},
170 #endif
171     {IPFRAGOKS, ASN_COUNTER, RONLY, var_ip, 1, {17}},
172     {IPFRAGFAILS, ASN_COUNTER, RONLY, var_ip, 1, {18}},
173     {IPFRAGCREATES, ASN_COUNTER, RONLY, var_ip, 1, {19}},
174     {IPADADDR, ASN_IPADDRESS, RONLY, var_ipAddrEntry, 3, {20, 1, 1}},
175     {IPADIFINDEX, ASN_INTEGER, RONLY, var_ipAddrEntry, 3, {20, 1, 2}},
176 #ifndef sunV3
177     {IPADNETMASK, ASN_IPADDRESS, RONLY, var_ipAddrEntry, 3, {20, 1, 3}},
178 #endif
179     {IPADBCASTADDR, ASN_INTEGER, RONLY, var_ipAddrEntry, 3, {20, 1, 4}},
180     {IPADREASMMAX, ASN_INTEGER, RONLY, var_ipAddrEntry, 3, {20, 1, 5}},
181 #ifdef BRCM_SNMP_WRITE_SUPPORT
182     {IPROUTEDEST, ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 3, {21, 1, 1}},
183     {IPROUTEIFINDEX, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 2}},
184     {IPROUTEMETRIC1, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 3}},
185     {IPROUTEMETRIC2, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 4}},
186     {IPROUTEMETRIC3, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 5}},
187     {IPROUTEMETRIC4, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 6}},
188     {IPROUTENEXTHOP, ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 3,
189      {21, 1, 7}},
190     {IPROUTETYPE, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 8}},
191     {IPROUTEPROTO, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 9}},
192     {IPROUTEAGE, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3, {21, 1, 10}},
193     {IPROUTEMASK, ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 3, {21, 1, 11}},
194     {IPROUTEMETRIC5, ASN_INTEGER, RWRITE, var_ipRouteEntry, 3,
195      {21, 1, 12}},
196     {IPROUTEINFO, ASN_OBJECT_ID, RONLY, var_ipRouteEntry, 3, {21, 1, 13}},
197 #else
198     {IPROUTEDEST, ASN_IPADDRESS, RONLY, var_ipRouteEntry, 3, {21, 1, 1}},
199     {IPROUTEIFINDEX, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 2}},
200     {IPROUTEMETRIC1, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 3}},
201     {IPROUTEMETRIC2, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 4}},
202     {IPROUTEMETRIC3, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 5}},
203     {IPROUTEMETRIC4, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 6}},
204     {IPROUTENEXTHOP, ASN_IPADDRESS, RONLY, var_ipRouteEntry, 3,
205      {21, 1, 7}},
206     {IPROUTETYPE, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 8}},
207     {IPROUTEPROTO, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 9}},
208     {IPROUTEAGE, ASN_INTEGER, RONLY, var_ipRouteEntry, 3, {21, 1, 10}},
209     {IPROUTEMASK, ASN_IPADDRESS, RONLY, var_ipRouteEntry, 3, {21, 1, 11}},
210     {IPROUTEMETRIC5, ASN_INTEGER, RONLY, var_ipRouteEntry, 3,
211      {21, 1, 12}},
212     {IPROUTEINFO, ASN_OBJECT_ID, RONLY, var_ipRouteEntry, 3, {21, 1, 13}},
213 #endif /* BRCM_SNMP_WRITE_SUPPORT */
214 #ifdef USING_MIBII_AT_MODULE
215 #ifdef WIN32
216     {IPMEDIAIFINDEX, ASN_INTEGER, RWRITE, var_atEntry, 3, {22, 1, 1}},
217     {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, RWRITE, var_atEntry, 3,
218      {22, 1, 2}},
219     {IPMEDIANETADDRESS, ASN_IPADDRESS, RWRITE, var_atEntry, 3, {22, 1, 3}},
220     {IPMEDIATYPE, ASN_INTEGER, RWRITE, var_atEntry, 3, {22, 1, 4}},
221 #else
222 #ifdef SNMP_AT_MIB
223     {IPMEDIAIFINDEX, ASN_INTEGER, RONLY, var_atEntry, 3, {22, 1, 1}},
224     {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 3, {22, 1, 2}},
225     {IPMEDIANETADDRESS, ASN_IPADDRESS, RONLY, var_atEntry, 3, {22, 1, 3}},
226     {IPMEDIATYPE, ASN_INTEGER, RONLY, var_atEntry, 3, {22, 1, 4}},
227 #endif /* SNMP_AT_MIB */
228 #endif
229 #endif
230     {IPROUTEDISCARDS, ASN_COUNTER, RONLY, var_ip, 1, {23}}
231 };
232
233 /*
234  * Define the OID pointer to the top of the mib tree that we're
235  * registering underneath, and the OID of the MIB module 
236  */
237 oid             ip_variables_oid[] = { SNMP_OID_MIB2, 4 };
238 oid             ip_module_oid[] = { SNMP_OID_MIB2, 4 };
239 oid             ip_module_oid_len = sizeof(ip_module_oid) / sizeof(oid);
240 int             ip_module_count = 0;    /* Need to liaise with icmp.c */
241
242 void
243 init_ip(void)
244 {
245     /*
246      * register ourselves with the agent to handle our mib tree 
247      */
248     REGISTER_MIB("mibII/ip", ip_variables, variable3, ip_variables_oid);
249
250 #ifdef SNMP_SYSOR_MIB
251     if (++ip_module_count == 2)
252         REGISTER_SYSOR_ENTRY(ip_module_oid,
253                              "The MIB module for managing IP and ICMP implementations");
254 #endif /* SNMP_SYSOR_MIB */
255
256     /*
257      * for speed optimization, we call this now to do the lookup 
258      */
259 #ifdef IPSTAT_SYMBOL
260     auto_nlist(IPSTAT_SYMBOL, 0, 0);
261 #endif
262 #ifdef IP_FORWARDING_SYMBOL
263     auto_nlist(IP_FORWARDING_SYMBOL, 0, 0);
264 #endif
265 #ifdef TCP_TTL_SYMBOL
266     auto_nlist(TCP_TTL_SYMBOL, 0, 0);
267 #endif
268 #ifdef MIB_IPCOUNTER_SYMBOL
269     auto_nlist(MIB_IPCOUNTER_SYMBOL, 0, 0);
270 #endif
271 #ifdef solaris2
272     init_kernel_sunos5();
273 #endif
274 }
275
276
277         /*********************
278          *
279          *  System specific implementation functions
280          *
281          *********************/
282
283 #ifdef linux
284 #define IP_STAT_STRUCTURE       struct ip_mib
285 #define USES_SNMP_DESIGNED_IPSTAT
286 #endif
287
288 #ifdef solaris2
289 #define IP_STAT_STRUCTURE       mib2_ip_t
290 #define USES_SNMP_DESIGNED_IPSTAT
291 #endif
292
293 #ifdef hpux11
294 #define IP_STAT_STRUCTURE       int
295 #endif
296
297 #ifdef HAVE_SYS_TCPIPSTATS_H
298 #define IP_STAT_STRUCTURE       struct kna
299 #define USES_TRADITIONAL_IPSTAT
300 #endif
301
302 #ifdef WIN32
303 #include <iphlpapi.h>
304 #define IP_STAT_STRUCTURE MIB_IPSTATS
305 WriteMethod     writeIpStats;
306 long            ipForwarding;
307 long            oldipForwarding;
308 long            ipTTL, oldipTTL;
309 #endif                          /* WIN32 */
310
311 #if !defined(IP_STAT_STRUCTURE)
312 #define IP_STAT_STRUCTURE       struct ipstat
313 #define USES_TRADITIONAL_IPSTAT
314 #endif
315
316 long            read_ip_stat(IP_STAT_STRUCTURE *, int);
317
318 u_char         *
319 var_ip(struct variable *vp,
320        oid * name,
321        size_t * length,
322        int exact, size_t * var_len, WriteMethod ** write_method)
323 {
324     static IP_STAT_STRUCTURE ipstat;
325     static long     ret_value;
326
327     if (header_generic(vp, name, length, exact, var_len, write_method) ==
328         MATCH_FAILED)
329         return NULL;
330
331     ret_value = read_ip_stat(&ipstat, vp->magic);
332     if (ret_value < 0)
333         return NULL;
334
335 #ifdef HAVE_SYS_TCPIPSTATS_H
336     /*
337      * This actually reads statistics for *all* the groups together,
338      * so we need to isolate the IP-specific bits.  
339      */
340 #define ipstat          ipstat.ipstat
341 #endif
342
343     switch (vp->magic) {
344 #ifdef USES_SNMP_DESIGNED_IPSTAT
345     case IPFORWARDING:
346         return (u_char *) & ipstat.ipForwarding;
347     case IPDEFAULTTTL:
348         return (u_char *) & ipstat.ipDefaultTTL;
349     case IPINRECEIVES:
350         return (u_char *) & ipstat.ipInReceives;
351     case IPINHDRERRORS:
352         return (u_char *) & ipstat.ipInHdrErrors;
353     case IPINADDRERRORS:
354         return (u_char *) & ipstat.ipInAddrErrors;
355     case IPFORWDATAGRAMS:
356         return (u_char *) & ipstat.ipForwDatagrams;
357     case IPINUNKNOWNPROTOS:
358         return (u_char *) & ipstat.ipInUnknownProtos;
359     case IPINDISCARDS:
360         return (u_char *) & ipstat.ipInDiscards;
361     case IPINDELIVERS:
362         return (u_char *) & ipstat.ipInDelivers;
363     case IPOUTREQUESTS:
364         return (u_char *) & ipstat.ipOutRequests;
365     case IPOUTDISCARDS:
366         return (u_char *) & ipstat.ipOutDiscards;
367     case IPOUTNOROUTES:
368         return (u_char *) & ipstat.ipOutNoRoutes;
369     case IPREASMTIMEOUT:
370         return (u_char *) & ipstat.ipReasmTimeout;
371     case IPREASMREQDS:
372         return (u_char *) & ipstat.ipReasmReqds;
373     case IPREASMOKS:
374         return (u_char *) & ipstat.ipReasmOKs;
375     case IPREASMFAILS:
376         return (u_char *) & ipstat.ipReasmFails;
377     case IPFRAGOKS:
378         return (u_char *) & ipstat.ipFragOKs;
379     case IPFRAGFAILS:
380         return (u_char *) & ipstat.ipFragFails;
381     case IPFRAGCREATES:
382         return (u_char *) & ipstat.ipFragCreates;
383     case IPROUTEDISCARDS:
384         return (u_char *) & ipstat.ipRoutingDiscards;
385 #endif
386
387
388
389 #ifdef USES_TRADITIONAL_IPSTAT
390     case IPFORWARDING:
391         return (u_char *) & ret_value;
392     case IPDEFAULTTTL:
393         return (u_char *) & ret_value;
394     case IPINRECEIVES:
395         long_return = ipstat.ips_total;
396         return (u_char *) & long_return;
397     case IPINHDRERRORS:
398         long_return = ipstat.ips_badsum
399             + ipstat.ips_tooshort
400             + ipstat.ips_toosmall + ipstat.ips_badhlen + ipstat.ips_badlen;
401         return (u_char *) & long_return;
402     case IPINADDRERRORS:
403         long_return = ipstat.ips_cantforward;
404         return (u_char *) & long_return;
405     case IPFORWDATAGRAMS:
406         long_return = ipstat.ips_forward;
407         return (u_char *) & long_return;
408     case IPINUNKNOWNPROTOS:
409 #if STRUCT_IPSTAT_HAS_IPS_NOPROTO
410         long_return = ipstat.ips_noproto;
411         return (u_char *) & long_return;
412 #else
413         return NULL;
414 #endif
415     case IPINDISCARDS:
416 #if STRUCT_IPSTAT_HAS_IPS_FRAGDROPPED
417         long_return = ipstat.ips_fragdropped;   /* ?? */
418         return (u_char *) & long_return;
419 #else
420         return NULL;
421 #endif
422     case IPINDELIVERS:
423 #if STRUCT_IPSTAT_HAS_IPS_DELIVERED
424         long_return = ipstat.ips_delivered;
425         return (u_char *) & long_return;
426 #else
427         return NULL;
428 #endif
429     case IPOUTREQUESTS:
430 #if STRUCT_IPSTAT_HAS_IPS_LOCALOUT
431         long_return = ipstat.ips_localout;
432         return (u_char *) & long_return;
433 #else
434         return NULL;
435 #endif
436     case IPOUTDISCARDS:
437 #if STRUCT_IPSTAT_HAS_IPS_ODROPPED
438         long_return = ipstat.ips_odropped;
439         return (u_char *) & long_return;
440 #else
441         return NULL;
442 #endif
443     case IPOUTNOROUTES:
444         /*
445          * XXX: how to calculate this (counts dropped routes, not packets)?
446          * ipstat.ips_cantforward isn't right, as it counts packets.
447          * ipstat.ips_noroute is also incorrect.
448          */
449         return NULL;
450     case IPREASMTIMEOUT:
451         long_return = IPFRAGTTL;
452         return (u_char *) & long_return;
453     case IPREASMREQDS:
454         long_return = ipstat.ips_fragments;
455         return (u_char *) & long_return;
456     case IPREASMOKS:
457 #if STRUCT_IPSTAT_HAS_IPS_REASSEMBLED
458         long_return = ipstat.ips_reassembled;
459         return (u_char *) & long_return;
460 #else
461         return NULL;
462 #endif
463     case IPREASMFAILS:
464         long_return = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
465         return (u_char *) & long_return;
466     case IPFRAGOKS:            /* XXX */
467         long_return = ipstat.ips_fragments
468             - (ipstat.ips_fragdropped + ipstat.ips_fragtimeout);
469         return (u_char *) & long_return;
470     case IPFRAGFAILS:
471 #if STRUCT_IPSTAT_HAS_IPS_CANTFRAG
472         long_return = ipstat.ips_cantfrag;
473         return (u_char *) & long_return;
474 #else
475         return NULL;
476 #endif
477     case IPFRAGCREATES:
478 #if STRUCT_IPSTAT_HAS_IPS_OFRAGMENTS
479         long_return = ipstat.ips_ofragments;
480         return (u_char *) & long_return;
481 #else
482         return NULL;
483 #endif
484     case IPROUTEDISCARDS:
485 #if STRUCT_IPSTAT_HAS_IPS_NOROUTE
486         long_return = ipstat.ips_noroute;
487         return (u_char *) & long_return;
488 #else
489         return NULL;
490 #endif
491
492 #endif                          /* USE_TRADITIONAL_IPSTAT */
493 #ifdef WIN32
494     case IPFORWARDING:
495         *write_method = writeIpStats;
496         ipForwarding = ipstat.dwForwarding;
497         return (u_char *) & ipstat.dwForwarding;
498     case IPDEFAULTTTL:
499         *write_method = writeIpStats;
500         ipTTL = ipstat.dwDefaultTTL;
501         return (u_char *) & ipstat.dwDefaultTTL;
502     case IPINRECEIVES:
503         return (u_char *) & ipstat.dwInReceives;
504     case IPINHDRERRORS:
505         return (u_char *) & ipstat.dwInHdrErrors;
506     case IPINADDRERRORS:
507         return (u_char *) & ipstat.dwInAddrErrors;
508     case IPFORWDATAGRAMS:
509         return (u_char *) & ipstat.dwForwDatagrams;
510     case IPINUNKNOWNPROTOS:
511         return (u_char *) & ipstat.dwInUnknownProtos;
512     case IPINDISCARDS:
513         return (u_char *) & ipstat.dwInDiscards;
514     case IPINDELIVERS:
515         return (u_char *) & ipstat.dwInDelivers;
516     case IPOUTREQUESTS:
517         return (u_char *) & ipstat.dwOutRequests;
518     case IPOUTDISCARDS:
519         return (u_char *) & ipstat.dwOutDiscards;
520     case IPOUTNOROUTES:
521         return (u_char *) & ipstat.dwOutNoRoutes;
522     case IPREASMTIMEOUT:
523         return (u_char *) & ipstat.dwReasmTimeout;
524     case IPREASMREQDS:
525         return (u_char *) & ipstat.dwReasmReqds;
526     case IPREASMOKS:
527         return (u_char *) & ipstat.dwReasmOks;
528     case IPREASMFAILS:
529         return (u_char *) & ipstat.dwReasmFails;
530     case IPFRAGOKS:
531         return (u_char *) & ipstat.dwFragOks;
532     case IPFRAGFAILS:
533         return (u_char *) & ipstat.dwFragFails;
534     case IPFRAGCREATES:
535         return (u_char *) & ipstat.dwFragCreates;
536     case IPROUTEDISCARDS:
537         return (u_char *) & ipstat.dwRoutingDiscards;
538 #endif                          /* WIN32 */
539
540     default:
541         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ip\n", vp->magic));
542     }
543     return NULL;
544
545 #ifdef HAVE_SYS_TCPIPSTATS_H
546 #undef  ipstat
547 #endif
548 }
549
550
551
552         /*********************
553          *
554          *  Internal implementation functions
555          *
556          *********************/
557
558 long
559 read_ip_stat(IP_STAT_STRUCTURE * ipstat, int magic)
560 {
561     long            ret_value = 0;
562 #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS))
563     int             i;
564 #endif
565 #if !(defined (linux) || defined(solaris2))
566     static int      ttl, forward;
567 #endif
568 #ifdef hpux11
569     int             fd;
570     struct nmparms  p;
571     unsigned int    ulen;
572 #endif
573
574 #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS))
575     static int      sname[4] = { CTL_NET, PF_INET, IPPROTO_IP, 0 };
576     size_t          len;
577 #endif
578
579 #ifdef hpux11
580     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0)
581         return (-1);            /* error */
582
583     switch (magic) {
584     case IPFORWARDING:
585         p.objid = ID_ipForwarding;
586         break;
587     case IPDEFAULTTTL:
588         p.objid = ID_ipDefaultTTL;
589         break;
590     case IPINRECEIVES:
591         p.objid = ID_ipInReceives;
592         break;
593     case IPINHDRERRORS:
594         p.objid = ID_ipInHdrErrors;
595         break;
596     case IPINADDRERRORS:
597         p.objid = ID_ipInAddrErrors;
598         break;
599     case IPFORWDATAGRAMS:
600         p.objid = ID_ipForwDatagrams;
601         break;
602     case IPINUNKNOWNPROTOS:
603         p.objid = ID_ipInUnknownProtos;
604         break;
605     case IPINDISCARDS:
606         p.objid = ID_ipInDiscards;
607         break;
608     case IPINDELIVERS:
609         p.objid = ID_ipInDelivers;
610         break;
611     case IPOUTREQUESTS:
612         p.objid = ID_ipOutRequests;
613         break;
614     case IPOUTDISCARDS:
615         p.objid = ID_ipOutDiscards;
616         break;
617     case IPOUTNOROUTES:
618         p.objid = ID_ipOutNoRoutes;
619         break;
620     case IPREASMTIMEOUT:
621         p.objid = ID_ipReasmTimeout;
622         break;
623     case IPREASMREQDS:
624         p.objid = ID_ipReasmReqds;
625         break;
626     case IPREASMOKS:
627         p.objid = ID_ipReasmOKs;
628         break;
629     case IPREASMFAILS:
630         p.objid = ID_ipReasmFails;
631         break;
632     case IPFRAGOKS:
633         p.objid = ID_ipFragOKs;
634         break;
635     case IPFRAGFAILS:
636         p.objid = ID_ipFragFails;
637         break;
638     case IPFRAGCREATES:
639         p.objid = ID_ipFragCreates;
640         break;
641     case IPROUTEDISCARDS:
642         p.objid = ID_ipRoutingDiscards;
643         break;
644     default:
645         *ipstat = 0;
646         close_mib(fd);
647         return (0);
648     }
649
650     p.buffer = (void *) ipstat;
651     ulen = sizeof(IP_STAT_STRUCTURE);
652     p.len = &ulen;
653     ret_value = get_mib_info(fd, &p);
654     close_mib(fd);
655
656     return (ret_value);         /* 0: ok, < 0: error */
657 #else                           /* hpux11 */
658
659
660     if (ip_stats_cache_marker &&
661         (!atime_ready
662          (ip_stats_cache_marker, IP_STATS_CACHE_TIMEOUT * 1000)))
663 #if !(defined(linux) || defined(solaris2))
664         return ((magic == IPFORWARDING ? forward :
665                  (magic == IPDEFAULTTTL ? ttl : 0)));
666 #else
667         return 0;
668 #endif
669
670     if (ip_stats_cache_marker)
671         atime_setMarker(ip_stats_cache_marker);
672     else
673         ip_stats_cache_marker = atime_newMarker();
674
675
676 #ifdef linux
677     ret_value = linux_read_ip_stat(ipstat);
678 #endif
679
680 #ifdef solaris2
681     ret_value =
682         getMibstat(MIB_IP, ipstat, sizeof(mib2_ip_t), GET_FIRST,
683                    &Get_everything, NULL);
684 #endif
685
686 #ifdef WIN32
687     ret_value = GetIpStatistics(ipstat);
688 #endif
689
690 #if !(defined(linux) || defined(solaris2) || defined(WIN32))
691     if (magic == IPFORWARDING) {
692
693 #if defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)
694         len = sizeof i;
695         sname[3] = IPCTL_FORWARDING;
696         if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
697             forward = -1;
698         else
699             forward = (i ? 1    /* GATEWAY */
700                        : 2 /* HOST    */ );
701 #else
702         if (!auto_nlist
703             (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
704             forward = -1;
705         else
706             forward = (ret_value ? 1    /* GATEWAY */
707                        : 2 /* HOST    */ );
708 #endif
709         if (forward == -1) {
710             free(ip_stats_cache_marker);
711             ip_stats_cache_marker = NULL;
712         }
713         return forward;
714     }
715
716     if (magic == IPDEFAULTTTL) {
717
718 #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS))
719         len = sizeof i;
720         sname[3] = IPCTL_DEFTTL;
721         if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
722             ttl = -1;
723         else
724             ttl = i;
725 #else
726         if (!auto_nlist
727             (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
728             ttl = -1;
729         else
730             ttl = ret_value;
731 #endif
732         if (ttl == -1) {
733             free(ip_stats_cache_marker);
734             ip_stats_cache_marker = NULL;
735         }
736         return ttl;
737     }
738
739 #ifdef HAVE_SYS_TCPIPSTATS_H
740     ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, ipstat, sizeof *ipstat);
741 #endif
742
743 #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS))
744     len = sizeof *ipstat;
745     sname[3] = IPCTL_STATS;
746     ret_value = sysctl(sname, 4, ipstat, &len, 0, 0);
747 #endif
748 #ifdef IPSTAT_SYMBOL
749     if (auto_nlist(IPSTAT_SYMBOL, (char *) ipstat, sizeof(*ipstat)))
750         ret_value = 0;
751 #endif
752 #endif                          /* !(defined(linux) || defined(solaris2)) */
753
754     if (ret_value == -1) {
755         free(ip_stats_cache_marker);
756         ip_stats_cache_marker = NULL;
757     }
758     return ret_value;
759 #endif                          /* hpux11 */
760 }
761
762 #ifdef WIN32
763 int
764 writeIpStats(int action,
765              u_char * var_val,
766              u_char var_val_type,
767              size_t var_val_len,
768              u_char * statP, oid * name, size_t name_len)
769 {
770     long           *buf, *oldbuf;
771     MIB_IPSTATS     ipStats;
772     int             var;
773     int             retval = SNMP_ERR_NOERROR;
774     /*
775      * #define for ip scalar objects are 1 less than corresponding sub-id in MIB
776      * * i.e. IPFORWARDING defined as 0, but ipForwarding registered as 1
777      */
778     var = name[7] - 1;
779     switch (var) {
780     case IPFORWARDING:
781         buf = &ipForwarding;
782         oldbuf = &oldipForwarding;
783         break;
784     case IPDEFAULTTTL:
785         buf = &ipTTL;
786         oldbuf = &oldipTTL;
787         break;
788     default:
789         return SNMP_ERR_NOTWRITABLE;
790     }
791
792     switch (action) {
793     case RESERVE1:             /* Check values for acceptability */
794         if (var_val_type != ASN_INTEGER) {
795             snmp_log(LOG_ERR, "not integer\n");
796             return SNMP_ERR_WRONGTYPE;
797         }
798         if (var_val_len > sizeof(int)) {
799             snmp_log(LOG_ERR, "bad length\n");
800             return SNMP_ERR_WRONGLENGTH;
801         }
802         switch (var) {
803         case IPFORWARDING:
804             if (((int) *var_val < 1) || ((int) *var_val > 2)) {
805                 snmp_log(LOG_ERR, "not supported ip forwarding : %d\n",
806                          *var_val);
807                 return SNMP_ERR_WRONGVALUE;
808             }
809             break;
810         case IPDEFAULTTTL:
811             if ((int) *var_val < 0) {
812                 snmp_log(LOG_ERR, "not supported ip Default : %d\n",
813                          (int) *var_val);
814                 return SNMP_ERR_WRONGVALUE;
815             }
816         }
817         break;
818
819     case RESERVE2:             /* Allocate memory and similar resources */
820         break;
821
822     case ACTION:
823         /*
824          * Save the old value, in case of UNDO 
825          */
826
827         *oldbuf = *buf;
828         *buf = (int) *var_val;
829         break;
830
831     case UNDO:                 /* Reverse the SET action and free resources */
832         *buf = *oldbuf;
833         break;
834
835     case COMMIT:               /* Confirm the SET, performing any irreversible actions,
836                                  * and free resources */
837         switch (var) {
838         case IPFORWARDING:
839             /*
840              * Currently windows supports only ON->OFF 
841              */
842             ipStats.dwForwarding = *buf;
843             ipStats.dwDefaultTTL = MIB_USE_CURRENT_TTL;
844             if (SetIpStatistics(&ipStats) != NO_ERROR) {
845                 retval = SNMP_ERR_COMMITFAILED;
846                 snmp_log(LOG_ERR,
847                          "Can't set ipForwarding, supports only enable->disable \n");
848             }
849             break;
850         case IPDEFAULTTTL:
851             if (SetIpTTL((UINT) * buf) != NO_ERROR) {
852                 retval = SNMP_ERR_COMMITFAILED;
853                 snmp_log(LOG_ERR, "Can't set ipDefaultTTL\n");
854             }
855             break;
856         }
857
858     case FREE:                 /* Free any resources allocated */
859         break;
860     }
861     return retval;
862 }                               /* end of writeIpStats */
863 #endif                          /* WIN32 */
864
865 #else
866 void
867 init_ip(void)
868 {
869 }
870 #endif /* SNMP_IP_MIB */