1 /* $NetBSD: snmp.c,v 1.10 2003/03/05 21:12:26 wiz Exp $ */
4 * Copyright (c) 1992, 2001 Xerox Corporation. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * Neither name of the Xerox, PARC, nor the names of its contributors may be used
17 * to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE XEROX CORPORATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <netinet/in_var.h>
36 #include "snmplib/asn1.h"
37 #include "snmplib/party.h"
38 #include "snmplib/snmp_impl.h"
40 #include "snmpd/snmp_vars.h"
42 in_port_t dest_port
= 0;
53 static struct addrCache addrCache
[10];
56 * Initialize the SNMP part of mrouted
58 int /* returns: 0 on success, true on error */
64 struct partyEntry
*pp
;
65 struct sockaddr_in me
;
66 int index
, sd
, portlist
[32];
69 /* init_mib(); why was this here? */
70 if (read_party_database("/etc/party.conf") > 0){
71 fprintf(stderr
, "Couldn't read party database from /etc/party.conf\n");
74 if (read_context_database("/etc/context.conf") > 0){
75 fprintf(stderr
, "Couldn't read context database from /etc/context.conf\n");
78 if (read_acl_database("/etc/acl.conf") > 0){
79 fprintf(stderr
, "Couldn't read acl database from /etc/acl.conf\n");
82 if (read_view_database("/etc/view.conf") > 0){
83 fprintf(stderr
, "Couldn't read view database from /etc/view.conf\n");
87 myaddr
= get_myaddr();
88 if (ret
= agent_party_init(myaddr
, ".1.3.6.1")){
90 fprintf(stderr
, "Conflict found with initial noAuth/noPriv parties... continuing\n");
91 } else if (ret
== -1){
92 fprintf(stderr
, "Error installing initial noAuth/noPriv parties, exiting\n");
95 fprintf(stderr
, "Unknown error, exiting\n");
100 printf("Opening port(s): ");
103 for(pp
= party_scanNext(); pp
; pp
= party_scanNext()){
104 if ((pp
->partyTDomain
!= DOMAINSNMPUDP
)
105 || bcmp((char *)&myaddr
, pp
->partyTAddress
, 4))
106 continue; /* don't listen for non-local parties */
109 bcopy(pp
->partyTAddress
+ 4, &dest_port
, 2);
110 for(index
= 0; index
< sdlen
; index
++)
111 if (dest_port
== portlist
[index
])
113 if (index
< sdlen
) /* found a hit before the end of the list */
115 printf("%u ", dest_port
);
117 /* Set up connections */
118 sd
= socket(AF_INET
, SOCK_DGRAM
, 0);
123 memset(&me
, 0, sizeof(me
));
124 me
.sin_family
= AF_INET
;
125 me
.sin_addr
.s_addr
= INADDR_ANY
;
126 /* already in network byte order (I think) */
127 me
.sin_port
= dest_port
;
128 if (bind(sd
, (struct sockaddr
*)&me
, sizeof(me
)) != 0){
132 register_input_handler(sd
, snmp_read_packet
);
133 portlist
[sdlen
] = dest_port
;
135 printf("No more sockets... ignoring rest of file\n");
140 bzero((char *)addrCache
, sizeof(addrCache
));
144 * Place an IP address into an OID starting at element n
147 put_address(name
, addr
, n
)
154 for (i
=n
+3; i
>=n
+0; i
--) {
155 name
[i
] = addr
& 0xFF;
160 /* Get an IP address from an OID starting at element n */
162 get_address(name
, length
, addr
, n
)
176 for (i
=n
; i
<n
+4; i
++) {
187 * Implements scalar objects from DVMRP and Multicast MIBs
190 o_scalar(vp
, name
, length
, exact
, var_len
, write_method
)
191 struct variable
*vp
; /* IN - pointer to variable entry that points here */
192 oid
*name
; /* IN/OUT - input name requested, output name found */
193 int *length
; /* IN/OUT - length of input and output oid's */
194 int exact
; /* IN - TRUE if an exact match was requested. */
195 int *var_len
; /* OUT - length of variable or 0 if function returned. */
196 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
201 result
= compare(name
, *length
, vp
->name
, (int)vp
->namelen
);
202 if ((exact
&& (result
!= 0)) || (!exact
&& (result
>= 0)))
205 bcopy((char *)vp
->name
, (char *)name
,
206 (int)vp
->namelen
* sizeof(oid
));
207 *length
= vp
->namelen
;
208 *var_len
= sizeof(long);
214 return (u_char
*) &long_return
;
217 static char buff
[15];
219 snprintf(buff
, sizeof(buff
), "mrouted%d.%d", PROTOCOL_VERSION
,
221 *var_len
= strlen(buff
);
222 return (u_char
*)buff
;
225 case dvmrpGenerationId
:
226 long_return
= dvmrp_genid
;
227 return (u_char
*) &long_return
;
236 * Find if a specific scoped boundary exists on a Vif
239 find_boundary(vifi
, addr
, mask
)
246 for (n
= uvifs
[vifi
].uv_acl
; n
!= NULL
; n
= n
->acl_next
) {
247 if (addr
== n
->acl_addr
&& mask
==n
->acl_mask
)
254 * Find the lowest boundary >= (V,A,M) spec
257 next_boundary(vifi
, addr
, mask
)
262 struct vif_acl
*bestn
, *n
;
265 for (i
= *vifi
; i
< numvifs
; i
++) {
267 for (n
= uvifs
[i
].uv_acl
; n
; n
=n
->acl_next
) {
268 if ((i
> *vifi
|| n
->acl_addr
> addr
269 || (n
->acl_addr
== addr
&& n
->acl_mask
>= mask
))
270 && (!bestn
|| n
->acl_addr
< bestn
->acl_addr
271 || (n
->acl_addr
==bestn
->acl_addr
&& n
->acl_mask
<bestn
->acl_mask
)))
283 * Implements the Boundary Table portion of the DVMRP MIB
286 o_dvmrpBoundaryTable(vp
, name
, length
, exact
, var_len
, write_method
)
287 struct variable
*vp
; /* IN - pointer to variable entry that points here */
288 oid
*name
; /* IN/OUT - input name requested, output name found */
289 int *length
; /* IN/OUT - length of input and output oid's */
290 int exact
; /* IN - TRUE if an exact match was requested. */
291 int *var_len
; /* OUT - length of variable or 0 if function returned. */
292 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
296 struct vif_acl
*bound
;
297 oid newname
[MAX_NAME_LEN
];
300 /* Copy name OID to new OID */
301 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
304 if (*length
!= vp
->namelen
+ 9)
307 if ((vifi
= name
[vp
->namelen
]) >= numvifs
)
310 if (!get_address(name
, *length
, &addr
, vp
->namelen
+1)
311 || !get_address(name
, *length
, &mask
, vp
->namelen
+5))
314 if (!(bound
= find_boundary(vifi
, addr
, mask
)))
317 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
320 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
323 if (len
< vp
->namelen
+ 9) { /* get first entry */
325 if (len
== vp
->namelen
) {
326 vifi
= addr
= mask
= 0;
328 vifi
= name
[vp
->namelen
];
329 get_address(name
, len
, &addr
, vp
->namelen
+1);
330 get_address(name
, len
, &mask
, vp
->namelen
+5);
333 bound
= next_boundary(&vifi
,addr
,mask
);
337 newname
[vp
->namelen
] = vifi
;
338 put_address(newname
, bound
->acl_addr
, vp
->namelen
+1);
339 put_address(newname
, bound
->acl_mask
, vp
->namelen
+5);
340 } else { /* get next entry given previous */
341 vifi
= name
[vp
->namelen
];
342 get_address(name
, *length
, &addr
, vp
->namelen
+1);
343 get_address(name
, *length
, &mask
, vp
->namelen
+5);
345 if (!(bound
= next_boundary(&vifi
,addr
,mask
+1)))
348 newname
[vp
->namelen
] = vifi
;
349 put_address(newname
, bound
->acl_addr
, vp
->namelen
+1);
350 put_address(newname
, bound
->acl_mask
, vp
->namelen
+5);
355 *length
= vp
->namelen
+ 9;
356 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
358 *var_len
= sizeof(long);
362 case dvmrpBoundaryVifIndex
:
364 return (u_char
*) &long_return
;
373 * Find the lowest neighbor >= (V,A) spec
376 next_neighbor(vifi
, addr
)
380 struct listaddr
*bestn
, *n
;
383 for (i
= *vifi
; i
< numvifs
; i
++) {
385 for (n
= uvifs
[i
].uv_neighbors
; n
; n
=n
->al_next
) {
386 if ((i
> *vifi
|| n
->al_addr
>= addr
)
387 && (!bestn
|| n
->al_addr
< bestn
->al_addr
))
399 * Find a neighbor, if it exists off a given Vif
402 find_neighbor(vifi
, addr
)
408 for (n
= uvifs
[vifi
].uv_neighbors
; n
!= NULL
; n
= n
->al_next
) {
409 if (addr
== n
->al_addr
)
416 o_dvmrpNeighborTable(vp
, name
, length
, exact
, var_len
, write_method
)
417 struct variable
*vp
; /* IN - pointer to variable entry that points here */
418 oid
*name
; /* IN/OUT - input name requested, output name found */
419 int *length
; /* IN/OUT - length of input and output oid's */
420 int exact
; /* IN - TRUE if an exact match was requested. */
421 int *var_len
; /* OUT - length of variable or 0 if function returned. */
422 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
426 struct listaddr
*neighbor
;
427 oid newname
[MAX_NAME_LEN
];
430 /* Copy name OID to new OID */
431 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
434 if (*length
!= vp
->namelen
+ 5)
437 if ((vifi
= name
[vp
->namelen
]) >= numvifs
)
440 if (!get_address(name
, *length
, &addr
, vp
->namelen
+1))
443 if (!(neighbor
= find_neighbor(vifi
, addr
)))
446 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
449 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
452 if (len
< vp
->namelen
+ 5) { /* get first entry */
454 if (len
== vp
->namelen
) {
457 vifi
= name
[vp
->namelen
];
458 get_address(name
, len
, &addr
, vp
->namelen
+1);
461 neighbor
= next_neighbor(&vifi
,addr
);
465 newname
[vp
->namelen
] = vifi
;
466 put_address(newname
, neighbor
->al_addr
, vp
->namelen
+1);
467 } else { /* get next entry given previous */
468 vifi
= name
[vp
->namelen
];
469 get_address(name
, *length
, &addr
, vp
->namelen
+1);
471 if (!(neighbor
= next_neighbor(&vifi
,addr
+1)))
474 newname
[vp
->namelen
] = vifi
;
475 put_address(newname
, neighbor
->al_addr
, vp
->namelen
+1);
480 *length
= vp
->namelen
+ 5;
481 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
483 *var_len
= sizeof(long);
487 case dvmrpNeighborUpTime
: {
490 long_return
= (currtime
- neighbor
->al_ctime
)*100;
491 return (u_char
*) &long_return
;
494 case dvmrpNeighborExpiryTime
:
495 long_return
= (NEIGHBOR_EXPIRE_TIME
- neighbor
->al_timer
496 + secs_remaining_offset()) * 100;
497 return (u_char
*) &long_return
;
499 case dvmrpNeighborVersion
: {
500 static char buff
[15];
502 snprintf(buff
, sizeof(buff
), "%d.%d", neighbor
->al_pv
, neighbor
->al_mv
);
503 *var_len
= strlen(buff
);
504 return (u_char
*)buff
;
507 case dvmrpNeighborGenerationId
:
508 long_return
= neighbor
->al_genid
;
509 return (u_char
*) &long_return
;
517 /* Look up ifIndex given uvifs[ifnum].uv_lcl_addr */
518 struct in_ifaddr
* /* returns: in_ifaddr structure, or null on error */
519 ipaddr_to_ifindex(ipaddr
, ifIndex
)
524 static struct in_ifaddr in_ifaddr
;
526 Interface_Scan_Init();
528 if (Interface_Scan_Next(&interface
, (char *)0, NULL
, &in_ifaddr
) == 0)
531 if (((struct sockaddr_in
*) &(in_ifaddr
.ia_addr
))->sin_addr
.s_addr
533 *ifIndex
= interface
;
540 * Find if a specific scoped boundary exists on a Vif
543 find_cache(grp
, vifi
)
549 for (n
= uvifs
[vifi
].uv_groups
; n
!= NULL
; n
= n
->al_next
) {
550 if (grp
== n
->al_addr
)
557 * Find the next group cache entry >= (A,V) spec
560 next_cache(addr
, vifi
)
564 struct listaddr
*bestn
=NULL
, *n
;
567 /* Step through all entries looking for the next one */
568 for (i
= 0; i
< numvifs
; i
++) {
569 for (n
= uvifs
[i
].uv_groups
; n
; n
=n
->al_next
) {
570 if ((n
->al_addr
> addr
|| (n
->al_addr
== addr
&& i
>= *vifi
))
571 && (!bestn
|| n
->al_addr
< bestn
->al_addr
572 || (n
->al_addr
== bestn
->al_addr
&& i
< besti
))) {
587 * Implements the IGMP Cache Table portion of the IGMP MIB
590 o_igmpCacheTable(vp
, name
, length
, exact
, var_len
, write_method
)
591 struct variable
*vp
; /* IN - pointer to variable entry that points here */
592 oid
*name
; /* IN/OUT - input name requested, output name found */
593 int *length
; /* IN/OUT - length of input and output oid's */
594 int exact
; /* IN - TRUE if an exact match was requested. */
595 int *var_len
; /* OUT - length of variable or 0 if function returned. */
596 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
601 struct listaddr
*cache
;
602 oid newname
[MAX_NAME_LEN
];
604 struct in_ifaddr
*in_ifaddr
;
605 struct in_multi in_multi
, *inm
;
607 /* Copy name OID to new OID */
608 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
611 if (*length
!= vp
->namelen
+ 5)
614 if ((vifi
= name
[vp
->namelen
+4]) >= numvifs
)
617 if (!get_address(name
, *length
, &grp
, vp
->namelen
))
620 if (!(cache
= find_cache(grp
, vifi
)))
623 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
626 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
629 if (len
< vp
->namelen
+ 5) { /* get first entry */
631 if (len
== vp
->namelen
) {
634 get_address(name
, len
, &grp
, vp
->namelen
);
635 vifi
= name
[vp
->namelen
+4];
638 cache
= next_cache(grp
,&vifi
);
642 put_address(newname
, cache
->al_addr
, vp
->namelen
);
643 newname
[vp
->namelen
+4] = vifi
;
644 } else { /* get next entry given previous */
645 get_address(name
, *length
, &grp
, vp
->namelen
);
646 vifi
= name
[vp
->namelen
+4]+1;
648 if (!(cache
= next_cache(grp
,&vifi
)))
651 put_address(newname
, cache
->al_addr
, vp
->namelen
);
652 newname
[vp
->namelen
+4] = vifi
;
657 *length
= vp
->namelen
+ 5;
658 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
660 *var_len
= sizeof(long);
662 /* Look up ifIndex given uvifs[vifi].uv_lcl_addr */
663 in_ifaddr
= ipaddr_to_ifindex(uvifs
[vifi
].uv_lcl_addr
, &ifIndex
);
668 inm
= in_ifaddr
->ia_multiaddrs
;
670 klookup( (int)inm
, (char *)&in_multi
, sizeof(in_multi
));
672 if (in_multi
.inm_addr
.s_addr
== cache
->al_addr
) {
673 long_return
= 1; /* true */
674 return (u_char
*) &long_return
;
677 inm
= in_multi
.inm_next
;
679 long_return
= 2; /* false */
680 return (u_char
*) &long_return
;
682 case igmpCacheLastReporter
:
683 return (u_char
*) &cache
->al_genid
;
685 case igmpCacheUpTime
: {
688 long_return
= (currtime
- cache
->al_ctime
)*100;
689 return (u_char
*) &long_return
;
692 case igmpCacheExpiryTime
:
693 long_return
= secs_remaining(cache
->al_timerid
)*100;
694 return (u_char
*) &long_return
;
696 case igmpCacheStatus
:
698 return (u_char
*) &long_return
;
707 * Implements the IGMP Interface Table portion of the IGMP MIB
710 o_igmpInterfaceTable(vp
, name
, length
, exact
, var_len
, write_method
)
711 struct variable
*vp
; /* IN - pointer to variable entry that points here */
712 oid
*name
; /* IN/OUT - input name requested, output name found */
713 int *length
; /* IN/OUT - length of input and output oid's */
714 int exact
; /* IN - TRUE if an exact match was requested. */
715 int *var_len
; /* OUT - length of variable or 0 if function returned. */
716 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
718 oid newname
[MAX_NAME_LEN
];
721 static struct sioc_vif_req v_req
;
723 /* Copy name OID to new OID */
724 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
726 /* find "next" interface */
727 for(ifnum
= 0; ifnum
< numvifs
; ifnum
++){
728 if (!(uvifs
[ifnum
].uv_flags
& VIFF_QUERIER
))
730 newname
[vp
->namelen
] = (oid
)ifnum
;
731 result
= compare(name
, *length
, newname
, (int)vp
->namelen
+ 1);
732 if ((exact
&& (result
== 0)) || (!exact
&& (result
< 0)))
735 if (ifnum
>= numvifs
)
739 bcopy((char *)newname
, (char *)name
, ((int)vp
->namelen
+ 1) * sizeof(oid
));
740 *length
= vp
->namelen
+ 1;
742 *var_len
= sizeof(long);
746 case igmpInterfaceQueryInterval
:
747 long_return
= GROUP_QUERY_INTERVAL
;
748 return (u_char
*) &long_return
;
750 case igmpInterfaceStatus
:
751 long_return
= 1; /* active */
752 return (u_char
*) &long_return
;
761 * Given a virtual interface number, make sure we have the current
762 * kernel information for that Vif.
764 refresh_vif(v_req
, ifnum
)
765 struct sioc_vif_req
*v_req
;
768 static int lastq
= -1;
770 if (quantum
!=lastq
|| v_req
->vifi
!= ifnum
) {
773 if (ioctl(igmp_socket
, SIOCGETVIFCNT
, (char *)v_req
) < 0)
774 v_req
->icount
= v_req
->ocount
= v_req
->ibytes
= v_req
->obytes
= 0;
779 * Implements the Multicast Routing Interface Table portion of the Multicast MIB
782 o_ipMRouteInterfaceTable(vp
, name
, length
, exact
, var_len
, write_method
)
783 struct variable
*vp
; /* IN - pointer to variable entry that points here */
784 oid
*name
; /* IN/OUT - input name requested, output name found */
785 int *length
; /* IN/OUT - length of input and output oid's */
786 int exact
; /* IN - TRUE if an exact match was requested. */
787 int *var_len
; /* OUT - length of variable or 0 if function returned. */
788 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
790 oid newname
[MAX_NAME_LEN
];
793 static struct sioc_vif_req v_req
;
795 /* Copy name OID to new OID */
796 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
798 /* find "next" interface */
799 for(ifnum
= 0; ifnum
< numvifs
; ifnum
++){
800 newname
[vp
->namelen
] = (oid
)ifnum
;
801 result
= compare(name
, *length
, newname
, (int)vp
->namelen
+ 1);
802 if ((exact
&& (result
== 0)) || (!exact
&& (result
< 0)))
805 if (ifnum
>= numvifs
)
809 bcopy((char *)newname
, (char *)name
, ((int)vp
->namelen
+ 1) * sizeof(oid
));
810 *length
= vp
->namelen
+ 1;
812 *var_len
= sizeof(long);
816 case ipMRouteInterfaceTtl
:
817 long_return
= uvifs
[ifnum
].uv_threshold
;
818 return (u_char
*) &long_return
;
820 case dvmrpVInterfaceType
:
821 if (uvifs
[ifnum
].uv_flags
& VIFF_SRCRT
)
823 else if (uvifs
[ifnum
].uv_flags
& VIFF_TUNNEL
)
825 else if (uvifs
[ifnum
].uv_flags
& VIFF_QUERIER
)
829 return (u_char
*) &long_return
;
831 case dvmrpVInterfaceState
:
832 if (uvifs
[ifnum
].uv_flags
& VIFF_DISABLED
)
834 else if ((uvifs
[ifnum
].uv_flags
& VIFF_DOWN
)
835 || ((uvifs
[ifnum
].uv_flags
& VIFF_TUNNEL
) && (uvifs
[ifnum
].uv_neighbors
==NULL
)))
839 return (u_char
*) &long_return
;
841 case dvmrpVInterfaceLocalAddress
:
842 return (u_char
*) &uvifs
[ifnum
].uv_lcl_addr
;
844 case dvmrpVInterfaceRemoteAddress
:
845 return (u_char
*) ((uvifs
[ifnum
].uv_flags
& VIFF_TUNNEL
) ?
846 &uvifs
[ifnum
].uv_rmt_addr
:
847 &uvifs
[ifnum
].uv_subnet
);
849 case dvmrpVInterfaceRemoteSubnetMask
:
850 return (u_char
*) &uvifs
[ifnum
].uv_subnetmask
;
852 case dvmrpVInterfaceMetric
:
853 long_return
= uvifs
[ifnum
].uv_metric
;
854 return (u_char
*) &long_return
;
856 case dvmrpVInterfaceRateLimit
:
857 long_return
= uvifs
[ifnum
].uv_rate_limit
;
858 return (u_char
*) &long_return
;
860 case dvmrpVInterfaceInPkts
:
861 refresh_vif(&v_req
, ifnum
);
862 long_return
= v_req
.icount
;
863 return (u_char
*) &long_return
;
865 case dvmrpVInterfaceOutPkts
:
866 refresh_vif(&v_req
, ifnum
);
867 long_return
= v_req
.ocount
;
868 return (u_char
*) &long_return
;
870 case dvmrpVInterfaceInOctets
:
871 refresh_vif(&v_req
, ifnum
);
872 long_return
= v_req
.ibytes
;
873 return (u_char
*) &long_return
;
875 case dvmrpVInterfaceOutOctets
:
876 refresh_vif(&v_req
, ifnum
);
877 long_return
= v_req
.obytes
;
878 return (u_char
*) &long_return
;
887 * Implements the DVMRP Route Table portion of the DVMRP MIB
890 o_dvmrpRouteTable(vp
, name
, length
, exact
, var_len
, write_method
)
891 struct variable
*vp
; /* IN - pointer to variable entry that points here */
892 oid
*name
; /* IN/OUT - input name requested, output name found */
893 int *length
; /* IN/OUT - length of input and output oid's */
894 int exact
; /* IN - TRUE if an exact match was requested. */
895 int *var_len
; /* OUT - length of variable or 0 if function returned. */
896 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
899 oid newname
[MAX_NAME_LEN
];
901 struct rtentry
*rt
= NULL
;
903 /* Copy name OID to new OID */
904 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
907 if (*length
!= vp
->namelen
+ 8)
910 if (!get_address(name
, *length
, &src
, vp
->namelen
)
911 || !get_address(name
, *length
, &mask
, vp
->namelen
+4))
914 if (!(rt
= snmp_find_route(src
, mask
)))
917 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
920 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
923 if (len
< vp
->namelen
+ 8) { /* get first entry */
925 if (len
== vp
->namelen
) {
928 get_address(name
, len
, &src
, vp
->namelen
);
929 get_address(name
, len
, &mask
, vp
->namelen
+4);
932 if (!next_route(&rt
,src
,mask
)) /* Get first entry */
935 put_address(newname
, rt
->rt_origin
, vp
->namelen
);
936 put_address(newname
, rt
->rt_originmask
, vp
->namelen
+4);
937 } else { /* get next entry given previous */
938 get_address(name
, *length
, &src
, vp
->namelen
);
939 get_address(name
, *length
, &mask
, vp
->namelen
+4);
941 if (!next_route(&rt
, src
,mask
))
944 put_address(newname
, rt
->rt_origin
, vp
->namelen
);
945 put_address(newname
, rt
->rt_originmask
, vp
->namelen
+4);
950 *length
= vp
->namelen
+ 8;
951 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
953 *var_len
= sizeof(long);
957 case dvmrpRouteUpstreamNeighbor
:
958 return (u_char
*) &rt
->rt_gateway
;
960 case dvmrpRouteInVifIndex
:
961 long_return
= rt
->rt_parent
;
962 return (u_char
*) &long_return
;
964 case dvmrpRouteMetric
:
965 long_return
= rt
->rt_metric
;
966 return (u_char
*) &long_return
;
968 case dvmrpRouteExpiryTime
:
969 long_return
= (ROUTE_EXPIRE_TIME
- rt
->rt_timer
970 + secs_remaining_offset()) * 100;
971 return (u_char
*) &long_return
;
980 * Implements the DVMRP Routing Next Hop Table portion of the DVMRP MIB
983 o_dvmrpRouteNextHopTable(vp
, name
, length
, exact
, var_len
, write_method
)
984 struct variable
*vp
; /* IN - pointer to variable entry that points here */
985 oid
*name
; /* IN/OUT - input name requested, output name found */
986 int *length
; /* IN/OUT - length of input and output oid's */
987 int exact
; /* IN - TRUE if an exact match was requested. */
988 int *var_len
; /* OUT - length of variable or 0 if function returned. */
989 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
993 struct rtentry
*rt
= NULL
;
994 oid newname
[MAX_NAME_LEN
];
997 /* Copy name OID to new OID */
998 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
1001 if (*length
!= vp
->namelen
+ 9)
1004 if (!get_address(name
, *length
, &src
, vp
->namelen
)
1005 || !get_address(name
, *length
, &mask
, vp
->namelen
+4)
1006 || (!(rt
=snmp_find_route(src
,mask
))))
1009 vifi
= name
[vp
->namelen
+8];
1010 if (!(VIFM_ISSET(vifi
, rt
->rt_children
)))
1013 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
1016 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
1019 if (len
< vp
->namelen
+ 9) { /* get first entry */
1021 get_address(name
, len
, &src
, vp
->namelen
);
1022 get_address(name
, len
, &mask
, vp
->namelen
+4);
1024 /* Find first child vif */
1026 if (!next_route_child(&rt
, src
, mask
, &vifi
))
1029 put_address(newname
, rt
->rt_origin
, vp
->namelen
);
1030 put_address(newname
, rt
->rt_originmask
, vp
->namelen
+4);
1031 newname
[vp
->namelen
+8] = vifi
;
1032 } else { /* get next entry given previous */
1033 vifi
= name
[vp
->namelen
+8] + 1;
1034 if (!get_address(name
, *length
, &src
, vp
->namelen
)
1035 || !get_address(name
, *length
, &mask
, vp
->namelen
+4)
1036 || !next_route_child(&rt
, src
, mask
, &vifi
))
1039 put_address(newname
, rt
->rt_origin
, vp
->namelen
);
1040 put_address(newname
, rt
->rt_originmask
, vp
->namelen
+4);
1041 newname
[vp
->namelen
+8] = vifi
;
1046 *length
= vp
->namelen
+ 9;
1047 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
1049 *var_len
= sizeof(long);
1051 switch (vp
->magic
) {
1053 case dvmrpRouteNextHopType
:
1054 long_return
= (VIFM_ISSET(vifi
, rt
->rt_leaves
))? 1 : 2;
1055 return (u_char
*) &long_return
;
1064 * Implements the IP Multicast Route Table portion of the Multicast MIB
1067 o_ipMRouteTable(vp
, name
, length
, exact
, var_len
, write_method
)
1068 struct variable
*vp
; /* IN - pointer to variable entry that points here */
1069 oid
*name
; /* IN/OUT - input name requested, output name found */
1070 int *length
; /* IN/OUT - length of input and output oid's */
1071 int exact
; /* IN - TRUE if an exact match was requested. */
1072 int *var_len
; /* OUT - length of variable or 0 if function returned. */
1073 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
1075 u_long src
, grp
, mask
;
1076 struct gtable
*gt
= NULL
;
1077 struct stable
*st
= NULL
;
1078 static struct sioc_sg_req sg_req
;
1079 oid newname
[MAX_NAME_LEN
];
1082 /* Copy name OID to new OID */
1083 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
1086 if (*length
!= vp
->namelen
+ 12)
1089 if (!get_address(name
, *length
, &grp
, vp
->namelen
)
1090 || !get_address(name
, *length
, &src
, vp
->namelen
+4)
1091 || !get_address(name
, *length
, &mask
, vp
->namelen
+8)
1092 || (mask
!= 0xFFFFFFFF) /* we keep sources now, not subnets */
1093 || !(gt
= find_grp(grp
))
1094 || !(st
= find_grp_src(gt
,src
)))
1097 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
1100 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
1103 if (len
< vp
->namelen
+ 12) { /* get first entry */
1105 get_address(name
, len
, &grp
, vp
->namelen
);
1106 get_address(name
, len
, &src
, vp
->namelen
+4);
1107 get_address(name
, len
, &mask
, vp
->namelen
+8);
1109 if (!next_grp_src_mask(>
,&st
,grp
,src
,mask
)) /* Get first entry */
1112 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
);
1113 put_address(newname
, st
->st_origin
, vp
->namelen
+4);
1114 put_address(newname
, 0xFFFFFFFF, vp
->namelen
+8);
1115 } else { /* get next entry given previous */
1116 get_address(name
, *length
, &grp
, vp
->namelen
);
1117 get_address(name
, *length
, &src
, vp
->namelen
+4);
1118 get_address(name
, *length
, &mask
, vp
->namelen
+8);
1120 if (!next_grp_src_mask(>
, &st
, grp
,src
,mask
))
1123 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
);
1124 put_address(newname
, st
->st_origin
, vp
->namelen
+4);
1125 put_address(newname
, 0xFFFFFFFF, vp
->namelen
+8);
1130 *length
= vp
->namelen
+ 12;
1131 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
1133 *var_len
= sizeof(long);
1135 switch (vp
->magic
) {
1137 case ipMRouteUpstreamNeighbor
:
1138 return (u_char
*) >
->gt_route
->rt_gateway
;
1140 case ipMRouteInIfIndex
:
1141 long_return
= gt
->gt_route
->rt_parent
;
1142 return (u_char
*) &long_return
;
1144 case ipMRouteUpTime
: {
1147 long_return
= (currtime
- gt
->gt_ctime
)*100;
1148 return (u_char
*) &long_return
;
1151 case ipMRouteExpiryTime
:
1152 long_return
= 5*((gt
->gt_timer
+4)/5); /* round up to nearest 5 */
1153 long_return
= (long_return
+ secs_remaining_offset()) * 100;
1154 return (u_char
*) &long_return
;
1157 refresh_sg(&sg_req
, gt
, st
);
1158 long_return
= sg_req
.pktcnt
;
1159 return (u_char
*) &long_return
;
1161 case ipMRouteOctets
:
1162 refresh_sg(&sg_req
, gt
, st
);
1163 long_return
= sg_req
.bytecnt
;
1164 return (u_char
*) &long_return
;
1166 case ipMRouteDifferentInIfIndexes
:
1167 refresh_sg(&sg_req
, gt
, st
);
1168 long_return
= sg_req
.wrong_if
;
1169 return (u_char
*) &long_return
;
1171 case ipMRouteProtocol
:
1173 return (u_char
*) &long_return
;
1182 * Implements the IP Multicast Routing Next Hop Table portion of the Multicast
1186 o_ipMRouteNextHopTable(vp
, name
, length
, exact
, var_len
, write_method
)
1187 struct variable
*vp
; /* IN - pointer to variable entry that points here */
1188 oid
*name
; /* IN/OUT - input name requested, output name found */
1189 int *length
; /* IN/OUT - length of input and output oid's */
1190 int exact
; /* IN - TRUE if an exact match was requested. */
1191 int *var_len
; /* OUT - length of variable or 0 if function returned. */
1192 int (**write_method
)(); /* OUT - pointer to function to set variable, otherwise 0 */
1194 u_long src
, grp
, mask
, addr
;
1198 oid newname
[MAX_NAME_LEN
];
1201 /* Copy name OID to new OID */
1202 bcopy((char *)vp
->name
, (char *)newname
, (int)vp
->namelen
* sizeof(oid
));
1205 if (*length
!= vp
->namelen
+ 17)
1208 if (!get_address(name
, *length
, &grp
, vp
->namelen
)
1209 || !get_address(name
, *length
, &src
, vp
->namelen
+4)
1210 || !get_address(name
, *length
, &mask
, vp
->namelen
+8)
1211 || !get_address(name
, *length
, &addr
, vp
->namelen
+13)
1214 || (!(gt
=find_grp(grp
)))
1215 || (!(st
=find_grp_src(gt
,src
))))
1218 vifi
= name
[vp
->namelen
+12];
1219 if (!(VIFM_ISSET(vifi
, gt
->gt_route
->rt_children
)))
1222 bcopy((char *)name
, (char *)newname
, ((int)*length
) * sizeof(oid
));
1225 if (compare(name
, *length
, vp
->name
, vp
->namelen
) < 0)
1228 if (len
< vp
->namelen
+ 17) { /* get first entry */
1230 get_address(name
, len
, &grp
, vp
->namelen
);
1231 get_address(name
, len
, &src
, vp
->namelen
+4);
1232 get_address(name
, len
, &mask
, vp
->namelen
+8);
1234 /* Find first child vif */
1236 if (!next_child(>
, &st
, grp
, src
, mask
, &vifi
))
1239 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
);
1240 put_address(newname
, st
->st_origin
, vp
->namelen
+4);
1241 put_address(newname
, 0xFFFFFFFF, vp
->namelen
+8);
1242 newname
[vp
->namelen
+12] = vifi
;
1243 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
+13);
1245 } else { /* get next entry given previous */
1246 vifi
= name
[vp
->namelen
+12]+1;
1247 if (!get_address(name
, *length
, &grp
, vp
->namelen
)
1248 || !get_address(name
, *length
, &src
, vp
->namelen
+4)
1249 || !get_address(name
, *length
, &mask
, vp
->namelen
+8)
1250 || !next_child(>
, &st
, grp
, src
, mask
, &vifi
))
1253 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
);
1254 put_address(newname
, st
->st_origin
, vp
->namelen
+4);
1255 put_address(newname
, 0xFFFFFFFF, vp
->namelen
+8);
1256 newname
[vp
->namelen
+12] = vifi
;
1257 put_address(newname
, gt
->gt_mcastgrp
, vp
->namelen
+13);
1262 *length
= vp
->namelen
+ 17;
1263 bcopy((char *)newname
, (char *)name
, ((int)*length
) * sizeof(oid
));
1265 *var_len
= sizeof(long);
1267 switch (vp
->magic
) {
1269 case ipMRouteNextHopState
:
1270 long_return
= (VIFM_ISSET(vifi
, gt
->gt_grpmems
))? 2 : 1;
1271 return (u_char
*) &long_return
;
1273 /* Currently equal to ipMRouteUpTime */
1274 case ipMRouteNextHopUpTime
: {
1277 long_return
= (currtime
- gt
->gt_ctime
)*100;
1278 return (u_char
*) &long_return
;
1281 case ipMRouteNextHopExpiryTime
:
1282 long_return
= 5*((gt
->gt_prsent_timer
+4)/5); /* round up to nearest 5*/
1283 long_return
= (long_return
+ secs_remaining_offset()) * 100;
1284 return (u_char
*) &long_return
;
1286 case ipMRouteNextHopClosestMemberHops
:
1288 return (u_char
*) &long_return
;
1290 case ipMRouteNextHopProtocol
:
1292 return (u_char
*) &long_return
;
1300 /* sync_timer is called by timer() every TIMER_INTERVAL seconds.
1301 * Its job is to record this time so that we can compute on demand
1302 * the approx # seconds remaining until the next timer() call
1304 static time_t lasttimer
;
1312 int /* in range [-TIMER_INTERVAL..0] */
1313 secs_remaining_offset()
1318 return lasttimer
-tm
;