Blame lib/check.c

Packit 022b05
/*
Packit 022b05
 * check.c --
Packit 022b05
 *
Packit 022b05
 *      This module contains semantics checks that are shared between
Packit 022b05
 *	the SMI parser backends.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2000 Frank Strauss, Technical University of Braunschweig.
Packit 022b05
 *
Packit 022b05
 * See the file "COPYING" for information on usage and redistribution
Packit 022b05
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Packit 022b05
 *
Packit 022b05
 * @(#) $Id: check.c 7640 2008-01-31 15:29:52Z schoenw $
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <string.h>
Packit 022b05
#include <errno.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
#include <sys/types.h>
Packit 022b05
#ifdef HAVE_UNISTD_H
Packit 022b05
#include <unistd.h>
Packit 022b05
#endif
Packit 022b05
#ifdef HAVE_WIN_H
Packit 022b05
#include "win.h"
Packit 022b05
#endif
Packit 022b05
Packit 022b05
#include "error.h"
Packit 022b05
#include "util.h"
Packit 022b05
#include "data.h"
Packit 022b05
#include "check.h"
Packit 022b05
#include "smi.h"
Packit 022b05
Packit 022b05
#ifdef HAVE_DMALLOC_H
Packit 022b05
#include <dmalloc.h>
Packit 022b05
#endif
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * compareValues --
Packit 022b05
 *
Packit 022b05
 *	Compare two SmiValues a and b.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      <= -2   if a is less than b-1
Packit 022b05
 *      -1      if a is b-1
Packit 022b05
 *      0       if equal
Packit 022b05
 *      1       if a is b+1
Packit 022b05
 *      >= 2    if a is greater than b+1
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *	None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
static int
Packit 022b05
compareValues(SmiValue *a, SmiValue *b) {
Packit 022b05
    if ((a->basetype == SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
	(b->basetype == SMI_BASETYPE_UNSIGNED32)) {
Packit 022b05
	if (a->value.unsigned32 == b->value.unsigned32) {
Packit 022b05
	    return 0;
Packit 022b05
	} else {
Packit 022b05
	    if (a->value.unsigned32 > b->value.unsigned32) {
Packit 022b05
		if (a->value.unsigned32 == b->value.unsigned32 + 1) {
Packit 022b05
		    return 1;
Packit 022b05
		} else {
Packit 022b05
		    return 2;
Packit 022b05
		}
Packit 022b05
	    } else if (a->value.unsigned32 < b->value.unsigned32) {
Packit 022b05
		if (a->value.unsigned32 + 1 == b->value.unsigned32) {
Packit 022b05
		    return -1;
Packit 022b05
		} else {
Packit 022b05
		    return -2;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    if ((a->basetype == SMI_BASETYPE_INTEGER32) &&
Packit 022b05
	(b->basetype == SMI_BASETYPE_INTEGER32)) {
Packit 022b05
	if (a->value.integer32 == b->value.integer32) {
Packit 022b05
	    return 0;
Packit 022b05
	} else {
Packit 022b05
	    if (a->value.integer32 > b->value.integer32) {
Packit 022b05
		if (a->value.integer32 == b->value.integer32 + 1) {
Packit 022b05
		    return 1;
Packit 022b05
		} else {
Packit 022b05
		    return 2;
Packit 022b05
		}
Packit 022b05
	    } else if (a->value.integer32 < b->value.integer32) {
Packit 022b05
		if (a->value.integer32 + 1 == b->value.integer32) {
Packit 022b05
		    return -1;
Packit 022b05
		} else {
Packit 022b05
		    return -2;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    if ((a->basetype == SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
	(b->basetype == SMI_BASETYPE_INTEGER32)) {
Packit 022b05
	if ((b->value.integer32 < -1) ||
Packit 022b05
	    ((a->value.unsigned32 > 1) &&
Packit 022b05
	     (a->value.unsigned32-1 > 2147483647))) {
Packit 022b05
	    return 2;
Packit 022b05
	}
Packit 022b05
	return a->value.unsigned32 - b->value.integer32;
Packit 022b05
    }
Packit 022b05
    if ((a->basetype == SMI_BASETYPE_INTEGER32) &&
Packit 022b05
	(b->basetype == SMI_BASETYPE_UNSIGNED32)) {
Packit 022b05
	if ((a->value.integer32 < -1) ||
Packit 022b05
	    ((b->value.unsigned32 > 1) &&
Packit 022b05
	     (b->value.unsigned32-1 > 2147483647))) {
Packit 022b05
	    return -2;
Packit 022b05
	}
Packit 022b05
	return b->value.unsigned32 - a->value.integer32;
Packit 022b05
    }
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * redefinition --
Packit 022b05
 *
Packit 022b05
 *	Print out error messages about a (case) redefinition.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *	None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *	None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
static void
Packit 022b05
redefinition(Parser *parser, int line1, char *name1, Module *module,
Packit 022b05
	     int line2, char *name2)
Packit 022b05
{
Packit 022b05
    char *tmp = parser->path;
Packit 022b05
    int equal = (strcmp(name1, name2) == 0);
Packit 022b05
Packit 022b05
    if (!strcmp(name1, "IpAddress") ||
Packit 022b05
	!strcmp(name1, "TimeTicks") ||
Packit 022b05
	!strcmp(name1, "Opaque") ||
Packit 022b05
	!strcmp(name1, "Integer32") ||
Packit 022b05
	!strcmp(name1, "Unsigned32") ||
Packit 022b05
	!strcmp(name1, "Counter32") ||
Packit 022b05
	!strcmp(name1, "Gauge32") ||
Packit 022b05
	!strcmp(name1, "Counter64") ||
Packit 022b05
	!strcmp(name1, "Integer64") ||
Packit 022b05
	!strcmp(name1, "Unsigned64")) {
Packit 022b05
	if (line1) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_BASETYPE_REDEFINITION, line1, name1);
Packit 022b05
	} else {
Packit 022b05
	    smiPrintError(parser, ERR_BASETYPE_REDEFINITION, name1);
Packit 022b05
	}
Packit 022b05
    } else {
Packit 022b05
	if (! module) {
Packit 022b05
	    if (equal) {
Packit 022b05
		if (line1) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_REDEFINITION, line1, name1);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintError(parser, ERR_REDEFINITION, name1);
Packit 022b05
		}
Packit 022b05
	    } else {
Packit 022b05
		if (line1) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_CASE_REDEFINITION,
Packit 022b05
					line1, name1, name2);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintError(parser, ERR_CASE_REDEFINITION, name1, name2);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	} else {
Packit 022b05
	    if (equal) {
Packit 022b05
		if (line1) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_EXT_REDEFINITION, line1,
Packit 022b05
					module->export.name, name1);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintError(parser, ERR_EXT_REDEFINITION,
Packit 022b05
				  module->export.name, name1);
Packit 022b05
		}
Packit 022b05
	    } else {
Packit 022b05
		if (line1) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_EXT_CASE_REDEFINITION, line1,
Packit 022b05
					name1, module->export.name, name2);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintError(parser, ERR_EXT_CASE_REDEFINITION,
Packit 022b05
				  name1, module->export.name, name2);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    parser->path = module->export.path;
Packit 022b05
	}
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_PREVIOUS_DEFINITION, line2, name2);
Packit 022b05
	if (module) {
Packit 022b05
	    parser->path = tmp;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckObjectName --
Packit 022b05
 *
Packit 022b05
 *      Check whether a given object name already exists
Packit 022b05
 *	in a given module.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckObjectName(Parser *parser, Module *module, char *name)
Packit 022b05
{
Packit 022b05
    Object	*objectPtr;
Packit 022b05
    Type        *typePtr;
Packit 022b05
    Module	*modPtr;
Packit 022b05
Packit 022b05
    int errRedef = smiGetErrorSeverity(ERR_REDEFINITION);
Packit 022b05
    int errExtRedef = smiGetErrorSeverity(ERR_EXT_REDEFINITION);
Packit 022b05
    int errCaseRedef = smiGetErrorSeverity(ERR_CASE_REDEFINITION);
Packit 022b05
    int errExtCaseRedef = smiGetErrorSeverity(ERR_EXT_CASE_REDEFINITION);
Packit 022b05
Packit 022b05
    if (! (parser->flags & SMI_FLAG_ERRORS)
Packit 022b05
	|| (errRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtRedef > smiHandle->errorLevel
Packit 022b05
	    && errCaseRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtCaseRedef > smiHandle->errorLevel)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * This would really benefit from having a hash table...
Packit 022b05
     */
