INTERNET-DRAFT Expires January 1997 INTERNET-DRAFT Draft SNMPv2 Lexical Specification July 30, 1996 A Lexical Specification for the SNMPv2 MIB Module Language July 30, 1996 David T. Perkins dperkins@scruznet.com 1. Status of this Memo This document is an Internet Draft. Internet Drafts are working documents of the Internet Engineering Task Force (IETF), its Areas, and its Working Groups. Note that other groups may also distribute working documents as Internet Drafts. Internet Drafts are draft documents valid for a maximum of six months. Internet Drafts may be updated, replaced, or obsoleted by other documents at any time. It is not appropriate to use Internet Drafts as reference material or to cite them other than as a "working draft" or "work in progress." To learn the current status of any Internet-Draft, please check the "1id-abstracts.txt" listing contained in the internet-drafts Shadow Directories on: ftp.is.co.za (Africa) nic.nordu.net (Europe) ds.internic.net (US East Coast) ftp.isi.edu (US West Coast) munnari.oz.au (Pacific Rim) Expires 1/30/1997 [Page 1] Draft SNMPv2 Lexical Specification July 30, 1996 2. Introduction This memo integrates the specifications for the lexical elements of the MIB module language from section 8 of the ASN.1 specification[4], augmented by the ASN.1 macros defined for the MIB module language, and modified by textual descriptions in SMIv2(RFCs 1902[1], 1903[2] and 1904[3]); and the standard practices found in most of the leading MIB compilers that are accepted by the SNMP community. Also include in this memo is a Lex specification for the tokens of the language. This memo is a rough first draft as requested by the SNMPv2 WG at the SMI Documentation BOF during the June 1996 IETF. 3. Lexical Elements The source for a MIB module must be contained in a MIB module source file. One or more MIB modules may be contained in a source file. A source file consists of a sequence of lines, each terminated by an end- of-line. ASN.1 has no restrictions on the length of a line or the number of lines in a MIB module source file. [??What should the limits be here?] Conforming MIB module compilers must allow lines to be at least 255 characters long (excluding the end-of-line indicator), and must allow source files to contain at least 65535 lines. 3.1 Characters in a Source File The "normal" characters in a source file are: A-Z the uppercase letters a-z the lowercase letters 0-9 the decimal digits { left curly brace } right curly brace ( left parenthesis ) right parenthesis : colon ; semicolon , coma - hyphen (dash) . period | vertical bar = equal sign " quote ' apostrophe a space a tab Expires 1/30/1997 [Page 2] Draft SNMPv2 Lexical Specification July 30, 1996 The "additional" characters are the remaining printable characters in the 7-bit ASCII character set. The "normal" and "additional" characters are only allowed in comments and in quoted strings. Note that the ASN.1 language includes characters "<", ">", "[", and "]", which are not used in the MIB module language. 3.2 Tokens The characters in a MIB module source file form a stream of tokens. The tokens are identifiers, keywords, literals (i.e., constants), punctuation, and white space. White space consists of space characters, line terminators, tab characters, and comments. White space is ignored other than for use to separate otherwise adjacent identifiers, keywords, and literals. If the input has been parsed into tokens up to a given character, the next token is the longest string of characters that could possibly constitute a token. 3.3 Comments A comment is started with a pair of adjacent hyphens (--) and is ended with the next pair of adjacent hyphens or the end of the line, whichever comes first. A comment may include any of the printable characters in the 7-bit ASCII character set, and spaces and tabs. A comment may occur between any two tokens and functions as white space. 3.4 Identifiers An identifier consists of 1 to 64 letters, digits, and hyphens. The initial character must be a letter. A hyphen cannot be the last character of an identifier. A hyphen cannot be immediately followed by another hyphen in an identifier. (NOTE: ASN.1 has no limit on number of characters in an identifier. Otherwise, the lexical rules for identifiers are identical.) There are two types of identifiers which are distinguished by the case of the initial letter. A "ucName" is an identifier that starts with an uppercase letter. A "lcName" is an identifier that starts with a lowercase letter. Identifiers whose lengths are greater than 24 may cause compatibility difficulties with tools that process MIB modules Also note that SMIv2 imposes restrictions on use of hyphens in most identifiers. Those restrictions are noted in the grammar description. Expires 1/30/1997 [Page 3] Draft SNMPv2 Lexical Specification July 30, 1996 3.5 Keywords Some identifiers are reserved for use as keywords. The keywords can not be used as ucNames. The keywords consist of the sub-set of ASN.1 keywords used in the MIB module language, and the elements of the macros defined for SNMP that conform to the rules for ucNames. The following are keywords in ASN.1, but are not keywords in the MIB module language: ABSENT, ANY, APPLICATION, BIT, BOOLEAN, BY, CHOICE, COMPONENT, COMPONENTS, DEFAULT, DEFINED, ENUMERATED, EXPLICIT, EXPORTS, EXTERNAL, FALSE, IMPLICIT, MAX, MIN, MINUS-INFINITY, NULL, OPTIONAL, PLUS-INFINITY, PRESENT, PRIVATE, REAL, SET, TAGS, TRUE, UNIVERSAL, and WITH The following are ASN.1 keywords used in the MIB module language: BEGIN, DEFINITIONS, END, FROM, IDENTIFIER, IMPORTS, INCLUDES, INTEGER, OBJECT, OCTET, OF, SEQUENCE, SIZE, and STRING The following are keywords only in the MIB module language: ACCESS, AGENT-CAPABILITIES, AUGMENTS, BITS, CONTACT-INFO, CREATION-REQUIRES, Counter32, Counter64, DEFVAL, DESCRIPTION, DISPLAY-HINT, GROUP, Gauge32, IMPLIED, INDEX, Integer32, IpAddress, LAST-UPDATED, MANDATORY-GROUPS, MIN-ACCESS, MODULE, MODULE- COMPLIANCE, MODULE-IDENTITY, NOTIFICATION-GROUP, NOTIFICATION-TYPE, OBJECT-GROUP, OBJECT-IDENTITY, OBJECT-TYPE, OBJECTS, ORGANIZATION, Opaque, PRODUCT-RELEASE, REFERENCE, REVISION, STATUS, SUPPORTS, SYNTAX, TEXTUAL-CONVENTION, TimeTicks, UNITS, Unsigned32, VARIATION, and WRITE-SYNTAX 3.6 Punctuation The following is a list of single characters used as punctuation tokens in the MIB module language: { left curly brace } right curly brace ( left parenthesis ) right parenthesis : colon ; semicolon , coma - hyphen (dash) . period | vertical bar Expires 1/30/1997 [Page 4] Draft SNMPv2 Lexical Specification July 30, 1996 The following is a list of character combinations used as punctuation tokens in the MIB module language: .. two periods ::= two colons and an equal sign 3.7 Literals The literals (or constants) are unsigned integers (called numbers), character strings, hexadecimal strings, and binary strings. (NOTE: the character strings in the MIB module language are not ASN.1 "cstrings".) 3.7.1 Numbers A number consists of one or more decimal digits. The first digit may not be zero unless the number is a single digit. The maximum value of a number is 4294967295. (NOTE: there is no limit on the maximum value of numbers in ASN.1.) 3.7.2 Binary Strings A binary string consists of an arbitrary number (possibly zero) of zeros and ones, preceded by a single (') and followed by either the pair ('B) or ('b). The maximum length is 128 binary digits. (NOTE: ASN.1 terminates a binary string with only a ('B). Also, ASN.1 has no limit on the length of a binary string.) 3.7.3 Hexadecimal Strings A hexadecimal string consists of an arbitrary number (possibly zero) of hexadecimal digits, preceded by a single (') and followed by either the pair ('H) or ('h). The maximum length is 128 hexadecimal digits. The hexadecimal digits are the characters "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "a", "B", "b", "C", "c", "D", "d", "E", "e", "F", and "f". (NOTE: ASN.1 terminates a hexadecimal string with only a ('H). Also, ASN.1 recognizes only the uppercase letters as hexadecimal digits and has no limit on the length of a hexadecimal string.) 3.7.4 Strings A character string consists of an arbitrary number (possibly zero) of the 7-bit graphic ASCII characters except the quote character ("), tabs, spaces, and line terminators, preceded and followed by the quote character ("). A line terminator is encoded in a quoted string as a newline (i.e., the '\n' character). The maximum length of a character string is 8192 characters. Expires 1/30/1997 [Page 5] Draft SNMPv2 Lexical Specification July 30, 1996 4. Lex Specification The specification below is the input for the Lex program, a widely used program to generate lexical analyzers. The specification can also be processed by the Flex program from the GNU project, which is a clone of Lex. 4.1 File v-scan.l /* file: v-scan.l - scanner for SNMPv1 and SNMPv2 * * Copyright 1996 David T. Perkins. All Rights Reserved. * * David T. Perkins grants a non-exclusive license to use, copy, * modify, and distribute this software for any purpose and * without fee, provided that this copyright notice and license * appear on all copies and supporting documentation. * David T. Perkins makes no representations about the suitability * of this software for any particular purpose. The software is * supplied "AS IS", and David T. Perkins makes no warranty, either * express or implied, as to the use, operation, condition, or * performance of the software. * David T. Perkins retains all title and ownership in the software. * * * $Revision: 1.0.1 $ * $Date: 28-jul-96 $ * */ %{ /* file: v-scan.c - generated scanner for SNMPv1 and SNMPv2 * from v-scan.l * */ #include #include #include #include "v-types.h" #include "v-scan.h" #include "yystype.h" MIBLOC locCur = { NULL, 1, 1 }; /* current location (line, column) */ BOOL fInStr; /* flag that in string */ USHORT usType; /* token type */ Expires 1/30/1997 [Page 6] Draft SNMPv2 Lexical Specification July 30, 1996 USHORT usColStart; /* start column for a string */ BOOL fOk2DropLWS; /* flag to allow dropping LWS */ BOOL fDropLWS; /* flag that dropping leading white space */ #define MAXSZNUM 10 /* max digits in a number */ #define MAXNUMSZ "4294967295" /* max value for a number */ #define MAXNUMUL 4294967295LU #define MAXSZNA 64 /* max length of a name */ CHAR szNa[MAXSZNA+1]; /* buffer for a name */ USHORT cSzNa; /* number of bytes in buffer */ #define MAXSZSTR 8192 /* max length of a string */ /* note that MAXSZBSTR and MAXSZHBSTR * must be less than or equal to MAXSZSTR */ #define MAXSZBSTR 128 /* max length of a binary string */ #define MAXSZHSTR 128 /* max length of a hex string */ CHAR szStr[MAXSZSTR+1]; /* buffer for a string */ USHORT cSzStr; /* number of bytes in buffer */ %} /* states for scanning: */ /* in a hex or bin string */ %s InHexOrBinString /* in a quoted string */ %s InQuotedString /* in a comment */ %s InComment /* in a name */ %s InName /* in a number */ %s InNumber /* leading zeros of a number */ %s LeadingZeros %n 800 /* increased number of DFA entries */ %e 1500 /* increased number of NFA entries */ %% /* Comment */ "--" { /* start of a comment */ locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); BEGIN InComment; } "--" { /* finished with comment */ Expires 1/30/1997 [Page 7] Draft SNMPv2 Lexical Specification July 30, 1996 locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); BEGIN 0; } "\n" { /* finished with comment */ locCur.ulLineNo++; locCur.usColNo = 1; BEGIN 0; } . { /* any other character in the comment */ locCur.usColNo++; } /* special tokens */ "{" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchLCB); } "}" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchRCB); } "(" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchLPR); } ")" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchRPR); } ";" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchSEMI); } "," { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchCOMMA); Expires 1/30/1997 [Page 8] Draft SNMPv2 Lexical Specification July 30, 1996 } "-" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchMINUS); } "." { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchDOT); } "|" { yylval.usval.loc = locCur; locCur.usColNo++; return(yylval.usval.us = XchOR); } ".." { yylval.usval.loc = locCur; locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); return(yylval.usval.us = XtokDOTDOT); } "::=" { yylval.usval.loc = locCur; locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); return(yylval.usval.us = XtokIS); } /* white space */ [ \t] { /* space or tab */ locCur.usColNo++; } "\n" { /* a newline */ locCur.ulLineNo++; locCur.usColNo = 1; } /* Name starting with uppercase letter, including keywords for the parser */ [A-Z] { /* ucName (identifier that starts with an uppercase letter) */ Expires 1/30/1997 [Page 9] Draft SNMPv2 Lexical Specification July 30, 1996 yylval.strval.pStr = NULL; yylval.strval.loc = locCur; locCur.usColNo++; cSzNa = 1; szNa[0] = yytext[0]; usType = XtokUCNAME; BEGIN InName; } /* Name starting with lowercase letter */ [a-z] { /* lcName (identifier that starts with a lowercase letter) */ yylval.strval.pStr = NULL; yylval.strval.loc = locCur; locCur.usColNo++; cSzNa = 1; szNa[0] = yytext[0]; usType = XtokLCNAME; BEGIN InName; } /* common for ucName and lcName */ "--" { /* a comment terminates a name */ locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); BEGIN InComment; /* terminate saved string and check on size of name */ if (cSzNa > MAXSZNA) { yyerror("Name too big, max size is %d", MAXSZNA); szNa[MAXSZNA] = 0; } else { szNa[cSzNa] = 0; } /* check if keyword */ if ((cSzNa <= MAXSZNA) && (usType == XtokUCNAME) && ((yylval.usval.us = getKwType(&szNa[0])) != 0)) { /* was a keyword */ return(yylval.usval.us); } /* Otherwise, store name in string table */ yylval.strval.pStr = StrTabInsert(&szNa[0]); return(usType); } "-"/([A-Z]|[a-z]|[0-9]) { /* a hyphen in name */ Expires 1/30/1997 [Page 10] Draft SNMPv2 Lexical Specification July 30, 1996 locCur.usColNo++; if (cSzNa < MAXSZNA) { szNa[cSzNa++] = yytext[0]; } else if (cSzNa == MAXSZNA) { /* max chars in string */ cSzNa++; } /* else, too many chars, so do nothing */ } ([A-Z]|[a-z]|[0-9]) { /* a letter or digit in name */ locCur.usColNo++; if (cSzNa < MAXSZNA) { szNa[cSzNa++] = yytext[0]; } else if (cSzNa == MAXSZNA) { /* max chars in string */ cSzNa++; } /* else, too many chars, so do nothing */ } (.|\n) { /* anything else or newline terminates the name */ /* pushback input */ yyless(0); BEGIN 0; /* terminate saved string and check on size of name */ if (cSzNa > MAXSZNA) { yyerror("Name too big, max size is %d", MAXSZNA); szNa[MAXSZNA] = 0; } else { szNa[cSzNa] = 0; } /* check if keyword */ if ((cSzNa <= MAXSZNA) && (usType == XtokUCNAME) && ((yylval.usval.us = getKwType(&szNa[0])) != 0)) { /* was a keyword */ return(yylval.usval.us); } /* Otherwise, store name in string table */ yylval.strval.pStr = StrTabInsert(&szNa[0]); return(usType); } /* number */ 0/[1-9] { Expires 1/30/1997 [Page 11] Draft SNMPv2 Lexical Specification July 30, 1996 /* a zero followed by nonzero digit */ locCur.usColNo++; yyerror("A leading zero on a number is illegal"); } 0/0 { /* a zero followed by a zero */ locCur.usColNo++; yyerror("Leading zero(s) on a number are illegal"); BEGIN LeadingZeros; } 0/0 { /* multiple leading zeros */ locCur.usColNo++; } 0 { /* zero followed by anything else */ /* pushback input, and rescan as a number */ yyless(0); BEGIN 0; } [0-9] { /* start of a number */ yylval.ulval.loc = locCur; locCur.usColNo++; cSzNa = 1; szNa[0] = yytext[0]; BEGIN InNumber; } [0-9] { /* digits in the number */ locCur.usColNo++; if (cSzNa < MAXSZNUM) { /* add char to string */ szNa[cSzNa++] = yytext[0]; } else if (cSzNa == MAXSZNUM) { /* max chars in string */ cSzNa++; } /* else, too many chars, so do nothing */ } (.|\n) { /* anything else in input terminates the number */ /* terminate string */ szNa[(cSzNa < MAXSZNUM) ? cSzNa : MAXSZNUM] = 0; Expires 1/30/1997 [Page 12] Draft SNMPv2 Lexical Specification July 30, 1996 /* check if number is valid, and compute value */ if ((cSzNa > MAXSZNUM) || ((cSzNa == MAXSZNUM) && ((strcmp(szNa, MAXNUMSZ) > 0)))) { yylval.ulval.ul = MAXNUMUL; yyerror("Number too big, max value is %lu", MAXNUMUL); } else { /* compute value of number */ { CHAR *pch; yylval.ulval.ul = 0; for (pch = &szNa[0]; *pch != 0; pch++) { yylval.ulval.ul = yylval.ulval.ul*10 + (*pch - '0'); } } } /* check for character */ if ((('a' <= yytext[0]) && (yytext[0] <= 'z')) || (('A' <= yytext[0]) && (yytext[0] <= 'Z'))) yyerror( "Missing separator between number and character"); /* pushback input */ yyless(0); BEGIN 0; return(XtokNUMBER); } /* Hex or Binary string */ "'" { /* start of a HEX or BINARY string */ yylval.strval.pStr = NULL; yylval.strval.loc = locCur; locCur.usColNo++; cSzStr = 0; fInStr = TRUE; BEGIN InHexOrBinString; } [0-9a-fA-F] { /* in a HEX or BINARY string */ locCur.usColNo++; if (cSzStr < MAXSZSTR) { /* add char to string */ szStr[cSzStr++] = yytext[0]; Expires 1/30/1997 [Page 13] Draft SNMPv2 Lexical Specification July 30, 1996 } else if (cSzStr == MAXSZSTR) { /* max chars in string */ cSzStr++; } /* else, too many chars, so do nothing */ } "'"[Hh] { /* end of HEX string */ locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); /* terminate string and check on size */ if (cSzStr > MAXSZHSTR) { yyerror( "Hexadecimal string too long, max length is %d", MAXSZHSTR); szStr[MAXSZHSTR] = 0; } else { szStr[cSzStr] = 0; } BEGIN 0; fInStr = FALSE; /* store in string table */ yylval.strval.pStr = StrTabInsert(&szStr[0]); return(XtokHSTR); } "'"[Bb] { /* end of BINARY string */ locCur.usColNo = (USHORT)(locCur.usColNo + yyleng); /* terminate string and check on size */ if (cSzStr > MAXSZBSTR) { yyerror("Binary string too long, max length is %d", MAXSZBSTR); szStr[MAXSZBSTR] = 0; } else { szStr[cSzStr] = 0; } /* check if all binary digits */ { CHAR *pch; for (pch = &szStr[0]; *pch != 0; pch++) { if ((*pch != '0') && (*pch != '1')) { yyerror("Invalid digit in Binary string"); *pch = 0; break; } } Expires 1/30/1997 [Page 14] Draft SNMPv2 Lexical Specification July 30, 1996 } BEGIN 0; fInStr = FALSE; /* store in string table */ yylval.strval.pStr = StrTabInsert(&szStr[0]); return(XtokBSTR); } (.|\n) { /* invalid char in HEX or BINARY string */ /* pushback input */ yyless(0); fInStr = FALSE; BEGIN 0; yyerror("Invalid Hexadecial or Binary string"); } /* quoted string */ \" { /* start of a quoted string */ yylval.strval.pStr = NULL; yylval.strval.loc = locCur; usColStart = locCur.usColNo++; if (fOk2DropLWS) fDropLWS = FALSE; cSzStr = 0; fInStr = TRUE; BEGIN InQuotedString; } "\n" { /* a newline in the quoted string */ locCur.ulLineNo++; locCur.usColNo = 1; if (fOk2DropLWS) fDropLWS = TRUE; /* add char to string if room */ if (cSzStr < MAXSZSTR) { /* add char to string */ szStr[cSzStr++] = yytext[0]; } else if (cSzStr == MAXSZSTR) { /* max chars in string */ cSzStr++; } /* else, too many chars, so do nothing */ } [^"\n] { /* a character in a quoted string */ Expires 1/30/1997 [Page 15] Draft SNMPv2 Lexical Specification July 30, 1996 locCur.usColNo++; /* check for leading white space */ if (fDropLWS) { /* check if before start column for string */ /* and char is white space */ if ((locCur.usColNo > usColStart) || ((yytext[0] ^= ' ') && (yytext[0] != '\t'))) /* stop ignoring leading whitespace */ fDropLWS = FALSE; } /* add char if not dropping leading white space */ if (!fDropLWS) { /* add char to string if room */ if (cSzStr < MAXSZSTR) { /* add char to string */ szStr[cSzStr++] = yytext[0]; } else if (cSzStr == MAXSZSTR) { /* max chars in string */ cSzStr++; } /* else, too many chars, so do nothing */ } } \" { /* end of quoted string */ locCur.usColNo++; /* terminate string and check on size */ if (cSzStr > MAXSZSTR) { yyerror("String too long, max length is %d", MAXSZSTR); szStr[MAXSZSTR] = 0; } else { szStr[cSzStr] = 0; } BEGIN 0; fInStr = FALSE; /* store in string table */ yylval.strval.pStr = StrTabInsert(&szStr[0]); return(XtokSTRING); } /* anything else in the input */ . { /* anything else in the input */ locCur.usColNo++; yyerror("Unrecognized item"); Expires 1/30/1997 [Page 16] Draft SNMPv2 Lexical Specification July 30, 1996 } %% /* parameters for hash function */ #define HASHSIZE 143 #define HASHBITS (sizeof(USHORT)*8) #define HASH3_4 ((HASHBITS*3)/4) #define HASH1_8 (HASHBITS/8) #define HASH_HI (~((USHORT)(~0) >> HASH1_8)) /* hash list */ KEYWORDNAME *apkwNa[HASHSIZE]; /** hashNa - hash a name * * From Compiler: Principles, Techniques, and Tools, * P.J. Weinberger * * call with: * pszName - name * * returns: * hash value */ USHORT #ifdef __STDC__ hashNa(PSZ pszName) #else hashNa(pszName) PSZ pszName; #endif /* __STDC__ */ { register USHORT usVal; register USHORT usTmp; for (usVal = 0; *pszName != 0; pszName++) { usVal = (USHORT)((usVal << HASH1_8) + *pszName); if ((usTmp = (USHORT)(usVal & HASH_HI)) != 0) { usVal = (USHORT)((usVal ^ (usTmp >> HASH3_4)) & ~HASH_HI); } } return((USHORT)(usVal%HASHSIZE)); } /* hashNa */ Expires 1/30/1997 [Page 17] Draft SNMPv2 Lexical Specification July 30, 1996 /** bldKwHash - build hash table for keywords * */ VOID #ifdef __STDC__ bldKwHash(VOID) #else bldKwHash() #endif /* __STDC__ */ { INT i; USHORT iHash; for (i = 0; i < HASHSIZE; i++) { apkwNa[i] = NULL; } for (i = cKw - 1; i >= 0; i--) { iHash = hashNa(kwNa[i].pszName); kwNa[i].pHashNext = apkwNa[iHash]; apkwNa[iHash] = &(kwNa[i]); } } /* bldKwHash */ #define MXFREQ 10 /** freqKwHash - print frequences of keyword hash collisions * */ VOID #ifdef __STDC__ freqKwHash(VOID) #else freqKwHash() #endif /* __STDC__ */ { INT i; USHORT iHash; USHORT acFreq[MXFREQ]; KEYWORDNAME *pkwNa; for (i = 0; i < MXFREQ; i++) { acFreq[i] = 0; } for (iHash = 0; iHash < HASHSIZE; iHash++) { for (i = 0, pkwNa = apkwNa[iHash]; Expires 1/30/1997 [Page 18] Draft SNMPv2 Lexical Specification July 30, 1996 (pkwNa != NULL) && (i < (MXFREQ-1)); i++) { pkwNa = pkwNa->pHashNext; } acFreq[i]++; if (i > 1) { fprintf(fhMsg, "Hash: %d, %d hits\n", iHash, i); for (pkwNa = apkwNa[iHash]; pkwNa != NULL; pkwNa = pkwNa->pHashNext) { fprintf(fhMsg, " \"%s\"\n", pkwNa->pszName); } } } for (i = 0; i < MXFREQ; i++) { if (acFreq[i] != 0) fprintf(fhMsg, "%3d: %d\n", i, acFreq[i]); } } /* freqKwHash */ /** getKwType - lookup item to see if keyword * * call with: * pszNa - name of item * * returns: * 0 - if not a keyword * otherwise, type of keyword * */ USHORT #ifdef __STDC__ getKwType(PSZ pszNa) #else getKwType(pszNa) PSZ pszNa; #endif /* __STDC__ */ { USHORT ikwNa; KEYWORDNAME *pkwNa; /* hash name */ ikwNa = hashNa(pszNa); /* check names on hash chain */ for (pkwNa = apkwNa[ikwNa]; pkwNa != NULL; pkwNa = pkwNa->pHashNext) { Expires 1/30/1997 [Page 19] Draft SNMPv2 Lexical Specification July 30, 1996 if (strcmp(pszNa, pkwNa->pszName) == 0) /* name matched, so return type */ return(pkwNa->usType); } /* no match */ return(0); } /* getKwType */ /** yywrap - check for more input since scanner (yylex) * got EOF from yygetc * * returns: * 0 - more input available on yyin * 1 - finished with all input */ INT #ifdef __STDC__ yywrap(VOID) #else yywrap() #endif /* __STDC__ */ { if (fInStr) { yyerror("EOF in string"); } return(1); } /* yywrap */ /* end of file */ 4.2 File v2c-scan.c /* file: v2c-sc.c - scanner data and functions for SNMPv2C * * Copyright 1996 David T. Perkins. All Rights Reserved. * * David T. Perkins grants a non-exclusive license to use, copy, * modify, and distribute this software for any purpose and * without fee, provided that this copyright notice and license * appear on all copies and supporting documentation. * David T. Perkins makes no representations about the suitability * of this software for any particular purpose. The software is * supplied "AS IS", and David T. Perkins makes no warranty, either * express or implied, as to the use, operation, condition, or * performance of the software. Expires 1/30/1997 [Page 20] Draft SNMPv2 Lexical Specification July 30, 1996 * David T. Perkins retains all title and ownership in the software. * * * $Revision: 1.0.2 $ * $Date: 27-jul-96 $ * */ #include #include #include #include "v-types.h" #include "v-scan.h" #include "v2c-prs.h" PSZ pszScanNa = "v2c-scan"; PSZ pszScanVer = "v1.0.2"; PSZ pszScanCopyright = "Copyright 1996 David T. Perkins. All Rights Reserved."; /* items whose value is defined in parser output */ USHORT XchLCB = chLCB; USHORT XchRCB = chRCB; USHORT XchLPR = chLPR; USHORT XchRPR = chRPR; USHORT XchSEMI = chSEMI; USHORT XchCOMMA = chCOMMA; USHORT XchMINUS = chMINUS; USHORT XchDOT = chDOT; USHORT XchOR = chOR; USHORT XtokDOTDOT = tokDOTDOT; USHORT XtokIS = tokIS; USHORT XtokUCNAME = tokUCNAME; USHORT XtokLCNAME = tokLCNAME; USHORT XtokNUMBER = tokNUMBER; USHORT XtokBSTR = tokBSTR; USHORT XtokHSTR = tokHSTR; USHORT XtokSTRING = tokSTRING; /* keywords */ KEYWORDNAME FAR kwNa[] = { { "ACCESS", kwACCESS, NULL }, { "AGENT-CAPABILITIES", kwAGENT_CAPABILITIES, NULL }, { "AUGMENTS", kwAUGMENTS, NULL }, { "BEGIN", kwBEGIN, NULL }, { "BITS", kwBITS, NULL }, { "CONTACT-INFO", kwCONTACT_INFO, NULL }, { "Counter32", kwCOUNTER32, NULL }, Expires 1/30/1997 [Page 21] Draft SNMPv2 Lexical Specification July 30, 1996 { "Counter64", kwCOUNTER64, NULL }, { "CREATION-REQUIRES", kwCREATION_REQUIRES, NULL }, { "DEFINITIONS", kwDEFINITIONS, NULL }, { "DEFVAL", kwDEFVAL, NULL }, { "DESCRIPTION", kwDESCRIPTION, NULL }, { "DISPLAY-HINT", kwDISPLAY_HINT, NULL }, { "END", kwEND, NULL }, { "FROM", kwFROM, NULL }, { "Gauge32", kwGAUGE32, NULL }, { "GROUP", kwGROUP, NULL }, { "IDENTIFIER", kwIDENTIFIER, NULL }, { "IMPLIED", kwIMPLIED, NULL }, { "IMPORTS", kwIMPORTS, NULL }, { "INCLUDES", kwINCLUDES, NULL }, { "INDEX", kwINDEX, NULL }, { "INTEGER", kwINTEGER, NULL }, { "Integer32", kwINTEGER32, NULL }, { "IpAddress", kwIPADDRESS, NULL }, { "LAST-UPDATED", kwLAST_UPDATED, NULL }, { "MANDATORY-GROUPS", kwMANDATORY_GROUPS, NULL }, { "MAX-ACCESS", kwMAX_ACCESS, NULL }, { "MIN-ACCESS", kwMIN_ACCESS, NULL }, { "MODULE", kwMODULE, NULL }, { "MODULE-COMPLIANCE", kwMODULE_COMPLIANCE, NULL }, { "MODULE-IDENTITY", kwMODULE_IDENTITY, NULL }, { "NOTIFICATION-GROUP", kwNOTIFICATION_GROUP, NULL }, { "NOTIFICATION-TYPE", kwNOTIFICATION_TYPE, NULL }, { "NOTIFICATIONS", kwNOTIFICATIONS, NULL }, { "OBJECT", kwOBJECT, NULL }, { "OBJECT-GROUP", kwOBJECT_GROUP, NULL }, { "OBJECT-IDENTITY", kwOBJECT_IDENTITY, NULL }, { "OBJECT-TYPE", kwOBJECT_TYPE, NULL }, { "OBJECTS", kwOBJECTS, NULL }, { "OCTET", kwOCTET, NULL }, { "OF", kwOF, NULL }, { "Opaque", kwOPAQUE, NULL }, { "ORGANIZATION", kwORGANIZATION, NULL }, { "PRODUCT-RELEASE", kwPRODUCT_RELEASE, NULL }, { "REFERENCE", kwREFERENCE, NULL }, { "REVISION", kwREVISION, NULL }, { "SEQUENCE", kwSEQUENCE, NULL }, { "SIZE", kwSIZE, NULL }, { "STATUS", kwSTATUS, NULL }, { "STRING", kwSTRING, NULL }, { "SUPPORTS", kwSUPPORTS, NULL }, { "SYNTAX", kwSYNTAX, NULL }, { "TEXTUAL-CONVENTION", kwTEXTUAL_CONVENTION, NULL }, { "TimeTicks", kwTIMETICKS, NULL }, { "UNITS", kwUNITS, NULL }, { "Unsigned32", kwUNSIGNED32, NULL }, { "VARIATION", kwVARIATION, NULL }, Expires 1/30/1997 [Page 22] Draft SNMPv2 Lexical Specification July 30, 1996 { "WRITE-SYNTAX", kwWRITE_SYNTAX, NULL } }; /* number of keywords */ USHORT cKw = sizeof(kwNa)/sizeof(KEYWORDNAME); /** printTokType - print type of a token * * call with: * iTokType - type of token * */ VOID #ifdef __STDC__ printTokType(INT iTokType) #else printTokType(iTokType) INT iTokType; #endif /* __STDC__ */ { /* check if in a file */ if ((yylval.usval.loc.ulLineNo > 0L) && (yylval.usval.loc.pszFn != NULL)) { /* output in format for editors */ /* check if column valid */ if (yylval.usval.loc.usColNo != 0) { /* print out file name, line and column number */ fprintf(fhOut, "%s(%lu,%u): ", yylval.usval.loc.pszFn, yylval.usval.loc.ulLineNo, yylval.usval.loc.usColNo); } else { /* print out just file name and line */ fprintf(fhOut, "%s(%lu): ", yylval.usval.loc.pszFn, yylval.usval.loc.ulLineNo); } } fprintf(fhOut, "T: (%d) ", iTokType); switch(iTokType) { case kwACCESS: fprintf(fhOut, "ACCESS\n"); break; case kwAGENT_CAPABILITIES: fprintf(fhOut, "AGENT_CAPABILITIES\n"); break; Expires 1/30/1997 [Page 23] Draft SNMPv2 Lexical Specification July 30, 1996 case kwAUGMENTS: fprintf(fhOut, "AUGMENTS\n"); break; case kwBEGIN: fprintf(fhOut, "BEGIN\n"); break; case kwBITS: fprintf(fhOut, "BITS\n"); break; case kwCONTACT_INFO: fprintf(fhOut, "CONTACT_INFO\n"); break; case kwCOUNTER32: fprintf(fhOut, "COUNTER32\n"); break; case kwCOUNTER64: fprintf(fhOut, "COUNTER64\n"); break; case kwCREATION_REQUIRES: fprintf(fhOut, "CREATION_REQUIRES\n"); break; case kwDEFINITIONS: fprintf(fhOut, "DEFINITIONS\n"); break; case kwDEFVAL: fprintf(fhOut, "DEFVAL\n"); break; case kwDESCRIPTION: fprintf(fhOut, "DESCRIPTION\n"); break; case kwDISPLAY_HINT: fprintf(fhOut, "DISPLAY_HINT\n"); break; case kwEND: fprintf(fhOut, "END\n"); break; case kwFROM: fprintf(fhOut, "FROM\n"); Expires 1/30/1997 [Page 24] Draft SNMPv2 Lexical Specification July 30, 1996 break; case kwGAUGE32: fprintf(fhOut, "GAUGE32\n"); break; case kwGROUP: fprintf(fhOut, "GROUP\n"); break; case kwIDENTIFIER: fprintf(fhOut, "IDENTIFIER\n"); break; case kwIMPLIED: fprintf(fhOut, "IMPLIED\n"); break; case kwIMPORTS: fprintf(fhOut, "IMPORTS\n"); break; case kwINCLUDES: fprintf(fhOut, "INCLUDES\n"); break; case kwINDEX: fprintf(fhOut, "INDEX\n"); break; case kwINTEGER: fprintf(fhOut, "INTEGER\n"); break; case kwINTEGER32: fprintf(fhOut, "INTEGER32\n"); break; case kwIPADDRESS: fprintf(fhOut, "IPADDRESS\n"); break; case kwLAST_UPDATED: fprintf(fhOut, "LAST_UPDATED\n"); break; case kwMANDATORY_GROUPS: fprintf(fhOut, "MANDATORY_GROUPS\n"); break; case kwMAX_ACCESS: Expires 1/30/1997 [Page 25] Draft SNMPv2 Lexical Specification July 30, 1996 fprintf(fhOut, "MAX_ACCESS\n"); break; case kwMIN_ACCESS: fprintf(fhOut, "MIN_ACCESS\n"); break; case kwMODULE: fprintf(fhOut, "MODULE\n"); break; case kwMODULE_COMPLIANCE: fprintf(fhOut, "MODULE_COMPLIANCE\n"); break; case kwMODULE_IDENTITY: fprintf(fhOut, "MODULE_IDENTITY\n"); break; case kwNOTIFICATION_GROUP: fprintf(fhOut, "NOTIFICATION_GROUP\n"); break; case kwNOTIFICATION_TYPE: fprintf(fhOut, "NOTIFICATION_TYPE\n"); break; case kwNOTIFICATIONS: fprintf(fhOut, "NOTIFICATIONS\n"); break; case kwOBJECT: fprintf(fhOut, "OBJECT\n"); break; case kwOBJECT_GROUP: fprintf(fhOut, "OBJECT_GROUP\n"); break; case kwOBJECT_IDENTITY: fprintf(fhOut, "OBJECT_IDENTITY\n"); break; case kwOBJECT_TYPE: fprintf(fhOut, "OBJECT_TYPE\n"); break; case kwOBJECTS: fprintf(fhOut, "OBJECTS\n"); break; Expires 1/30/1997 [Page 26] Draft SNMPv2 Lexical Specification July 30, 1996 case kwOCTET: fprintf(fhOut, "OCTET\n"); break; case kwOF: fprintf(fhOut, "OF\n"); break; case kwOPAQUE: fprintf(fhOut, "OPAQUE\n"); break; case kwORGANIZATION: fprintf(fhOut, "ORGANIZATION\n"); break; case kwPRODUCT_RELEASE: fprintf(fhOut, "PRODUCT_RELEASE\n"); break; case kwREFERENCE: fprintf(fhOut, "REFERENCE\n"); break; case kwREVISION: fprintf(fhOut, "REVISION\n"); break; case kwSEQUENCE: fprintf(fhOut, "SEQUENCE\n"); break; case kwSIZE: fprintf(fhOut, "SIZE\n"); break; case kwSTATUS: fprintf(fhOut, "STATUS\n"); break; case kwSTRING: fprintf(fhOut, "STRING\n"); break; case kwSUPPORTS: fprintf(fhOut, "SUPPORTS\n"); break; case kwSYNTAX: fprintf(fhOut, "SYNTAX\n"); break; Expires 1/30/1997 [Page 27] Draft SNMPv2 Lexical Specification July 30, 1996 case kwTEXTUAL_CONVENTION: fprintf(fhOut, "TEXTUAL_CONVENTION\n"); break; case kwTIMETICKS: fprintf(fhOut, "TIMETICKS\n"); break; case kwUNITS: fprintf(fhOut, "UNITS\n"); break; case kwUNSIGNED32: fprintf(fhOut, "UNSIGNED32\n"); break; case kwVARIATION: fprintf(fhOut, "VARIATION\n"); break; case kwWRITE_SYNTAX: fprintf(fhOut, "WRITE_SYNTAX\n"); break; case chLCB: fprintf(fhOut, "LCB\n"); break; case chRCB: fprintf(fhOut, "RCB\n"); break; case chLPR: fprintf(fhOut, "LPR\n"); break; case chRPR: fprintf(fhOut, "RPR\n"); break; case chSEMI: fprintf(fhOut, "SEMI\n"); break; case chCOMMA: fprintf(fhOut, "COMMA\n"); break; case chMINUS: fprintf(fhOut, "MINUS\n"); Expires 1/30/1997 [Page 28] Draft SNMPv2 Lexical Specification July 30, 1996 break; case chDOT: fprintf(fhOut, "DOT\n"); break; case chOR: fprintf(fhOut, "OR\n"); break; case tokDOTDOT: fprintf(fhOut, "DOTDOT\n"); break; case tokIS: fprintf(fhOut, "IS\n"); break; case tokUCNAME: /* name starting with uppercase letter */ fprintf(fhOut, "UCNAME - "); if (yylval.strval.pStr == NULL) fprintf(fhOut, "NULL ptr\n"); else if (yylval.strval.pStr->pszVal == NULL) fprintf(fhOut, "Value is NULL ptr\n"); else fprintf(fhOut, "\"%s\"\n", yylval.strval.pStr->pszVal); break; case tokLCNAME: /* name starting with lowercase letter */ fprintf(fhOut, "LCNAME - "); if (yylval.strval.pStr == NULL) fprintf(fhOut, "NULL ptr\n"); else if (yylval.strval.pStr->pszVal == NULL) fprintf(fhOut, "Value is NULL ptr\n"); else fprintf(fhOut, "\"%s\"\n", yylval.strval.pStr->pszVal); break; case tokSTRING: /* string */ fprintf(fhOut, "STRING - "); if (yylval.strval.pStr == NULL) fprintf(fhOut, "NULL ptr\n"); else if (yylval.strval.pStr->pszVal == NULL) fprintf(fhOut, "Value is NULL ptr\n"); else fprintf(fhOut, "\"%s\"\n", Expires 1/30/1997 [Page 29] Draft SNMPv2 Lexical Specification July 30, 1996 yylval.strval.pStr->pszVal); break; case tokNUMBER: fprintf(fhOut, "NUMBER, value %lu\n", yylval.ulval.ul); break; case tokBSTR: /* bit string */ fprintf(fhOut, "BSTR - "); if (yylval.strval.pStr == NULL) fprintf(fhOut, "NULL ptr\n"); else if (yylval.strval.pStr->pszVal == NULL) fprintf(fhOut, "Value is NULL ptr\n"); else fprintf(fhOut, "'%s'B\n", yylval.strval.pStr->pszVal); break; case tokHSTR: /* hex string */ fprintf(fhOut, "HSTR - "); if (yylval.strval.pStr == NULL) fprintf(fhOut, "NULL ptr\n"); else if (yylval.strval.pStr->pszVal == NULL) fprintf(fhOut, "Value is NULL ptr\n"); else fprintf(fhOut, "'%s'H\n", yylval.strval.pStr->pszVal); break; default: fprintf(fhOut, "unknown type %d\n", iTokType); break; } } /* printTokType */ /* end of file: v2c-sc.c */ Expires 1/30/1997 [Page 30] Draft SNMPv2 Lexical Specification July 30, 1996 5. References [1] J. Case, K. McCloghrie, M. Rose, S. Waldbusser, "Structure of Management Information for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1902, 01/22/1996. [2] J. Case, K. McCloghrie, M. Rose, S. Waldbusser, "Textual Conventions for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1903, 01/22/1996. [3] J. Case, K. McCloghrie, M. Rose, S. Waldbusser, "Conformance Statements for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1904, 01/22/1996. Management Information for version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1442, 05/03/1993. [4] Information processing systems - Open Systems Interconnection - Specification of Abstract Syntax Notation One (ASN.1), International Organization for Standardization. International Standard 8824, (December, 1987). Expires 1/30/1997 [Page 31]