|
|
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.