Packit 022b05
Packit 022b05
    for (modPtr = smiHandle->firstModulePtr;
Packit 022b05
	 modPtr; modPtr = modPtr->nextPtr) {
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * Skip all external modules if we are not interested in
Packit 022b05
	 * generating warning on extern redefinitions.
Packit 022b05
	 */
Packit 022b05
Packit 022b05
	if (errExtRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtCaseRedef > smiHandle->errorLevel
Packit 022b05
	    && modPtr != module) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
Packit 022b05
        for (objectPtr = modPtr->firstObjectPtr;
Packit 022b05
	     objectPtr; objectPtr = objectPtr->nextPtr) {
Packit 022b05
	    if (! (objectPtr->flags & FLAG_INCOMPLETE)
Packit 022b05
		&& ! strcasecmp(name, objectPtr->export.name)) {
Packit 022b05
		redefinition(parser, 0, name,
Packit 022b05
			     modPtr == module ? NULL : objectPtr->modulePtr,
Packit 022b05
			     objectPtr->line, objectPtr->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	for (typePtr = modPtr->firstTypePtr;
Packit 022b05
	     typePtr; typePtr = typePtr->nextPtr) {
Packit 022b05
	    /* TODO: must ignore SEQUENCE types here ... */
Packit 022b05
	    if (! (typePtr->flags & FLAG_INCOMPLETE)
Packit 022b05
		&& typePtr->export.name
Packit 022b05
		&& !strcasecmp(name, typePtr->export.name)) {
Packit 022b05
		redefinition(parser, 0, name,
Packit 022b05
			     modPtr == module ? NULL : typePtr->modulePtr,
Packit 022b05
			     typePtr->line, typePtr->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckTypeName --
Packit 022b05
 *
Packit 022b05
 *      Check whether a given type name already exists
Packit 022b05
 *	in a given module.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckTypeName(Parser *parser, Module *module, char *name, int line)
Packit 022b05
{
Packit 022b05
    Object	*objectPtr;
Packit 022b05
    Type        *typePtr;
Packit 022b05
    Module	*modPtr;
Packit 022b05
Packit 022b05
    int errRedef = smiGetErrorSeverity(ERR_REDEFINITION);
Packit 022b05
    int errExtRedef = smiGetErrorSeverity(ERR_EXT_REDEFINITION);
Packit 022b05
    int errCaseRedef = smiGetErrorSeverity(ERR_CASE_REDEFINITION);
Packit 022b05
    int errExtCaseRedef = smiGetErrorSeverity(ERR_EXT_CASE_REDEFINITION);
Packit 022b05
Packit 022b05
    if (! (parser->flags & SMI_FLAG_ERRORS)
Packit 022b05
	|| (errRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtRedef > smiHandle->errorLevel
Packit 022b05
	    && errCaseRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtCaseRedef > smiHandle->errorLevel)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * This would really benefit from having a hash table...
Packit 022b05
     */
Packit 022b05
Packit 022b05
    for (modPtr = smiHandle->firstModulePtr;
Packit 022b05
	 modPtr; modPtr = modPtr->nextPtr) {
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * Skip all external modules if we are not interested in
Packit 022b05
	 * generating warning on extern redefinitions.
Packit 022b05
	 */
Packit 022b05
Packit 022b05
	if (errExtRedef > smiHandle->errorLevel
Packit 022b05
	    && errExtCaseRedef > smiHandle->errorLevel
Packit 022b05
	    && modPtr != module) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	for (typePtr = modPtr->firstTypePtr;
Packit 022b05
	     typePtr; typePtr = typePtr->nextPtr) {
Packit 022b05
	    /* TODO: must ignore SEQUENCE types here ... */
Packit 022b05
	    if (! (typePtr->flags & FLAG_INCOMPLETE)
Packit 022b05
		&& typePtr->export.name
Packit 022b05
		&& !strcasecmp(name, typePtr->export.name)) {
Packit 022b05
		redefinition(parser, line, name,
Packit 022b05
			     modPtr == module ? NULL : typePtr->modulePtr,
Packit 022b05
			     typePtr->line, typePtr->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
        for (objectPtr = modPtr->firstObjectPtr;
Packit 022b05
	     objectPtr; objectPtr = objectPtr->nextPtr) {
Packit 022b05
	    if (! (objectPtr->flags & FLAG_INCOMPLETE)
Packit 022b05
		&& ! strcasecmp(name, objectPtr->export.name)) {
Packit 022b05
		redefinition(parser, line, name,
Packit 022b05
			     modPtr == module ? NULL : objectPtr->modulePtr,
Packit 022b05
			     objectPtr->line, objectPtr->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckFormat --
Packit 022b05
 *
Packit 022b05
 *      Check whether a format specification is valid.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      Returns 1 of the format is acceptable and 0 otherwise.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
int
Packit 022b05
smiCheckFormat(Parser *parser, SmiBasetype basetype, char *format, int line)
Packit 022b05
{
Packit 022b05
    int n, repeat, error = 1;
Packit 022b05
    char *p = format;
Packit 022b05
Packit 022b05
    switch (basetype) {
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	if (*p == 'x' || *p == 'o' || *p == 'b') {
Packit 022b05
	    p++;
Packit 022b05
	    error = (*p != 0);
Packit 022b05
	} else if (*p == 'd') {
Packit 022b05
	    p++;
Packit 022b05
	    if (! *p) {
Packit 022b05
		error = 0;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    if (*p != '-') {
Packit 022b05
		error = 0;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    for (n = 0, p++; *p && isdigit((int) *p); p++, n++) ;
Packit 022b05
	    error = (*p != 0 || n <= 0);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	while (*p) {
Packit 022b05
	    if ((repeat = (*p == '*'))) p++;                /* part 1 */
Packit 022b05
	    
Packit 022b05
	    for (n = 0; *p && isdigit((int) *p); p++, n++) ;/* part 2 */
Packit 022b05
	    if (! *p || n == 0) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    if (*p != 'x' && *p != 'd' && *p != 'o'         /* part 3 */
Packit 022b05
		&& *p != 'a' && *p != 't') {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    p++;
Packit 022b05
	    
Packit 022b05
	    if (*p                                          /* part 4 */
Packit 022b05
		&& ! isdigit((int) *p) && *p != '*') p++;
Packit 022b05
	    
Packit 022b05
	    if (repeat && *p                                /* part 5 */
Packit 022b05
		&& ! isdigit((int) *p) && *p != '*') p++;
Packit 022b05
	}
Packit 022b05
	error = *p;
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (error) {
Packit 022b05
	if (line) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_INVALID_FORMAT, line, format);
Packit 022b05
	} else {
Packit 022b05
	    smiPrintError(parser, ERR_INVALID_FORMAT, format);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return ! error;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckNamedNumberRedefinition --
Packit 022b05
 *
Packit 022b05
 *      Check whether named numbers redefine names or numbers.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckNamedNumberRedefinition(Parser *parser, Type *type)
Packit 022b05
{
Packit 022b05
    List *list1Ptr, *list2Ptr;
Packit 022b05
    NamedNumber *nn1Ptr, *nn2Ptr;
Packit 022b05
Packit 022b05
    if (! type || (type->export.basetype != SMI_BASETYPE_ENUM
Packit 022b05
		      && type->export.basetype != SMI_BASETYPE_BITS)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
	    
Packit 022b05
    for (list1Ptr = type->listPtr;
Packit 022b05
	 list1Ptr; list1Ptr = list1Ptr->nextPtr) {
Packit 022b05
	
Packit 022b05
	nn1Ptr = (NamedNumber *)(list1Ptr->ptr);
Packit 022b05
Packit 022b05
	for (list2Ptr = list1Ptr->nextPtr;
Packit 022b05
	     list2Ptr; list2Ptr = list2Ptr->nextPtr) {
Packit 022b05
	    
Packit 022b05
	    nn2Ptr = (NamedNumber *)(list2Ptr->ptr);
Packit 022b05
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_ENUM) {
Packit 022b05
		if (!strcmp(nn1Ptr->export.name, nn2Ptr->export.name)) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_ENUM_NAME_REDEFINITION,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name);
Packit 022b05
		}
Packit 022b05
		if (nn1Ptr->export.value.value.integer32
Packit 022b05
		    == nn2Ptr->export.value.value.integer32) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_ENUM_NUMBER_REDEFINITION,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.value.value.integer32);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_BITS) {
Packit 022b05
		if (!strcmp(nn1Ptr->export.name, nn2Ptr->export.name)) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_BITS_NAME_REDEFINITION,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name);
Packit 022b05
		}
Packit 022b05
		if (nn1Ptr->export.value.value.unsigned32
Packit 022b05
		    == nn2Ptr->export.value.value.unsigned32) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_BITS_NUMBER_REDEFINITION,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.value.value.unsigned32);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }   
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckNamedNumberSubtyping --
Packit 022b05
 *
Packit 022b05
 *      Check whether named numbers in a derived type are compatible
Packit 022b05
 *	with the named numbers in the parent type.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckNamedNumberSubtyping(Parser *parser, Type *type)
Packit 022b05
{
Packit 022b05
    List *list1Ptr, *list2Ptr;
Packit 022b05
    NamedNumber *nn1Ptr, *nn2Ptr;
Packit 022b05
	
Packit 022b05
    if (! type || ! type->parentPtr || ! type->parentPtr->parentPtr
Packit 022b05
	|| (type->export.basetype != SMI_BASETYPE_ENUM
Packit 022b05
	    && type->export.basetype != SMI_BASETYPE_BITS)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (list1Ptr = type->listPtr;
Packit 022b05
	 list1Ptr; list1Ptr = list1Ptr->nextPtr) {
Packit 022b05
	
Packit 022b05
	nn1Ptr = (NamedNumber *)(list1Ptr->ptr);
Packit 022b05
	
Packit 022b05
	for (list2Ptr = type->parentPtr->listPtr;
Packit 022b05
	     list2Ptr; list2Ptr = list2Ptr->nextPtr) {
Packit 022b05
	    
Packit 022b05
	    nn2Ptr = (NamedNumber *)(list2Ptr->ptr);
Packit 022b05
	    
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_ENUM) {
Packit 022b05
		if (! strcmp(nn1Ptr->export.name, nn2Ptr->export.name)
Packit 022b05
		    && nn1Ptr->export.value.value.integer32
Packit 022b05
		    == nn2Ptr->export.value.value.integer32) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_BITS) {
Packit 022b05
		if (! strcmp(nn1Ptr->export.name, nn2Ptr->export.name)
Packit 022b05
		    && nn1Ptr->export.value.value.unsigned32
Packit 022b05
		    == nn2Ptr->export.value.value.unsigned32) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	    
Packit 022b05
	if (! list2Ptr) {
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_ENUM) {
Packit 022b05
		if (type->parentPtr->export.name) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_ENUM_SUBTYPE_OF,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name,
Packit 022b05
					nn1Ptr->export.value.value.integer32,
Packit 022b05
					type->parentPtr->export.name);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_ENUM_SUBTYPE,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name,
Packit 022b05
					nn1Ptr->export.value.value.integer32);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if (type->export.basetype == SMI_BASETYPE_BITS) {
Packit 022b05
		if (type->parentPtr->export.name) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_BITS_SUBTYPE_OF,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name,
Packit 022b05
					type->parentPtr->export.name);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_BITS_SUBTYPE,
Packit 022b05
					type->line,
Packit 022b05
					nn1Ptr->export.name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckNamedNumbersOrder --
Packit 022b05
 *
Packit 022b05
 *      Check and normalize the order of named numbers in a bits
Packit 022b05
 *	or enumeration type.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckNamedNumbersOrder(Parser *parser, Type *type)
Packit 022b05
{
Packit 022b05
    List *listPtr, *lastPtr, *nextPtr, *ptr;
Packit 022b05
    NamedNumber *nnPtr;
Packit 022b05
    int shutup = 0;
Packit 022b05
    
Packit 022b05
    if (! type || ! type->parentPtr
Packit 022b05
	|| (type->export.basetype != SMI_BASETYPE_ENUM
Packit 022b05
	    && type->export.basetype != SMI_BASETYPE_BITS)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* Check whether the first bit has been given a name. */
Packit 022b05
Packit 022b05
    if (type->export.basetype == SMI_BASETYPE_BITS) {
Packit 022b05
	for (listPtr = type->listPtr; listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	    nnPtr = (NamedNumber *)(listPtr->ptr);
Packit 022b05
	    if (nnPtr->export.value.value.unsigned32 == 0) break;
Packit 022b05
	}
Packit 022b05
	if (! listPtr) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_BITS_ZERO_NOT_NAMED, type->line);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    lastPtr = NULL;
Packit 022b05
    for (listPtr = type->listPtr; listPtr; listPtr = nextPtr) {
Packit 022b05
Packit 022b05
	nextPtr = listPtr->nextPtr;
Packit 022b05
Packit 022b05
	nnPtr = (NamedNumber *)(listPtr->ptr);
Packit 022b05
Packit 022b05
	if (lastPtr) {
Packit 022b05
	    
Packit 022b05
	    if ((type->export.basetype == SMI_BASETYPE_ENUM) &&
Packit 022b05
		(((NamedNumber *)(listPtr->ptr))->export.value.value.integer32 <=
Packit 022b05
		 ((NamedNumber *)(lastPtr->ptr))->export.value.value.integer32)) {
Packit 022b05
		if (!shutup) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_NAMED_NUMBERS_NOT_ASCENDING,
Packit 022b05
					type->line,
Packit 022b05
					type->export.name);
Packit 022b05
		    shutup = 1;
Packit 022b05
		}
Packit 022b05
		/* remove listPtr from the list */
Packit 022b05
		lastPtr->nextPtr = listPtr->nextPtr;
Packit 022b05
		/* re-insert listPtr at the right position */
Packit 022b05
		if (((NamedNumber *)(type->listPtr->ptr))->export.value.value.integer32 > ((NamedNumber *)(listPtr->ptr))->export.value.value.integer32) {
Packit 022b05
		    listPtr->nextPtr = type->listPtr;
Packit 022b05
		    type->listPtr = listPtr;
Packit 022b05
		} else {
Packit 022b05
		    for (ptr = type->listPtr; ptr; ptr = ptr->nextPtr) {
Packit 022b05
			if ((!ptr->nextPtr) ||
Packit 022b05
			    (((NamedNumber *)(ptr->nextPtr->ptr))->export.value.value.integer32 >= ((NamedNumber *)(listPtr->ptr))->export.value.value.integer32)) {
Packit 022b05
			    listPtr->nextPtr = ptr->nextPtr;
Packit 022b05
			    ptr->nextPtr = listPtr;
Packit 022b05
			    break;
Packit 022b05
			}
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		/* set lastPtr to the last processed item */
Packit 022b05
		for (lastPtr = listPtr; lastPtr->nextPtr != nextPtr;
Packit 022b05
		     lastPtr = lastPtr->nextPtr);
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    if ((type->export.basetype == SMI_BASETYPE_BITS) &&
Packit 022b05
		(((NamedNumber *)(listPtr->ptr))->export.value.value.unsigned32 <=
Packit 022b05
		 ((NamedNumber *)(lastPtr->ptr))->export.value.value.unsigned32)) {
Packit 022b05
		if (!shutup) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_NAMED_NUMBERS_NOT_ASCENDING,
Packit 022b05
					type->line,
Packit 022b05
					type->export.name);
Packit 022b05
		    shutup = 1;
Packit 022b05
		}
Packit 022b05
		/* remove listPtr from the list */
Packit 022b05
		lastPtr->nextPtr = listPtr->nextPtr;
Packit 022b05
		/* re-insert listPtr at the right position */
Packit 022b05
		if (((NamedNumber *)(type->listPtr->ptr))->export.value.value.unsigned32 > ((NamedNumber *)(listPtr->ptr))->export.value.value.unsigned32) {
Packit 022b05
		    listPtr->nextPtr = type->listPtr;
Packit 022b05
		    type->listPtr = listPtr;
Packit 022b05
		} else {
Packit 022b05
		    for (ptr = type->listPtr; ptr; ptr = ptr->nextPtr) {
Packit 022b05
			if ((!ptr->nextPtr) ||
Packit 022b05
			    (((NamedNumber *)(ptr->nextPtr->ptr))->export.value.value.unsigned32 > ((NamedNumber *)(listPtr->ptr))->export.value.value.unsigned32)) {
Packit 022b05
			    listPtr->nextPtr = ptr->nextPtr;
Packit 022b05
			    ptr->nextPtr = listPtr;
Packit 022b05
			    break;
Packit 022b05
			}
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		/* set lastPtr to the last processed item */
Packit 022b05
		for (lastPtr = listPtr; lastPtr->nextPtr != nextPtr;
Packit 022b05
		     lastPtr = lastPtr->nextPtr);
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	lastPtr = listPtr;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckIndex --
Packit 022b05
 *
Packit 022b05
 *      Check whether an index conforms to the SMI restrictions.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckIndex(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    List *listPtr, *list2Ptr;
Packit 022b05
    Object *indexPtr;
Packit 022b05
    Type *typePtr, *rTypePtr;
Packit 022b05
    Range *rangePtr;
Packit 022b05
    NamedNumber *nnPtr;
Packit 022b05
    Node *nodePtr;
Packit 022b05
    int minSize, maxSize, len = 0;
Packit 022b05
    int aux = 0, cols = 0, acc = 0;
Packit 022b05
Packit 022b05
    for (nodePtr = object->nodePtr->firstChildPtr, cols = 0;
Packit 022b05
	 nodePtr; nodePtr = nodePtr->nextPtr) {
Packit 022b05
	cols++;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (listPtr = object->listPtr; listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	indexPtr = (Object *) listPtr->ptr;
Packit 022b05
	typePtr = indexPtr->typePtr;
Packit 022b05
Packit 022b05
	/* checkObjects() already handles unknown objects */
Packit 022b05
	if (indexPtr->export.nodekind != SMI_NODEKIND_COLUMN &&
Packit 022b05
	    ((indexPtr->flags & FLAG_INCOMPLETE) == 0)) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_INDEX_NOT_COLUMN,
Packit 022b05
				indexPtr->line,
Packit 022b05
				indexPtr->export.name,
Packit 022b05
				object->export.name);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (!typePtr)
Packit 022b05
	    continue;
Packit 022b05
	
Packit 022b05
	switch (typePtr->export.basetype) {
Packit 022b05
	case SMI_BASETYPE_INTEGER32:
Packit 022b05
	    for (rTypePtr = typePtr; rTypePtr && ! rTypePtr->listPtr;
Packit 022b05
 		 rTypePtr = rTypePtr->parentPtr) {
Packit 022b05
	    }
Packit 022b05
	    if (! rTypePtr) {
Packit 022b05
		if (object->modulePtr != indexPtr->modulePtr) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_INDEX_NO_RANGE_MOD,
Packit 022b05
					object->line,
Packit 022b05
					indexPtr->modulePtr->export.name,
Packit 022b05
					indexPtr->export.name,
Packit 022b05
					object->export.name);
Packit 022b05
Packit 022b05
		} else {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_INDEX_NO_RANGE,
Packit 022b05
					indexPtr->line,
Packit 022b05
					indexPtr->export.name,
Packit 022b05
					object->export.name);
Packit 022b05
		}
Packit 022b05
	    } else {
Packit 022b05
		for (list2Ptr = rTypePtr->listPtr;
Packit 022b05
		     list2Ptr; list2Ptr = list2Ptr->nextPtr) {
Packit 022b05
		    rangePtr = (Range *) list2Ptr->ptr;
Packit 022b05
		    if (rangePtr->export.maxValue.value.integer32 < 0) {
Packit 022b05
			smiPrintErrorAtLine(parser, ERR_INDEX_RANGE_NEGATIVE,
Packit 022b05
					    indexPtr->line,
Packit 022b05
					    indexPtr->export.name,
Packit 022b05
					    object->export.name);
Packit 022b05
			break;
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    len++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    /* TODO: We need to check ranges of parent types as well
Packit 022b05
	       if this type does not have a range restriction. */
Packit 022b05
	    for (rTypePtr = typePtr; rTypePtr && ! rTypePtr->listPtr;
Packit 022b05
		 rTypePtr = rTypePtr->parentPtr) {
Packit 022b05
	    }
Packit 022b05
	    minSize = 65535;
Packit 022b05
	    maxSize = -1;
Packit 022b05
	    if (! rTypePtr) {
Packit 022b05
		if (object->modulePtr != indexPtr->modulePtr) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_INDEX_STRING_NO_SIZE_MOD,
Packit 022b05
					object->line,
Packit 022b05
					indexPtr->modulePtr->export.name,
Packit 022b05
					indexPtr->export.name,
Packit 022b05
					object->export.name);
Packit 022b05
		} else {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_INDEX_STRING_NO_SIZE,
Packit 022b05
					indexPtr->line,
Packit 022b05
					indexPtr->export.name,
Packit 022b05
					object->export.name);
Packit 022b05
		}
Packit 022b05
		minSize = 0;
Packit 022b05
		maxSize = 65535;
Packit 022b05
	    } else {
Packit 022b05
	        for (list2Ptr = rTypePtr->listPtr;
Packit 022b05
		     list2Ptr; list2Ptr = list2Ptr->nextPtr) {
Packit 022b05
		    rangePtr = (Range *) list2Ptr->ptr;
Packit 022b05
		    if (rangePtr->export.minValue.value.integer32 < minSize) {
Packit 022b05
			minSize = rangePtr->export.minValue.value.integer32;
Packit 022b05
		    }
Packit 022b05
		    if (rangePtr->export.maxValue.value.integer32 > maxSize) {
Packit 022b05
			maxSize = rangePtr->export.maxValue.value.integer32;
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		if (minSize == 65535) {
Packit 022b05
		    minSize = 0;
Packit 022b05
		}
Packit 022b05
		if (maxSize < 0) {
Packit 022b05
		    maxSize = 65535;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    len += maxSize;
Packit 022b05
	    if (minSize != maxSize) {
Packit 022b05
		if (! (object->export.implied && (! listPtr->nextPtr))) {
Packit 022b05
		    len++;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	    if (object->modulePtr != indexPtr->modulePtr) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_INDEX_OID_NO_SIZE_MOD,
Packit 022b05
				    object->line,
Packit 022b05
				    indexPtr->modulePtr->export.name,
Packit 022b05
				    indexPtr->export.name,
Packit 022b05
				    object->export.name);
Packit 022b05
	    } else {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_INDEX_OID_NO_SIZE,
Packit 022b05
				    indexPtr->line,
Packit 022b05
				    indexPtr->export.name,
Packit 022b05
				    object->export.name);
Packit 022b05
	    }
Packit 022b05
	    len += 128;
Packit 022b05
	    if (!indexPtr->export.implied) {
Packit 022b05
		len++;
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	    len++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_INTEGER64:
Packit 022b05
	case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	case SMI_BASETYPE_FLOAT32:
Packit 022b05
	case SMI_BASETYPE_FLOAT64:
Packit 022b05
	case SMI_BASETYPE_FLOAT128:
Packit 022b05
	case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_INDEX_BASETYPE, object->line,
Packit 022b05
				typePtr->export.name ? typePtr->export.name
Packit 022b05
				                     : "[unknown]",
Packit 022b05
				indexPtr->export.name, object->export.name);
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_BITS:
Packit 022b05
	    /* TODO: BITS are somehow treated as octet strings - but
Packit 022b05
	       what is the max len? */
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_ENUM:
Packit 022b05
	    for (list2Ptr = typePtr->listPtr;
Packit 022b05
		 list2Ptr; list2Ptr = list2Ptr->nextPtr) {
Packit 022b05
		
Packit 022b05
		nnPtr = (NamedNumber *)(list2Ptr->ptr);
Packit 022b05
Packit 022b05
		if (nnPtr->export.value.value.integer32 < 0) {
Packit 022b05
			smiPrintErrorAtLine(parser, ERR_INDEX_ENUM_NEGATIVE,
Packit 022b05
					    indexPtr->line,
Packit 022b05
					    indexPtr->export.name,
Packit 022b05
					    object->export.name);
Packit 022b05
			break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    len++;
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (indexPtr->export.value.basetype != SMI_BASETYPE_UNKNOWN) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_INDEX_DEFVAL,
Packit 022b05
				indexPtr->line,
Packit 022b05
				indexPtr->export.name,
Packit 022b05
				object->export.name);
Packit 022b05
	}
Packit 022b05
Packit 022b05
    	for (nodePtr = object->nodePtr->firstChildPtr;
Packit 022b05
	     nodePtr; nodePtr = nodePtr->nextPtr) {
Packit 022b05
	    if (indexPtr == nodePtr->lastObjectPtr) {
Packit 022b05
		aux++;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->export.oidlen + 1 + len > 128) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_INDEX_TOO_LARGE, object->line,
Packit 022b05
			    object->export.name,
Packit 022b05
			    (object->export.oidlen + 1 + len) - 128);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* RFC 2578 section 7.7: Auxiliary objects must be not-accessible except
Packit 022b05
       in some interesting corner cases. */
Packit 022b05
Packit 022b05
    for (listPtr = object->listPtr; listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	indexPtr = (Object *) listPtr->ptr;
Packit 022b05
	typePtr = indexPtr->typePtr;
Packit 022b05
Packit 022b05
	if (aux < cols) {
Packit 022b05
	    if ((parser->modulePtr->export.language == SMI_LANGUAGE_SMIV2)
Packit 022b05
		&& (indexPtr->nodePtr->parentPtr == object->nodePtr)) {
Packit 022b05
		if (indexPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE) {
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_INDEX_ACCESSIBLE,
Packit 022b05
					object->line,
Packit 022b05
					indexPtr->export.name, object->export.name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	for (nodePtr = object->nodePtr->firstChildPtr, acc = 0;
Packit 022b05
	     nodePtr; nodePtr = nodePtr->nextPtr) {
Packit 022b05
	    if (indexPtr == nodePtr->lastObjectPtr
Packit 022b05
		&& indexPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE) {
Packit 022b05
		acc++;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if ((parser->modulePtr->export.language == SMI_LANGUAGE_SMIV2)
Packit 022b05
	&& aux == cols && acc != 1) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_INDEX_NON_ACCESSIBLE,
Packit 022b05
			    object->line, object->export.name);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckAugment --
Packit 022b05
 *
Packit 022b05
 *      Check whether a table augmentation conforms to the SMI
Packit 022b05
 *	restrictions.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckAugment(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    if (! object->relatedPtr) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->relatedPtr->export.nodekind != SMI_NODEKIND_ROW) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_AUGMENT_NO_ROW, object->line,
Packit 022b05
			    object->export.name,
Packit 022b05
			    object->relatedPtr->export.name);
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (object->relatedPtr->export.indexkind == SMI_INDEX_INDEX)
Packit 022b05
        return;
Packit 022b05
    
Packit 022b05
    if (object->export.indexkind == SMI_INDEX_AUGMENT)
Packit 022b05
    {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_AUGMENT_NESTED, object->line,
Packit 022b05
			    object->export.name,
Packit 022b05
			    object->relatedPtr->export.name);
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (object->relatedPtr->export.indexkind != SMI_INDEX_SPARSE) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_EXTENDS_WRONG_ROW_TYPE, object->line,
Packit 022b05
			    object->export.name,
Packit 022b05
			    object->relatedPtr->export.name);
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /*
Packit 022b05
     * TODO: Check the size of the instance identifier and the OID
Packit 022b05
     * for this entry node.
Packit 022b05
     */
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckTypeRanges --
Packit 022b05
 *
Packit 022b05
 *      Check whether all ranges of a given type are valid.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckTypeRanges(Parser *parser, Type *type)
Packit 022b05
{
Packit 022b05
    List *p, *nextPtr, *pp, *nextPP;
Packit 022b05
    
Packit 022b05
    for (p = type->listPtr; p; p = nextPtr) {
Packit 022b05
Packit 022b05
	nextPtr = p->nextPtr;
Packit 022b05
	
Packit 022b05
	((Range *)p->ptr)->typePtr = type;
Packit 022b05
Packit 022b05
	if (type->export.basetype == SMI_BASETYPE_INTEGER32) {
Packit 022b05
	    if ((((Range *)p->ptr)->export.minValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
		(((Range *)p->ptr)->export.minValue.value.unsigned32 >
Packit 022b05
		    2147483647)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    if ((((Range *)p->ptr)->export.maxValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
		(((Range *)p->ptr)->export.maxValue.value.unsigned32 >
Packit 022b05
		    2147483647)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    ((Range *)p->ptr)->export.minValue.basetype =
Packit 022b05
		SMI_BASETYPE_INTEGER32;
Packit 022b05
	    ((Range *)p->ptr)->export.maxValue.basetype =
Packit 022b05
		SMI_BASETYPE_INTEGER32;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (type->export.basetype == SMI_BASETYPE_UNSIGNED32) {
Packit 022b05
	    if ((((Range *)p->ptr)->export.minValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_INTEGER32) &&
Packit 022b05
		(((Range *)p->ptr)->export.minValue.value.integer32 < 0)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    if ((((Range *)p->ptr)->export.maxValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_INTEGER32) &&
Packit 022b05
		(((Range *)p->ptr)->export.maxValue.value.integer32 < 0)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    ((Range *)p->ptr)->export.minValue.basetype =
Packit 022b05
		SMI_BASETYPE_UNSIGNED32;
Packit 022b05
	    ((Range *)p->ptr)->export.maxValue.basetype =
Packit 022b05
		SMI_BASETYPE_UNSIGNED32;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (type->export.basetype == SMI_BASETYPE_OCTETSTRING) {
Packit 022b05
	    if ((((Range *)p->ptr)->export.minValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_INTEGER32) &&
Packit 022b05
		(((Range *)p->ptr)->export.minValue.value.integer32 < 0)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    if ((((Range *)p->ptr)->export.maxValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_INTEGER32) &&
Packit 022b05
		(((Range *)p->ptr)->export.maxValue.value.integer32 < 0)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    if ((((Range *)p->ptr)->export.minValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
		(((Range *)p->ptr)->export.minValue.value.unsigned32 > 65535)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    if ((((Range *)p->ptr)->export.maxValue.basetype ==
Packit 022b05
		 SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
		(((Range *)p->ptr)->export.maxValue.value.unsigned32 > 65535)) {
Packit 022b05
		smiPrintError(parser, ERR_RANGE_OUT_OF_BASETYPE);
Packit 022b05
	    }
Packit 022b05
	    ((Range *)p->ptr)->export.minValue.basetype =
Packit 022b05
		SMI_BASETYPE_UNSIGNED32;
Packit 022b05
	    ((Range *)p->ptr)->export.maxValue.basetype =
Packit 022b05
		SMI_BASETYPE_UNSIGNED32;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (compareValues(&((Range *)p->ptr)->export.minValue,
Packit 022b05
			  &((Range *)p->ptr)->export.maxValue) > 0) {
Packit 022b05
	    SmiValue v;
Packit 022b05
	    v = ((Range *)p->ptr)->export.minValue;
Packit 022b05
	    ((Range *)p->ptr)->export.minValue = ((Range *)p->ptr)->export.maxValue;
Packit 022b05
	    ((Range *)p->ptr)->export.maxValue = v;
Packit 022b05
	    smiPrintError(parser, ERR_EXCHANGED_RANGE_LIMITS);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	/* sort */
Packit 022b05
	p->nextPtr = NULL;
Packit 022b05
	if (p != type->listPtr) {
Packit 022b05
	    if (compareValues(&((Range *)p->ptr)->export.minValue,
Packit 022b05
	      	       &((Range *)type->listPtr->ptr)->export.minValue) <= 0) {
Packit 022b05
		if (compareValues(&((Range *)p->ptr)->export.maxValue,
Packit 022b05
	      	       &((Range *)type->listPtr->ptr)->export.minValue) >= 0) {
Packit 022b05
		    smiPrintError(parser, ERR_RANGE_OVERLAP);
Packit 022b05
		}
Packit 022b05
		smiPrintError(parser, ERR_RANGES_NOT_ASCENDING);
Packit 022b05
		p->nextPtr = type->listPtr;
Packit 022b05
		type->listPtr = p;
Packit 022b05
	    } else {
Packit 022b05
		for (pp = type->listPtr; pp; pp = nextPP) {
Packit 022b05
		    nextPP = pp->nextPtr;
Packit 022b05
		    if ((!nextPP) ||
Packit 022b05
			(compareValues(&((Range *)p->ptr)->export.minValue,
Packit 022b05
			     &((Range *)nextPP->ptr)->export.minValue) <= 0)) {
Packit 022b05
			if (((nextPP) &&
Packit 022b05
			     (compareValues(&((Range *)p->ptr)->export.maxValue,
Packit 022b05
					    &((Range *)nextPP->ptr)->export.minValue) >= 0)) ||
Packit 022b05
			    (compareValues(&((Range *)p->ptr)->export.minValue,
Packit 022b05
					   &((Range *)pp->ptr)->export.maxValue) <= 0)) {
Packit 022b05
			    smiPrintError(parser, ERR_RANGE_OVERLAP);
Packit 022b05
			}
Packit 022b05
			p->nextPtr = pp->nextPtr;
Packit 022b05
			pp->nextPtr = p;
Packit 022b05
			if (p->nextPtr) {
Packit 022b05
			    smiPrintError(parser, ERR_RANGES_NOT_ASCENDING);
Packit 022b05
			    pp->nextPtr = NULL;
Packit 022b05
			} 
Packit 022b05
			break;
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* range normalization */
Packit 022b05
    for (p = type->listPtr, pp = p; p; p = nextPtr) {
Packit 022b05
	nextPtr = p->nextPtr;
Packit 022b05
	if (nextPtr &&
Packit 022b05
	    compareValues(&((Range *)p->ptr)->export.maxValue,
Packit 022b05
			  &((Range *)nextPtr->ptr)->export.minValue) == -1) {
Packit 022b05
	    ((Range *)nextPtr->ptr)->export.minValue =
Packit 022b05
		((Range *)p->ptr)->export.minValue;
Packit 022b05
	    if (p == type->listPtr) {
Packit 022b05
		type->listPtr = nextPtr;
Packit 022b05
		pp = nextPtr;
Packit 022b05
	    } else {
Packit 022b05
		pp->nextPtr = nextPtr;
Packit 022b05
	    }
Packit 022b05
	    smiFree(p);
Packit 022b05
	} else {
Packit 022b05
	    pp = p;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckTypeFormat --
Packit 022b05
 *
Packit 022b05
 *      Check whether we know a format specification for integer types.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckTypeFormat(Parser *parser, Type *type)
Packit 022b05
{
Packit 022b05
    Type *t;
Packit 022b05
    
Packit 022b05
    if (! type || !type->export.name) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (type->export.basetype != SMI_BASETYPE_INTEGER32
Packit 022b05
	&& type->export.basetype != SMI_BASETYPE_INTEGER64
Packit 022b05
	&& type->export.basetype != SMI_BASETYPE_UNSIGNED32
Packit 022b05
	&& type->export.basetype != SMI_BASETYPE_UNSIGNED64
Packit 022b05
	&& type->export.basetype != SMI_BASETYPE_OCTETSTRING) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (t = type; t; t = t->parentPtr) {
Packit 022b05
	if (t->export.format) {
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! t) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_TYPE_WITHOUT_FORMAT, type->line,
Packit 022b05
			    type->export.name);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckValueType --
Packit 022b05
 *
Packit 022b05
 *      Check whether a given value matches a given type.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckValueType(Parser *parser, SmiValue *value, Type *type, int line)
Packit 022b05
{
Packit 022b05
    List *p, *nextPtr;
Packit 022b05
    
Packit 022b05
    if (value && (value->basetype != SMI_BASETYPE_UNKNOWN) && type) {
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * If defval type and object type don't match, check whether
Packit 022b05
	 * the defval value is in the allowed range of the object's basetype.
Packit 022b05
	 */
Packit 022b05
	if ((type->export.basetype == SMI_BASETYPE_INTEGER32) ||
Packit 022b05
	    (type->export.basetype == SMI_BASETYPE_ENUM)) {
Packit 022b05
	    if (((value->basetype == SMI_BASETYPE_INTEGER64) &&
Packit 022b05
		 ((value->value.integer64 < (SmiInteger64)(-2147483647 - 1)) ||
Packit 022b05
		  (value->value.integer64 > (SmiInteger64)2147483647))) ||
Packit 022b05
		((value->basetype == SMI_BASETYPE_UNSIGNED32) &&
Packit 022b05
		 ((value->value.unsigned32 > 2147483647))) ||
Packit 022b05
		((value->basetype == SMI_BASETYPE_UNSIGNED64) &&
Packit 022b05
		 ((value->value.unsigned32 > 2147483647)))) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_DEFVAL_OUT_OF_BASETYPE, line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (type->export.basetype == SMI_BASETYPE_UNSIGNED32) {
Packit 022b05
	    if (((value->basetype == SMI_BASETYPE_INTEGER64) &&
Packit 022b05
		 ((value->value.integer64 < 0) ||
Packit 022b05
		  (value->value.integer64 > (SmiInteger64)4294967295UL))) ||
Packit 022b05
		((value->basetype == SMI_BASETYPE_INTEGER32) &&
Packit 022b05
		 ((value->value.integer32 < 0))) ||
Packit 022b05
		((value->basetype == SMI_BASETYPE_UNSIGNED64) &&
Packit 022b05
		 ((value->value.unsigned32 > (SmiUnsigned32)4294967295UL)))) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_DEFVAL_OUT_OF_BASETYPE, line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * "cast" the defval to the object's basetype.
Packit 022b05
	 */
Packit 022b05
	value->basetype = type->export.basetype;
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * check whether the defval matches the object's range restriction.
Packit 022b05
	 */
Packit 022b05
	if ((value->basetype == SMI_BASETYPE_UNSIGNED32) ||
Packit 022b05
	    (value->basetype == SMI_BASETYPE_UNSIGNED64) ||
Packit 022b05
	    (value->basetype == SMI_BASETYPE_INTEGER32) ||
Packit 022b05
	    (value->basetype == SMI_BASETYPE_INTEGER64)) {
Packit 022b05
	    for (p = type->listPtr; p; p = nextPtr) {
Packit 022b05
		nextPtr = p->nextPtr;
Packit 022b05
		if ((compareValues(&((Range *)p->ptr)->export.minValue,
Packit 022b05
				   value) <= 0) &&
Packit 022b05
		    (compareValues(&((Range *)p->ptr)->export.maxValue,
Packit 022b05
				   value) >= 0)) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if ((p == NULL) && type->listPtr) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_DEFVAL_OUT_OF_RANGE, line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * check whether the defval matches the object's enumeration.
Packit 022b05
	 */
Packit 022b05
	if (value->basetype == SMI_BASETYPE_ENUM) {
Packit 022b05
	    for (p = type->listPtr; p; p = nextPtr) {
Packit 022b05
		nextPtr = p->nextPtr;
Packit 022b05
Packit 022b05
		if (((NamedNumber *)(p->ptr))->export.value.value.integer32 ==
Packit 022b05
		    value->value.integer32) {
Packit 022b05
			break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if (p == NULL) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_DEFVAL_OUT_OF_ENUM, line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckDefault --
Packit 022b05
 *
Packit 022b05
 *      Check whether the default value (if present) matches the
Packit 022b05
 *	underlying type and restrictions.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckDefault(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    smiCheckValueType(parser, &object->export.value, object->typePtr,
Packit 022b05
		      object->line);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckTypeUsage --
Packit 022b05
 *
Packit 022b05
 *      Check whether the types of all objects are used appropriately.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
static void
Packit 022b05
checkInetAddressType(Parser *parserPtr, Module *modulePtr, Object *objectPtr)
Packit 022b05
{
Packit 022b05
    Module *inetModulePtr = NULL;		/* RFC 3291 */
Packit 022b05
    Type *inetAddressTypePtr = NULL;		/* RFC 3291 */
Packit 022b05
    Type *inetAddressPtr = NULL;		/* RFC 3291 */
Packit 022b05
    Node *nodePtr;
Packit 022b05
    List *listPtr = NULL;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    const char *protected[] = {
Packit 022b05
	"InetAddressIPv4", "InetAddressIPv6",
Packit 022b05
	"InetAddressIPv4z", "InetAddressIPv6z",
Packit 022b05
	"InetAddressDNS", NULL
Packit 022b05
    };
Packit 022b05
Packit 022b05
    inetModulePtr = findModuleByName("INET-ADDRESS-MIB");
Packit 022b05
    if (! inetModulePtr) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    inetAddressTypePtr = findTypeByModuleAndName(inetModulePtr,
Packit 022b05
						 "InetAddressType");
Packit 022b05
    inetAddressPtr = findTypeByModuleAndName(inetModulePtr,
Packit 022b05
					     "InetAddress");
Packit 022b05
    
Packit 022b05
    if (!inetAddressTypePtr || !inetAddressPtr) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /* check InetAddressType/InetAddress pair */
Packit 022b05
    if (smiTypeDerivedFrom(objectPtr->typePtr, inetAddressPtr)) {
Packit 022b05
	Object *indexObject = NULL;
Packit 022b05
	Object *entryObject = objectPtr->nodePtr->parentPtr->lastObjectPtr;
Packit 022b05
	if (entryObject) {
Packit 022b05
	    switch (entryObject->export.indexkind) {
Packit 022b05
	    case SMI_INDEX_INDEX:
Packit 022b05
		indexObject = entryObject;
Packit 022b05
		break;
Packit 022b05
	    case SMI_INDEX_AUGMENT:
Packit 022b05
		indexObject = entryObject->relatedPtr;
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		/* xxx need to handle other index constructions */
Packit 022b05
		indexObject = NULL;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (indexObject) {
Packit 022b05
	    for (listPtr = indexObject->listPtr; listPtr;
Packit 022b05
		 listPtr = listPtr->nextPtr) {
Packit 022b05
		Object *iObject = (Object *) listPtr->ptr;
Packit 022b05
		if (iObject
Packit 022b05
		    && iObject->typePtr == inetAddressTypePtr) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	}
Packit 022b05
	if (! indexObject || ! listPtr) {
Packit 022b05
	    for (nodePtr =
Packit 022b05
		     objectPtr->nodePtr->parentPtr->firstChildPtr;
Packit 022b05
		 nodePtr &&
Packit 022b05
		     nodePtr->subid < objectPtr->nodePtr->subid &&
Packit 022b05
		     nodePtr->lastObjectPtr->typePtr !=
Packit 022b05
		     inetAddressTypePtr;
Packit 022b05
		 nodePtr = nodePtr->nextPtr);
Packit 022b05
	    if (!nodePtr ||
Packit 022b05
		nodePtr->subid >= objectPtr->nodePtr->subid) {
Packit 022b05
		smiPrintErrorAtLine(parserPtr,
Packit 022b05
				    ERR_INETADDRESS_WITHOUT_TYPE,
Packit 022b05
				    objectPtr->line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /* check InetAddressType subtyping */
Packit 022b05
    if (objectPtr->typePtr->parentPtr == inetAddressTypePtr) {
Packit 022b05
	smiPrintErrorAtLine(parserPtr,
Packit 022b05
			    ERR_INETADDRESSTYPE_SUBTYPED,
Packit 022b05
			    objectPtr->line);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* check for TCs that should not be used directly */
Packit 022b05
    for (i = 0; protected[i]; i++) {
Packit 022b05
	if (objectPtr->typePtr == findTypeByModuleAndName(inetModulePtr,
Packit 022b05
							  protected[i])) {
Packit 022b05
	    smiPrintErrorAtLine(parserPtr,
Packit 022b05
				ERR_INETADDRESS_SPECIFIC,
Packit 022b05
				objectPtr->line,
Packit 022b05
				objectPtr->typePtr->export.name);
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
checkTransportAddressType(Parser *parserPtr, Module *modulePtr, Object *objectPtr)
Packit 022b05
{
Packit 022b05
    Module *transportModulePtr = NULL;		/* RFC 3419 */
Packit 022b05
    Type *transportAddressTypePtr = NULL;	/* RFC 3419 */
Packit 022b05
    Type *transportAddressPtr = NULL;		/* RFC 3419 */
Packit 022b05
    Type *transportDomainPtr = NULL;		/* RFC 3419 */
Packit 022b05
    Node *nodePtr;
Packit 022b05
    List *listPtr = NULL;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    const char *protected[] = {
Packit 022b05
	"TransportAddressIPv4", "TransportAddressIPv6",
Packit 022b05
	"TransportAddressIPv4z", "TransportAddressIPv6z",
Packit 022b05
	"TransportAddressDNS", "TransportAddressLocal",
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
Packit 022b05
    transportModulePtr = findModuleByName("TRANSPORT-ADDRESS-MIB");
Packit 022b05
    if (! transportModulePtr) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    transportAddressTypePtr = findTypeByModuleAndName(transportModulePtr,
Packit 022b05
						 "TransportAddressType");
Packit 022b05
    transportAddressPtr = findTypeByModuleAndName(transportModulePtr,
Packit 022b05
					     "TransportAddress");
Packit 022b05
    transportDomainPtr = findTypeByModuleAndName(transportModulePtr,
Packit 022b05
						 "TransportDomain");
Packit 022b05
Packit 022b05
    if (!transportAddressTypePtr || !transportAddressPtr || !transportDomainPtr) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /* check TransportAddressType/TransportAddress pair */
Packit 022b05
    if (smiTypeDerivedFrom(objectPtr->typePtr, transportAddressPtr)) {
Packit 022b05
	Object *indexObject = NULL;
Packit 022b05
	Object *entryObject = objectPtr->nodePtr->parentPtr->lastObjectPtr;
Packit 022b05
	if (entryObject) {
Packit 022b05
	    switch (entryObject->export.indexkind) {
Packit 022b05
	    case SMI_INDEX_INDEX:
Packit 022b05
		indexObject = entryObject;
Packit 022b05
		break;
Packit 022b05
	    case SMI_INDEX_AUGMENT:
Packit 022b05
		indexObject = entryObject->relatedPtr;
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		/* xxx need to handle other index constructions */
Packit 022b05
		indexObject = NULL;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (indexObject) {
Packit 022b05
	    for (listPtr = indexObject->listPtr; listPtr;
Packit 022b05
		 listPtr = listPtr->nextPtr) {
Packit 022b05
		Object *iObject = (Object *) listPtr->ptr;
Packit 022b05
		if (iObject
Packit 022b05
		    && (iObject->typePtr == transportAddressTypePtr
Packit 022b05
			|| iObject->typePtr == transportDomainPtr)) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (! indexObject || ! listPtr) {
Packit 022b05
	    for (nodePtr =
Packit 022b05
		     objectPtr->nodePtr->parentPtr->firstChildPtr;
Packit 022b05
		 nodePtr &&
Packit 022b05
		     nodePtr->subid < objectPtr->nodePtr->subid &&
Packit 022b05
		     nodePtr->lastObjectPtr->typePtr !=
Packit 022b05
		     transportAddressTypePtr &&
Packit 022b05
		     nodePtr->lastObjectPtr->typePtr !=
Packit 022b05
		     transportDomainPtr;
Packit 022b05
		 nodePtr = nodePtr->nextPtr);
Packit 022b05
	    if (!nodePtr ||
Packit 022b05
		nodePtr->subid >= objectPtr->nodePtr->subid) {
Packit 022b05
		smiPrintErrorAtLine(parserPtr,
Packit 022b05
				    ERR_TRANSPORTADDRESS_WITHOUT_TYPE,
Packit 022b05
				    objectPtr->line);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /* check TransportAddressType subtyping */
Packit 022b05
    if (objectPtr->typePtr->parentPtr == transportAddressTypePtr) {
Packit 022b05
	smiPrintErrorAtLine(parserPtr,
Packit 022b05
			    ERR_TRANSPORTADDRESSTYPE_SUBTYPED,
Packit 022b05
			    objectPtr->line);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* check for TCs that should not be used directly */
Packit 022b05
    for (i = 0; protected[i]; i++) {
Packit 022b05
	if (objectPtr->typePtr == findTypeByModuleAndName(transportModulePtr,
Packit 022b05
							  protected[i])) {
Packit 022b05
	    smiPrintErrorAtLine(parserPtr,
Packit 022b05
				ERR_TRANSPORTADDRESS_SPECIFIC,
Packit 022b05
				objectPtr->line,
Packit 022b05
				objectPtr->typePtr->export.name);
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckTypeUsage(Parser *parserPtr, Module *modulePtr)
Packit 022b05
{
Packit 022b05
    Object *objectPtr;
Packit 022b05
    Module *tcModulePtr = NULL;
Packit 022b05
    Type *rowStatusPtr = NULL;
Packit 022b05
    Type *storageTypePtr = NULL;
Packit 022b05
    Type *taddressPtr = NULL;
Packit 022b05
    Type *tdomainPtr = NULL;
Packit 022b05
    NamedNumber *nnPtr;
Packit 022b05
    Node *nodePtr;
Packit 022b05
    
Packit 022b05
    tcModulePtr = findModuleByName("SNMPv2-TC");
Packit 022b05
    if (tcModulePtr) {
Packit 022b05
	rowStatusPtr = findTypeByModuleAndName(tcModulePtr, "RowStatus");
Packit 022b05
	storageTypePtr = findTypeByModuleAndName(tcModulePtr, "StorageType");
Packit 022b05
	taddressPtr = findTypeByModuleAndName(tcModulePtr, "TAddress");
Packit 022b05
	tdomainPtr = findTypeByModuleAndName(tcModulePtr, "TDomain");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (objectPtr = modulePtr->firstObjectPtr;
Packit 022b05
	 objectPtr; objectPtr = objectPtr->nextPtr) {
Packit 022b05
Packit 022b05
	if (objectPtr->typePtr) {
Packit 022b05
Packit 022b05
	    if (tcModulePtr) {
Packit 022b05
Packit 022b05
		/* check RowStatus DEFVAL */
Packit 022b05
		if (objectPtr->typePtr == rowStatusPtr) {
Packit 022b05
		    if ((objectPtr->export.value.value.integer32 >= 4) &&
Packit 022b05
			(objectPtr->export.value.value.integer32 <= 6)) {
Packit 022b05
			nnPtr = findTypeNamedNumber(rowStatusPtr,
Packit 022b05
				     objectPtr->export.value.value.integer32);
Packit 022b05
			smiPrintErrorAtLine(parserPtr,
Packit 022b05
					    ERR_ILLEGAL_ROWSTATUS_DEFAULT,
Packit 022b05
					    objectPtr->line,
Packit 022b05
					    nnPtr->export.name);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
Packit 022b05
		/* check RowStatus read-create status */
Packit 022b05
		if (objectPtr->typePtr == rowStatusPtr) {
Packit 022b05
		    Object *entryObject
Packit 022b05
			= objectPtr->nodePtr->parentPtr->lastObjectPtr;
Packit 022b05
		    if (objectPtr->export.access != SMI_ACCESS_READ_WRITE
Packit 022b05
			|| !entryObject->export.create) {
Packit 022b05
			smiPrintErrorAtLine(parserPtr,
Packit 022b05
					    ERR_ILLEGAL_ROWSTATUS_ACCESS,
Packit 022b05
					    objectPtr->line);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		/* check StorageType DEFVAL */
Packit 022b05
		if (objectPtr->typePtr == storageTypePtr) {
Packit 022b05
		    if ((objectPtr->export.value.value.integer32 >= 4) &&
Packit 022b05
			(objectPtr->export.value.value.integer32 <= 5)) {
Packit 022b05
			nnPtr = findTypeNamedNumber(storageTypePtr,
Packit 022b05
				     objectPtr->export.value.value.integer32);
Packit 022b05
			smiPrintErrorAtLine(parserPtr,
Packit 022b05
					    ERR_ILLEGAL_STORAGETYPE_DEFAULT,
Packit 022b05
					    objectPtr->line,
Packit 022b05
					    nnPtr->export.name);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
Packit 022b05
		/* check TDomain/TAddress pair */
Packit 022b05
		if (smiTypeDerivedFrom(objectPtr->typePtr, taddressPtr)) {
Packit 022b05
		    for (nodePtr =
Packit 022b05
			     objectPtr->nodePtr->parentPtr->firstChildPtr;
Packit 022b05
			 nodePtr &&
Packit 022b05
			     nodePtr->lastObjectPtr->typePtr != tdomainPtr;
Packit 022b05
			 nodePtr = nodePtr->nextPtr);
Packit 022b05
		    if (!nodePtr ||
Packit 022b05
			nodePtr->lastObjectPtr->typePtr != tdomainPtr) {
Packit 022b05
			smiPrintErrorAtLine(parserPtr,
Packit 022b05
					    ERR_TADDRESS_WITHOUT_TDOMAIN,
Packit 022b05
					    objectPtr->line);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
	    }
Packit 022b05
	    checkInetAddressType(parserPtr, modulePtr, objectPtr);
Packit 022b05
	    checkTransportAddressType(parserPtr, modulePtr, objectPtr);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static char *status[] = { "Unknown", "current", "deprecated",
Packit 022b05
			  "mandatory", "optional", "obsolete" };
Packit 022b05
Packit 022b05
static int
Packit 022b05
memberOfGroup(Object *object, Object *group)
Packit 022b05
{
Packit 022b05
    List *listPtr;
Packit 022b05
Packit 022b05
    for (listPtr = group->listPtr; listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	if (listPtr->ptr == object) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckComplianceStatus --
Packit 022b05
 *
Packit 022b05
 *      Make sure that all groups and objects in a compliance statement
Packit 022b05
 *      are at least as current as the compliance itself.
Packit 022b05
 *      XXX I'm not sure I traversed the whole compliance statement,
Packit 022b05
 *          this at least covers the common case
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckComplianceStatus(Parser *parser, Object *compliance)
Packit 022b05
{
Packit 022b05
    List *listPtr, *groupListPtr;
Packit 022b05
    Object *memberPtr;
Packit 022b05
    Object *group;
Packit 022b05
Packit 022b05
    for (listPtr = compliance->listPtr;
Packit 022b05
	 listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	memberPtr = (Object *) listPtr->ptr;
Packit 022b05
	if (!memberPtr)
Packit 022b05
	    continue;
Packit 022b05
	addObjectFlags(memberPtr, FLAG_INCOMPLIANCE);
Packit 022b05
	if (memberPtr->export.status > compliance->export.status) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_COMPLIANCE_GROUP_STATUS,
Packit 022b05
				compliance->line,
Packit 022b05
				status[compliance->export.status],
Packit 022b05
				compliance->export.name,
Packit 022b05
				status[memberPtr->export.status],
Packit 022b05
				memberPtr->export.name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    for (listPtr = compliance->optionlistPtr;
Packit 022b05
	 listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	memberPtr = ((Option *) listPtr->ptr)->objectPtr;
Packit 022b05
	addObjectFlags(memberPtr, FLAG_INCOMPLIANCE);
Packit 022b05
	if (memberPtr->export.status > compliance->export.status) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_COMPLIANCE_GROUP_STATUS,
Packit 022b05
				((Option *) listPtr->ptr)->line,
Packit 022b05
				status[compliance->export.status],
Packit 022b05
				compliance->export.name,
Packit 022b05
				status[memberPtr->export.status],
Packit 022b05
				memberPtr->export.name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    for (listPtr = compliance->refinementlistPtr;
Packit 022b05
	 listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	memberPtr = ((Refinement *) listPtr->ptr)->objectPtr;
Packit 022b05
Packit 022b05
	for (groupListPtr = compliance->listPtr;
Packit 022b05
	     groupListPtr; groupListPtr = groupListPtr->nextPtr) {
Packit 022b05
Packit 022b05
	    group = (Object *) groupListPtr->ptr;
Packit 022b05
	    if (group && memberOfGroup(memberPtr, group)) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! groupListPtr) {
Packit 022b05
	    for (groupListPtr = compliance->optionlistPtr;
Packit 022b05
		 groupListPtr; groupListPtr = groupListPtr->nextPtr) {
Packit 022b05
Packit 022b05
		group = ((Option *) groupListPtr->ptr)->objectPtr;
Packit 022b05
		if (group && memberOfGroup(memberPtr, group)) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! groupListPtr) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_REFINEMENT_NOT_LISTED,
Packit 022b05
				((Refinement *) listPtr->ptr)->line,
Packit 022b05
				memberPtr->export.name);
Packit 022b05
	}
Packit 022b05
		
Packit 022b05
	addObjectFlags(memberPtr, FLAG_INCOMPLIANCE);
Packit 022b05
	if (memberPtr->export.status > compliance->export.status) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_COMPLIANCE_OBJECT_STATUS,
Packit 022b05
				((Refinement *) listPtr->ptr)->line,
Packit 022b05
				status[compliance->export.status],
Packit 022b05
				compliance->export.name,
Packit 022b05
				status[memberPtr->export.status],
Packit 022b05
				memberPtr->export.name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckGroupMembers --
Packit 022b05
 *
Packit 022b05
 *      Check whether only scalar and column nodes and notifications
Packit 022b05
 *	are contained in a conformance group.
Packit 022b05
 *
Packit 022b05
 *      Also ensure that group members are at least as current
Packit 022b05
 *      as the group itself.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckGroupMembers(Parser *parser, Object *group)
Packit 022b05
{
Packit 022b05
    List *listPtr;
Packit 022b05
    Object *memberPtr;
Packit 022b05
    int scalarsOrColumns = 0;
Packit 022b05
    int notifications = 0;
Packit 022b05
    
Packit 022b05
    for (listPtr = group->listPtr;
Packit 022b05
	 listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	memberPtr = (Object *) listPtr->ptr;
Packit 022b05
Packit 022b05
	if (((memberPtr->export.nodekind == SMI_NODEKIND_COLUMN
Packit 022b05
	      || memberPtr->export.nodekind == SMI_NODEKIND_SCALAR)
Packit 022b05
	     && memberPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE)
Packit 022b05
	    || memberPtr->export.nodekind == SMI_NODEKIND_NOTIFICATION) {
Packit 022b05
	    if (memberPtr->export.nodekind == SMI_NODEKIND_NOTIFICATION) {
Packit 022b05
		notifications++;
Packit 022b05
		if (group->export.decl == SMI_DECL_OBJECTGROUP) {
Packit 022b05
		    smiPrintErrorAtLine(parser,
Packit 022b05
					ERR_NOTIFICATION_IN_OBJECT_GROUP,
Packit 022b05
					group->line,
Packit 022b05
					group->export.name,
Packit 022b05
					memberPtr->export.name);
Packit 022b05
		}
Packit 022b05
	    } else {
Packit 022b05
		scalarsOrColumns++;
Packit 022b05
		if (group->export.decl == SMI_DECL_NOTIFICATIONGROUP) {
Packit 022b05
		    smiPrintErrorAtLine(parser,
Packit 022b05
					ERR_OBJECT_IN_NOTIFICATION_GROUP,
Packit 022b05
					group->line,
Packit 022b05
					group->export.name,
Packit 022b05
					memberPtr->export.name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    addObjectFlags(memberPtr, FLAG_INGROUP);
Packit 022b05
	} else if (!(memberPtr->flags & FLAG_INCOMPLETE)) {
Packit 022b05
	    /* unknown OIDs are already flagged */
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_INVALID_GROUP_MEMBER,
Packit 022b05
				group->line,
Packit 022b05
				memberPtr->export.name,
Packit 022b05
				group->export.name);
Packit 022b05
	}
Packit 022b05
	if (memberPtr->export.status > group->export.status) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_GROUP_OBJECT_STATUS,
Packit 022b05
				group->line,
Packit 022b05
				status[group->export.status],
Packit 022b05
				group->export.name,
Packit 022b05
				status[memberPtr->export.status],
Packit 022b05
				memberPtr->export.name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (scalarsOrColumns && notifications) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_MIXED_GROUP_MEMBERS,
Packit 022b05
			    group->line,
Packit 022b05
			    group->export.name);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckGroupMembership --
Packit 022b05
 *
Packit 022b05
 *      Check whether scalar and column nodes and notifications are
Packit 022b05
 *	contained in at least one conformance group.
Packit 022b05
 *
Packit 022b05
 *	This function assumes that smiCheckGroupMembers() has been
Packit 022b05
 *	called on all group objects and smiCheckComplianceStatus()
Packit 022b05
 *      has been called on all compliance objects before.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckGroupMembership(Parser *parser, Object *objectPtr)
Packit 022b05
{
Packit 022b05
    int found;
Packit 022b05
    
Packit 022b05
    if (((objectPtr->export.nodekind == SMI_NODEKIND_COLUMN
Packit 022b05
	  || objectPtr->export.nodekind == SMI_NODEKIND_SCALAR)
Packit 022b05
	 && objectPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE)
Packit 022b05
	|| objectPtr->export.nodekind == SMI_NODEKIND_NOTIFICATION) {
Packit 022b05
Packit 022b05
	found = (objectPtr->flags & FLAG_INGROUP);
Packit 022b05
	    
Packit 022b05
	if (! found) {
Packit 022b05
	    if (objectPtr->export.nodekind == SMI_NODEKIND_NOTIFICATION) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_NOTIFICATION_NOT_IN_GROUP,
Packit 022b05
				    objectPtr->line,
Packit 022b05
				    objectPtr->export.name);
Packit 022b05
	    } else {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_NODE_NOT_IN_GROUP,
Packit 022b05
				    objectPtr->line,
Packit 022b05
				    objectPtr->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    if (objectPtr->export.nodekind == SMI_NODEKIND_GROUP) {
Packit 022b05
Packit 022b05
	found = (objectPtr->flags & FLAG_INCOMPLIANCE);
Packit 022b05
Packit 022b05
	if (!found && objectPtr->export.status != SMI_STATUS_OBSOLETE) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_GROUP_UNREF,
Packit 022b05
				objectPtr->line,
Packit 022b05
				status[objectPtr->export.status],
Packit 022b05
				objectPtr->export.name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckObjectReuse --
Packit 022b05
 *
Packit 022b05
 *      Check whether a newly defined Object represents a duplicate
Packit 022b05
 *      or a reused OID.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      Allocates a new Object and adjusts the objectPtr parameter.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckObjectReuse(Parser *parser, char *name, Object **objectPtr)
Packit 022b05
{
Packit 022b05
    if ((((*objectPtr)->flags & FLAG_INCOMPLETE) == 0) &&
Packit 022b05
	strcmp(name, (*objectPtr)->export.name)) {
Packit 022b05
	if ((*objectPtr)->export.decl >= SMI_DECL_OBJECTTYPE) {
Packit 022b05
	    smiPrintError(parser, ERR_OID_REGISTERED, name,
Packit 022b05
			  (*objectPtr)->export.name);
Packit 022b05
	} else {
Packit 022b05
	    smiPrintError(parser, ERR_OID_REUSE, name,
Packit 022b05
			  (*objectPtr)->export.name);
Packit 022b05
	}
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_PREVIOUS_DEFINITION,
Packit 022b05
			    (*objectPtr)->line, (*objectPtr)->export.name);
Packit 022b05
	*objectPtr = duplicateObject(*objectPtr, 0, parser);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if ((*objectPtr)->modulePtr != parser->modulePtr) {
Packit 022b05
	*objectPtr = duplicateObject(*objectPtr, 0, parser);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckNotificationOid --
Packit 022b05
 *
Packit 022b05
 *      Check whether SMIv2 notifications are reversible and whether
Packit 022b05
 *	the last sub-identifer fits into a signed 32-bit integer.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckNotificationOid(Parser *parser, Module *module, Object *object)
Packit 022b05
{
Packit 022b05
    static const char *name[] = {
Packit 022b05
	"SNMPv2-MIB", "coldStart",
Packit 022b05
	"SNMPv2-MIB", "warmStart",
Packit 022b05
	"IF-MIB", "linkDown",
Packit 022b05
	"IF-MIB", "linkUp",
Packit 022b05
	"SNMPv2-MIB", "authenticationFailure",
Packit 022b05
	/* egpNeighborLoss is not really defined in any SMI module */
Packit 022b05
	NULL, NULL };
Packit 022b05
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    if (parser->modulePtr->export.language == SMI_LANGUAGE_SMIV2) {
Packit 022b05
	for (i = 0; name[i]; i+= 2) {
Packit 022b05
	    if (strcmp(name[i], module->export.name) == 0
Packit 022b05
		&& strcmp(name[i+1], object->export.name) == 0) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (! name[i]) {
Packit 022b05
	    Node *parent = object->nodePtr->parentPtr;
Packit 022b05
	    if (parent && parent->subid != 0) {
Packit 022b05
		smiPrintErrorAtLine(parser, ERR_NOTIFICATION_NOT_REVERSIBLE,
Packit 022b05
				    object->line, object->export.name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->nodePtr->subid > 2147483647) {
Packit 022b05
	smiPrintErrorAtLine(parser, ERR_NOTIFICATION_ID_TOO_LARGE,
Packit 022b05
			    object->line, object->export.name);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckNotificationMembers --
Packit 022b05
 *
Packit 022b05
 *      Check whether a newly defined notification contains only members
Packit 022b05
 *	of a single logical object.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckNotificationMembers(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    List *listPtr;
Packit 022b05
    Object *memberPtr;
Packit 022b05
#if 0
Packit 022b05
    Node *parent = NULL;
Packit 022b05
#endif
Packit 022b05
    Node *node = NULL;
Packit 022b05
Packit 022b05
    for (listPtr = object->listPtr;
Packit 022b05
	 listPtr; listPtr = listPtr->nextPtr) {
Packit 022b05
	
Packit 022b05
	memberPtr = (Object *) listPtr->ptr;
Packit 022b05
Packit 022b05
	if (memberPtr->export.nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	    if (memberPtr->nodePtr && memberPtr->nodePtr->parentPtr) {
Packit 022b05
		node = memberPtr->nodePtr->parentPtr;
Packit 022b05
	    }
Packit 022b05
	} else if (memberPtr->export.nodekind == SMI_NODEKIND_COLUMN) {
Packit 022b05
	    if (memberPtr->nodePtr && memberPtr->nodePtr->parentPtr
Packit 022b05
		&& memberPtr->nodePtr->parentPtr->parentPtr) {
Packit 022b05
		node = memberPtr->nodePtr->parentPtr->parentPtr;
Packit 022b05
	    }
Packit 022b05
	} else {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_NOTIFICATION_OBJECT_TYPE,
Packit 022b05
				object->line, memberPtr->export.name,
Packit 022b05
				object->export.name);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (memberPtr->export.access == SMI_ACCESS_NOT_ACCESSIBLE) {
Packit 022b05
	    smiPrintErrorAtLine(parser, ERR_NOTIFICATION_OBJECT_ACCESS,
Packit 022b05
				object->line, memberPtr->export.name,
Packit 022b05
				object->export.name);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	/* xxx check for duplicates */
Packit 022b05
#if 0
Packit 022b05
	if (node) {
Packit 022b05
	    if (! parent) {
Packit 022b05
		parent = node;
Packit 022b05
	    } else {
Packit 022b05
		if (parent != node) {
Packit 022b05
		    /* xxx do not report multiple times xxx */
Packit 022b05
		    smiPrintErrorAtLine(parser, ERR_NOTIFICATION_OBJECT_MIX,
Packit 022b05
					object->line, object->export.name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
#endif
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckUniqueness --
Packit 022b05
 *
Packit 022b05
 *      Check whether all entries for an UNIQUENESS clause are in fact
Packit 022b05
 *      columns.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void smiCheckUniqueness(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    List *p;
Packit 022b05
Packit 022b05
    for (p = object->uniquenessPtr; p; p = p->nextPtr) {
Packit 022b05
        Object *uniq = (Object *)p->ptr;
Packit 022b05
        int found = 0;
Packit 022b05
        List *pp;
Packit 022b05
Packit 022b05
        if (uniq && object->typePtr) {
Packit 022b05
            for (pp = object->typePtr->listPtr; pp; pp = pp->nextPtr)
Packit 022b05
                if (pp->ptr &&
Packit 022b05
                    !strcmp(uniq->export.name, ((Object *)pp->ptr)->export.name)) {
Packit 022b05
                    found = 1;
Packit 022b05
                    break;
Packit 022b05
                }
Packit 022b05
            if (!found) {
Packit 022b05
                if (((object->export.indexkind == SMI_INDEX_AUGMENT) ||
Packit 022b05
                    (object->export.indexkind == SMI_INDEX_SPARSE)) &&
Packit 022b05
                    (object->relatedPtr && object->relatedPtr->typePtr)) {
Packit 022b05
                    for (pp = object->relatedPtr->typePtr->listPtr; pp;
Packit 022b05
                         pp = pp->nextPtr)
Packit 022b05
                        if (pp->ptr &&
Packit 022b05
                            !strcmp(uniq->export.name, ((Object *)pp->ptr)->export.name)) {
Packit 022b05
                            found = 1;
Packit 022b05
                            break;
Packit 022b05
                        }
Packit 022b05
                }
Packit 022b05
            }
Packit 022b05
            if (!found)
Packit 022b05
                smiPrintErrorAtLine(parser, ERR_NOT_A_COLUMN,
Packit 022b05
                                    object->line, uniq->export.name);
Packit 022b05
        }
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiCheckModuleIdentityRegistration --
Packit 022b05
 *
Packit 022b05
 *      Check whether the module identity is registered in a well
Packit 022b05
 *	known (IANA) controlled location. In particular, warn if
Packit 022b05
 *	the OID is below iso(1).org(3).dod(6).mgmt(1) and not
Packit 022b05
 *	below well known registration locations such as mib-2,
Packit 022b05
 *	transmission, or snmpModules.
Packit 022b05
 *
Packit 022b05
 * Results:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 * Side effects:
Packit 022b05
 *      None.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
Packit 022b05
void
Packit 022b05
smiCheckModuleIdentityRegistration(Parser *parser, Object *object)
Packit 022b05
{
Packit 022b05
    static const SmiSubid mgmt[] = { 1, 3, 6, 1, 2 };
Packit 022b05
    static const SmiSubid mib2[] = { 1, 3, 6, 1, 2, 1 };
Packit 022b05
    static const SmiSubid transmission[] = { 1, 3, 6, 1, 2, 1, 10 };
Packit 022b05
    static const SmiSubid snmpModules[] = { 1, 3, 6, 1, 6, 3 };
Packit 022b05
Packit 022b05
    if (object->export.oidlen < sizeof(mgmt)/sizeof(SmiSubid)
Packit 022b05
	|| memcmp(object->export.oid, mgmt, sizeof(mgmt)) != 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->export.oidlen == sizeof(mib2)/sizeof(SmiSubid) + 1
Packit 022b05
	&& memcmp(object->export.oid, mib2, sizeof(mib2)) == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->export.oidlen == sizeof(transmission)/sizeof(SmiSubid) + 1
Packit 022b05
	&& memcmp(object->export.oid, transmission, sizeof(transmission)) == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (object->export.oidlen == sizeof(snmpModules)/sizeof(SmiSubid) + 1
Packit 022b05
	&& memcmp(object->export.oid, snmpModules, sizeof(snmpModules)) == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiPrintErrorAtLine(parser, ERR_MODULE_IDENTITY_REGISTRATION,
Packit 022b05
			object->line);
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 *
Packit 022b05
 * smiyyerror --
Packit 022b05
 *
Packit 022b05
 *      Prints an error message from the parser.  In SMIv1 and v2,
Packit 022b05
 *      a common error is to terminate a comment early, so if the
Packit 022b05
 *	current line contains a comment (parserPtr->lcline) print
Packit 022b05
 *	the ERR_COMMENT_TERMINATES.
Packit 022b05
 *
Packit 022b05
 *----------------------------------------------------------------------
Packit 022b05
 */
Packit 022b05
void smiyyerror(char *msg, Parser *parserPtr)
Packit 022b05
{
Packit 022b05
	if (parserPtr->line == parserPtr->lcline &&
Packit 022b05
	    parserPtr->modulePtr &&
Packit 022b05
	    (parserPtr->modulePtr->export.language == SMI_LANGUAGE_SMIV1 ||
Packit 022b05
	     parserPtr->modulePtr->export.language == SMI_LANGUAGE_SMIV2))
Packit 022b05
		smiPrintError(parserPtr, ERR_COMMENT_TERMINATES);
Packit 022b05
	smiPrintError(parserPtr, ERR_OTHER_ERROR, msg);
Packit 022b05
}