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