/**************************************************************************** **.COPYRIGHT (C)Copyright 1993 ** CSE Computer Systems Expertise ** DNPAP (Data Network Performance Analysis) group. ** See file COPYING 'GNU General Public Licence' for details **.AUTHORS Ling Thio, CSE ,H.L.Thio@et.tudelft.nl ** Dirk Wisse, DNPAP ,D.M.Wisse@et.tudelft.nl **.DATE Sep 1993 ****************************************************************************/ #include #include #include #include #include #include "winmib.h" #define MAX_VARS 1024 #define MAX_LINELEN 128 #define OID_SEP '.' #define MibAlloc(size) malloc(size) #define MibFree(ptr) free(ptr) typedef struct _MIBVAR { char FAR *name; struct _MIBVAR *parent; SMI_UINT32 index; struct _MIBVAR *firstChild; struct _MIBVAR *nextSibling; } MIBVAR; static MIBVAR isoVar = { "iso", NULL, 1, NULL, NULL }; static MIB_STATUS mibLasterror; static MIBVAR *varTbl[MAX_VARS]; static unsigned varTblCount; static MIBVAR sVar; static MIBVAR *searchVar = &sVar; static MIBVAR **foundVar; static char *lastFilename; static SMI_UINT32 lastLine; MIBVAR *rootVar; typedef int (*CMPFUNC)(const void *, const void *); static int MibSetLasterror(int error) { mibLasterror=error; return MIB_FAILURE; } static int CmpVarName(MIBVAR **var1, MIBVAR **var2) { return strcmp((*var1)->name, (*var2)->name); } //static int CmpVarParent(MIBVAR **var1, MIBVAR **var2) //{ // return ((*var1)->parent!=(*var2)->parent || // (*var1)->index!=(*var2)->index); //} static void SortVarTbl(void) { qsort(varTbl, varTblCount, sizeof(MIBVAR *), (CMPFUNC)CmpVarName); } static MIB_STATUS AddVar(char FAR *name, MIBVAR *parent, SMI_UINT32 index) { MIBVAR *var; /* check paramenters */ if (parent==NULL) return MibSetLasterror(MIB_INVALID_PARENT); if (varTblCount>=MAX_VARS) return MibSetLasterror(MIB_ALLOC_ERROR); /* alloc var */ var = MibAlloc(sizeof(MIBVAR)+strlen(name)+1); if (var==NULL) return MibSetLasterror(MIB_ALLOC_ERROR); /* fill var */ memset(var, 0, sizeof(*var)); var->name = (char FAR *)(var+1); strcpy(var->name, name); var->parent = parent; var->index = index; /* add to table */ varTbl[varTblCount++] = var; /* add to parent's list */ var->nextSibling = parent->firstChild; parent->firstChild = var; return MIB_SUCCESS; } /* parse line of format " ." */ static MIB_STATUS ParseLine(char FAR **name, char FAR **parent, SMI_UINT32 *index, char FAR *buf) { char FAR *ptr; static char strSep[] = " \t\n\r."; *name = buf; for (ptr=*name; strchr(strSep, *ptr)==NULL; ptr++); *ptr = 0; for (ptr++; *ptr!=0 && strchr(strSep, *ptr)!=NULL; ptr++); if (*ptr==0) return MibSetLasterror(MIB_SYNTAX_ERROR); *parent = ptr; for (ptr=*parent; strchr(strSep, *ptr)==NULL; ptr++); *ptr = 0; *index = atoi(ptr+1); if (*index==0) return MibSetLasterror(MIB_SYNTAX_ERROR); return MIB_SUCCESS; } /**************************************************************************** .FUNC Returns last Mib error code. .DESCR This function is used to retrieve last Mib error code when a Mib function returns MIB_FAILURE. .RETURN .INC mib_errors ****************************************************************************/ MIB_STATUS MIB_API MibGetLasterror( OUT char FAR *FAR *filename, /*.PARAM Pointer to hold current filename */ OUT SMI_PUINT32 line) /*.PARAM Pointer to hold current line number */ { if (filename!=NULL) *filename = lastFilename; if (line!=NULL) *line = lastLine; return mibLasterror; } /**************************************************************************** .FUNC Converts Object ID to logical MIB name .DESCR This function converts a numeric Object ID into a human readable MIB variable name. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibOidToStr( OUT char FAR *buf, /* Buffer to receive MIB name */ IN unsigned bufsize, /* Size of buffer */ IN SMI_POID oid) /* Pointer to Object ID structure */ { SMI_UINT32 index; MIBVAR *prevVar = NULL; MIBVAR tmpVar; MIBVAR *var = rootVar; buf[0] = 0; if (oid->len==0) return MibSetLasterror(MIB_INVALID_OID); tmpVar.firstChild = rootVar; var = &tmpVar; for (index=0; indexlen && var!=NULL; index++) { for (var=var->firstChild; var!=NULL && var->index!=oid->ptr[index]; var=var->nextSibling); if (var!=NULL && var->index==oid->ptr[index]) { prevVar = var; } } if (var!=NULL) { prevVar = var; } else { index--; } if (strlen(prevVar->name)>=bufsize) return MibSetLasterror(MIB_OUTPUT_TRUNCATED); strcpy(buf, prevVar->name); if (indexlen) { unsigned varnameLen; unsigned totLen; strcat(buf, "["); varnameLen = totLen = strlen(buf); for (; indexlen; index++) { char szNumber[33]; /* ltoa buffer */ ltoa(oid->ptr[index], szNumber, 10); if (totLen+strlen(szNumber)+2>=bufsize) { /* Error: String buffer is too small */ return MibSetLasterror(MIB_INVALID_OID); } if (totLen!=varnameLen) { buf[totLen++] = '.'; } strcpy(buf+totLen, szNumber); totLen += strlen(szNumber); } buf[totLen++] = ']'; buf[totLen++] = 0; } return MIB_SUCCESS; } /**************************************************************************** .FUNC Converts a MIB name into a Object ID. .DESCR This function converts the human readable MIB variable name into a numeric Object ID. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibStrToOid( IN OUT SMI_POID oid, /*.PARAM Pointer to receive Object ID */ IN char FAR *name) /*.PARAM MIB variable name */ { SMI_UINT32 len; SMI_UINT32 index; char FAR *ptrName; char FAR *ptrNumber; /* "1.3.6.1.1.2.3": ptrName=NULL, ptrNumber="1.3.6.1.1.2.3" */ /* "internet": ptrName="internet", ptrNumber=NULL */ /* "internet[1.2.3]": ptrName="internet", ptrNumber="1.2.3]" */ if (isdigit(name[0])) { ptrName = NULL; ptrNumber = name; } else { ptrName = name; ptrNumber = strchr(name, '['); if (ptrNumber!=NULL) { *(ptrNumber++) = 0; } } len = 0; if (ptrName!=NULL) { SMI_PUINT32 ptr; MIBVAR *var; searchVar->name = name; foundVar = bsearch(&searchVar, varTbl, varTblCount, sizeof(MIBVAR *), (CMPFUNC)CmpVarName); if (foundVar == NULL) return MibSetLasterror(MIB_INVALID_NAME); var = *foundVar; /* fill oid from bottom up */ for (index=oid->len-1, ptr=oid->ptr+(oid->len-1); index>0; index--,ptr--) { *ptr = var->index; if (var->parent == NULL) break; /* this is the root node */ var = var->parent; } if (var->parent != NULL) return MibSetLasterror(MIB_INVALID_NAME); if (index>0) { /* move oid's to top */ memmove(oid->ptr, ptr, (oid->len-index)*sizeof(oid->ptr[0])); len = oid->len-index; /* oid len */ } else { return MibSetLasterror(MIB_OUTPUT_TRUNCATED); } } index = 0; if (ptrNumber!=NULL) { char FAR *string = ptrNumber; while (*string!=0 && *string!=']' && len+indexlen) { /* for all "[.]number[.]"s... */ SMI_UINT32 number = 0; if (*string==OID_SEP) string++; /* skip possible '.' */ while (isdigit(*string)) { number=number*10 + *(string++)-'0'; } if (*string!=0 && *string!=']' && *string!='.') { /* Error: Invalid character in string */ return MibSetLasterror(MIB_INVALID_OID); } oid->ptr[len+index] = number; index++; } *(--ptrNumber) = '['; } return len+index; } /**************************************************************************** .FUNC Reads MIB definition in .def file format. .DESCR Reads a MIB definition file in .def format. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibReadDef(IN char FAR *filename) { FILE *fh; char line[MAX_LINELEN+1]; if (varTblCount == 0) { /* init var table once .. */ varTbl[varTblCount++] = rootVar = &isoVar; /* .. with root var */ } /* try open file in current dir */ fh = fopen(filename, "r"); if (fh==NULL) { char path[128]; /* try open file in "%MIBHOME%" dir */ _searchenv(filename, "MIBHOME", path); if (path[0]!=0) { fh = fopen(path, "r"); } if (fh==NULL) { return MibSetLasterror(MIB_FILE_ERROR); } } lastFilename = filename; lastLine = 0; while (!feof(fh)) { /* for all lines in .DEF file */ lastLine++; fgets(line, MAX_LINELEN, fh); line[MAX_LINELEN] = 0; if (line[strlen(line)-1]=='\n') { /* cut off trailing newline */ line[strlen(line)-1]=0; } if (isalnum(line[0])) { /* skip empty & comment lines */ char FAR *name; char FAR *parent; SMI_UINT32 index; if (ParseLine(&name, &parent, &index, line)!=MIB_FAILURE) { unsigned num = varTblCount; /* TODO: give warning on redefinitions */ searchVar->name = parent; foundVar = lsearch(&searchVar, varTbl, &num, sizeof(MIBVAR *), (CMPFUNC)CmpVarName); if (foundVar==NULL) return MibSetLasterror(MIB_SYNTAX_ERROR); if (AddVar(name, *foundVar, index)==MIB_FAILURE) { fclose(fh); return MIB_FAILURE; } } } } fclose(fh); SortVarTbl(); return MIB_SUCCESS; } /**************************************************************************** .FUNC Reads MIB definition in rfc????.txt file format. .DESCR Reads a MIB definition file in rfc????.txt format. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibReadRfc(IN char FAR *filename) { /* TODO */ return MIB_FAILURE; } /**************************************************************************** .FUNC Initializes Mib functions. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibStartup(void) { return MIB_SUCCESS; } /**************************************************************************** .FUNC Terminates Mib functions. .RETURN .INC mib_status ****************************************************************************/ MIB_STATUS MIB_API MibCleanup(void) { int index; for (index=0; index