|
|
1.1 ! root 1: /* syntax.c - SMI syntax handling */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/snmp/RCS/syntax.c,v 7.8 90/07/09 14:49:41 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/snmp/RCS/syntax.c,v 7.8 90/07/09 14:49:41 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: syntax.c,v $ ! 17: * Revision 7.8 90/07/09 14:49:41 mrose ! 18: * sync ! 19: * ! 20: * Revision 7.7 90/04/18 08:52:03 mrose ! 21: * oid_normalize ! 22: * ! 23: * Revision 7.6 90/04/08 03:23:20 mrose ! 24: * touch-up ! 25: * ! 26: * Revision 7.5 90/03/23 17:27:35 mrose ! 27: * update ! 28: * ! 29: * Revision 7.4 90/03/08 08:05:25 mrose ! 30: * touch-up ! 31: * ! 32: * Revision 7.3 90/02/19 19:23:14 mrose ! 33: * again ! 34: * ! 35: * Revision 7.2 90/02/19 19:17:11 mrose ! 36: * again ! 37: * ! 38: * Revision 7.1 90/01/11 18:34:48 mrose ! 39: * real-sync ! 40: * ! 41: * Revision 7.0 89/11/23 22:23:32 mrose ! 42: * Release 6.0 ! 43: * ! 44: */ ! 45: ! 46: /* ! 47: * NOTICE ! 48: * ! 49: * Acquisition, use, and distribution of this module and related ! 50: * materials are subject to the restrictions of a license agreement. ! 51: * Consult the Preface in the User's Manual for the full terms of ! 52: * this agreement. ! 53: * ! 54: */ ! 55: ! 56: ! 57: #include <ctype.h> ! 58: #include <stdio.h> ! 59: #include "SNMP-types.h" ! 60: #include "objects.h" ! 61: #include "tailor.h" ! 62: ! 63: #include "internet.h" ! 64: #include "clnp.h" ! 65: ! 66: /* DATA */ ! 67: ! 68: #define MAXSYN 50 ! 69: ! 70: static object_syntax syntaxes[MAXSYN + 1]; ! 71: static OS synlast = syntaxes; ! 72: ! 73: ! 74: #if defined(sun) || defined(BSD44) ! 75: #define HAVE_STRTOL ! 76: ! 77: long strtol (); ! 78: #endif ! 79: ! 80: ! 81: /* INTEGER */ ! 82: ! 83: static int integer_encode (x, pe) ! 84: integer *x; ! 85: PE *pe; ! 86: { ! 87: if ((*pe = int2prim (*x)) == NULLPE) ! 88: return NOTOK; ! 89: ! 90: return OK; ! 91: } ! 92: ! 93: ! 94: static int integer_decode (x, pe) ! 95: integer **x; ! 96: PE pe; ! 97: { ! 98: integer i = prim2num (pe); ! 99: ! 100: if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE) ! 101: return NOTOK; ! 102: if ((*x = (integer *) malloc (sizeof **x)) == NULL) ! 103: return NOTOK; ! 104: **x = i; ! 105: ! 106: return OK; ! 107: } ! 108: ! 109: ! 110: static int integer_free (x) ! 111: integer *x; ! 112: { ! 113: free ((char *) x); ! 114: } ! 115: ! 116: ! 117: static int integer_parse (x, s) ! 118: integer **x; ! 119: char *s; ! 120: { ! 121: long l; ! 122: #ifdef HAVE_STRTOL ! 123: char *cp; ! 124: #endif ! 125: ! 126: #ifdef HAVE_STRTOL ! 127: if ((l = strtol (s, &cp, 0)) == 0L && cp == s) ! 128: return NOTOK; ! 129: #else ! 130: if (sscanf (s, "%ld", &l) != 1) ! 131: return NOTOK; ! 132: #endif ! 133: if ((*x = (integer *) malloc (sizeof **x)) == NULL) ! 134: return NOTOK; ! 135: **x = (integer) l; ! 136: ! 137: return OK; ! 138: } ! 139: ! 140: ! 141: /* ARGSUSED */ ! 142: ! 143: static int integer_print (x, os) ! 144: integer *x; ! 145: OS os; ! 146: { ! 147: printf ("%d", *x); ! 148: } ! 149: ! 150: ! 151: /* ARGSUSED */ ! 152: ! 153: static int services_print (x, os) ! 154: integer *x; ! 155: OS os; ! 156: { ! 157: printf ("%s", sprintb (*x, ! 158: "\020\01physical\02datalink/subnetwork\03internet\04transport\05session\06presentation\07application")); ! 159: } ! 160: ! 161: ! 162: /* ARGSUSED */ ! 163: ! 164: static int privs_print (x, os) ! 165: integer *x; ! 166: OS os; ! 167: { ! 168: printf ("%s", sprintb (*x, ! 169: "\020\01get\02get-next\03get-response\04set\05trap")); ! 170: } ! 171: ! 172: ! 173: static add_integer () ! 174: { ! 175: (void) add_syntax ("INTEGER", integer_encode, integer_decode, integer_free, ! 176: integer_parse, integer_print); ! 177: (void) add_syntax ("Services", integer_encode, integer_decode, ! 178: integer_free, integer_parse, services_print); ! 179: (void) add_syntax ("Privileges", integer_encode, integer_decode, ! 180: integer_free, integer_parse, privs_print); ! 181: } ! 182: ! 183: /* OCTET STRING */ ! 184: ! 185: static int string_encode (x, pe) ! 186: struct qbuf *x; ! 187: PE *pe; ! 188: { ! 189: if ((*pe = qb2prim_aux (x, PE_CLASS_UNIV, PE_PRIM_OCTS, 0)) == NULLPE) ! 190: return NOTOK; ! 191: ! 192: return OK; ! 193: } ! 194: ! 195: ! 196: static int string_decode (x, pe) ! 197: struct qbuf **x; ! 198: PE pe; ! 199: { ! 200: struct qbuf *qb = prim2qb (pe); ! 201: ! 202: if (qb == NULL) ! 203: return NOTOK; ! 204: *x = qb; ! 205: ! 206: return OK; ! 207: } ! 208: ! 209: ! 210: static int string_parse (x, s) ! 211: struct qbuf **x; ! 212: char *s; ! 213: { ! 214: struct qbuf *qb = str2qb (s, strlen (s), 1); ! 215: ! 216: if (qb == NULL) ! 217: return NOTOK; ! 218: *x = qb; ! 219: ! 220: return OK; ! 221: } ! 222: ! 223: ! 224: /* ARGSUSED */ ! 225: ! 226: static int string_print (x, os) ! 227: struct qbuf *x; ! 228: OS os; ! 229: { ! 230: register char *cp, ! 231: *ep; ! 232: char *p; ! 233: register struct qbuf *qb; ! 234: ! 235: p = ""; ! 236: for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw) ! 237: for (ep = (cp = qb -> qb_data) + qb -> qb_len; cp < ep; cp++) { ! 238: printf ("%s%02x", p, *cp & 0xff); ! 239: p = ":"; ! 240: } ! 241: } ! 242: ! 243: ! 244: /* ARGSUSED */ ! 245: ! 246: static int string_display (x, os) ! 247: struct qbuf *x; ! 248: OS os; ! 249: { ! 250: register struct qbuf *qb; ! 251: ! 252: printf ("\""); ! 253: for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw) ! 254: printf ("%*.*s", qb -> qb_len, qb -> qb_len, qb -> qb_data); ! 255: printf ("\""); ! 256: } ! 257: ! 258: ! 259: static add_string () ! 260: { ! 261: (void) add_syntax ("OctetString", string_encode, string_decode, qb_free, ! 262: string_parse, string_print); ! 263: (void) add_syntax ("DisplayString", string_encode, string_decode, qb_free, ! 264: string_parse, string_display); ! 265: } ! 266: ! 267: /* OBJECT IDENTIFIER */ ! 268: ! 269: static int object_encode (x, pe) ! 270: OID x; ! 271: PE *pe; ! 272: { ! 273: if ((*pe = oid2prim (x)) == NULLPE) ! 274: return NOTOK; ! 275: ! 276: return OK; ! 277: } ! 278: ! 279: ! 280: static int object_decode (x, pe) ! 281: OID *x; ! 282: PE pe; ! 283: { ! 284: OID oid = prim2oid (pe); ! 285: ! 286: if (oid == NULLOID || (*x = oid_cpy (oid)) == NULLOID) ! 287: return NOTOK; ! 288: ! 289: return OK; ! 290: } ! 291: ! 292: ! 293: static int object_parse (x, s) ! 294: OID *x; ! 295: char *s; ! 296: { ! 297: OID oid = text2oid (s); ! 298: ! 299: if (oid == NULL) ! 300: return NOTOK; ! 301: *x = oid; ! 302: ! 303: return OK; ! 304: } ! 305: ! 306: ! 307: /* ARGSUSED */ ! 308: ! 309: static int object_print (x, os) ! 310: OID x; ! 311: OS os; ! 312: { ! 313: char *cp, ! 314: ode[BUFSIZ]; ! 315: ! 316: (void) strcpy (ode, oid2ode (x)); ! 317: printf ("%s", ode); ! 318: if (strcmp (ode, cp = sprintoid (x))) ! 319: printf (" (%s)", cp); ! 320: } ! 321: ! 322: ! 323: static add_object () ! 324: { ! 325: (void) add_syntax ("ObjectID", object_encode, object_decode, oid_free, ! 326: object_parse, object_print); ! 327: } ! 328: ! 329: /* NULL */ ! 330: ! 331: /* ARGSUSED */ ! 332: ! 333: static int null_encode (x, pe) ! 334: char *x; ! 335: PE *pe; ! 336: { ! 337: if ((*pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) == NULLPE) ! 338: return NOTOK; ! 339: ! 340: return OK; ! 341: } ! 342: ! 343: ! 344: /* ARGSUSED */ ! 345: ! 346: static int null_decode (x, pe) ! 347: char **x; ! 348: PE pe; ! 349: { ! 350: if ((*x = (char *) calloc (1, sizeof **x)) == NULL) ! 351: return NOTOK; ! 352: ! 353: return OK; ! 354: } ! 355: ! 356: ! 357: static int null_free (x) ! 358: char *x; ! 359: { ! 360: free ((char *) x); ! 361: } ! 362: ! 363: ! 364: static int null_parse (x, s) ! 365: char **x; ! 366: char *s; ! 367: { ! 368: if (lexequ (s, "NULL")) ! 369: return NOTOK; ! 370: ! 371: if ((*x = (char *) calloc (1, sizeof **x)) == NULL) ! 372: return NOTOK; ! 373: ! 374: return OK; ! 375: } ! 376: ! 377: ! 378: /* ARGSUSED */ ! 379: ! 380: static int null_print (x, os) ! 381: char *x; ! 382: OS os; ! 383: { ! 384: printf ("NULL"); ! 385: } ! 386: ! 387: ! 388: static add_null () ! 389: { ! 390: (void) add_syntax ("NULL", null_encode, null_decode, null_free, null_parse, ! 391: null_print); ! 392: } ! 393: ! 394: /* IpAddress */ ! 395: ! 396: static int ipaddr_encode (x, pe) ! 397: struct sockaddr_in *x; ! 398: PE *pe; ! 399: { ! 400: if ((*pe = str2prim ((char *) &x -> sin_addr, 4, PE_CLASS_APPL, 0)) ! 401: == NULLPE) ! 402: return NOTOK; ! 403: ! 404: return OK; ! 405: } ! 406: ! 407: ! 408: static int ipaddr_decode (x, pe) ! 409: struct sockaddr_in **x; ! 410: PE pe; ! 411: { ! 412: struct type_SNMP_IpAddress *ip; ! 413: struct qbuf *qb; ! 414: struct sockaddr_in *isock; ! 415: ! 416: if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK) ! 417: return NOTOK; ! 418: if (qb_pullup (ip) == NOTOK ! 419: || (isock = (struct sockaddr_in *) calloc (1, sizeof *isock)) ! 420: == NULL) { ! 421: free_SNMP_IpAddress (ip); ! 422: return NOTOK; ! 423: } ! 424: if ((qb = ip -> qb_forw) -> qb_len != 4) { ! 425: free_SNMP_IpAddress (ip); ! 426: return NOTOK; ! 427: } ! 428: isock -> sin_family = AF_INET; ! 429: bcopy (qb -> qb_data, ! 430: (char *) &isock -> sin_addr, ! 431: sizeof isock -> sin_addr); ! 432: ! 433: *x = isock; ! 434: ! 435: free_SNMP_IpAddress (ip); ! 436: return OK; ! 437: } ! 438: ! 439: ! 440: static int ipaddr_free (x) ! 441: struct sockaddr_in *x; ! 442: { ! 443: free ((char *) x); ! 444: } ! 445: ! 446: ! 447: static int ipaddr_parse (x, s) ! 448: struct sockaddr_in **x; ! 449: char *s; ! 450: { ! 451: register struct hostent *hp = gethostbystring (s); ! 452: register struct sockaddr_in *isock; ! 453: ! 454: if (hp == NULL) ! 455: return NOTOK; ! 456: ! 457: if ((isock = (struct sockaddr_in *) calloc (1, sizeof *isock)) == NULL) ! 458: return NOTOK; ! 459: isock -> sin_family = AF_INET; ! 460: inaddr_copy (hp, isock); ! 461: *x = isock; ! 462: ! 463: return OK; ! 464: } ! 465: ! 466: ! 467: /* ARGSUSED */ ! 468: ! 469: static int ipaddr_print (x, os) ! 470: struct sockaddr_in *x; ! 471: OS os; ! 472: { ! 473: printf ("%s", inet_ntoa (x -> sin_addr)); ! 474: } ! 475: ! 476: ! 477: static add_ipaddr () ! 478: { ! 479: (void) add_syntax ("IpAddress", ipaddr_encode, ipaddr_decode, ipaddr_free, ! 480: ipaddr_parse, ipaddr_print); ! 481: } ! 482: ! 483: /* NetworkAddress */ ! 484: ! 485: /* good enough for now (and probably forever)... */ ! 486: ! 487: static add_netaddr () ! 488: { ! 489: (void) add_syntax ("NetworkAddress", ipaddr_encode, ipaddr_decode, ! 490: ipaddr_free, ipaddr_parse, ipaddr_print); ! 491: } ! 492: ! 493: /* Counter */ ! 494: ! 495: static int counter_encode (x, pe) ! 496: integer *x; ! 497: PE *pe; ! 498: { ! 499: if ((*pe = num2prim (*x, PE_CLASS_APPL, 1)) == NULLPE) ! 500: return NOTOK; ! 501: ! 502: return OK; ! 503: } ! 504: ! 505: ! 506: static int counter_parse (x, s) ! 507: integer **x; ! 508: char *s; ! 509: { ! 510: long l; ! 511: char *cp; ! 512: ! 513: #ifdef HAVE_STRTOL ! 514: if ((l = strtol (s, &cp, 0)) == 0L && cp == s) ! 515: return NOTOK; ! 516: #else ! 517: if (sscanf (s, "%ld", &l) != 1) ! 518: return NOTOK; ! 519: #endif ! 520: if (l < 0 || l > 4294967295L) ! 521: return NOTOK; ! 522: if ((*x = (integer *) malloc (sizeof **x)) == NULL) ! 523: return NOTOK; ! 524: **x = (integer) l; ! 525: ! 526: return OK; ! 527: } ! 528: ! 529: ! 530: static add_counter () ! 531: { ! 532: (void) add_syntax ("Counter", counter_encode, integer_decode, integer_free, ! 533: counter_parse, integer_print); ! 534: } ! 535: ! 536: /* Gauge */ ! 537: ! 538: static int gauge_encode (x, pe) ! 539: integer *x; ! 540: PE *pe; ! 541: { ! 542: if ((*pe = num2prim (*x, PE_CLASS_APPL, 2)) == NULLPE) ! 543: return NOTOK; ! 544: ! 545: return OK; ! 546: } ! 547: ! 548: ! 549: static add_gauge () ! 550: { ! 551: (void) add_syntax ("Gauge", gauge_encode, integer_decode, integer_free, ! 552: counter_parse, integer_print); ! 553: } ! 554: ! 555: /* TimeTicks */ ! 556: ! 557: static int timeticks_encode (x, pe) ! 558: integer *x; ! 559: PE *pe; ! 560: { ! 561: if ((*pe = num2prim (*x, PE_CLASS_APPL, 3)) == NULLPE) ! 562: return NOTOK; ! 563: ! 564: return OK; ! 565: } ! 566: ! 567: ! 568: /* ARGSUSED */ ! 569: ! 570: static int timeticks_print (x, os) ! 571: integer *x; ! 572: OS os; ! 573: { ! 574: int d, ! 575: h, ! 576: m, ! 577: s, ! 578: ds; ! 579: ! 580: ds = *x; ! 581: s = ds / 100, ds = ds % 100; ! 582: m = s / 60, s = s % 60; ! 583: h = m / 60, m = m % 60; ! 584: d = h / 24, h = h % 24; ! 585: ! 586: if (d > 0) ! 587: printf ("%d days, ", d); ! 588: if (d > 0 || h > 0) ! 589: printf ("%d hours, ", h); ! 590: if (d > 0 || h > 0 || m > 0) ! 591: printf ("%d minutes, ", m); ! 592: printf ("%d", s); ! 593: if (ds > 0) ! 594: printf (".%02d", ds); ! 595: printf (" seconds (%d timeticks)", *x); ! 596: } ! 597: ! 598: ! 599: static add_timeticks () ! 600: { ! 601: (void) add_syntax ("TimeTicks", timeticks_encode, integer_decode, ! 602: integer_free, integer_parse, timeticks_print); ! 603: } ! 604: ! 605: /* CnlpAddress */ ! 606: ! 607: static int clnpaddr_encode (x, pe) ! 608: struct sockaddr_iso *x; ! 609: PE *pe; ! 610: { ! 611: char buffer[sizeof x -> siso_data + 1]; ! 612: ! 613: buffer[0] = x -> siso_nlen & 0xff; ! 614: bcopy (x -> siso_data, buffer + 1, (int) x -> siso_nlen); ! 615: ! 616: if ((*pe = str2prim (buffer, (int) (x -> siso_nlen + 1), PE_CLASS_APPL, ! 617: 5)) == NULLPE) ! 618: return NOTOK; ! 619: ! 620: return OK; ! 621: } ! 622: ! 623: ! 624: static int clnpaddr_decode (x, pe) ! 625: struct sockaddr_iso **x; ! 626: PE pe; ! 627: { ! 628: int len; ! 629: struct type_SNMP_ClnpAddress *clnp; ! 630: struct qbuf *qb; ! 631: struct sockaddr_iso *isock; ! 632: ! 633: if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK) ! 634: return NOTOK; ! 635: if (qb_pullup (clnp) == NOTOK ! 636: || (isock = (struct sockaddr_iso *) calloc (1, sizeof *isock)) ! 637: == NULL) { ! 638: free_SNMP_ClnpAddress (clnp); ! 639: return NOTOK; ! 640: } ! 641: qb = clnp -> qb_forw; ! 642: isock -> siso_family = AF_ISO; ! 643: if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len) ! 644: len = qb -> qb_len - 1; ! 645: bcopy (qb -> qb_data + 1, isock -> siso_data, ! 646: (int) (isock -> siso_nlen = len)); ! 647: ! 648: *x = isock; ! 649: ! 650: free_SNMP_ClnpAddress (clnp); ! 651: return OK; ! 652: } ! 653: ! 654: ! 655: static int clnpaddr_free (x) ! 656: struct sockaddr_iso *x; ! 657: { ! 658: free ((char *) x); ! 659: } ! 660: ! 661: ! 662: static int clnpaddr_parse (x, s) ! 663: struct sockaddr_iso **x; ! 664: char *s; ! 665: { ! 666: register struct sockaddr_iso *isock; ! 667: ! 668: if ((isock = (struct sockaddr_iso *) calloc (1, sizeof *isock)) == NULL) ! 669: return NOTOK; ! 670: isock -> siso_family = AF_ISO; ! 671: isock -> siso_nlen = implode ((u_char *) isock -> siso_data, s, ! 672: strlen (s)); ! 673: *x = isock; ! 674: ! 675: return OK; ! 676: } ! 677: ! 678: ! 679: /* ARGSUSED */ ! 680: ! 681: static int clnpaddr_print (x, os) ! 682: struct sockaddr_iso *x; ! 683: OS os; ! 684: { ! 685: char buffer[sizeof x -> siso_data * 2 + 1]; ! 686: ! 687: buffer[explode (buffer, (u_char *) x -> siso_data, (int) x -> siso_nlen)] = ! 688: NULL; ! 689: printf ("NS+%s", buffer); ! 690: } ! 691: ! 692: ! 693: static add_clnpaddr () ! 694: { ! 695: (void) add_syntax ("ClnpAddress", clnpaddr_encode, clnpaddr_decode, ! 696: clnpaddr_free, clnpaddr_parse, clnpaddr_print); ! 697: } ! 698: ! 699: /* */ ! 700: ! 701: int readsyntax () ! 702: { ! 703: add_integer (); ! 704: add_string (); ! 705: add_object (); ! 706: add_null (); ! 707: add_ipaddr (); ! 708: add_netaddr (); ! 709: add_counter (); ! 710: add_gauge (); ! 711: add_timeticks (); ! 712: ! 713: add_clnpaddr (); ! 714: } ! 715: ! 716: /* */ ! 717: ! 718: int add_syntax (name, f_encode, f_decode, f_free, f_parse, f_print) ! 719: char *name; ! 720: IFP f_encode, ! 721: f_decode, ! 722: f_free, ! 723: f_parse, ! 724: f_print; ! 725: { ! 726: int i; ! 727: register OS os = synlast++; ! 728: ! 729: if ((i = synlast - syntaxes) >= MAXSYN) ! 730: return NOTOK; ! 731: os -> os_name = name; ! 732: os -> os_encode = f_encode; ! 733: os -> os_decode = f_decode; ! 734: os -> os_free = f_free; ! 735: os -> os_parse = f_parse; ! 736: os -> os_print = f_print; ! 737: ! 738: return i; ! 739: } ! 740: ! 741: /* */ ! 742: ! 743: OS text2syn (name) ! 744: char *name; ! 745: { ! 746: register OS os; ! 747: ! 748: for (os = syntaxes; os < synlast; os++) ! 749: if (lexequ (os -> os_name, name) == 0) ! 750: return os; ! 751: ! 752: return NULLOS; ! 753: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.