Commit | Line | Data |
---|---|---|
b62cce74 C |
1 | /* unixd.c - daemon for UNIX MIB */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $ | |
9 | * | |
10 | * Contributed by NYSERNet Inc. This work was partially supported by the | |
11 | * U.S. Defense Advanced Research Projects Agency and the Rome Air Development | |
12 | * Center of the U.S. Air Force Systems Command under contract number | |
13 | * F30602-88-C-0016. | |
14 | * | |
15 | * | |
16 | * $Log: unixd.c,v $ | |
17 | * Revision 7.13 91/03/09 11:57:58 mrose | |
18 | * update | |
19 | * | |
20 | * Revision 7.12 91/02/22 09:44:55 mrose | |
21 | * Interim 6.8 | |
22 | * | |
23 | * Revision 7.11 91/01/11 15:35:40 mrose | |
24 | * sets | |
25 | * | |
26 | * Revision 7.10 91/01/08 12:48:55 mrose | |
27 | * update | |
28 | * | |
29 | * Revision 7.9 90/12/18 10:14:22 mrose | |
30 | * update | |
31 | * | |
32 | * Revision 7.8 90/10/17 11:57:41 mrose | |
33 | * sync | |
34 | * | |
35 | * Revision 7.7 90/07/09 14:49:48 mrose | |
36 | * sync | |
37 | * | |
38 | * Revision 7.6 90/03/06 13:51:01 mrose | |
39 | * jch | |
40 | * | |
41 | * Revision 7.5 90/02/23 17:48:05 mrose | |
42 | * update | |
43 | * | |
44 | * Revision 7.4 90/02/19 15:54:09 mrose | |
45 | * touch-up | |
46 | * | |
47 | * Revision 7.3 90/02/19 15:39:08 mrose | |
48 | * one more time | |
49 | * | |
50 | * Revision 7.2 90/02/17 17:19:01 mrose | |
51 | * touch-up | |
52 | * | |
53 | * Revision 7.1 90/02/17 10:42:20 mrose | |
54 | * touch-up | |
55 | * | |
56 | * Revision 7.0 90/02/17 10:36:48 mrose | |
57 | * *** empty log message *** | |
58 | * | |
59 | */ | |
60 | ||
61 | /* | |
62 | * NOTICE | |
63 | * | |
64 | * Acquisition, use, and distribution of this module and related | |
65 | * materials are subject to the restrictions of a license agreement. | |
66 | * Consult the Preface in the User's Manual for the full terms of | |
67 | * this agreement. | |
68 | * | |
69 | */ | |
70 | ||
71 | ||
72 | #include <errno.h> | |
73 | #include <signal.h> | |
74 | #include <stdio.h> | |
75 | #include <varargs.h> | |
76 | #include "smux.h" | |
77 | #include "objects.h" | |
78 | #include <sys/ioctl.h> | |
79 | #ifdef BSD42 | |
80 | #include <sys/file.h> | |
81 | #endif | |
82 | #ifdef SYS5 | |
83 | #include <fcntl.h> | |
84 | #endif | |
85 | #include "tailor.h" | |
86 | ||
87 | /* \f DATA */ | |
88 | ||
89 | int debug = 0; | |
90 | static int nbits = FD_SETSIZE; | |
91 | ||
92 | static LLog _pgm_log = { | |
93 | "unixd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, | |
94 | LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK | |
95 | }; | |
96 | static LLog *pgm_log = &_pgm_log; | |
97 | ||
98 | static char *myname = "unixd"; | |
99 | ||
100 | ||
101 | static int smux_fd = NOTOK; | |
102 | static int rock_and_roll = 0; | |
103 | static int dont_bother_anymore = 0; | |
104 | ||
105 | static OID subtree = NULLOID; | |
106 | static struct smuxEntry *se = NULL; | |
107 | ||
108 | ||
109 | static fd_set ifds; | |
110 | static fd_set ofds; | |
111 | ||
112 | ||
113 | void adios (), advise (); | |
114 | ||
115 | /* \f MAIN */ | |
116 | ||
117 | /* ARGSUSED */ | |
118 | ||
119 | main (argc, argv, envp) | |
120 | int argc; | |
121 | char **argv, | |
122 | **envp; | |
123 | { | |
124 | int nfds; | |
125 | ||
126 | arginit (argv); | |
127 | envinit (); | |
128 | ||
129 | FD_ZERO (&ifds); | |
130 | FD_ZERO (&ofds); | |
131 | nfds = 0; | |
132 | ||
133 | /* set fd's for other purposes here... */ | |
134 | ||
135 | for (;;) { | |
136 | int n, | |
137 | secs; | |
138 | fd_set rfds, | |
139 | wfds; | |
140 | ||
141 | secs = NOTOK; | |
142 | ||
143 | rfds = ifds; /* struct copy */ | |
144 | wfds = ofds; /* .. */ | |
145 | ||
146 | if (smux_fd == NOTOK && !dont_bother_anymore) | |
147 | secs = 5 * 60L; | |
148 | else | |
149 | if (rock_and_roll) | |
150 | FD_SET (smux_fd, &rfds); | |
151 | else | |
152 | FD_SET (smux_fd, &wfds); | |
153 | if (smux_fd >= nfds) | |
154 | nfds = smux_fd + 1; | |
155 | ||
156 | if ((n = xselect (nfds, &rfds, &wfds, NULLFD, secs)) == NOTOK) | |
157 | adios ("failed", "xselect"); | |
158 | ||
159 | /* check fd's for other purposes here... */ | |
160 | ||
161 | if (smux_fd == NOTOK && !dont_bother_anymore) { | |
162 | if (n == 0) { | |
163 | if ((smux_fd = smux_init (debug)) == NOTOK) | |
164 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_init: %s [%s]", | |
165 | smux_error (smux_errno), smux_info); | |
166 | else | |
167 | rock_and_roll = 0; | |
168 | } | |
169 | } | |
170 | else | |
171 | if (rock_and_roll) { | |
172 | if (FD_ISSET (smux_fd, &rfds)) | |
173 | doit_smux (); | |
174 | } | |
175 | else | |
176 | if (FD_ISSET (smux_fd, &wfds)) | |
177 | start_smux (); | |
178 | } | |
179 | } | |
180 | ||
181 | /* \f MISCELLANY */ | |
182 | ||
183 | static arginit (vec) | |
184 | char **vec; | |
185 | { | |
186 | register char *ap; | |
187 | ||
188 | if (myname = rindex (*vec, '/')) | |
189 | myname++; | |
190 | if (myname == NULL || *myname == NULL) | |
191 | myname = *vec; | |
192 | if (strncmp (myname, "smux.", 5) == 0 && myname[5] != NULL) | |
193 | myname += 5; | |
194 | ||
195 | isodetailor (myname, 0); | |
196 | ll_hdinit (pgm_log, myname); | |
197 | ||
198 | for (vec++; ap = *vec; vec++) { | |
199 | if (*ap == '-') | |
200 | switch (*++ap) { | |
201 | case 'd': | |
202 | debug++; | |
203 | continue; | |
204 | ||
205 | default: | |
206 | adios (NULLCP, "-%s: unknown switch", ap); | |
207 | } | |
208 | ||
209 | adios (NULLCP, "usage: %s [switches]", myname); | |
210 | } | |
211 | ||
212 | ||
213 | } | |
214 | ||
215 | /* \f */ | |
216 | ||
217 | static envinit () { | |
218 | int i, | |
219 | sd; | |
220 | char file[BUFSIZ]; | |
221 | FILE *fp; | |
222 | ||
223 | nbits = getdtablesize (); | |
224 | ||
225 | if (debug == 0 && !(debug = isatty (2))) { | |
226 | for (i = 0; i < 5; i++) { | |
227 | switch (fork ()) { | |
228 | case NOTOK: | |
229 | sleep (5); | |
230 | continue; | |
231 | ||
232 | case OK: | |
233 | break; | |
234 | ||
235 | default: | |
236 | _exit (0); | |
237 | } | |
238 | break; | |
239 | } | |
240 | ||
241 | (void) chdir ("/"); | |
242 | ||
243 | if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) | |
244 | adios ("/dev/null", "unable to read"); | |
245 | if (sd != 0) | |
246 | (void) dup2 (sd, 0), (void) close (sd); | |
247 | (void) dup2 (0, 1); | |
248 | (void) dup2 (0, 2); | |
249 | ||
250 | #ifdef SETSID | |
251 | if (setsid () == NOTOK) | |
252 | advise (LLOG_EXCEPTIONS, "failed", "setsid"); | |
253 | #endif | |
254 | #ifdef TIOCNOTTY | |
255 | if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { | |
256 | (void) ioctl (sd, TIOCNOTTY, NULLCP); | |
257 | (void) close (sd); | |
258 | } | |
259 | #else | |
260 | #ifdef SYS5 | |
261 | (void) setpgrp (); | |
262 | (void) signal (SIGINT, SIG_IGN); | |
263 | (void) signal (SIGQUIT, SIG_IGN); | |
264 | #endif | |
265 | #endif | |
266 | } | |
267 | else | |
268 | ll_dbinit (pgm_log, myname); | |
269 | ||
270 | #ifndef sun /* damn YP... */ | |
271 | for (sd = 3; sd < nbits; sd++) | |
272 | if (pgm_log -> ll_fd != sd) | |
273 | (void) close (sd); | |
274 | #endif | |
275 | ||
276 | (void) signal (SIGPIPE, SIG_IGN); | |
277 | ||
278 | ll_hdinit (pgm_log, myname); | |
279 | ||
280 | mibinit (); | |
281 | ||
282 | (void) sprintf (file, "/etc/%s.pid", myname); | |
283 | if (fp = fopen (file, "w")) { | |
284 | (void) fprintf (fp, "%d\n", getpid ()); | |
285 | (void) fclose (fp); | |
286 | } | |
287 | ||
288 | advise (LLOG_NOTICE, NULLCP, "starting"); | |
289 | } | |
290 | ||
291 | /* \f MIB */ | |
292 | ||
293 | #include <nlist.h> | |
294 | ||
295 | static int kd; | |
296 | static int quantum = 0; | |
297 | static int lastq = -1; | |
298 | ||
299 | static struct nlist nl[] = { | |
300 | #define N_MBSTAT 0 | |
301 | { "_mbstat" }, | |
302 | ||
303 | NULL | |
304 | }; | |
305 | ||
306 | ||
307 | static mibinit () { | |
308 | OT ot; | |
309 | register struct nlist *nz; | |
310 | ||
311 | if ((se = getsmuxEntrybyname ("unixd")) == NULL) | |
312 | adios (NULLCP, "no SMUX entry for \"%s\"", "unixd"); | |
313 | ||
314 | if (readobjects ("unixd.defs") == NOTOK) | |
315 | adios (NULLCP, "readobjects: %s", PY_pepy); | |
316 | ||
317 | if ((ot = text2obj ("mbuf")) == NULL) | |
318 | adios (NULLCP, "text2obj (\"%s\") fails", "mbuf"); | |
319 | subtree = ot -> ot_name; | |
320 | ||
321 | if (nlist ("/vmunix", nl) == NOTOK) | |
322 | adios ("/vmunix", "unable to nlist"); | |
323 | for (nz = nl; nz -> n_name; nz++) | |
324 | if (nz -> n_value == 0) | |
325 | advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix (warning)", | |
326 | nz -> n_name); | |
327 | ||
328 | if ((kd = open ("/dev/kmem", O_RDONLY)) == NOTOK) | |
329 | adios ("/vmunix", "unable to read"); | |
330 | ||
331 | init_unix (); /* UNIX-specific enterprise */ | |
332 | ||
333 | if ((smux_fd = smux_init (debug)) == NOTOK) | |
334 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_init: %s [%s]", | |
335 | smux_error (smux_errno), smux_info); | |
336 | else | |
337 | rock_and_roll = 0; | |
338 | } | |
339 | ||
340 | /* \f */ | |
341 | ||
342 | static start_smux () { | |
343 | if (smux_simple_open (&se -> se_identity, "SMUX UNIX daemon", | |
344 | se -> se_password, strlen (se -> se_password)) | |
345 | == NOTOK) { | |
346 | if (smux_errno == inProgress) | |
347 | return; | |
348 | ||
349 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_simple_open: %s [%s]", | |
350 | smux_error (smux_errno), smux_info); | |
351 | losing: ; | |
352 | smux_fd = NOTOK; | |
353 | return; | |
354 | } | |
355 | advise (LLOG_NOTICE, NULLCP, "SMUX open: %s \"%s\"", | |
356 | oid2ode (&se -> se_identity), se -> se_name); | |
357 | rock_and_roll = 1; | |
358 | ||
359 | if (smux_register (subtree, -1, readOnly) == NOTOK) { | |
360 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_register: %s [%s]", | |
361 | smux_error (smux_errno), smux_info); | |
362 | goto losing; | |
363 | } | |
364 | advise (LLOG_NOTICE, NULLCP, "SMUX register: readOnly %s in=%d", | |
365 | oid2ode (subtree), -1); | |
366 | } | |
367 | ||
368 | /* \f */ | |
369 | ||
370 | static doit_smux () { | |
371 | struct type_SNMP_SMUX__PDUs *event; | |
372 | ||
373 | if (smux_wait (&event, NOTOK) == NOTOK) { | |
374 | if (smux_errno == inProgress) | |
375 | return; | |
376 | ||
377 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_wait: %s [%s]", | |
378 | smux_error (smux_errno), smux_info); | |
379 | losing: ; | |
380 | smux_fd = NOTOK; | |
381 | return; | |
382 | } | |
383 | ||
384 | switch (event -> offset) { | |
385 | case type_SNMP_SMUX__PDUs_registerResponse: | |
386 | { | |
387 | struct type_SNMP_RRspPDU *rsp = event -> un.registerResponse; | |
388 | ||
389 | if (rsp -> parm == int_SNMP_RRspPDU_failure) { | |
390 | advise (LLOG_NOTICE, NULLCP, | |
391 | "SMUX registration of %s failed", | |
392 | oid2ode (subtree)); | |
393 | dont_bother_anymore = 1; | |
394 | (void) smux_close (goingDown); | |
395 | goto losing; | |
396 | } | |
397 | else | |
398 | advise (LLOG_NOTICE, NULLCP, | |
399 | "SMUX register: readOnly %s out=%d", | |
400 | oid2ode (subtree), rsp -> parm); | |
401 | } | |
402 | if (smux_trap (int_SNMP_generic__trap_coldStart, | |
403 | 0, (struct type_SNMP_VarBindList *) 0) == NOTOK) { | |
404 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_trap: %s [%s]", | |
405 | smux_error (smux_errno), smux_info); | |
406 | goto losing; | |
407 | } | |
408 | break; | |
409 | ||
410 | case type_SNMP_SMUX__PDUs_get__request: | |
411 | case type_SNMP_SMUX__PDUs_get__next__request: | |
412 | get_smux (event -> un.get__request, event -> offset); | |
413 | break; | |
414 | ||
415 | case type_SNMP_SMUX__PDUs_close: | |
416 | advise (LLOG_NOTICE, NULLCP, "SMUX close: %s", | |
417 | smux_error (event -> un.close -> parm)); | |
418 | goto losing; | |
419 | ||
420 | case type_SNMP_SMUX__PDUs_simple: | |
421 | case type_SNMP_SMUX__PDUs_registerRequest: | |
422 | case type_SNMP_SMUX__PDUs_get__response: | |
423 | case type_SNMP_SMUX__PDUs_trap: | |
424 | advise (LLOG_EXCEPTIONS, NULLCP, "unexpectedOperation: %d", | |
425 | event -> offset); | |
426 | (void) smux_close (protocolError); | |
427 | goto losing; | |
428 | ||
429 | case type_SNMP_SMUX__PDUs_set__request: | |
430 | case type_SNMP_SMUX__PDUs_commitOrRollback: | |
431 | set_smux (event); | |
432 | break; | |
433 | ||
434 | default: | |
435 | advise (LLOG_EXCEPTIONS, NULLCP, "badOperation: %d", | |
436 | event -> offset); | |
437 | (void) smux_close (protocolError); | |
438 | goto losing; | |
439 | } | |
440 | } | |
441 | ||
442 | /* \f */ | |
443 | ||
444 | static get_smux (pdu, offset) | |
445 | register struct type_SNMP_GetRequest__PDU *pdu; | |
446 | int offset; | |
447 | { | |
448 | int idx, | |
449 | status; | |
450 | object_instance ois; | |
451 | register struct type_SNMP_VarBindList *vp; | |
452 | ||
453 | quantum = pdu -> request__id; | |
454 | idx = 0; | |
455 | for (vp = pdu -> variable__bindings; vp; vp = vp -> next) { | |
456 | register OI oi; | |
457 | register OT ot; | |
458 | register struct type_SNMP_VarBind *v = vp -> VarBind; | |
459 | ||
460 | idx++; | |
461 | ||
462 | if (offset == type_SNMP_SMUX__PDUs_get__next__request) { | |
463 | if ((oi = name2inst (v -> name)) == NULLOI | |
464 | && (oi = next2inst (v -> name)) == NULLOI) | |
465 | goto no_name; | |
466 | ||
467 | if ((ot = oi -> oi_type) -> ot_getfnx == NULLIFP) | |
468 | goto get_next; | |
469 | } | |
470 | else | |
471 | if ((oi = name2inst (v -> name)) == NULLOI | |
472 | || (ot = oi -> oi_type) -> ot_getfnx == NULLIFP) { | |
473 | no_name: ; | |
474 | pdu -> error__status = int_SNMP_error__status_noSuchName; | |
475 | goto out; | |
476 | } | |
477 | ||
478 | try_again: ; | |
479 | switch (ot -> ot_access) { | |
480 | case OT_NONE: | |
481 | if (offset == type_SNMP_SMUX__PDUs_get__next__request) | |
482 | goto get_next; | |
483 | goto no_name; | |
484 | ||
485 | case OT_RDONLY: | |
486 | if (offset == type_SNMP_SMUX__PDUs_set__request) { | |
487 | pdu -> error__status = int_SNMP_error__status_noSuchName; | |
488 | goto out; | |
489 | } | |
490 | break; | |
491 | ||
492 | case OT_RDWRITE: | |
493 | break; | |
494 | } | |
495 | ||
496 | switch (status = (*ot -> ot_getfnx) (oi, v, offset)) { | |
497 | case NOTOK: /* get-next wants a bump */ | |
498 | get_next: ; | |
499 | oi = &ois; | |
500 | for (;;) { | |
501 | if ((ot = ot -> ot_next) == NULLOT) { | |
502 | pdu -> error__status = | |
503 | int_SNMP_error__status_noSuchName; | |
504 | goto out; | |
505 | } | |
506 | oi -> oi_name = (oi -> oi_type = ot) -> ot_name; | |
507 | if (ot -> ot_getfnx) | |
508 | goto try_again; | |
509 | } | |
510 | ||
511 | case int_SNMP_error__status_noError: | |
512 | break; | |
513 | ||
514 | default: | |
515 | pdu -> error__status = status; | |
516 | goto out; | |
517 | } | |
518 | } | |
519 | idx = 0; | |
520 | ||
521 | out: ; | |
522 | pdu -> error__index = idx; | |
523 | ||
524 | if (smux_response (pdu) == NOTOK) { | |
525 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_response: %s [%s]", | |
526 | smux_error (smux_errno), smux_info); | |
527 | smux_fd = NOTOK; | |
528 | } | |
529 | } | |
530 | ||
531 | /* \f */ | |
532 | ||
533 | static set_smux (event) | |
534 | struct type_SNMP_SMUX__PDUs *event; | |
535 | { | |
536 | switch (event -> offset) { | |
537 | case type_SNMP_SMUX__PDUs_set__request: | |
538 | { | |
539 | register struct type_SNMP_GetRequest__PDU *pdu = | |
540 | event -> un.get__response; | |
541 | ||
542 | pdu -> error__status = int_SNMP_error__status_noSuchName; | |
543 | pdu -> error__index = pdu -> variable__bindings ? 1 : 0; | |
544 | ||
545 | if (smux_response (pdu) == NOTOK) { | |
546 | advise (LLOG_EXCEPTIONS, NULLCP, "smux_response: %s [%s]", | |
547 | smux_error (smux_errno), smux_info); | |
548 | smux_fd = NOTOK; | |
549 | } | |
550 | } | |
551 | break; | |
552 | ||
553 | case type_SNMP_SMUX__PDUs_commitOrRollback: | |
554 | { | |
555 | struct type_SNMP_SOutPDU *cor = event -> un.commitOrRollback; | |
556 | ||
557 | if (cor -> parm == int_SNMP_SOutPDU_commit) { | |
558 | /* "should not happen" */ | |
559 | (void) smux_close (protocolError); | |
560 | smux_fd = NOTOK; | |
561 | } | |
562 | } | |
563 | break; | |
564 | } | |
565 | } | |
566 | ||
567 | /* \f UNIX */ | |
568 | ||
569 | #ifdef BSD44 | |
570 | #include <sys/param.h> | |
571 | #endif | |
572 | #include <sys/mbuf.h> | |
573 | ||
574 | /* \f */ | |
575 | ||
576 | static struct mbstat mbstat; | |
577 | ||
578 | /* \f */ | |
579 | ||
580 | #define mbufS 0 | |
581 | #define mbufClusters 1 | |
582 | #define mbufFreeClusters 2 | |
583 | #define mbufDrops 3 | |
584 | #ifdef BSD44 | |
585 | #define mbufWaits 4 | |
586 | #define mbufDrains 5 | |
587 | #endif | |
588 | #if !defined(BSD43) && !defined(BSD44) | |
589 | #define mbufFrees 6 | |
590 | #endif | |
591 | ||
592 | ||
593 | static int o_mbuf (oi, v, offset) | |
594 | OI oi; | |
595 | register struct type_SNMP_VarBind *v; | |
596 | int offset; | |
597 | { | |
598 | int ifvar; | |
599 | register struct mbstat *m = &mbstat; | |
600 | register OID oid = oi -> oi_name; | |
601 | register OT ot = oi -> oi_type; | |
602 | ||
603 | ifvar = (int) ot -> ot_info; | |
604 | switch (offset) { | |
605 | case type_SNMP_SMUX__PDUs_get__request: | |
606 | if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 | |
607 | || oid -> oid_elements[oid -> oid_nelem - 1] != 0) | |
608 | return int_SNMP_error__status_noSuchName; | |
609 | break; | |
610 | ||
611 | case type_SNMP_SMUX__PDUs_get__next__request: | |
612 | if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { | |
613 | OID new; | |
614 | ||
615 | if ((new = oid_extend (oid, 1)) == NULLOID) | |
616 | return NOTOK; | |
617 | new -> oid_elements[new -> oid_nelem - 1] = 0; | |
618 | ||
619 | if (v -> name) | |
620 | free_SNMP_ObjectName (v -> name); | |
621 | v -> name = new; | |
622 | } | |
623 | else | |
624 | return NOTOK; | |
625 | break; | |
626 | ||
627 | default: | |
628 | return int_SNMP_error__status_genErr; | |
629 | } | |
630 | ||
631 | if (quantum != lastq) { | |
632 | lastq = quantum; | |
633 | ||
634 | if (getkmem (nl + N_MBSTAT, (caddr_t) m, sizeof *m) == NOTOK) | |
635 | return (offset == type_SNMP_PDUs_get__next__request ? NOTOK | |
636 | : int_SNMP_error__status_genErr); | |
637 | } | |
638 | ||
639 | switch (ifvar) { | |
640 | case mbufS: | |
641 | return o_integer (oi, v, m -> m_mbufs); | |
642 | ||
643 | case mbufClusters: | |
644 | return o_integer (oi, v, m -> m_clusters); | |
645 | ||
646 | case mbufFreeClusters: | |
647 | return o_integer (oi, v, m -> m_clfree); | |
648 | ||
649 | case mbufDrops: | |
650 | return o_integer (oi, v, m -> m_drops); | |
651 | ||
652 | #ifdef mbufWaits | |
653 | case mbufWaits: | |
654 | return o_integer (oi, v, m -> m_wait); | |
655 | #endif | |
656 | ||
657 | #ifdef mbufDrains | |
658 | case mbufDrains: | |
659 | return o_integer (oi, v, m -> m_drain); | |
660 | #endif | |
661 | ||
662 | #ifdef mbufFrees | |
663 | case mbufFrees: | |
664 | return o_integer (oi, v, m -> m_mbfree); | |
665 | #endif | |
666 | ||
667 | default: | |
668 | return int_SNMP_error__status_noSuchName; | |
669 | } | |
670 | } | |
671 | ||
672 | /* \f */ | |
673 | ||
674 | #define mbufType 0 | |
675 | #define mbufAllocates 1 | |
676 | ||
677 | ||
678 | static int o_mbufType (oi, v, offset) | |
679 | OI oi; | |
680 | register struct type_SNMP_VarBind *v; | |
681 | int offset; | |
682 | { | |
683 | int ifnum, | |
684 | ifvar; | |
685 | register struct mbstat *m = &mbstat; | |
686 | register OID oid = oi -> oi_name; | |
687 | register OT ot = oi -> oi_type; | |
688 | ||
689 | ifvar = (int) ot -> ot_info; | |
690 | switch (offset) { | |
691 | case type_SNMP_SMUX__PDUs_get__request: | |
692 | if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) | |
693 | return int_SNMP_error__status_noSuchName; | |
694 | if ((ifnum = oid -> oid_elements[oid -> oid_nelem - 1]) | |
695 | >= sizeof m -> m_mtypes / sizeof m -> m_mtypes[0]) | |
696 | return int_SNMP_error__status_noSuchName; | |
697 | break; | |
698 | ||
699 | case type_SNMP_SMUX__PDUs_get__next__request: | |
700 | again: ; | |
701 | if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { | |
702 | OID new; | |
703 | ||
704 | ifnum = 0; | |
705 | ||
706 | if ((new = oid_extend (oid, 1)) == NULLOID) | |
707 | return NOTOK; | |
708 | new -> oid_elements[new -> oid_nelem - 1] = ifnum; | |
709 | ||
710 | if (v -> name) | |
711 | free_SNMP_ObjectName (v -> name); | |
712 | v -> name = new; | |
713 | ||
714 | oid = new; /* for hack... */ | |
715 | } | |
716 | else { | |
717 | int i = ot -> ot_name -> oid_nelem; | |
718 | ||
719 | if ((ifnum = oid -> oid_elements[i] + 1) | |
720 | >= sizeof m -> m_mtypes / sizeof m -> m_mtypes[0]) | |
721 | return NOTOK; | |
722 | ||
723 | oid -> oid_elements[i] = ifnum; | |
724 | oid -> oid_nelem = i + 1; | |
725 | } | |
726 | break; | |
727 | ||
728 | default: | |
729 | return int_SNMP_error__status_genErr; | |
730 | } | |
731 | ||
732 | if (quantum != lastq) { | |
733 | lastq = quantum; | |
734 | ||
735 | if (getkmem (nl + N_MBSTAT, (caddr_t) m, sizeof *m) == NOTOK) | |
736 | return (offset == type_SNMP_PDUs_get__next__request ? NOTOK | |
737 | : int_SNMP_error__status_genErr); | |
738 | } | |
739 | ||
740 | /* hack to compress table size... */ | |
741 | if (offset == type_SNMP_SMUX__PDUs_get__next__request | |
742 | && m -> m_mtypes[ifnum] == 0) | |
743 | goto again; | |
744 | ||
745 | switch (ifvar) { | |
746 | case mbufType: | |
747 | return o_integer (oi, v, ifnum); | |
748 | ||
749 | case mbufAllocates: | |
750 | return o_integer (oi, v, m -> m_mtypes[ifnum]); | |
751 | ||
752 | default: | |
753 | return int_SNMP_error__status_noSuchName; | |
754 | } | |
755 | } | |
756 | ||
757 | /* \f */ | |
758 | ||
759 | init_unix () { | |
760 | register OT ot; | |
761 | ||
762 | if (ot = text2obj ("mbufS")) | |
763 | ot -> ot_getfnx = o_mbuf, | |
764 | ot -> ot_info = (caddr_t) mbufS; | |
765 | if (ot = text2obj ("mbufClusters")) | |
766 | ot -> ot_getfnx = o_mbuf, | |
767 | ot -> ot_info = (caddr_t) mbufClusters; | |
768 | if (ot = text2obj ("mbufFreeClusters")) | |
769 | ot -> ot_getfnx = o_mbuf, | |
770 | ot -> ot_info = (caddr_t) mbufFreeClusters; | |
771 | if (ot = text2obj ("mbufDrops")) | |
772 | ot -> ot_getfnx = o_mbuf, | |
773 | ot -> ot_info = (caddr_t) mbufDrops; | |
774 | #ifdef mbufWaits | |
775 | if (ot = text2obj ("mbufWaits")) | |
776 | ot -> ot_getfnx = o_mbuf, | |
777 | ot -> ot_info = (caddr_t) mbufWaits; | |
778 | #endif | |
779 | #ifdef mbufDrains | |
780 | if (ot = text2obj ("mbufDrains")) | |
781 | ot -> ot_getfnx = o_mbuf, | |
782 | ot -> ot_info = (caddr_t) mbufDrains; | |
783 | #endif | |
784 | #ifdef mbufFrees | |
785 | if (ot = text2obj ("mbufFrees")) | |
786 | ot -> ot_getfnx = o_mbuf, | |
787 | ot -> ot_info = (caddr_t) mbufFrees; | |
788 | #endif | |
789 | if (ot = text2obj ("mbufType")) | |
790 | ot -> ot_getfnx = o_mbufType, | |
791 | ot -> ot_info = (caddr_t) mbufType; | |
792 | if (ot = text2obj ("mbufAllocates")) | |
793 | ot -> ot_getfnx = o_mbufType, | |
794 | ot -> ot_info = (caddr_t) mbufAllocates; | |
795 | } | |
796 | ||
797 | /* \f */ | |
798 | ||
799 | int getkmem (n, buffer, cc) | |
800 | struct nlist *n; | |
801 | caddr_t buffer; | |
802 | int cc; | |
803 | { | |
804 | if (n -> n_value == 0) { | |
805 | advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix", n -> n_name); | |
806 | return NOTOK; | |
807 | } | |
808 | if (lseek (kd, (long) n -> n_value, L_SET) == NOTOK) { | |
809 | advise (LLOG_EXCEPTIONS, "failed", "lseek of 0x%x for \"%s\" in kmem", | |
810 | (long) n -> n_value, n -> n_name); | |
811 | return NOTOK; | |
812 | } | |
813 | if (read (kd, buffer, cc) != cc) { | |
814 | advise (LLOG_EXCEPTIONS, "failed", "read of \"%s\" from kmem", | |
815 | n -> n_name); | |
816 | return NOTOK; | |
817 | } | |
818 | ||
819 | return OK; | |
820 | } | |
821 | ||
822 | /* \f ERRORS */ | |
823 | ||
824 | #ifndef lint | |
825 | void adios (va_alist) | |
826 | va_dcl | |
827 | { | |
828 | va_list ap; | |
829 | ||
830 | va_start (ap); | |
831 | ||
832 | _ll_log (pgm_log, LLOG_FATAL, ap); | |
833 | ||
834 | va_end (ap); | |
835 | ||
836 | _exit (1); | |
837 | } | |
838 | #else | |
839 | /* VARARGS */ | |
840 | ||
841 | void adios (what, fmt) | |
842 | char *what, | |
843 | *fmt; | |
844 | { | |
845 | adios (what, fmt); | |
846 | } | |
847 | #endif | |
848 | ||
849 | ||
850 | #ifndef lint | |
851 | void advise (va_alist) | |
852 | va_dcl | |
853 | { | |
854 | int code; | |
855 | va_list ap; | |
856 | ||
857 | va_start (ap); | |
858 | ||
859 | code = va_arg (ap, int); | |
860 | ||
861 | _ll_log (pgm_log, code, ap); | |
862 | ||
863 | va_end (ap); | |
864 | } | |
865 | #else | |
866 | /* VARARGS */ | |
867 | ||
868 | void advise (code, what, fmt) | |
869 | char *what, | |
870 | *fmt; | |
871 | int code; | |
872 | { | |
873 | advise (code, what, fmt); | |
874 | } | |
875 | #endif |