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