|
|
1.1 root 1: /* smux.c - SMUX initiator library */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/snmp/RCS/smux.c,v 7.2 90/04/09 08:50:13 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/snmp/RCS/smux.c,v 7.2 90/04/09 08:50:13 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: smux.c,v $
17: * Revision 7.2 90/04/09 08:50:13 mrose
18: * update
19: *
20: * Revision 7.1 90/02/19 15:38:45 mrose
21: * one more time
22: *
23: * Revision 7.0 90/02/17 10:36:45 mrose
24: * *** empty log message ***
25: *
26: */
27:
28: /*
29: * NOTICE
30: *
31: * Acquisition, use, and distribution of this module and related
32: * materials are subject to the restrictions of a license agreement.
33: * Consult the Preface in the User's Manual for the full terms of
34: * this agreement.
35: *
36: */
37:
38:
39: /* LINTLIBRARY */
40:
41: #include <stdio.h>
42: #include <varargs.h>
43: #include "smux.h"
44: #include "tailor.h"
45:
46:
47: #include <errno.h>
48: #include "internet.h"
49: #ifdef BSD42
50: #include <sys/ioctl.h>
51: #endif
52:
53: /* DATA */
54:
55: int smux_errno;
56: char smux_info[BUFSIZ];
57:
58:
59: static int sd = NOTOK;
60: static PS ps = NULLPS;
61:
62: static struct sockaddr_in in_socket;
63:
64:
65: static int smux_debug = 0;
66: static PE smux_pe = NULL;
67: static struct type_SNMP_SMUX__PDUs *smux_pdu;
68: static OID smux_enterprise = NULL;
69: static struct type_SNMP_NetworkAddress *smux_addr = NULL;
70: static struct type_SNMP_TimeTicks *smux_stamp = NULL;
71:
72: extern int errno;
73:
74: /* INIT */
75:
76: int smux_init (debug)
77: int debug;
78: {
79: int onoff;
80: register struct sockaddr_in *isock = &in_socket;
81: register struct hostent *hp;
82: register struct servent *sp;
83: static int inited = 0;
84:
85: if (!inited) {
86: isodetailor ("smux", 0);
87:
88: inited = 1;
89: }
90:
91: smux_debug = debug;
92: if (smux_pe)
93: pe_free (smux_pe), smux_pe = NULL;
94: if (smux_pdu)
95: free_SNMP_SMUX__PDUs (smux_pdu), smux_pdu = NULL;
96: if (smux_enterprise)
97: oid_free (smux_enterprise), smux_enterprise = NULL;
98: if (smux_addr)
99: free_SNMP_NetworkAddress (smux_addr), smux_addr = NULL;
100: if (smux_stamp == NULL
101: && (smux_stamp = (struct type_SNMP_TimeTicks *)
102: calloc (1, sizeof *smux_stamp)) == NULL)
103: return smuxlose (congestion, NULLCP, "out of memory");
104:
105: bzero ((char *) isock, sizeof *isock);
106: if ((hp = gethostbystring ("127.0.0.1")) == NULL)
107: return smuxlose (youLoseBig, NULLCP, "%s: unknown host", "127.0.0.1");
108: isock -> sin_family = hp -> h_addrtype;
109: isock -> sin_port = (sp = getservbyname ("smux", "tcp"))
110: ? sp -> s_port
111: : htons ((u_short) 199);
112: inaddr_copy (hp, isock);
113:
114: if ((sd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK)
115: return smuxlose (systemError, "failed", "start_tcp_client");
116:
117: (void) ioctl (sd, FIONBIO, (onoff = 1, (char *) &onoff));
118:
119: if (join_tcp_server (sd, isock) == NOTOK)
120: switch (errno) {
121: case EINPROGRESS:
122: return sd;
123:
124: case EISCONN:
125: break;
126:
127: default:
128: (void) smuxlose (systemError, "failed", "join_tcp_server");
129: (void) close_tcp_socket (sd);
130: return (sd = NOTOK);
131: }
132:
133: if (smuxalloc () == NOTOK)
134: return NOTOK;
135:
136: return sd;
137: }
138:
139: /* */
140:
141: static int smuxalloc ()
142: {
143: int len;
144:
145: if ((ps = ps_alloc (fdx_open)) == NULLPS || fdx_setup (ps, sd) == NOTOK) {
146: if (ps) {
147: ps_free (ps), ps = NULLPS;
148: (void) smuxlose (youLoseBig, NULLCP, "fdx_setup: %s",
149: ps_error (ps -> ps_errno));
150: }
151: else
152: (void) smuxlose (youLoseBig, NULLCP, "ps_alloc: failed");
153:
154: you_lose: ;
155: (void) close_tcp_socket (sd);
156: return (sd = NOTOK);
157: }
158:
159: if (getsockname (sd, (struct sockaddr *) &in_socket,
160: (len = sizeof in_socket, &len)) == NOTOK)
161: bzero ((char *) &in_socket.sin_addr, 4);
162: if ((smux_addr = str2qb ((char *) &in_socket.sin_addr, 4, 1)) == NULL) {
163: (void) smuxlose (youLoseBig, NULLCP, "str2qb: failed");
164:
165: ps_free (ps), ps = NULLPS;
166: goto you_lose;
167: }
168:
169: return OK;
170: }
171:
172: /* SIMPLE OPEN */
173:
174: int smux_simple_open (identity, description, commname, commlen)
175: OID identity;
176: char *description;
177: char *commname;
178: int commlen;
179: {
180: int result;
181: struct type_SNMP_SMUX__PDUs pdu;
182: register struct type_SNMP_SimpleOpen *simple;
183:
184: if (identity == NULL
185: || description == NULL
186: || (commname == NULL && commlen != 0))
187: return smuxlose (parameterMissing, NULLCP, "missing parameter");
188:
189: if (sd == NOTOK)
190: return smuxlose (invalidOperation, NULLCP, "SMUX not inited");
191: if (ps == NULLPS) {
192: fd_set mask;
193: register struct sockaddr_in *isock = &in_socket;
194:
195: FD_ZERO (&mask);
196: FD_SET (sd, &mask);
197: if (xselect (sd + 1, NULLFD, &mask, NULLFD, 0) < 1)
198: goto not_yet;
199:
200: if (join_tcp_server (sd, isock) == NOTOK)
201: switch (errno) {
202: case EINPROGRESS:
203: not_yet: ;
204: return smuxlose (inProgress, NULLCP, NULLCP);
205:
206: case EISCONN:
207: break;
208:
209: default:
210: (void) smuxlose (systemError, "failed", "join_tcp_server");
211: (void) close_tcp_socket (sd);
212: return (sd = NOTOK);
213: }
214:
215: if (smuxalloc () == NOTOK)
216: return NOTOK;
217: }
218:
219: bzero ((char *) &pdu, sizeof pdu);
220:
221: if ((simple = (struct type_SNMP_SimpleOpen *) calloc (1, sizeof *simple))
222: == NULL) {
223: no_mem: ;
224: (void) smuxlose (congestion, NULLCP, "out of memory");
225: if (simple)
226: free_SNMP_SimpleOpen (simple);
227:
228: ps_free (ps), ps = NULLPS;
229: (void) close_tcp_socket (sd);
230: return (sd = NOTOK);
231: }
232: pdu.offset = type_SNMP_SMUX__PDUs_simple;
233: pdu.un.simple = simple;
234:
235: if ((smux_enterprise = oid_cpy (identity)) == NULL)
236: goto no_mem;
237:
238: simple -> version = int_SNMP_version_version__1;
239: if ((simple -> identity = oid_cpy (identity)) == NULL
240: || (simple -> description = str2qb (description,
241: strlen (description),
242: 1)) == NULL
243: || (simple -> password = str2qb (commname, commlen, 1)) == NULL)
244: goto no_mem;
245:
246: result = smuxsend (&pdu);
247:
248: free_SNMP_SimpleOpen (simple);
249:
250: return result;
251: }
252:
253: /* */
254:
255: static int smuxsend (pdu)
256: struct type_SNMP_SMUX__PDUs *pdu;
257: {
258: int result;
259: PE pe;
260:
261: pe = NULLPE;
262: if (encode_SNMP_SMUX__PDUs (&pe, 1, 0, NULLCP, pdu) == NOTOK) {
263: result = smuxlose (youLoseBig, NULLCP, "encode_SNMP_SMUX__PDUs: %s",
264: PY_pepy);
265: goto out;
266: }
267:
268: #ifdef DEBUG
269: if (smux_debug)
270: (void) print_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, NULLCP);
271: #endif
272:
273: if (pe2ps (ps, pe) == NOTOK) {
274: result = smuxlose (youLoseBig, NULLCP, "pe2ps: %s",
275: ps_error (ps -> ps_errno));
276: goto out;
277: }
278:
279: result = OK;
280:
281: out: ;
282: if (pe)
283: pe_free (pe);
284:
285: if (result == NOTOK) {
286: ps_free (ps), ps = NULLPS;
287: (void) close_tcp_socket (sd);
288: return (sd = NOTOK);
289: }
290:
291: return OK;
292: }
293:
294: /* CLOSE */
295:
296: int smux_close (reason)
297: int reason;
298: {
299: int result;
300: struct type_SNMP_SMUX__PDUs pdu;
301: register struct type_SNMP_ClosePDU *close;
302:
303: if (ps == NULLPS)
304: return smuxlose (invalidOperation, NULLCP, "SMUX not opened");
305:
306: bzero ((char *) &pdu, sizeof pdu);
307:
308: if ((close = (struct type_SNMP_ClosePDU *) calloc (1, sizeof *close))
309: == NULL) {
310: result = smuxlose (congestion, NULLCP, "out of memory");
311: if (close)
312: free_SNMP_ClosePDU (close);
313:
314: ps_free (ps), ps = NULLPS;
315: (void) close_tcp_socket (sd);
316: return (sd = NOTOK);
317: }
318: pdu.offset = type_SNMP_SMUX__PDUs_close;
319: pdu.un.close = close;
320:
321: close -> parm = reason;
322:
323: result = smuxsend (&pdu);
324:
325: free_SNMP_ClosePDU (close);
326:
327: ps_free (ps), ps = NULLPS;
328: (void) close_tcp_socket (sd);
329: sd = NOTOK;
330:
331: if (smux_pe)
332: pe_free (smux_pe), smux_pe = NULL;
333: if (smux_pdu)
334: free_SNMP_SMUX__PDUs (smux_pdu), smux_pdu = NULL;
335: if (smux_enterprise)
336: oid_free (smux_enterprise), smux_enterprise = NULL;
337: if (smux_addr)
338: free_SNMP_NetworkAddress (smux_addr), smux_addr = NULL;
339:
340: return result;
341: }
342:
343: /* REGISTER */
344:
345: int smux_register (subtree, priority, operation)
346: OID subtree;
347: int priority,
348: operation;
349: {
350: int result;
351: struct type_SNMP_SMUX__PDUs pdu;
352: register struct type_SNMP_RReqPDU *rreq;
353:
354: if (subtree == NULL)
355: return smuxlose (parameterMissing, NULLCP, "missing parameter");
356:
357: if (ps == NULLPS)
358: return smuxlose (invalidOperation, NULLCP, "SMUX not opened");
359:
360: bzero ((char *) &pdu, sizeof pdu);
361:
362: if ((rreq = (struct type_SNMP_RReqPDU *) calloc (1, sizeof *rreq))
363: == NULL) {
364: no_mem: ;
365: result = smuxlose (congestion, NULLCP, "out of memory");
366: if (rreq)
367: free_SNMP_RReqPDU (rreq);
368:
369: ps_free (ps), ps = NULLPS;
370: (void) close_tcp_socket (sd);
371: return (sd = NOTOK);
372: }
373: pdu.offset = type_SNMP_SMUX__PDUs_registerRequest;
374: pdu.un.registerRequest = rreq;
375:
376: if ((rreq -> subtree = oid_cpy (subtree)) == NULLOID)
377: goto no_mem;
378: rreq -> priority = priority;
379: rreq -> operation = operation;
380:
381: result = smuxsend (&pdu);
382:
383: free_SNMP_RReqPDU (rreq);
384:
385: return result;
386: }
387:
388: /* WAIT */
389:
390: int smux_wait (event, secs)
391: struct type_SNMP_SMUX__PDUs **event;
392: int secs;
393: {
394: fd_set mask;
395: PE pe;
396:
397: if (event == NULL)
398: return smuxlose (parameterMissing, NULLCP, "missing parameter");
399:
400: if (ps == NULLPS)
401: return smuxlose (invalidOperation, NULLCP, "SMUX not opened");
402:
403: FD_ZERO (&mask);
404: FD_SET (sd, &mask);
405: if ((ps -> ps_primeP == NULLIFP || (*ps -> ps_primeP) (ps, 1) == OK)
406: && xselect (sd + 1, &mask, NULLFD, NULLFD, secs) < 1) {
407: errno = EWOULDBLOCK;
408: return smuxlose (inProgress, NULLCP, NULLCP);
409: }
410:
411: if ((pe = ps2pe (ps)) == NULLPE) {
412: (void) smuxlose (youLoseBig, NULLCP, "pe2ps: %s",
413: ps_error (ps -> ps_errno));
414: goto out;
415: }
416:
417: if (decode_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, event) == NOTOK) {
418: (void) smuxlose (youLoseBig, NULLCP, "encode_SNMP_SMUX__PDUs: %s",
419: PY_pepy);
420: goto out;
421: }
422:
423: #ifdef DEBUG
424: if (smux_debug)
425: (void) print_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, NULLCP);
426: #endif
427:
428: if (smux_pe)
429: pe_free (smux_pe);
430: smux_pe = pe;
431: if (smux_pdu)
432: free_SNMP_SMUX__PDUs (smux_pdu);
433: smux_pdu = *event;
434:
435: if (smux_pdu -> offset == type_SNMP_SMUX__PDUs_close) {
436: ps_free (ps), ps = NULLPS;
437: (void) close_tcp_socket (sd);
438: sd = NOTOK;
439: }
440: return OK;
441:
442: out: ;
443: if (pe)
444: pe_free (pe);
445:
446: ps_free (ps), ps = NULLPS;
447: (void) close_tcp_socket (sd);
448: return (sd = NOTOK);
449: }
450:
451: /* RESPONSE */
452:
453: int smux_response (event)
454: struct type_SNMP_GetResponse__PDU *event;
455: {
456: struct type_SNMP_SMUX__PDUs pdu;
457:
458: if (event == NULL)
459: return smuxlose (parameterMissing, NULLCP, "missing parameter");
460:
461: if (ps == NULLPS)
462: return smuxlose (invalidOperation, NULLCP, "SMUX not opened");
463:
464: bzero ((char *) &pdu, sizeof pdu);
465:
466: pdu.offset = type_SNMP_SMUX__PDUs_get__response;
467: pdu.un.get__response = event;
468:
469: return smuxsend (&pdu);
470: }
471:
472: /* TRAP */
473:
474: int smux_trap (generic, specific, bindings)
475: int generic,
476: specific;
477: struct type_SNMP_VarBindList *bindings;
478: {
479: int result;
480: struct type_SNMP_SMUX__PDUs pdu;
481: register struct type_SNMP_Trap__PDU *trap;
482:
483: if (ps == NULLPS)
484: return smuxlose (invalidOperation, NULLCP, "SMUX not opened");
485:
486: bzero ((char *) &pdu, sizeof pdu);
487:
488: if ((trap = (struct type_SNMP_Trap__PDU *) calloc (1, sizeof *trap))
489: == NULL) {
490: result = smuxlose (congestion, NULLCP, "out of memory");
491: if (trap)
492: free_SNMP_Trap__PDU (trap);
493:
494: ps_free (ps), ps = NULLPS;
495: (void) close_tcp_socket (sd);
496: return (sd = NOTOK);
497: }
498: pdu.offset = type_SNMP_SMUX__PDUs_trap;
499: pdu.un.trap = trap;
500:
501: trap -> enterprise = smux_enterprise;
502: trap -> agent__addr = smux_addr;
503: trap -> generic__trap = generic;
504: trap -> specific__trap = specific;
505: trap -> time__stamp = smux_stamp;
506: trap -> time__stamp -> parm = uptime ();
507: trap -> variable__bindings = bindings;
508:
509: result = smuxsend (&pdu);
510:
511: trap -> enterprise = NULL;
512: trap -> agent__addr = NULL;
513: trap -> time__stamp = NULL;
514: trap -> variable__bindings = NULL;
515:
516: free_SNMP_Trap__PDU (trap);
517:
518: return result;
519: }
520:
521: /* */
522:
523: #include <nlist.h>
524: #ifdef BSD42
525: #include <sys/file.h>
526: #endif
527: #ifdef SYS5
528: #include <fcntl.h>
529: #endif
530:
531:
532: static struct nlist nl[] = {
533: { "_boottime" },
534:
535: NULL
536: };
537:
538:
539: static int uptime ()
540: {
541: struct timeval now;
542: static int inited = 0;
543: static struct timeval boottime;
544:
545: if (!inited) {
546: int kd;
547:
548: if (nlist ("/vmunix", nl) == NOTOK || nl -> n_value == 0)
549: return 0;
550:
551: if ((kd = open ("/dev/kmem", O_RDONLY)) == NOTOK)
552: return 0;
553:
554: if (lseek (kd, (long) nl -> n_value, L_SET) == NOTOK) {
555: (void) close (kd);
556: return 0;
557: }
558:
559: if (read (kd, (char *) &boottime, sizeof boottime)
560: != sizeof boottime) {
561: (void) close (kd);
562: return 0;
563: }
564:
565: (void) close (kd);
566:
567: inited = 1;
568: }
569:
570: if (gettimeofday (&now, (struct timezone *) 0) == NOTOK)
571: return 0;
572:
573: return (now.tv_sec - boottime.tv_sec) * 100
574: + (now.tv_usec - boottime.tv_usec);
575: }
576:
577: /* LOSE */
578:
579: #ifndef lint
580: static int smuxlose (va_alist)
581: va_dcl
582: {
583: va_list ap;
584:
585: va_start (ap);
586:
587: smux_errno = va_arg (ap, int);
588:
589: asprintf (smux_info, ap);
590:
591: va_end (ap);
592:
593: return NOTOK;
594: }
595: #else
596: /* VARARGS3 */
597:
598: static int smuxlose (reason, what, fmt)
599: int reason;
600: char *what,
601: *fmt;
602: {
603: return smuxlose (reason, what, fmt);
604: }
605: #endif
606:
607: /* */
608:
609: static char *errors_up[] = {
610: "goingDown",
611: "unsupportedVersion",
612: "packetFormat",
613: "protocolError",
614: "internalError",
615: "authenticationFailure"
616: };
617:
618: static char *errors_down[] = {
619: "SMUX error 0",
620: "invalidOperation",
621: "parameterMissing",
622: "systemError",
623: "youLoseBig",
624: "congestion",
625: "inProgress"
626: };
627:
628: char *smux_error (i)
629: int i;
630: {
631: int j;
632: char **ap;
633: static char buffer[BUFSIZ];
634:
635: if (i < 0) {
636: ap = errors_down, j = sizeof errors_down / sizeof errors_down[0];
637: i = -i;
638: }
639: else
640: ap = errors_up, j = sizeof errors_up / sizeof errors_up[0];
641: if (0 <= i && i < j)
642: return ap[i];
643:
644: (void) sprintf (buffer, "SMUX error %s%d", ap == errors_down ? "-" : "",i);
645:
646: return buffer;
647: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.