snmp.c revision 1.10 1 1.10 wiz /* $NetBSD: snmp.c,v 1.10 2003/03/05 21:12:26 wiz Exp $ */
2 1.10 wiz
3 1.10 wiz /*
4 1.10 wiz * Copyright (c) 1992, 2001 Xerox Corporation. All rights reserved.
5 1.10 wiz *
6 1.10 wiz * Redistribution and use in source and binary forms, with or without modification,
7 1.10 wiz * are permitted provided that the following conditions are met:
8 1.10 wiz *
9 1.10 wiz * Redistributions of source code must retain the above copyright notice,
10 1.10 wiz * this list of conditions and the following disclaimer.
11 1.10 wiz *
12 1.10 wiz * Redistributions in binary form must reproduce the above copyright notice,
13 1.10 wiz * this list of conditions and the following disclaimer in the documentation
14 1.10 wiz * and/or other materials provided with the distribution.
15 1.10 wiz *
16 1.10 wiz * Neither name of the Xerox, PARC, nor the names of its contributors may be used
17 1.10 wiz * to endorse or promote products derived from this software
18 1.10 wiz * without specific prior written permission.
19 1.10 wiz *
20 1.10 wiz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 1.10 wiz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 1.10 wiz * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.10 wiz * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE XEROX CORPORATION OR CONTRIBUTORS
24 1.10 wiz * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.10 wiz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.10 wiz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 1.10 wiz * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 1.10 wiz * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 1.10 wiz * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 1.10 wiz * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.10 wiz */
32 1.1 mycroft
33 1.1 mycroft #include "defs.h"
34 1.3 mycroft #include <netinet/in_var.h>
35 1.1 mycroft #include "snmp.h"
36 1.3 mycroft #include "snmplib/asn1.h"
37 1.3 mycroft #include "snmplib/party.h"
38 1.3 mycroft #include "snmplib/snmp_impl.h"
39 1.3 mycroft #define MROUTED
40 1.3 mycroft #include "snmpd/snmp_vars.h"
41 1.3 mycroft
42 1.7 itojun in_port_t dest_port = 0;
43 1.3 mycroft int sdlen = 0;
44 1.3 mycroft
45 1.3 mycroft struct addrCache {
46 1.3 mycroft u_long addr;
47 1.3 mycroft int status;
48 1.3 mycroft #define UNUSED 0
49 1.3 mycroft #define USED 1
50 1.3 mycroft #define OLD 2
51 1.3 mycroft };
52 1.1 mycroft
53 1.3 mycroft static struct addrCache addrCache[10];
54 1.1 mycroft
55 1.3 mycroft /*
56 1.3 mycroft * Initialize the SNMP part of mrouted
57 1.3 mycroft */
58 1.3 mycroft int /* returns: 0 on success, true on error */
59 1.3 mycroft snmp_init(dest_port)
60 1.7 itojun in_port_t dest_port;
61 1.3 mycroft {
62 1.3 mycroft u_long myaddr;
63 1.3 mycroft int ret;
64 1.3 mycroft struct partyEntry *pp;
65 1.3 mycroft struct sockaddr_in me;
66 1.3 mycroft int index, sd, portlist[32];
67 1.3 mycroft
68 1.3 mycroft init_snmp();
69 1.3 mycroft /* init_mib(); why was this here? */
70 1.3 mycroft if (read_party_database("/etc/party.conf") > 0){
71 1.3 mycroft fprintf(stderr, "Couldn't read party database from /etc/party.conf\n");
72 1.3 mycroft exit(0);
73 1.3 mycroft }
74 1.3 mycroft if (read_context_database("/etc/context.conf") > 0){
75 1.3 mycroft fprintf(stderr, "Couldn't read context database from /etc/context.conf\n");
76 1.3 mycroft exit(0);
77 1.3 mycroft }
78 1.3 mycroft if (read_acl_database("/etc/acl.conf") > 0){
79 1.3 mycroft fprintf(stderr, "Couldn't read acl database from /etc/acl.conf\n");
80 1.3 mycroft exit(0);
81 1.3 mycroft }
82 1.3 mycroft if (read_view_database("/etc/view.conf") > 0){
83 1.3 mycroft fprintf(stderr, "Couldn't read view database from /etc/view.conf\n");
84 1.3 mycroft exit(0);
85 1.3 mycroft }
86 1.3 mycroft
87 1.3 mycroft myaddr = get_myaddr();
88 1.3 mycroft if (ret = agent_party_init(myaddr, ".1.3.6.1")){
89 1.3 mycroft if (ret == 1){
90 1.3 mycroft fprintf(stderr, "Conflict found with initial noAuth/noPriv parties... continuing\n");
91 1.3 mycroft } else if (ret == -1){
92 1.3 mycroft fprintf(stderr, "Error installing initial noAuth/noPriv parties, exiting\n");
93 1.3 mycroft exit(1);
94 1.3 mycroft } else {
95 1.3 mycroft fprintf(stderr, "Unknown error, exiting\n");
96 1.3 mycroft exit(2);
97 1.3 mycroft }
98 1.3 mycroft }
99 1.1 mycroft
100 1.3 mycroft printf("Opening port(s): ");
101 1.3 mycroft fflush(stdout);
102 1.3 mycroft party_scanInit();
103 1.3 mycroft for(pp = party_scanNext(); pp; pp = party_scanNext()){
104 1.3 mycroft if ((pp->partyTDomain != DOMAINSNMPUDP)
105 1.3 mycroft || bcmp((char *)&myaddr, pp->partyTAddress, 4))
106 1.3 mycroft continue; /* don't listen for non-local parties */
107 1.3 mycroft
108 1.3 mycroft dest_port = 0;
109 1.3 mycroft bcopy(pp->partyTAddress + 4, &dest_port, 2);
110 1.3 mycroft for(index = 0; index < sdlen; index++)
111 1.3 mycroft if (dest_port == portlist[index])
112 1.3 mycroft break;
113 1.3 mycroft if (index < sdlen) /* found a hit before the end of the list */
114 1.3 mycroft continue;
115 1.3 mycroft printf("%u ", dest_port);
116 1.3 mycroft fflush(stdout);
117 1.3 mycroft /* Set up connections */
118 1.3 mycroft sd = socket(AF_INET, SOCK_DGRAM, 0);
119 1.3 mycroft if (sd < 0){
120 1.3 mycroft perror("socket");
121 1.3 mycroft return 1;
122 1.3 mycroft }
123 1.5 itojun memset(&me, 0, sizeof(me));
124 1.3 mycroft me.sin_family = AF_INET;
125 1.3 mycroft me.sin_addr.s_addr = INADDR_ANY;
126 1.3 mycroft /* already in network byte order (I think) */
127 1.3 mycroft me.sin_port = dest_port;
128 1.3 mycroft if (bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0){
129 1.3 mycroft perror("bind");
130 1.3 mycroft return 2;
131 1.3 mycroft }
132 1.3 mycroft register_input_handler(sd, snmp_read_packet);
133 1.3 mycroft portlist[sdlen] = dest_port;
134 1.3 mycroft if (++sdlen == 32){
135 1.3 mycroft printf("No more sockets... ignoring rest of file\n");
136 1.3 mycroft break;
137 1.3 mycroft }
138 1.3 mycroft }
139 1.3 mycroft printf("\n");
140 1.3 mycroft bzero((char *)addrCache, sizeof(addrCache));
141 1.3 mycroft }
142 1.1 mycroft
143 1.1 mycroft /*
144 1.3 mycroft * Place an IP address into an OID starting at element n
145 1.1 mycroft */
146 1.1 mycroft void
147 1.3 mycroft put_address(name, addr, n)
148 1.3 mycroft oid *name;
149 1.1 mycroft u_long addr;
150 1.1 mycroft int n;
151 1.1 mycroft {
152 1.1 mycroft int i;
153 1.1 mycroft
154 1.1 mycroft for (i=n+3; i>=n+0; i--) {
155 1.3 mycroft name[i] = addr & 0xFF;
156 1.1 mycroft addr >>= 8;
157 1.1 mycroft }
158 1.1 mycroft }
159 1.1 mycroft
160 1.1 mycroft /* Get an IP address from an OID starting at element n */
161 1.1 mycroft int
162 1.3 mycroft get_address(name, length, addr, n)
163 1.3 mycroft oid *name;
164 1.3 mycroft int length;
165 1.1 mycroft u_long *addr;
166 1.1 mycroft int n;
167 1.1 mycroft {
168 1.1 mycroft int i;
169 1.1 mycroft int ok = 1;
170 1.1 mycroft
171 1.1 mycroft (*addr) = 0;
172 1.1 mycroft
173 1.3 mycroft if (length < n+4)
174 1.1 mycroft return 0;
175 1.1 mycroft
176 1.1 mycroft for (i=n; i<n+4; i++) {
177 1.1 mycroft (*addr) <<= 8;
178 1.3 mycroft if (i >= length)
179 1.1 mycroft ok = 0;
180 1.1 mycroft else
181 1.3 mycroft (*addr) |= name[i];
182 1.1 mycroft }
183 1.1 mycroft return ok;
184 1.1 mycroft }
185 1.1 mycroft
186 1.1 mycroft /*
187 1.3 mycroft * Implements scalar objects from DVMRP and Multicast MIBs
188 1.1 mycroft */
189 1.3 mycroft u_char *
190 1.3 mycroft o_scalar(vp, name, length, exact, var_len, write_method)
191 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
192 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
193 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
194 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
195 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
196 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
197 1.3 mycroft {
198 1.3 mycroft int result;
199 1.3 mycroft
200 1.3 mycroft *write_method = 0;
201 1.3 mycroft result = compare(name, *length, vp->name, (int)vp->namelen);
202 1.3 mycroft if ((exact && (result != 0)) || (!exact && (result >= 0)))
203 1.3 mycroft return NULL;
204 1.3 mycroft
205 1.3 mycroft bcopy((char *)vp->name, (char *)name,
206 1.3 mycroft (int)vp->namelen * sizeof(oid));
207 1.3 mycroft *length = vp->namelen;
208 1.3 mycroft *var_len = sizeof(long);
209 1.3 mycroft
210 1.3 mycroft switch (vp->magic) {
211 1.3 mycroft
212 1.3 mycroft case ipMRouteEnable:
213 1.3 mycroft long_return = 1;
214 1.3 mycroft return (u_char *) &long_return;
215 1.3 mycroft
216 1.3 mycroft case dvmrpVersion: {
217 1.3 mycroft static char buff[15];
218 1.3 mycroft
219 1.3 mycroft sprintf(buff, "mrouted%d.%d", PROTOCOL_VERSION, MROUTED_VERSION);
220 1.3 mycroft *var_len = strlen(buff);
221 1.3 mycroft return (u_char *)buff;
222 1.3 mycroft }
223 1.1 mycroft
224 1.3 mycroft case dvmrpGenerationId:
225 1.3 mycroft long_return = dvmrp_genid;
226 1.3 mycroft return (u_char *) &long_return;
227 1.1 mycroft
228 1.3 mycroft default:
229 1.3 mycroft ERROR("");
230 1.1 mycroft }
231 1.3 mycroft return NULL;
232 1.1 mycroft }
233 1.1 mycroft
234 1.3 mycroft /*
235 1.1 mycroft * Find if a specific scoped boundary exists on a Vif
236 1.1 mycroft */
237 1.1 mycroft struct vif_acl *
238 1.1 mycroft find_boundary(vifi, addr, mask)
239 1.3 mycroft vifi_t vifi;
240 1.3 mycroft u_long addr;
241 1.3 mycroft u_long mask;
242 1.1 mycroft {
243 1.1 mycroft struct vif_acl *n;
244 1.1 mycroft
245 1.1 mycroft for (n = uvifs[vifi].uv_acl; n != NULL; n = n->acl_next) {
246 1.1 mycroft if (addr == n->acl_addr && mask==n->acl_mask)
247 1.1 mycroft return n;
248 1.1 mycroft }
249 1.1 mycroft return NULL;
250 1.1 mycroft }
251 1.1 mycroft
252 1.1 mycroft /*
253 1.3 mycroft * Find the lowest boundary >= (V,A,M) spec
254 1.1 mycroft */
255 1.1 mycroft struct vif_acl *
256 1.1 mycroft next_boundary(vifi, addr, mask)
257 1.3 mycroft vifi_t *vifi;
258 1.3 mycroft u_long addr;
259 1.3 mycroft u_long mask;
260 1.1 mycroft {
261 1.1 mycroft struct vif_acl *bestn, *n;
262 1.1 mycroft int i;
263 1.1 mycroft
264 1.1 mycroft for (i = *vifi; i < numvifs; i++) {
265 1.1 mycroft bestn = NULL;
266 1.1 mycroft for (n = uvifs[i].uv_acl; n; n=n->acl_next) {
267 1.3 mycroft if ((i > *vifi || n->acl_addr > addr
268 1.3 mycroft || (n->acl_addr == addr && n->acl_mask >= mask))
269 1.3 mycroft && (!bestn || n->acl_addr < bestn->acl_addr
270 1.1 mycroft || (n->acl_addr==bestn->acl_addr && n->acl_mask<bestn->acl_mask)))
271 1.1 mycroft bestn = n;
272 1.1 mycroft }
273 1.1 mycroft if (bestn) {
274 1.1 mycroft *vifi = i;
275 1.1 mycroft return bestn;
276 1.1 mycroft }
277 1.1 mycroft }
278 1.1 mycroft return NULL;
279 1.1 mycroft }
280 1.1 mycroft
281 1.1 mycroft /*
282 1.1 mycroft * Implements the Boundary Table portion of the DVMRP MIB
283 1.1 mycroft */
284 1.3 mycroft u_char *
285 1.3 mycroft o_dvmrpBoundaryTable(vp, name, length, exact, var_len, write_method)
286 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
287 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
288 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
289 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
290 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
291 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
292 1.3 mycroft {
293 1.3 mycroft vifi_t vifi;
294 1.3 mycroft u_long addr, mask;
295 1.1 mycroft struct vif_acl *bound;
296 1.3 mycroft oid newname[MAX_NAME_LEN];
297 1.3 mycroft int len;
298 1.1 mycroft
299 1.3 mycroft /* Copy name OID to new OID */
300 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
301 1.3 mycroft
302 1.3 mycroft if (exact) {
303 1.3 mycroft if (*length != vp->namelen + 9)
304 1.3 mycroft return NULL;
305 1.3 mycroft
306 1.3 mycroft if ((vifi = name[vp->namelen]) >= numvifs)
307 1.3 mycroft return NULL;
308 1.3 mycroft
309 1.3 mycroft if (!get_address(name, *length, &addr, vp->namelen+1)
310 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+5))
311 1.3 mycroft return NULL;
312 1.1 mycroft
313 1.1 mycroft if (!(bound = find_boundary(vifi, addr, mask)))
314 1.3 mycroft return NULL;
315 1.1 mycroft
316 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
317 1.3 mycroft } else {
318 1.3 mycroft len = *length;
319 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
320 1.3 mycroft len = vp->namelen;
321 1.3 mycroft
322 1.3 mycroft if (len < vp->namelen + 9) { /* get first entry */
323 1.3 mycroft
324 1.3 mycroft if (len == vp->namelen) {
325 1.3 mycroft vifi = addr = mask = 0;
326 1.3 mycroft } else {
327 1.3 mycroft vifi = name[vp->namelen];
328 1.3 mycroft get_address(name, len, &addr, vp->namelen+1);
329 1.3 mycroft get_address(name, len, &mask, vp->namelen+5);
330 1.3 mycroft }
331 1.1 mycroft
332 1.3 mycroft bound = next_boundary(&vifi,addr,mask);
333 1.3 mycroft if (!bound)
334 1.3 mycroft return NULL;
335 1.3 mycroft
336 1.3 mycroft newname[vp->namelen] = vifi;
337 1.3 mycroft put_address(newname, bound->acl_addr, vp->namelen+1);
338 1.3 mycroft put_address(newname, bound->acl_mask, vp->namelen+5);
339 1.1 mycroft } else { /* get next entry given previous */
340 1.3 mycroft vifi = name[vp->namelen];
341 1.3 mycroft get_address(name, *length, &addr, vp->namelen+1);
342 1.3 mycroft get_address(name, *length, &mask, vp->namelen+5);
343 1.1 mycroft
344 1.1 mycroft if (!(bound = next_boundary(&vifi,addr,mask+1)))
345 1.3 mycroft return NULL;
346 1.1 mycroft
347 1.3 mycroft newname[vp->namelen] = vifi;
348 1.3 mycroft put_address(newname, bound->acl_addr, vp->namelen+1);
349 1.3 mycroft put_address(newname, bound->acl_mask, vp->namelen+5);
350 1.1 mycroft }
351 1.3 mycroft }
352 1.1 mycroft
353 1.3 mycroft /* Save new OID */
354 1.3 mycroft *length = vp->namelen + 9;
355 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
356 1.3 mycroft *write_method = 0;
357 1.3 mycroft *var_len = sizeof(long);
358 1.1 mycroft
359 1.3 mycroft switch (vp->magic) {
360 1.1 mycroft
361 1.1 mycroft case dvmrpBoundaryVifIndex:
362 1.3 mycroft long_return = vifi;
363 1.3 mycroft return (u_char *) &long_return;
364 1.1 mycroft
365 1.3 mycroft default:
366 1.3 mycroft ERROR("");
367 1.1 mycroft }
368 1.3 mycroft return NULL;
369 1.1 mycroft }
370 1.1 mycroft
371 1.3 mycroft /*
372 1.3 mycroft * Find the lowest neighbor >= (V,A) spec
373 1.1 mycroft */
374 1.1 mycroft struct listaddr *
375 1.1 mycroft next_neighbor(vifi, addr)
376 1.3 mycroft vifi_t *vifi;
377 1.3 mycroft u_long addr;
378 1.1 mycroft {
379 1.1 mycroft struct listaddr *bestn, *n;
380 1.1 mycroft int i;
381 1.1 mycroft
382 1.1 mycroft for (i = *vifi; i < numvifs; i++) {
383 1.1 mycroft bestn = NULL;
384 1.1 mycroft for (n = uvifs[i].uv_neighbors; n; n=n->al_next) {
385 1.3 mycroft if ((i > *vifi || n->al_addr >= addr)
386 1.1 mycroft && (!bestn || n->al_addr < bestn->al_addr))
387 1.1 mycroft bestn = n;
388 1.1 mycroft }
389 1.1 mycroft if (bestn) {
390 1.1 mycroft *vifi = i;
391 1.1 mycroft return bestn;
392 1.1 mycroft }
393 1.1 mycroft }
394 1.1 mycroft return NULL;
395 1.1 mycroft }
396 1.1 mycroft
397 1.1 mycroft /*
398 1.1 mycroft * Find a neighbor, if it exists off a given Vif
399 1.1 mycroft */
400 1.1 mycroft struct listaddr *
401 1.1 mycroft find_neighbor(vifi, addr)
402 1.3 mycroft vifi_t vifi;
403 1.3 mycroft u_long addr;
404 1.1 mycroft {
405 1.1 mycroft struct listaddr *n;
406 1.1 mycroft
407 1.1 mycroft for (n = uvifs[vifi].uv_neighbors; n != NULL; n = n->al_next) {
408 1.1 mycroft if (addr == n->al_addr)
409 1.1 mycroft return n;
410 1.1 mycroft }
411 1.1 mycroft return NULL;
412 1.1 mycroft }
413 1.1 mycroft
414 1.3 mycroft u_char *
415 1.3 mycroft o_dvmrpNeighborTable(vp, name, length, exact, var_len, write_method)
416 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
417 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
418 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
419 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
420 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
421 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
422 1.3 mycroft {
423 1.3 mycroft vifi_t vifi;
424 1.3 mycroft u_long addr, mask;
425 1.1 mycroft struct listaddr *neighbor;
426 1.3 mycroft oid newname[MAX_NAME_LEN];
427 1.3 mycroft int len;
428 1.1 mycroft
429 1.3 mycroft /* Copy name OID to new OID */
430 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
431 1.1 mycroft
432 1.3 mycroft if (exact) {
433 1.3 mycroft if (*length != vp->namelen + 5)
434 1.3 mycroft return NULL;
435 1.1 mycroft
436 1.3 mycroft if ((vifi = name[vp->namelen]) >= numvifs)
437 1.3 mycroft return NULL;
438 1.3 mycroft
439 1.3 mycroft if (!get_address(name, *length, &addr, vp->namelen+1))
440 1.3 mycroft return NULL;
441 1.1 mycroft
442 1.1 mycroft if (!(neighbor = find_neighbor(vifi, addr)))
443 1.3 mycroft return NULL;
444 1.1 mycroft
445 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
446 1.3 mycroft } else {
447 1.3 mycroft len = *length;
448 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
449 1.3 mycroft len = vp->namelen;
450 1.3 mycroft
451 1.3 mycroft if (len < vp->namelen + 5) { /* get first entry */
452 1.3 mycroft
453 1.3 mycroft if (len == vp->namelen) {
454 1.3 mycroft vifi = addr = 0;
455 1.3 mycroft } else {
456 1.3 mycroft vifi = name[vp->namelen];
457 1.3 mycroft get_address(name, len, &addr, vp->namelen+1);
458 1.3 mycroft }
459 1.1 mycroft
460 1.3 mycroft neighbor = next_neighbor(&vifi,addr);
461 1.3 mycroft if (!neighbor)
462 1.3 mycroft return NULL;
463 1.1 mycroft
464 1.3 mycroft newname[vp->namelen] = vifi;
465 1.3 mycroft put_address(newname, neighbor->al_addr, vp->namelen+1);
466 1.1 mycroft } else { /* get next entry given previous */
467 1.3 mycroft vifi = name[vp->namelen];
468 1.3 mycroft get_address(name, *length, &addr, vp->namelen+1);
469 1.1 mycroft
470 1.1 mycroft if (!(neighbor = next_neighbor(&vifi,addr+1)))
471 1.3 mycroft return NULL;
472 1.1 mycroft
473 1.3 mycroft newname[vp->namelen] = vifi;
474 1.3 mycroft put_address(newname, neighbor->al_addr, vp->namelen+1);
475 1.1 mycroft }
476 1.3 mycroft }
477 1.1 mycroft
478 1.3 mycroft /* Save new OID */
479 1.3 mycroft *length = vp->namelen + 5;
480 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
481 1.3 mycroft *write_method = 0;
482 1.3 mycroft *var_len = sizeof(long);
483 1.1 mycroft
484 1.3 mycroft switch (vp->magic) {
485 1.1 mycroft
486 1.1 mycroft case dvmrpNeighborUpTime: {
487 1.1 mycroft time_t currtime;
488 1.1 mycroft time(&currtime);
489 1.3 mycroft long_return = (currtime - neighbor->al_ctime)*100;
490 1.3 mycroft return (u_char *) &long_return;
491 1.1 mycroft }
492 1.1 mycroft
493 1.3 mycroft case dvmrpNeighborExpiryTime:
494 1.3 mycroft long_return = (NEIGHBOR_EXPIRE_TIME - neighbor->al_timer
495 1.3 mycroft + secs_remaining_offset()) * 100;
496 1.3 mycroft return (u_char *) &long_return;
497 1.1 mycroft
498 1.1 mycroft case dvmrpNeighborVersion: {
499 1.1 mycroft static char buff[15];
500 1.1 mycroft
501 1.1 mycroft sprintf(buff, "%d.%d", neighbor->al_pv, neighbor->al_mv);
502 1.3 mycroft *var_len = strlen(buff);
503 1.3 mycroft return (u_char *)buff;
504 1.1 mycroft }
505 1.1 mycroft
506 1.3 mycroft case dvmrpNeighborGenerationId:
507 1.3 mycroft long_return = neighbor->al_genid;
508 1.3 mycroft return (u_char *) &long_return;
509 1.3 mycroft
510 1.3 mycroft default:
511 1.3 mycroft ERROR("");
512 1.3 mycroft }
513 1.3 mycroft return NULL;
514 1.3 mycroft }
515 1.3 mycroft
516 1.3 mycroft /* Look up ifIndex given uvifs[ifnum].uv_lcl_addr */
517 1.3 mycroft struct in_ifaddr * /* returns: in_ifaddr structure, or null on error */
518 1.3 mycroft ipaddr_to_ifindex(ipaddr, ifIndex)
519 1.3 mycroft u_long ipaddr;
520 1.3 mycroft int *ifIndex;
521 1.3 mycroft {
522 1.3 mycroft int interface;
523 1.3 mycroft static struct in_ifaddr in_ifaddr;
524 1.3 mycroft
525 1.3 mycroft Interface_Scan_Init();
526 1.3 mycroft for (;;) {
527 1.3 mycroft if (Interface_Scan_Next(&interface, (char *)0, NULL, &in_ifaddr) == 0)
528 1.3 mycroft return NULL;
529 1.3 mycroft
530 1.3 mycroft if (((struct sockaddr_in *) &(in_ifaddr.ia_addr))->sin_addr.s_addr
531 1.3 mycroft == ipaddr) {
532 1.3 mycroft *ifIndex = interface;
533 1.3 mycroft return &in_ifaddr;
534 1.3 mycroft }
535 1.3 mycroft }
536 1.3 mycroft }
537 1.3 mycroft
538 1.3 mycroft /*
539 1.3 mycroft * Find if a specific scoped boundary exists on a Vif
540 1.3 mycroft */
541 1.3 mycroft struct listaddr *
542 1.3 mycroft find_cache(grp, vifi)
543 1.3 mycroft u_long grp;
544 1.3 mycroft vifi_t vifi;
545 1.3 mycroft {
546 1.3 mycroft struct listaddr *n;
547 1.3 mycroft
548 1.3 mycroft for (n = uvifs[vifi].uv_groups; n != NULL; n = n->al_next) {
549 1.3 mycroft if (grp == n->al_addr)
550 1.3 mycroft return n;
551 1.3 mycroft }
552 1.3 mycroft return NULL;
553 1.3 mycroft }
554 1.3 mycroft
555 1.3 mycroft /*
556 1.3 mycroft * Find the next group cache entry >= (A,V) spec
557 1.3 mycroft */
558 1.3 mycroft struct listaddr *
559 1.3 mycroft next_cache(addr, vifi)
560 1.3 mycroft u_long addr;
561 1.3 mycroft vifi_t *vifi;
562 1.3 mycroft {
563 1.3 mycroft struct listaddr *bestn=NULL, *n;
564 1.3 mycroft int i, besti;
565 1.3 mycroft
566 1.3 mycroft /* Step through all entries looking for the next one */
567 1.3 mycroft for (i = 0; i < numvifs; i++) {
568 1.3 mycroft for (n = uvifs[i].uv_groups; n; n=n->al_next) {
569 1.3 mycroft if ((n->al_addr > addr || (n->al_addr == addr && i >= *vifi))
570 1.3 mycroft && (!bestn || n->al_addr < bestn->al_addr
571 1.3 mycroft || (n->al_addr == bestn->al_addr && i < besti))) {
572 1.3 mycroft bestn = n;
573 1.3 mycroft besti = i;
574 1.3 mycroft }
575 1.3 mycroft }
576 1.3 mycroft }
577 1.3 mycroft
578 1.3 mycroft if (bestn) {
579 1.3 mycroft *vifi = besti;
580 1.3 mycroft return bestn;
581 1.3 mycroft }
582 1.3 mycroft return NULL;
583 1.3 mycroft }
584 1.3 mycroft
585 1.3 mycroft /*
586 1.3 mycroft * Implements the IGMP Cache Table portion of the IGMP MIB
587 1.3 mycroft */
588 1.3 mycroft u_char *
589 1.3 mycroft o_igmpCacheTable(vp, name, length, exact, var_len, write_method)
590 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
591 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
592 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
593 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
594 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
595 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
596 1.3 mycroft {
597 1.3 mycroft vifi_t vifi;
598 1.3 mycroft u_long grp;
599 1.3 mycroft int ifIndex;
600 1.3 mycroft struct listaddr *cache;
601 1.3 mycroft oid newname[MAX_NAME_LEN];
602 1.3 mycroft int len;
603 1.3 mycroft struct in_ifaddr *in_ifaddr;
604 1.3 mycroft struct in_multi in_multi, *inm;
605 1.3 mycroft
606 1.3 mycroft /* Copy name OID to new OID */
607 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
608 1.3 mycroft
609 1.3 mycroft if (exact) {
610 1.3 mycroft if (*length != vp->namelen + 5)
611 1.3 mycroft return NULL;
612 1.3 mycroft
613 1.3 mycroft if ((vifi = name[vp->namelen+4]) >= numvifs)
614 1.3 mycroft return NULL;
615 1.3 mycroft
616 1.3 mycroft if (!get_address(name, *length, &grp, vp->namelen))
617 1.3 mycroft return NULL;
618 1.3 mycroft
619 1.3 mycroft if (!(cache = find_cache(grp, vifi)))
620 1.3 mycroft return NULL;
621 1.3 mycroft
622 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
623 1.3 mycroft } else {
624 1.3 mycroft len = *length;
625 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
626 1.3 mycroft len = vp->namelen;
627 1.3 mycroft
628 1.3 mycroft if (len < vp->namelen + 5) { /* get first entry */
629 1.3 mycroft
630 1.3 mycroft if (len == vp->namelen) {
631 1.3 mycroft vifi = grp = 0;
632 1.3 mycroft } else {
633 1.3 mycroft get_address(name, len, &grp, vp->namelen);
634 1.3 mycroft vifi = name[vp->namelen+4];
635 1.3 mycroft }
636 1.3 mycroft
637 1.3 mycroft cache = next_cache(grp,&vifi);
638 1.3 mycroft if (!cache)
639 1.3 mycroft return NULL;
640 1.3 mycroft
641 1.3 mycroft put_address(newname, cache->al_addr, vp->namelen);
642 1.3 mycroft newname[vp->namelen+4] = vifi;
643 1.3 mycroft } else { /* get next entry given previous */
644 1.3 mycroft get_address(name, *length, &grp, vp->namelen);
645 1.3 mycroft vifi = name[vp->namelen+4]+1;
646 1.3 mycroft
647 1.3 mycroft if (!(cache = next_cache(grp,&vifi)))
648 1.3 mycroft return NULL;
649 1.3 mycroft
650 1.3 mycroft put_address(newname, cache->al_addr, vp->namelen);
651 1.3 mycroft newname[vp->namelen+4] = vifi;
652 1.3 mycroft }
653 1.3 mycroft }
654 1.3 mycroft
655 1.3 mycroft /* Save new OID */
656 1.3 mycroft *length = vp->namelen + 5;
657 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
658 1.3 mycroft *write_method = 0;
659 1.3 mycroft *var_len = sizeof(long);
660 1.3 mycroft
661 1.3 mycroft /* Look up ifIndex given uvifs[vifi].uv_lcl_addr */
662 1.3 mycroft in_ifaddr = ipaddr_to_ifindex(uvifs[vifi].uv_lcl_addr, &ifIndex);
663 1.3 mycroft
664 1.3 mycroft switch (vp->magic) {
665 1.3 mycroft
666 1.3 mycroft case igmpCacheSelf:
667 1.3 mycroft inm = in_ifaddr->ia_multiaddrs;
668 1.3 mycroft while (inm) {
669 1.3 mycroft klookup( (int)inm, (char *)&in_multi, sizeof(in_multi));
670 1.3 mycroft
671 1.3 mycroft if (in_multi.inm_addr.s_addr == cache->al_addr) {
672 1.3 mycroft long_return = 1; /* true */
673 1.3 mycroft return (u_char *) &long_return;
674 1.3 mycroft }
675 1.3 mycroft
676 1.3 mycroft inm = in_multi.inm_next;
677 1.3 mycroft }
678 1.3 mycroft long_return = 2; /* false */
679 1.3 mycroft return (u_char *) &long_return;
680 1.3 mycroft
681 1.3 mycroft case igmpCacheLastReporter:
682 1.3 mycroft return (u_char *) &cache->al_genid;
683 1.3 mycroft
684 1.3 mycroft case igmpCacheUpTime: {
685 1.3 mycroft time_t currtime;
686 1.3 mycroft time(&currtime);
687 1.3 mycroft long_return = (currtime - cache->al_ctime)*100;
688 1.3 mycroft return (u_char *) &long_return;
689 1.3 mycroft }
690 1.3 mycroft
691 1.3 mycroft case igmpCacheExpiryTime:
692 1.3 mycroft long_return = secs_remaining(cache->al_timerid)*100;
693 1.3 mycroft return (u_char *) &long_return;
694 1.3 mycroft
695 1.3 mycroft case igmpCacheStatus:
696 1.3 mycroft long_return = 1;
697 1.3 mycroft return (u_char *) &long_return;
698 1.3 mycroft
699 1.3 mycroft default:
700 1.3 mycroft ERROR("");
701 1.3 mycroft }
702 1.3 mycroft return NULL;
703 1.3 mycroft }
704 1.3 mycroft
705 1.3 mycroft /*
706 1.3 mycroft * Implements the IGMP Interface Table portion of the IGMP MIB
707 1.3 mycroft */
708 1.3 mycroft u_char *
709 1.3 mycroft o_igmpInterfaceTable(vp, name, length, exact, var_len, write_method)
710 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
711 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
712 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
713 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
714 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
715 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
716 1.3 mycroft {
717 1.3 mycroft oid newname[MAX_NAME_LEN];
718 1.6 wiz int ifnum;
719 1.3 mycroft int result;
720 1.3 mycroft static struct sioc_vif_req v_req;
721 1.3 mycroft
722 1.3 mycroft /* Copy name OID to new OID */
723 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
724 1.3 mycroft
725 1.3 mycroft /* find "next" interface */
726 1.3 mycroft for(ifnum = 0; ifnum < numvifs; ifnum++){
727 1.3 mycroft if (!(uvifs[ifnum].uv_flags & VIFF_QUERIER))
728 1.3 mycroft continue;
729 1.3 mycroft newname[vp->namelen] = (oid)ifnum;
730 1.3 mycroft result = compare(name, *length, newname, (int)vp->namelen + 1);
731 1.3 mycroft if ((exact && (result == 0)) || (!exact && (result < 0)))
732 1.3 mycroft break;
733 1.3 mycroft }
734 1.3 mycroft if (ifnum >= numvifs)
735 1.3 mycroft return NULL;
736 1.3 mycroft
737 1.3 mycroft /* Save new OID */
738 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)vp->namelen + 1) * sizeof(oid));
739 1.3 mycroft *length = vp->namelen + 1;
740 1.3 mycroft *write_method = 0;
741 1.3 mycroft *var_len = sizeof(long);
742 1.3 mycroft
743 1.3 mycroft switch (vp->magic){
744 1.3 mycroft
745 1.3 mycroft case igmpInterfaceQueryInterval:
746 1.3 mycroft long_return = GROUP_QUERY_INTERVAL;
747 1.3 mycroft return (u_char *) &long_return;
748 1.3 mycroft
749 1.3 mycroft case igmpInterfaceStatus:
750 1.3 mycroft long_return = 1; /* active */
751 1.3 mycroft return (u_char *) &long_return;
752 1.1 mycroft
753 1.1 mycroft default:
754 1.3 mycroft ERROR("");
755 1.1 mycroft }
756 1.3 mycroft return NULL;
757 1.1 mycroft }
758 1.1 mycroft
759 1.1 mycroft /*
760 1.1 mycroft * Given a virtual interface number, make sure we have the current
761 1.1 mycroft * kernel information for that Vif.
762 1.1 mycroft */
763 1.1 mycroft refresh_vif(v_req, ifnum)
764 1.1 mycroft struct sioc_vif_req *v_req;
765 1.1 mycroft int ifnum;
766 1.1 mycroft {
767 1.1 mycroft static int lastq = -1;
768 1.1 mycroft
769 1.1 mycroft if (quantum!=lastq || v_req->vifi != ifnum) {
770 1.1 mycroft lastq = quantum;
771 1.1 mycroft v_req->vifi = ifnum;
772 1.4 hwr if (ioctl(igmp_socket, SIOCGETVIFCNT, (char *)v_req) < 0)
773 1.1 mycroft v_req->icount = v_req->ocount = v_req->ibytes = v_req->obytes = 0;
774 1.1 mycroft }
775 1.1 mycroft }
776 1.1 mycroft
777 1.1 mycroft /*
778 1.1 mycroft * Implements the Multicast Routing Interface Table portion of the Multicast MIB
779 1.1 mycroft */
780 1.3 mycroft u_char *
781 1.3 mycroft o_ipMRouteInterfaceTable(vp, name, length, exact, var_len, write_method)
782 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
783 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
784 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
785 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
786 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
787 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
788 1.3 mycroft {
789 1.3 mycroft oid newname[MAX_NAME_LEN];
790 1.6 wiz int ifnum;
791 1.3 mycroft int result;
792 1.1 mycroft static struct sioc_vif_req v_req;
793 1.1 mycroft
794 1.3 mycroft /* Copy name OID to new OID */
795 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
796 1.1 mycroft
797 1.3 mycroft /* find "next" interface */
798 1.3 mycroft for(ifnum = 0; ifnum < numvifs; ifnum++){
799 1.3 mycroft newname[vp->namelen] = (oid)ifnum;
800 1.3 mycroft result = compare(name, *length, newname, (int)vp->namelen + 1);
801 1.3 mycroft if ((exact && (result == 0)) || (!exact && (result < 0)))
802 1.1 mycroft break;
803 1.1 mycroft }
804 1.3 mycroft if (ifnum >= numvifs)
805 1.3 mycroft return NULL;
806 1.1 mycroft
807 1.3 mycroft /* Save new OID */
808 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)vp->namelen + 1) * sizeof(oid));
809 1.3 mycroft *length = vp->namelen + 1;
810 1.3 mycroft *write_method = 0;
811 1.3 mycroft *var_len = sizeof(long);
812 1.3 mycroft
813 1.3 mycroft switch (vp->magic){
814 1.3 mycroft
815 1.3 mycroft case ipMRouteInterfaceTtl:
816 1.3 mycroft long_return = uvifs[ifnum].uv_threshold;
817 1.3 mycroft return (u_char *) &long_return;
818 1.1 mycroft
819 1.3 mycroft case dvmrpVInterfaceType:
820 1.1 mycroft if (uvifs[ifnum].uv_flags & VIFF_SRCRT)
821 1.3 mycroft long_return = 2;
822 1.1 mycroft else if (uvifs[ifnum].uv_flags & VIFF_TUNNEL)
823 1.3 mycroft long_return = 1;
824 1.1 mycroft else if (uvifs[ifnum].uv_flags & VIFF_QUERIER)
825 1.3 mycroft long_return = 3;
826 1.1 mycroft else /* SUBNET */
827 1.3 mycroft long_return = 4;
828 1.3 mycroft return (u_char *) &long_return;
829 1.1 mycroft
830 1.3 mycroft case dvmrpVInterfaceState:
831 1.1 mycroft if (uvifs[ifnum].uv_flags & VIFF_DISABLED)
832 1.3 mycroft long_return = 3;
833 1.3 mycroft else if ((uvifs[ifnum].uv_flags & VIFF_DOWN)
834 1.3 mycroft || ((uvifs[ifnum].uv_flags & VIFF_TUNNEL) && (uvifs[ifnum].uv_neighbors==NULL)))
835 1.3 mycroft long_return = 2;
836 1.1 mycroft else /* UP */
837 1.3 mycroft long_return = 1;
838 1.3 mycroft return (u_char *) &long_return;
839 1.1 mycroft
840 1.3 mycroft case dvmrpVInterfaceLocalAddress:
841 1.3 mycroft return (u_char *) &uvifs[ifnum].uv_lcl_addr;
842 1.1 mycroft
843 1.3 mycroft case dvmrpVInterfaceRemoteAddress:
844 1.3 mycroft return (u_char *) ((uvifs[ifnum].uv_flags & VIFF_TUNNEL) ?
845 1.3 mycroft &uvifs[ifnum].uv_rmt_addr :
846 1.3 mycroft &uvifs[ifnum].uv_subnet);
847 1.1 mycroft
848 1.3 mycroft case dvmrpVInterfaceRemoteSubnetMask:
849 1.3 mycroft return (u_char *) &uvifs[ifnum].uv_subnetmask;
850 1.1 mycroft
851 1.3 mycroft case dvmrpVInterfaceMetric:
852 1.3 mycroft long_return = uvifs[ifnum].uv_metric;
853 1.3 mycroft return (u_char *) &long_return;
854 1.1 mycroft
855 1.3 mycroft case dvmrpVInterfaceRateLimit:
856 1.3 mycroft long_return = uvifs[ifnum].uv_rate_limit;
857 1.3 mycroft return (u_char *) &long_return;
858 1.1 mycroft
859 1.3 mycroft case dvmrpVInterfaceInPkts:
860 1.1 mycroft refresh_vif(&v_req, ifnum);
861 1.3 mycroft long_return = v_req.icount;
862 1.3 mycroft return (u_char *) &long_return;
863 1.1 mycroft
864 1.3 mycroft case dvmrpVInterfaceOutPkts:
865 1.1 mycroft refresh_vif(&v_req, ifnum);
866 1.3 mycroft long_return = v_req.ocount;
867 1.3 mycroft return (u_char *) &long_return;
868 1.1 mycroft
869 1.3 mycroft case dvmrpVInterfaceInOctets:
870 1.1 mycroft refresh_vif(&v_req, ifnum);
871 1.3 mycroft long_return = v_req.ibytes;
872 1.3 mycroft return (u_char *) &long_return;
873 1.1 mycroft
874 1.3 mycroft case dvmrpVInterfaceOutOctets:
875 1.1 mycroft refresh_vif(&v_req, ifnum);
876 1.3 mycroft long_return = v_req.obytes;
877 1.3 mycroft return (u_char *) &long_return;
878 1.1 mycroft
879 1.1 mycroft default:
880 1.3 mycroft ERROR("");
881 1.1 mycroft }
882 1.3 mycroft return NULL;
883 1.1 mycroft }
884 1.1 mycroft
885 1.1 mycroft /*
886 1.3 mycroft * Implements the DVMRP Route Table portion of the DVMRP MIB
887 1.1 mycroft */
888 1.3 mycroft u_char *
889 1.3 mycroft o_dvmrpRouteTable(vp, name, length, exact, var_len, write_method)
890 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
891 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
892 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
893 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
894 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
895 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
896 1.3 mycroft {
897 1.3 mycroft u_long src, mask;
898 1.3 mycroft oid newname[MAX_NAME_LEN];
899 1.3 mycroft int len;
900 1.3 mycroft struct rtentry *rt = NULL;
901 1.1 mycroft
902 1.3 mycroft /* Copy name OID to new OID */
903 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
904 1.1 mycroft
905 1.3 mycroft if (exact) {
906 1.3 mycroft if (*length != vp->namelen + 8)
907 1.3 mycroft return NULL;
908 1.3 mycroft
909 1.3 mycroft if (!get_address(name, *length, &src, vp->namelen)
910 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+4))
911 1.3 mycroft return NULL;
912 1.3 mycroft
913 1.3 mycroft if (!(rt = snmp_find_route(src, mask)))
914 1.3 mycroft return NULL;
915 1.3 mycroft
916 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
917 1.3 mycroft } else {
918 1.3 mycroft len = *length;
919 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
920 1.3 mycroft len = vp->namelen;
921 1.3 mycroft
922 1.3 mycroft if (len < vp->namelen + 8) { /* get first entry */
923 1.3 mycroft
924 1.3 mycroft if (len == vp->namelen) {
925 1.3 mycroft src = mask = 0;
926 1.3 mycroft } else {
927 1.3 mycroft get_address(name, len, &src, vp->namelen);
928 1.3 mycroft get_address(name, len, &mask, vp->namelen+4);
929 1.3 mycroft }
930 1.1 mycroft
931 1.3 mycroft if (!next_route(&rt,src,mask)) /* Get first entry */
932 1.3 mycroft return NULL;
933 1.1 mycroft
934 1.3 mycroft put_address(newname, rt->rt_origin , vp->namelen);
935 1.3 mycroft put_address(newname, rt->rt_originmask, vp->namelen+4);
936 1.3 mycroft } else { /* get next entry given previous */
937 1.3 mycroft get_address(name, *length, &src, vp->namelen);
938 1.3 mycroft get_address(name, *length, &mask, vp->namelen+4);
939 1.1 mycroft
940 1.3 mycroft if (!next_route(&rt, src,mask))
941 1.3 mycroft return NULL;
942 1.1 mycroft
943 1.3 mycroft put_address(newname, rt->rt_origin, vp->namelen);
944 1.3 mycroft put_address(newname, rt->rt_originmask, vp->namelen+4);
945 1.3 mycroft }
946 1.1 mycroft }
947 1.1 mycroft
948 1.3 mycroft /* Save new OID */
949 1.3 mycroft *length = vp->namelen + 8;
950 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
951 1.3 mycroft *write_method = 0;
952 1.3 mycroft *var_len = sizeof(long);
953 1.1 mycroft
954 1.3 mycroft switch (vp->magic) {
955 1.1 mycroft
956 1.3 mycroft case dvmrpRouteUpstreamNeighbor:
957 1.3 mycroft return (u_char *) &rt->rt_gateway;
958 1.1 mycroft
959 1.1 mycroft case dvmrpRouteInVifIndex:
960 1.3 mycroft long_return = rt->rt_parent;
961 1.3 mycroft return (u_char *) &long_return;
962 1.1 mycroft
963 1.1 mycroft case dvmrpRouteMetric:
964 1.3 mycroft long_return = rt->rt_metric;
965 1.3 mycroft return (u_char *) &long_return;
966 1.1 mycroft
967 1.1 mycroft case dvmrpRouteExpiryTime:
968 1.3 mycroft long_return = (ROUTE_EXPIRE_TIME - rt->rt_timer
969 1.3 mycroft + secs_remaining_offset()) * 100;
970 1.3 mycroft return (u_char *) &long_return;
971 1.1 mycroft
972 1.3 mycroft default:
973 1.3 mycroft ERROR("");
974 1.3 mycroft }
975 1.3 mycroft return NULL;
976 1.1 mycroft }
977 1.1 mycroft
978 1.3 mycroft /*
979 1.3 mycroft * Implements the DVMRP Routing Next Hop Table portion of the DVMRP MIB
980 1.1 mycroft */
981 1.3 mycroft u_char *
982 1.3 mycroft o_dvmrpRouteNextHopTable(vp, name, length, exact, var_len, write_method)
983 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
984 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
985 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
986 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
987 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
988 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
989 1.1 mycroft {
990 1.3 mycroft u_long src, mask;
991 1.3 mycroft vifi_t vifi;
992 1.1 mycroft struct rtentry *rt = NULL;
993 1.3 mycroft oid newname[MAX_NAME_LEN];
994 1.3 mycroft int len;
995 1.3 mycroft
996 1.3 mycroft /* Copy name OID to new OID */
997 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
998 1.1 mycroft
999 1.3 mycroft if (exact) {
1000 1.3 mycroft if (*length != vp->namelen + 9)
1001 1.3 mycroft return NULL;
1002 1.1 mycroft
1003 1.3 mycroft if (!get_address(name, *length, &src, vp->namelen)
1004 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+4)
1005 1.1 mycroft || (!(rt=snmp_find_route(src,mask))))
1006 1.3 mycroft return NULL;
1007 1.1 mycroft
1008 1.3 mycroft vifi = name[vp->namelen+8];
1009 1.1 mycroft if (!(VIFM_ISSET(vifi, rt->rt_children)))
1010 1.3 mycroft return NULL;
1011 1.1 mycroft
1012 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
1013 1.3 mycroft } else {
1014 1.3 mycroft len = *length;
1015 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
1016 1.3 mycroft len = vp->namelen;
1017 1.1 mycroft
1018 1.3 mycroft if (len < vp->namelen + 9) { /* get first entry */
1019 1.1 mycroft
1020 1.3 mycroft get_address(name, len, &src, vp->namelen);
1021 1.3 mycroft get_address(name, len, &mask, vp->namelen+4);
1022 1.1 mycroft
1023 1.1 mycroft /* Find first child vif */
1024 1.1 mycroft vifi=0;
1025 1.1 mycroft if (!next_route_child(&rt, src, mask, &vifi))
1026 1.3 mycroft return NULL;
1027 1.1 mycroft
1028 1.3 mycroft put_address(newname, rt->rt_origin, vp->namelen);
1029 1.3 mycroft put_address(newname, rt->rt_originmask, vp->namelen+4);
1030 1.3 mycroft newname[vp->namelen+8] = vifi;
1031 1.3 mycroft } else { /* get next entry given previous */
1032 1.3 mycroft vifi = name[vp->namelen+8] + 1;
1033 1.3 mycroft if (!get_address(name, *length, &src, vp->namelen)
1034 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+4)
1035 1.1 mycroft || !next_route_child(&rt, src, mask, &vifi))
1036 1.3 mycroft return NULL;
1037 1.1 mycroft
1038 1.3 mycroft put_address(newname, rt->rt_origin, vp->namelen);
1039 1.3 mycroft put_address(newname, rt->rt_originmask, vp->namelen+4);
1040 1.3 mycroft newname[vp->namelen+8] = vifi;
1041 1.3 mycroft }
1042 1.3 mycroft }
1043 1.1 mycroft
1044 1.3 mycroft /* Save new OID */
1045 1.3 mycroft *length = vp->namelen + 9;
1046 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
1047 1.3 mycroft *write_method = 0;
1048 1.3 mycroft *var_len = sizeof(long);
1049 1.3 mycroft
1050 1.3 mycroft switch (vp->magic) {
1051 1.3 mycroft
1052 1.3 mycroft case dvmrpRouteNextHopType:
1053 1.3 mycroft long_return = (VIFM_ISSET(vifi, rt->rt_leaves))? 1 : 2;
1054 1.3 mycroft return (u_char *) &long_return;
1055 1.1 mycroft
1056 1.3 mycroft default:
1057 1.3 mycroft ERROR("");
1058 1.3 mycroft }
1059 1.3 mycroft return NULL;
1060 1.1 mycroft }
1061 1.1 mycroft
1062 1.3 mycroft /*
1063 1.3 mycroft * Implements the IP Multicast Route Table portion of the Multicast MIB
1064 1.1 mycroft */
1065 1.3 mycroft u_char *
1066 1.3 mycroft o_ipMRouteTable(vp, name, length, exact, var_len, write_method)
1067 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
1068 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
1069 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
1070 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
1071 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
1072 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
1073 1.1 mycroft {
1074 1.1 mycroft u_long src, grp, mask;
1075 1.1 mycroft struct gtable *gt = NULL;
1076 1.1 mycroft struct stable *st = NULL;
1077 1.1 mycroft static struct sioc_sg_req sg_req;
1078 1.3 mycroft oid newname[MAX_NAME_LEN];
1079 1.3 mycroft int len;
1080 1.1 mycroft
1081 1.3 mycroft /* Copy name OID to new OID */
1082 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
1083 1.3 mycroft
1084 1.3 mycroft if (exact) {
1085 1.3 mycroft if (*length != vp->namelen + 12)
1086 1.3 mycroft return NULL;
1087 1.3 mycroft
1088 1.3 mycroft if (!get_address(name, *length, &grp, vp->namelen)
1089 1.3 mycroft || !get_address(name, *length, &src, vp->namelen+4)
1090 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+8)
1091 1.1 mycroft || (mask != 0xFFFFFFFF) /* we keep sources now, not subnets */
1092 1.1 mycroft || !(gt = find_grp(grp))
1093 1.1 mycroft || !(st = find_grp_src(gt,src)))
1094 1.3 mycroft return NULL;
1095 1.1 mycroft
1096 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
1097 1.3 mycroft } else {
1098 1.3 mycroft len = *length;
1099 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
1100 1.3 mycroft len = vp->namelen;
1101 1.3 mycroft
1102 1.3 mycroft if (len < vp->namelen + 12) { /* get first entry */
1103 1.3 mycroft
1104 1.3 mycroft get_address(name, len, &grp, vp->namelen);
1105 1.3 mycroft get_address(name, len, &src, vp->namelen+4);
1106 1.3 mycroft get_address(name, len, &mask, vp->namelen+8);
1107 1.1 mycroft
1108 1.3 mycroft if (!next_grp_src_mask(>,&st,grp,src,mask)) /* Get first entry */
1109 1.3 mycroft return NULL;
1110 1.1 mycroft
1111 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen);
1112 1.3 mycroft put_address(newname, st->st_origin, vp->namelen+4);
1113 1.3 mycroft put_address(newname, 0xFFFFFFFF, vp->namelen+8);
1114 1.3 mycroft } else { /* get next entry given previous */
1115 1.3 mycroft get_address(name, *length, &grp , vp->namelen);
1116 1.3 mycroft get_address(name, *length, &src , vp->namelen+4);
1117 1.3 mycroft get_address(name, *length, &mask, vp->namelen+8);
1118 1.1 mycroft
1119 1.1 mycroft if (!next_grp_src_mask(>, &st, grp,src,mask))
1120 1.3 mycroft return NULL;
1121 1.3 mycroft
1122 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen);
1123 1.3 mycroft put_address(newname, st->st_origin, vp->namelen+4);
1124 1.3 mycroft put_address(newname, 0xFFFFFFFF, vp->namelen+8);
1125 1.3 mycroft }
1126 1.3 mycroft }
1127 1.1 mycroft
1128 1.3 mycroft /* Save new OID */
1129 1.3 mycroft *length = vp->namelen + 12;
1130 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
1131 1.3 mycroft *write_method = 0;
1132 1.3 mycroft *var_len = sizeof(long);
1133 1.1 mycroft
1134 1.3 mycroft switch (vp->magic) {
1135 1.1 mycroft
1136 1.3 mycroft case ipMRouteUpstreamNeighbor:
1137 1.3 mycroft return (u_char *) >->gt_route->rt_gateway;
1138 1.1 mycroft
1139 1.1 mycroft case ipMRouteInIfIndex:
1140 1.3 mycroft long_return = gt->gt_route->rt_parent;
1141 1.3 mycroft return (u_char *) &long_return;
1142 1.1 mycroft
1143 1.1 mycroft case ipMRouteUpTime: {
1144 1.1 mycroft time_t currtime;
1145 1.1 mycroft time(&currtime);
1146 1.3 mycroft long_return = (currtime - gt->gt_ctime)*100;
1147 1.3 mycroft return (u_char *) &long_return;
1148 1.1 mycroft }
1149 1.1 mycroft
1150 1.1 mycroft case ipMRouteExpiryTime:
1151 1.3 mycroft long_return = 5*((gt->gt_timer+4)/5); /* round up to nearest 5 */
1152 1.3 mycroft long_return = (long_return + secs_remaining_offset()) * 100;
1153 1.3 mycroft return (u_char *) &long_return;
1154 1.1 mycroft
1155 1.1 mycroft case ipMRoutePkts:
1156 1.1 mycroft refresh_sg(&sg_req, gt, st);
1157 1.3 mycroft long_return = sg_req.pktcnt;
1158 1.3 mycroft return (u_char *) &long_return;
1159 1.3 mycroft
1160 1.1 mycroft case ipMRouteOctets:
1161 1.1 mycroft refresh_sg(&sg_req, gt, st);
1162 1.3 mycroft long_return = sg_req.bytecnt;
1163 1.3 mycroft return (u_char *) &long_return;
1164 1.1 mycroft
1165 1.1 mycroft case ipMRouteDifferentInIfIndexes:
1166 1.1 mycroft refresh_sg(&sg_req, gt, st);
1167 1.3 mycroft long_return = sg_req.wrong_if;
1168 1.3 mycroft return (u_char *) &long_return;
1169 1.1 mycroft
1170 1.1 mycroft case ipMRouteProtocol:
1171 1.3 mycroft long_return = 4;
1172 1.3 mycroft return (u_char *) &long_return;
1173 1.1 mycroft
1174 1.3 mycroft default:
1175 1.3 mycroft ERROR("");
1176 1.3 mycroft }
1177 1.3 mycroft return NULL;
1178 1.1 mycroft }
1179 1.1 mycroft
1180 1.3 mycroft /*
1181 1.1 mycroft * Implements the IP Multicast Routing Next Hop Table portion of the Multicast
1182 1.3 mycroft * MIB
1183 1.1 mycroft */
1184 1.3 mycroft u_char *
1185 1.3 mycroft o_ipMRouteNextHopTable(vp, name, length, exact, var_len, write_method)
1186 1.6 wiz struct variable *vp; /* IN - pointer to variable entry that points here */
1187 1.6 wiz oid *name; /* IN/OUT - input name requested, output name found */
1188 1.6 wiz int *length; /* IN/OUT - length of input and output oid's */
1189 1.3 mycroft int exact; /* IN - TRUE if an exact match was requested. */
1190 1.3 mycroft int *var_len; /* OUT - length of variable or 0 if function returned. */
1191 1.3 mycroft int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */
1192 1.1 mycroft {
1193 1.1 mycroft u_long src, grp, mask, addr;
1194 1.1 mycroft vifi_t vifi;
1195 1.1 mycroft struct gtable *gt;
1196 1.1 mycroft struct stable *st;
1197 1.3 mycroft oid newname[MAX_NAME_LEN];
1198 1.3 mycroft int len;
1199 1.1 mycroft
1200 1.3 mycroft /* Copy name OID to new OID */
1201 1.3 mycroft bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
1202 1.3 mycroft
1203 1.3 mycroft if (exact) {
1204 1.3 mycroft if (*length != vp->namelen + 17)
1205 1.3 mycroft return NULL;
1206 1.3 mycroft
1207 1.3 mycroft if (!get_address(name, *length, &grp, vp->namelen)
1208 1.3 mycroft || !get_address(name, *length, &src, vp->namelen+4)
1209 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+8)
1210 1.3 mycroft || !get_address(name, *length, &addr, vp->namelen+13)
1211 1.1 mycroft || grp!=addr
1212 1.1 mycroft || mask!=0xFFFFFFFF
1213 1.1 mycroft || (!(gt=find_grp(grp)))
1214 1.1 mycroft || (!(st=find_grp_src(gt,src))))
1215 1.3 mycroft return NULL;
1216 1.1 mycroft
1217 1.3 mycroft vifi = name[vp->namelen+12];
1218 1.1 mycroft if (!(VIFM_ISSET(vifi, gt->gt_route->rt_children)))
1219 1.3 mycroft return NULL;
1220 1.1 mycroft
1221 1.3 mycroft bcopy((char *)name, (char *)newname, ((int)*length) * sizeof(oid));
1222 1.3 mycroft } else {
1223 1.3 mycroft len = *length;
1224 1.3 mycroft if (compare(name, *length, vp->name, vp->namelen) < 0)
1225 1.3 mycroft len = vp->namelen;
1226 1.3 mycroft
1227 1.3 mycroft if (len < vp->namelen + 17) { /* get first entry */
1228 1.3 mycroft
1229 1.3 mycroft get_address(name, len, &grp, vp->namelen);
1230 1.3 mycroft get_address(name, len, &src, vp->namelen+4);
1231 1.3 mycroft get_address(name, len, &mask, vp->namelen+8);
1232 1.1 mycroft
1233 1.1 mycroft /* Find first child vif */
1234 1.1 mycroft vifi=0;
1235 1.1 mycroft if (!next_child(>, &st, grp, src, mask, &vifi))
1236 1.3 mycroft return NULL;
1237 1.3 mycroft
1238 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen);
1239 1.3 mycroft put_address(newname, st->st_origin, vp->namelen+4);
1240 1.3 mycroft put_address(newname, 0xFFFFFFFF, vp->namelen+8);
1241 1.3 mycroft newname[vp->namelen+12] = vifi;
1242 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen+13);
1243 1.1 mycroft
1244 1.3 mycroft } else { /* get next entry given previous */
1245 1.3 mycroft vifi = name[vp->namelen+12]+1;
1246 1.3 mycroft if (!get_address(name, *length, &grp, vp->namelen)
1247 1.3 mycroft || !get_address(name, *length, &src, vp->namelen+4)
1248 1.3 mycroft || !get_address(name, *length, &mask, vp->namelen+8)
1249 1.1 mycroft || !next_child(>, &st, grp, src, mask, &vifi))
1250 1.3 mycroft return NULL;
1251 1.1 mycroft
1252 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen);
1253 1.3 mycroft put_address(newname, st->st_origin, vp->namelen+4);
1254 1.3 mycroft put_address(newname, 0xFFFFFFFF, vp->namelen+8);
1255 1.3 mycroft newname[vp->namelen+12] = vifi;
1256 1.3 mycroft put_address(newname, gt->gt_mcastgrp, vp->namelen+13);
1257 1.3 mycroft }
1258 1.3 mycroft }
1259 1.1 mycroft
1260 1.3 mycroft /* Save new OID */
1261 1.3 mycroft *length = vp->namelen + 17;
1262 1.3 mycroft bcopy((char *)newname, (char *)name, ((int)*length) * sizeof(oid));
1263 1.3 mycroft *write_method = 0;
1264 1.3 mycroft *var_len = sizeof(long);
1265 1.1 mycroft
1266 1.3 mycroft switch (vp->magic) {
1267 1.1 mycroft
1268 1.1 mycroft case ipMRouteNextHopState:
1269 1.3 mycroft long_return = (VIFM_ISSET(vifi, gt->gt_grpmems))? 2 : 1;
1270 1.3 mycroft return (u_char *) &long_return;
1271 1.1 mycroft
1272 1.1 mycroft /* Currently equal to ipMRouteUpTime */
1273 1.1 mycroft case ipMRouteNextHopUpTime: {
1274 1.1 mycroft time_t currtime;
1275 1.1 mycroft time(&currtime);
1276 1.3 mycroft long_return = (currtime - gt->gt_ctime)*100;
1277 1.3 mycroft return (u_char *) &long_return;
1278 1.1 mycroft }
1279 1.1 mycroft
1280 1.1 mycroft case ipMRouteNextHopExpiryTime:
1281 1.3 mycroft long_return = 5*((gt->gt_prsent_timer+4)/5); /* round up to nearest 5*/
1282 1.3 mycroft long_return = (long_return + secs_remaining_offset()) * 100;
1283 1.3 mycroft return (u_char *) &long_return;
1284 1.1 mycroft
1285 1.1 mycroft case ipMRouteNextHopClosestMemberHops:
1286 1.3 mycroft long_return = 0;
1287 1.3 mycroft return (u_char *) &long_return;
1288 1.1 mycroft
1289 1.1 mycroft case ipMRouteNextHopProtocol:
1290 1.3 mycroft long_return = 4;
1291 1.3 mycroft return (u_char *) &long_return;
1292 1.3 mycroft
1293 1.3 mycroft default:
1294 1.3 mycroft ERROR("");
1295 1.3 mycroft }
1296 1.3 mycroft return NULL;
1297 1.3 mycroft }
1298 1.3 mycroft
1299 1.3 mycroft /* sync_timer is called by timer() every TIMER_INTERVAL seconds.
1300 1.3 mycroft * Its job is to record this time so that we can compute on demand
1301 1.3 mycroft * the approx # seconds remaining until the next timer() call
1302 1.3 mycroft */
1303 1.3 mycroft static time_t lasttimer;
1304 1.3 mycroft
1305 1.3 mycroft void
1306 1.3 mycroft sync_timer()
1307 1.3 mycroft {
1308 1.3 mycroft time(&lasttimer);
1309 1.3 mycroft }
1310 1.3 mycroft
1311 1.3 mycroft int /* in range [-TIMER_INTERVAL..0] */
1312 1.3 mycroft secs_remaining_offset()
1313 1.3 mycroft {
1314 1.3 mycroft time_t tm;
1315 1.1 mycroft
1316 1.3 mycroft time(&tm);
1317 1.3 mycroft return lasttimer-tm;
1318 1.1 mycroft }
1319