Blame tools/dump-sizes.c

Packit 022b05
/*
Packit 022b05
 * dump-sizes.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to compute and dump SNMPv3 PDU sizes.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2003 J. Schoenwaelder, International University Bremen.
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: dump-sizes.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <string.h>
Packit 022b05
#ifdef HAVE_WIN_H
Packit 022b05
#include "win.h"
Packit 022b05
#endif
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
static int silent = 0;
Packit 022b05
static int detail = 0;
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * help functions
Packit 022b05
 */
Packit 022b05
#define m_abs(a)	((a) < 0 ? -(a) : (a))
Packit 022b05
Packit 022b05
typedef struct WellKnowType {
Packit 022b05
    char *module;
Packit 022b05
    char *name;
Packit 022b05
    int max;
Packit 022b05
    int mean;
Packit 022b05
    int min;
Packit 022b05
} WellKnowType;
Packit 022b05
Packit 022b05
static WellKnowType specialTypes[] = {
Packit 022b05
    { "SNMPv2-TC", "PhysAddress", 65535, 6, 0 },
Packit 022b05
    { "INET-ADDRESS-MIB", "InetAddress", 255, 4, 0 },
Packit 022b05
    { "IANATn3270eTC-MIB", "IANATn3270eAddress", 255, 4, 0 },
Packit 022b05
    { NULL, NULL, 0, 0, 0 }
Packit 022b05
};
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef enum len_type {
Packit 022b05
    len_min,
Packit 022b05
    len_mean,
Packit 022b05
    len_max
Packit 022b05
} len_type;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger32
Packit 022b05
getAbsMinEnum(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiNamedNumber *nn;
Packit 022b05
     SmiInteger32 min = SMI_BASETYPE_INTEGER32_MAX;
Packit 022b05
Packit 022b05
     for (nn = smiGetFirstNamedNumber(smiType);
Packit 022b05
	  nn;
Packit 022b05
	  nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	  if (abs(nn->value.value.integer32) < min) {
Packit 022b05
	       min = abs(nn->value.value.integer32);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return min;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger32
Packit 022b05
getAbsMaxEnum(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiNamedNumber *nn;
Packit 022b05
     SmiInteger32 max = 0;
Packit 022b05
Packit 022b05
     for (nn = smiGetFirstNamedNumber(smiType);
Packit 022b05
	  nn;
Packit 022b05
	  nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	  if (abs(nn->value.value.integer32) > max) {
Packit 022b05
	       max = abs(nn->value.value.integer32);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return max;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger32
Packit 022b05
getAbsMinInteger32(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger32 min = SMI_BASETYPE_INTEGER32_MAX;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getAbsMinInteger32(parent) : 0;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (abs(range->minValue.value.integer32) < min) {
Packit 022b05
	       min = abs(range->minValue.value.integer32);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return min;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger32
Packit 022b05
getAbsMaxInteger32(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger32 max = SMI_BASETYPE_INTEGER32_MIN;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent
Packit 022b05
	      ? getAbsMaxInteger32(parent) : SMI_BASETYPE_INTEGER32_MAX;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (abs(range->maxValue.value.integer32) > max) {
Packit 022b05
	       max = abs(range->maxValue.value.integer32);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return max;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiUnsigned32
Packit 022b05
getMinUnsigned32(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger32 min = 0xffffffff;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getMinUnsigned32(parent) : 0;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (range->minValue.value.unsigned32 < min) {
Packit 022b05
	       min = range->minValue.value.unsigned32;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return min;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiUnsigned32
Packit 022b05
getMaxUnsigned32(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiUnsigned32 max = 0;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getMaxUnsigned32(parent) : 0xffffffff;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (range->maxValue.value.unsigned32 > max) {
Packit 022b05
	       max = range->maxValue.value.unsigned32;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return max;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger64
Packit 022b05
getAbsMinInteger64(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger64 min = SMI_BASETYPE_INTEGER64_MAX;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getAbsMinInteger64(parent) : min;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (m_abs(range->minValue.value.integer64) < min) {
Packit 022b05
	       min = m_abs(range->minValue.value.integer64);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return min;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiInteger64
Packit 022b05
getAbsMaxInteger64(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger64 max = SMI_BASETYPE_INTEGER64_MIN;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getAbsMaxInteger64(parent) : max;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (m_abs(range->maxValue.value.integer64) > max) {
Packit 022b05
	       max = m_abs(range->maxValue.value.integer64);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return max;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiUnsigned64
Packit 022b05
getMinUnsigned64(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiInteger64 min = SMI_BASETYPE_UNSIGNED64_MAX;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getMinUnsigned64(parent) : min;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (range->minValue.value.unsigned64 < min) {
Packit 022b05
	       min = range->minValue.value.unsigned64;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return min;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static SmiUnsigned64
Packit 022b05
getMaxUnsigned64(SmiType *smiType)
Packit 022b05
{
Packit 022b05
     SmiType *parent;
Packit 022b05
     SmiRange *range;
Packit 022b05
     SmiUnsigned64 max = SMI_BASETYPE_UNSIGNED64_MIN;
Packit 022b05
Packit 022b05
     range = smiGetFirstRange(smiType);
Packit 022b05
     if (! range) {
Packit 022b05
	  parent = smiGetParentType(smiType);
Packit 022b05
	  return parent ? getMaxUnsigned64(parent) : max;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (; range; range = smiGetNextRange(range)) {
Packit 022b05
	  if (range->maxValue.value.unsigned64 > max) {
Packit 022b05
	       max = range->maxValue.value.unsigned64;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     return max;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_length(int length)
Packit 022b05
{
Packit 022b05
     int len;
Packit 022b05
     
Packit 022b05
     if (length < 0x80) {
Packit 022b05
	  return 1;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     for (len = 0; length > 0; len++) {
Packit 022b05
	  length >>= 8;
Packit 022b05
     }
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_subid(SmiSubid subid)
Packit 022b05
{
Packit 022b05
     int len = 0;
Packit 022b05
Packit 022b05
     do {
Packit 022b05
	  subid >>= 7;
Packit 022b05
	  len++;
Packit 022b05
     } while (subid > 0);
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_oid(const SmiSubid *oid, unsigned int oidlen)
Packit 022b05
{
Packit 022b05
     int len = 0;
Packit 022b05
     int i;
Packit 022b05
     
Packit 022b05
     len += ber_len_subid(oid[1] + oid[0] * 40);
Packit 022b05
     for (i = 2; i < oidlen; i++) {
Packit 022b05
	  len += ber_len_subid(oid[i]);
Packit 022b05
     }
Packit 022b05
Packit 022b05
     len += ber_len_length(len);	/* length */
Packit 022b05
     len += 1;				/* tag */
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_int32(const SmiInteger32 value)
Packit 022b05
{
Packit 022b05
     SmiInteger32 val = value;
Packit 022b05
     unsigned char ch, sign;
Packit 022b05
     int lim;
Packit 022b05
     int len = 0;
Packit 022b05
     
Packit 022b05
     if (val < 0) {
Packit 022b05
	  lim  = -1;
Packit 022b05
	  sign = 0x80;
Packit 022b05
     } else {
Packit 022b05
	  lim  = 0;
Packit 022b05
	  sign = 0x00;
Packit 022b05
     }
Packit 022b05
     do {
Packit 022b05
	  ch = (unsigned char) val;
Packit 022b05
	  val >>= 8;
Packit 022b05
	  len++;
Packit 022b05
     } while ((val != lim) || (unsigned char) (ch & 0x80) != sign);
Packit 022b05
Packit 022b05
     len += ber_len_length(len);	/* length */
Packit 022b05
     len += 1;				/* tag */
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_uint32(const SmiUnsigned32 value)
Packit 022b05
{
Packit 022b05
     SmiUnsigned32 val = value;
Packit 022b05
     unsigned char ch;
Packit 022b05
     int len = 0;
Packit 022b05
     
Packit 022b05
     do {
Packit 022b05
	  ch = (unsigned char) val;
Packit 022b05
	  val >>= 8;
Packit 022b05
	  len++;
Packit 022b05
     } while ((val != 0) || (ch & 0x80) != 0x00);
Packit 022b05
Packit 022b05
     len += ber_len_length(len);	/* length */
Packit 022b05
     len += 1;				/* tag */
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_int64(const SmiInteger64 value)
Packit 022b05
{
Packit 022b05
     SmiInteger64 val = value;
Packit 022b05
     unsigned char ch, sign;
Packit 022b05
     int lim;
Packit 022b05
     int len = 0;
Packit 022b05
     
Packit 022b05
     if (val < 0) {
Packit 022b05
	  lim  = -1;
Packit 022b05
	  sign = 0x80;
Packit 022b05
     } else {
Packit 022b05
	  lim  = 0;
Packit 022b05
	  sign = 0x00;
Packit 022b05
     }
Packit 022b05
     do {
Packit 022b05
	  ch = (unsigned char) val;
Packit 022b05
	  val >>= 8;
Packit 022b05
	  len++;
Packit 022b05
     } while ((val != lim) || (unsigned char) (ch & 0x80) != sign);
Packit 022b05
Packit 022b05
     len += ber_len_length(len);	/* length */
Packit 022b05
     len += 1;				/* tag */
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_uint64(const SmiUnsigned64 value)
Packit 022b05
{
Packit 022b05
     SmiUnsigned64 val = value;
Packit 022b05
     unsigned char ch;
Packit 022b05
     int len = 0;
Packit 022b05
     
Packit 022b05
     do {
Packit 022b05
	  ch = (unsigned char) val;
Packit 022b05
	  val >>= 8;
Packit 022b05
	  len++;
Packit 022b05
     } while ((val != 0) || (ch & 0x80) != 0x00);
Packit 022b05
Packit 022b05
     len += ber_len_length(len);	/* length */
Packit 022b05
     len += 1;				/* tag */
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_oid(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    SmiSubid      oid[128];
Packit 022b05
    unsigned int  oidlen = sizeof(oid)/sizeof(oid[0]);
Packit 022b05
    int i;
Packit 022b05
    
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max: 
Packit 022b05
	oid[0] = 2;
Packit 022b05
	for (i = 1; i < 128; i++) {
Packit 022b05
	    oid[i] = 4294967295UL;
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	/* see Aiko's measurements */
Packit 022b05
	for (oidlen = 0; oidlen < 15; oidlen++) {
Packit 022b05
	    oid[oidlen] = 1;
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	oid[0] = oid[1] = 0, oidlen = 2;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return ber_len_oid(oid, oidlen);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_octs(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    int len = 0;
Packit 022b05
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
Packit 022b05
    smiModule = smiGetTypeModule(smiType);
Packit 022b05
    if (smiModule && smiModule->name && smiType->name) {
Packit 022b05
	int i;
Packit 022b05
	for (i = 0; specialTypes[i].module; i++) {
Packit 022b05
	    if (strcmp(specialTypes[i].module, smiModule->name) == 0
Packit 022b05
		&& (strcmp(specialTypes[i].name, smiType->name) == 0)) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	if (specialTypes[i].module) {
Packit 022b05
	    switch (flags) {
Packit 022b05
	    case len_max:
Packit 022b05
		return specialTypes[i].max;
Packit 022b05
		break;
Packit 022b05
	    case len_mean:
Packit 022b05
		return specialTypes[i].mean;
Packit 022b05
		break;
Packit 022b05
	    case len_min:
Packit 022b05
		return specialTypes[i].min;
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	len = smiGetMaxSize(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	len = (smiGetMaxSize(smiType) + smiGetMinSize(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	len = smiGetMinSize(smiType);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_bits(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    int len = 0;
Packit 022b05
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	len = smiGetMaxSize(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	len = (smiGetMaxSize(smiType) + smiGetMinSize(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	len = smiGetMinSize(smiType);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_enum(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
     SmiInteger32 val = 0;
Packit 022b05
Packit 022b05
     switch (flags) {
Packit 022b05
     case len_max:
Packit 022b05
	 val = getAbsMaxEnum(smiType);
Packit 022b05
	 break;
Packit 022b05
     case len_mean:
Packit 022b05
	 val = (getAbsMaxEnum(smiType) + getAbsMinEnum(smiType)) / 2;
Packit 022b05
	 break;
Packit 022b05
     case len_min:
Packit 022b05
	 val = getAbsMinEnum(smiType);
Packit 022b05
	 break;
Packit 022b05
     }
Packit 022b05
     return ber_len_int32(val);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_int32(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    SmiInteger32 val = 0;
Packit 022b05
    
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	val = getAbsMaxInteger32(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	val = (getAbsMaxInteger32(smiType) + getAbsMinInteger32(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	val = getAbsMinInteger32(smiType);
Packit 022b05
	break;	     
Packit 022b05
    }
Packit 022b05
    return ber_len_int32(val);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_uint32(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    SmiUnsigned32 val = 0;
Packit 022b05
    
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	val = getMaxUnsigned32(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	val = (getMaxUnsigned32(smiType) + getMinUnsigned32(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	val = getMinUnsigned32(smiType);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return ber_len_uint32(val);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_int64(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    SmiInteger64 val = 0;
Packit 022b05
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	val = getAbsMaxInteger64(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	val = (getAbsMaxInteger64(smiType) + getAbsMinInteger64(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	val = getAbsMinInteger64(smiType);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return ber_len_int64(val);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val_uint64(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
    SmiUnsigned64 val = 0;
Packit 022b05
Packit 022b05
    switch (flags) {
Packit 022b05
    case len_max:
Packit 022b05
	val = getMaxUnsigned64(smiType);
Packit 022b05
	break;
Packit 022b05
    case len_mean:
Packit 022b05
	val = (getMaxUnsigned64(smiType) + getMinUnsigned64(smiType)) / 2;
Packit 022b05
	break;
Packit 022b05
    case len_min:
Packit 022b05
	val = getMinUnsigned64(smiType);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return ber_len_uint64(val);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_val(SmiType *smiType, len_type flags)
Packit 022b05
{
Packit 022b05
     int len = 0;
Packit 022b05
     
Packit 022b05
     switch (smiType->basetype) {
Packit 022b05
     case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	 len = ber_len_val_oid(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	 len = ber_len_val_octs(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_BITS:
Packit 022b05
	 len = ber_len_val_bits(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_ENUM:
Packit 022b05
	 len = ber_len_val_enum(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_INTEGER32:
Packit 022b05
	 len = ber_len_val_int32(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	 len = ber_len_val_uint32(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_INTEGER64:
Packit 022b05
	 len = ber_len_val_int64(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	 len = ber_len_val_uint64(smiType, flags);
Packit 022b05
	 break;
Packit 022b05
     default:
Packit 022b05
	 break;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
append_index(SmiSubid *oid, unsigned int *oidlen,
Packit 022b05
	     SmiNode *indexNode, len_type flags)
Packit 022b05
{
Packit 022b05
     SmiInteger32  int32 = 0;
Packit 022b05
     SmiUnsigned32 uint32 = 0;
Packit 022b05
     SmiType *indexType;
Packit 022b05
     SmiModule *indexModule;
Packit 022b05
     int i, len = 0;
Packit 022b05
Packit 022b05
     if (! indexNode) return;
Packit 022b05
Packit 022b05
     indexType = smiGetNodeType(indexNode);
Packit 022b05
     if (! indexType) return;
Packit 022b05
Packit 022b05
     indexModule = smiGetTypeModule(indexType);
Packit 022b05
Packit 022b05
     switch (indexType->basetype) {
Packit 022b05
     case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
Packit 022b05
	 switch (flags) {
Packit 022b05
	 case len_max:
Packit 022b05
	     len = 128 - *oidlen;
Packit 022b05
	     if (indexNode->implied) len--;
Packit 022b05
	     break;
Packit 022b05
	 case len_mean:
Packit 022b05
	     len = 16;
Packit 022b05
	     break;
Packit 022b05
	 case len_min:
Packit 022b05
	     len = 2;
Packit 022b05
	     break;
Packit 022b05
	 }
Packit 022b05
	 
Packit 022b05
	 if (! indexNode->implied && *oidlen < 128) {
Packit 022b05
	     oid[(*oidlen)++] = len;
Packit 022b05
	 }
Packit 022b05
	 for (i = 0; i < len && *oidlen < 128; i++) {
Packit 022b05
	     switch (flags) {
Packit 022b05
	     case len_max:
Packit 022b05
		 if (i == 0) {
Packit 022b05
		     oid[(*oidlen)++] = 2;
Packit 022b05
		 } else {
Packit 022b05
		     oid[(*oidlen)++] = 4294967295UL;
Packit 022b05
		 }
Packit 022b05
		 break;
Packit 022b05
	     case len_mean:
Packit 022b05
		 oid[(*oidlen)++] = i + 1;
Packit 022b05
		 break;
Packit 022b05
	     case len_min:
Packit 022b05
		 oid[(*oidlen)++] = 0;
Packit 022b05
		 break;
Packit 022b05
	     }
Packit 022b05
	 }
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
     case SMI_BASETYPE_BITS:
Packit 022b05
	 switch (flags) {
Packit 022b05
	 case len_max:
Packit 022b05
	     len = smiGetMaxSize(indexType);
Packit 022b05
	     break;
Packit 022b05
	 case len_mean:
Packit 022b05
	     len = (smiGetMaxSize(indexType) + smiGetMinSize(indexType) / 2);
Packit 022b05
	     break;
Packit 022b05
	 case len_min:
Packit 022b05
	     len = smiGetMinSize(indexType);
Packit 022b05
	     break;
Packit 022b05
	 }
Packit 022b05
Packit 022b05
	 if (indexModule && indexModule->name && indexType->name) {
Packit 022b05
	     int i;
Packit 022b05
	     for (i = 0; specialTypes[i].module; i++) {
Packit 022b05
		 if (strcmp(specialTypes[i].module, indexModule->name) == 0
Packit 022b05
		     && (strcmp(specialTypes[i].name, indexType->name) == 0)) {
Packit 022b05
		     break;
Packit 022b05
		 }
Packit 022b05
	     }
Packit 022b05
	     if (specialTypes[i].module) {
Packit 022b05
		 switch (flags) {
Packit 022b05
		 case len_max:
Packit 022b05
		     len = specialTypes[i].max;
Packit 022b05
		     break;
Packit 022b05
		 case len_mean:
Packit 022b05
		     len = specialTypes[i].mean;
Packit 022b05
		     break;
Packit 022b05
		 case len_min:
Packit 022b05
		     len = specialTypes[i].min;
Packit 022b05
		     break;
Packit 022b05
		 }
Packit 022b05
	     }
Packit 022b05
	 }
Packit 022b05
	 
Packit 022b05
	 if (! indexNode->implied && *oidlen < 128) {
Packit 022b05
	     oid[(*oidlen)++] = len;
Packit 022b05
	 }
Packit 022b05
	 for (i = 0; i < len && *oidlen < 128; i++) {
Packit 022b05
	     switch (flags) {
Packit 022b05
	     case len_max:
Packit 022b05
		 oid[(*oidlen)++] = 255;
Packit 022b05
		 break;
Packit 022b05
	     case len_mean:
Packit 022b05
		 if (i == 0) {
Packit 022b05
		     oid[(*oidlen)++] = 1;
Packit 022b05
		 } else {
Packit 022b05
		     oid[(*oidlen)++] = (i%2) ? 85 : 170;
Packit 022b05
		 }
Packit 022b05
		 break;
Packit 022b05
	     case len_min:
Packit 022b05
		 oid[(*oidlen)++] = 0;
Packit 022b05
		 break;
Packit 022b05
	     }
Packit 022b05
	  }
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_ENUM:
Packit 022b05
	 switch (flags) {
Packit 022b05
	 case len_max:
Packit 022b05
	     int32 = getAbsMaxEnum(indexType);
Packit 022b05
	     break;
Packit 022b05
	 case len_mean:
Packit 022b05
	     int32 = (getAbsMaxEnum(indexType) - getAbsMinEnum(indexType)) / 2;
Packit 022b05
	     break;
Packit 022b05
	 case len_min:
Packit 022b05
	     int32 = getAbsMinEnum(indexType);
Packit 022b05
	     break;
Packit 022b05
	 }
Packit 022b05
	 if (*oidlen < 128) {
Packit 022b05
	     oid[(*oidlen)++] = int32;
Packit 022b05
	 }
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_INTEGER32:
Packit 022b05
	 switch (flags) {
Packit 022b05
	 case len_max:
Packit 022b05
	     int32 = getAbsMaxInteger32(indexType);
Packit 022b05
	     break;
Packit 022b05
	 case len_mean:
Packit 022b05
	     int32 = (getAbsMaxInteger32(indexType)
Packit 022b05
		      + getAbsMinInteger32(indexType)) / 2;
Packit 022b05
	     break;
Packit 022b05
	 case len_min:
Packit 022b05
	     int32 = getAbsMinInteger32(indexType);
Packit 022b05
	     break;
Packit 022b05
	 }
Packit 022b05
	 if (*oidlen < 128) {
Packit 022b05
	     oid[(*oidlen)++] = int32;
Packit 022b05
	 }
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	 switch (flags) {
Packit 022b05
	 case len_max:
Packit 022b05
	     uint32 = getMaxUnsigned32(indexType);
Packit 022b05
	     break;
Packit 022b05
	 case len_mean:
Packit 022b05
	     uint32 = (getMaxUnsigned32(indexType)
Packit 022b05
		       + getMinUnsigned32(indexType)) / 2;
Packit 022b05
	     break;
Packit 022b05
	 case len_min:
Packit 022b05
	     uint32 = getMinUnsigned32(indexType);
Packit 022b05
	     break;
Packit 022b05
	 }
Packit 022b05
	 if (*oidlen < 128) {
Packit 022b05
	     oid[(*oidlen)++] = uint32;
Packit 022b05
	 }
Packit 022b05
	 break;
Packit 022b05
     case SMI_BASETYPE_UNKNOWN:
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_POINTER:
Packit 022b05
	 /* should never really get here */
Packit 022b05
	 break;
Packit 022b05
     }
Packit 022b05
}
Packit 022b05
Packit 022b05
#undef DUMP_OID
Packit 022b05
Packit 022b05
static int
Packit 022b05
ber_len_varbind(SmiNode *smiNode, len_type flags)
Packit 022b05
{
Packit 022b05
     SmiNode *row;
Packit 022b05
     SmiSubid oid[128];
Packit 022b05
     unsigned int oidlen = sizeof(oid)/sizeof(oid[0]);
Packit 022b05
     int len = 0;
Packit 022b05
#ifdef DUMP_OID
Packit 022b05
     int x;
Packit 022b05
#endif
Packit 022b05
Packit 022b05
     switch (smiNode->nodekind) {
Packit 022b05
     case SMI_NODEKIND_SCALAR:
Packit 022b05
	  for (oidlen = 0; oidlen < smiNode->oidlen; oidlen++) {
Packit 022b05
	       oid[oidlen] = smiNode->oid[oidlen];
Packit 022b05
	  }
Packit 022b05
	  oid[oidlen++] = 0;
Packit 022b05
	  break;
Packit 022b05
     case SMI_NODEKIND_COLUMN:
Packit 022b05
	  for (oidlen = 0; oidlen < smiNode->oidlen; oidlen++) {
Packit 022b05
	       oid[oidlen] = smiNode->oid[oidlen];
Packit 022b05
	  }
Packit 022b05
	  row = smiGetParentNode(smiNode);
Packit 022b05
	  if (row) {
Packit 022b05
	       SmiNode *indexNode = NULL, *iNode;
Packit 022b05
	       SmiElement *smiElement;
Packit 022b05
	       
Packit 022b05
	       switch (row->indexkind) {
Packit 022b05
	       case SMI_INDEX_INDEX:
Packit 022b05
	       case SMI_INDEX_REORDER:
Packit 022b05
		    indexNode = row;
Packit 022b05
		    break;
Packit 022b05
	       case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
Packit 022b05
		    break;
Packit 022b05
	       case SMI_INDEX_AUGMENT:
Packit 022b05
	       case SMI_INDEX_SPARSE:
Packit 022b05
		    indexNode = smiGetRelatedNode(row);
Packit 022b05
		    break;
Packit 022b05
	       case SMI_INDEX_UNKNOWN:
Packit 022b05
		    break;
Packit 022b05
	       }
Packit 022b05
	       if (indexNode) {
Packit 022b05
		    for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
			 smiElement;
Packit 022b05
			 smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
			 iNode = smiGetElementNode(smiElement);
Packit 022b05
			 append_index(oid, &oidlen, iNode, flags);
Packit 022b05
		    }
Packit 022b05
	       }
Packit 022b05
	  }
Packit 022b05
	  break;
Packit 022b05
     default:
Packit 022b05
	  return 0;
Packit 022b05
     }
Packit 022b05
Packit 022b05
#ifdef DUMP_OID
Packit 022b05
     fprintf(stderr, "%-32s\t", smiNode->name);
Packit 022b05
     for (x = 0; x < oidlen; x++) {
Packit 022b05
	  fprintf(stderr, ".%u", oid[x]);
Packit 022b05
     }
Packit 022b05
     fprintf(stderr, "\n");
Packit 022b05
#endif
Packit 022b05
Packit 022b05
     len += ber_len_oid(oid, oidlen);
Packit 022b05
     len += ber_len_val(smiGetNodeType(smiNode), flags);
Packit 022b05
     len += ber_len_length(len) + 1;
Packit 022b05
Packit 022b05
     return len;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isGroup(SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    SmiNode *childNode;
Packit 022b05
Packit 022b05
    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	return 1;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (childNode = smiGetFirstChildNode(smiNode);
Packit 022b05
	 childNode;
Packit 022b05
	 childNode = smiGetNextChildNode(childNode)) {
Packit 022b05
	if (childNode->nodekind == SMI_NODEKIND_SCALAR
Packit 022b05
		&& childNode->access > SMI_ACCESS_NOTIFY) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpSizeOfPDU(FILE *f, SmiModule *smiModule, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
     SmiNode *child;
Packit 022b05
     int worst = 0;
Packit 022b05
     int best = 0;
Packit 022b05
     int avg = 0;
Packit 022b05
     int b, w, a, n = 0;
Packit 022b05
     
Packit 022b05
     for (child = smiGetFirstChildNode(smiNode);
Packit 022b05
	  child;
Packit 022b05
	  child = smiGetNextChildNode(child)) {
Packit 022b05
	  if (child->access == SMI_ACCESS_READ_WRITE
Packit 022b05
	      || child->access == SMI_ACCESS_READ_ONLY) {
Packit 022b05
Packit 022b05
	       b = ber_len_varbind(child, len_min);
Packit 022b05
	       a = ber_len_varbind(child, len_mean);
Packit 022b05
	       w = ber_len_varbind(child, len_max);
Packit 022b05
	       
Packit 022b05
	       best += b, worst += w, avg += a, n++;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
Packit 022b05
     /* varbind list sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg   += ber_len_length(avg)   + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
Packit 022b05
     /* request-id as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(1073741824);
Packit 022b05
     worst += ber_len_int32(-214783648);
Packit 022b05
     
Packit 022b05
     /* error-status as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(18);
Packit 022b05
     
Packit 022b05
     /* error-index as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(n-1);
Packit 022b05
Packit 022b05
     /* PDU sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg += ber_len_length(avg) + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
     
Packit 022b05
     fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n", smiModule->name, smiNode->name,
Packit 022b05
	     avg, best, worst);
Packit 022b05
Packit 022b05
     if (detail) {
Packit 022b05
	 for (child = smiGetFirstChildNode(smiNode);
Packit 022b05
	      child;
Packit 022b05
	      child = smiGetNextChildNode(child)) {
Packit 022b05
	     if (child->access == SMI_ACCESS_READ_WRITE
Packit 022b05
		 || child->access == SMI_ACCESS_READ_ONLY) {
Packit 022b05
		 
Packit 022b05
		 b = ber_len_varbind(child, len_min);
Packit 022b05
		 a = ber_len_varbind(child, len_mean);
Packit 022b05
		 w = ber_len_varbind(child, len_max);
Packit 022b05
		 
Packit 022b05
		 fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n",
Packit 022b05
			 "", child->name, a, b, w);
Packit 022b05
	     }
Packit 022b05
	 }
Packit 022b05
     }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpSizeOfCreatePDU(FILE *f, SmiModule *smiModule, SmiNode *smiNode,
Packit 022b05
		    int ignoreDefaultColumns)
Packit 022b05
{
Packit 022b05
     SmiNode *child;
Packit 022b05
     SmiType *childType;
Packit 022b05
     SmiModule *childTypeModule;
Packit 022b05
     
Packit 022b05
     int worst = 0;
Packit 022b05
     int best = 0;
Packit 022b05
     int avg = 0;
Packit 022b05
     int b, w, a, n = 0;
Packit 022b05
     int isRowStatus;
Packit 022b05
     
Packit 022b05
     for (child = smiGetFirstChildNode(smiNode);
Packit 022b05
	  child;
Packit 022b05
	  child = smiGetNextChildNode(child)) {
Packit 022b05
	  if (child->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
Packit 022b05
	       /* Ensure RowStatus columns are present even if they
Packit 022b05
		* have a default value. */
Packit 022b05
Packit 022b05
	       childType = smiGetNodeType(child);
Packit 022b05
	       childTypeModule = childType
Packit 022b05
		    ? smiGetTypeModule(childType) : NULL;
Packit 022b05
	       
Packit 022b05
	       isRowStatus
Packit 022b05
		    = (childType && childType->name
Packit 022b05
		       && childTypeModule && childTypeModule->name)
Packit 022b05
		    ? (strcmp(childType->name, "RowStatus") == 0
Packit 022b05
		       && strcmp(childTypeModule->name, "SNMPv2-TC") == 0)
Packit 022b05
		    : 0;
Packit 022b05
Packit 022b05
	       /* xxx at least one PDU must be present xxx */
Packit 022b05
Packit 022b05
	       if (ignoreDefaultColumns
Packit 022b05
		   && child->value.basetype != SMI_BASETYPE_UNKNOWN
Packit 022b05
		   && !isRowStatus) {
Packit 022b05
		    continue;
Packit 022b05
	       }
Packit 022b05
Packit 022b05
	       b = ber_len_varbind(child, len_min);
Packit 022b05
	       a = ber_len_varbind(child, len_mean);
Packit 022b05
	       w = ber_len_varbind(child, len_max);
Packit 022b05
Packit 022b05
#if 0
Packit 022b05
	       fprintf(f, "  %-32s\t[%d..%d] | %d\n", child->name, b, w, a);
Packit 022b05
#endif
Packit 022b05
	       
Packit 022b05
	       best += b, worst += w, avg += a, n++;
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
Packit 022b05
     /* varbind list sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg   += ber_len_length(avg)   + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
Packit 022b05
     /* request-id as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(1073741824);
Packit 022b05
     worst += ber_len_int32(-214783648);
Packit 022b05
     
Packit 022b05
     /* error-status as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(18);
Packit 022b05
     
Packit 022b05
     /* error-index as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(n-1);
Packit 022b05
Packit 022b05
     /* PDU sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg += ber_len_length(avg) + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
     
Packit 022b05
     fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n", smiModule->name, smiNode->name,
Packit 022b05
	     avg, best, worst);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpSizeOfNotificationPDU(FILE *f, SmiModule *smiModule, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
     SmiElement *smiElement;
Packit 022b05
     SmiNode *varNode;
Packit 022b05
     int worst = 0;
Packit 022b05
     int best = 0;
Packit 022b05
     int avg = 0;
Packit 022b05
     int w, b, a;
Packit 022b05
     int len = 0;
Packit 022b05
     static const SmiSubid snmpTrapOid0[]
Packit 022b05
	  = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
Packit 022b05
     static const int snmpTrapOid0Len
Packit 022b05
	  = sizeof(snmpTrapOid0) / sizeof(SmiSubid);
Packit 022b05
     
Packit 022b05
     b = 15, w = 19, a = 18;
Packit 022b05
     best += b, worst += w, avg += a;
Packit 022b05
     
Packit 022b05
     len += ber_len_oid(smiNode->oid, smiNode->oidlen);
Packit 022b05
     len += ber_len_oid(snmpTrapOid0, snmpTrapOid0Len);
Packit 022b05
     len += ber_len_length(len) + 1;
Packit 022b05
     b = len, w = len, a = len;
Packit 022b05
     best += b, worst += w, avg += a;
Packit 022b05
     
Packit 022b05
     for (smiElement = smiGetFirstElement(smiNode);
Packit 022b05
	  smiElement;
Packit 022b05
	  smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	  varNode = smiGetElementNode(smiElement);
Packit 022b05
	  if (! varNode) continue;
Packit 022b05
Packit 022b05
	  b = ber_len_varbind(varNode, len_min);
Packit 022b05
	  a = ber_len_varbind(varNode, len_mean);
Packit 022b05
	  w = ber_len_varbind(varNode, len_max);
Packit 022b05
	  
Packit 022b05
	  best += b, worst += w, avg += a;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     /* varbind list sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg   += ber_len_length(avg)   + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
     
Packit 022b05
     /* request-id as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(1073741824);
Packit 022b05
     worst += ber_len_int32(-214783648);
Packit 022b05
     
Packit 022b05
     /* error-status as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(18);
Packit 022b05
     
Packit 022b05
     /* error-index as defined in RFC 3416 */
Packit 022b05
     best += ber_len_int32(0);
Packit 022b05
     avg += ber_len_int32(0);
Packit 022b05
     worst += ber_len_int32(0);
Packit 022b05
Packit 022b05
     /* PDU sequence length and tag */
Packit 022b05
     best  += ber_len_length(best)  + 1;
Packit 022b05
     avg += ber_len_length(avg) + 1;
Packit 022b05
     worst += ber_len_length(worst) + 1;
Packit 022b05
     
Packit 022b05
     fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n", smiModule->name, smiNode->name,
Packit 022b05
	     avg, best, worst);
Packit 022b05
Packit 022b05
     if (detail) {
Packit 022b05
	 b = 15, w = 19, a = 18;
Packit 022b05
	 fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n",
Packit 022b05
		 "", "sysUpTime", a, b, w);
Packit 022b05
	 
Packit 022b05
	 len = 0;
Packit 022b05
	 len += ber_len_oid(smiNode->oid, smiNode->oidlen);
Packit 022b05
	 len += ber_len_oid(snmpTrapOid0, snmpTrapOid0Len);
Packit 022b05
	 len += ber_len_length(len) + 1;
Packit 022b05
	 b = len, w = len, a = len;
Packit 022b05
	 fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n",
Packit 022b05
		 "", "snmpTrapOID", a, b, w);
Packit 022b05
	 
Packit 022b05
	 for (smiElement = smiGetFirstElement(smiNode);
Packit 022b05
	      smiElement;
Packit 022b05
	      smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	     varNode = smiGetElementNode(smiElement);
Packit 022b05
	     if (! varNode) continue;
Packit 022b05
	     
Packit 022b05
	     b = ber_len_varbind(varNode, len_min);
Packit 022b05
	     a = ber_len_varbind(varNode, len_mean);
Packit 022b05
	     w = ber_len_varbind(varNode, len_max);
Packit 022b05
	     
Packit 022b05
	     fprintf(f, "%-23s %-23s \t%d\t[%d..%d]\n",
Packit 022b05
		     "", varNode->name, a, b, w);
Packit 022b05
	 }
Packit 022b05
     }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpGroupPduSizes(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode)) {
Packit 022b05
	    dumpSizeOfPDU(f, smiModule, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpFullRowCreatePduSizes(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ROW);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ROW)) {
Packit 022b05
	if (smiNode->create) {
Packit 022b05
	    dumpSizeOfCreatePDU(f, smiModule, smiNode, 0);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
     
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpSmallRowCreatePduSizes(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ROW);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ROW)) {
Packit 022b05
	if (smiNode->create) {
Packit 022b05
	    dumpSizeOfCreatePDU(f, smiModule, smiNode, 1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpNotificationPduSizes(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
Packit 022b05
	dumpSizeOfNotificationPDU(f, smiModule, smiNode);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpSizes(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
     int       i;
Packit 022b05
     FILE      *f = stdout;
Packit 022b05
     
Packit 022b05
     silent = (flags & SMIDUMP_FLAG_SILENT);
Packit 022b05
     
Packit 022b05
     if (output) {
Packit 022b05
	  f = fopen(output, "w");
Packit 022b05
	  if (!f) {
Packit 022b05
	       fprintf(stderr, "smidump: cannot open %s for writing: ", output);
Packit 022b05
	       perror(NULL);
Packit 022b05
	       exit(1);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     
Packit 022b05
     if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	  if (! silent) {
Packit 022b05
	       int pos = 8888;
Packit 022b05
	       fprintf(f, "# united module PDU sizes (generated by smidump "
Packit 022b05
		       SMI_VERSION_STRING ")\n");
Packit 022b05
	       fprintf(f, "#\n# smidump -u -f sizes");
Packit 022b05
	       for (i = 0; i < modc; i++) {
Packit 022b05
		    int len = strlen(modv[i]->name);
Packit 022b05
		    if (pos + len > 70) {
Packit 022b05
			 fprintf(f, " \\\n#\t"), pos = 8;
Packit 022b05
		    }
Packit 022b05
		    fprintf(f, "%s ", modv[i]->name);
Packit 022b05
		    pos += len + 1;
Packit 022b05
	       }
Packit 022b05
	       fprintf(f, "%s\n", (pos == 8) ? "" : "\n");
Packit 022b05
	  }
Packit 022b05
	  fprintf(f, "\n# size of PDUs for groups and rows:\n\n");
Packit 022b05
	  for (i = 0; i < modc; i++) {
Packit 022b05
	      dumpGroupPduSizes(f, modv[i]);
Packit 022b05
	  }
Packit 022b05
	  fprintf(f, "\n# size of one-shot row creation PDUs including columns with default values:\n\n");
Packit 022b05
	  for (i = 0; i < modc; i++) {
Packit 022b05
	      dumpFullRowCreatePduSizes(f, modv[i]);
Packit 022b05
	  }
Packit 022b05
	  fprintf(f, "\n# size of one-shot row creation PDUs excluding columns with default values:\n\n");
Packit 022b05
	  for (i = 0; i < modc; i++) {
Packit 022b05
	      dumpSmallRowCreatePduSizes(f, modv[i]);
Packit 022b05
	  }
Packit 022b05
	  fprintf(f, "\n# size of notification PDUs:\n\n");
Packit 022b05
	  for (i = 0; i < modc; i++) {
Packit 022b05
	      dumpNotificationPduSizes(f, modv[i]);
Packit 022b05
	  }
Packit 022b05
     } else {
Packit 022b05
	  for (i = 0; i < modc; i++) {
Packit 022b05
	       if (! silent) {
Packit 022b05
		    fprintf(f, "# %s module PDU sizes (generated by smidump "
Packit 022b05
			    SMI_VERSION_STRING ")\n\n", modv[i]->name);
Packit 022b05
	       }
Packit 022b05
	       fprintf(f, "\n# size of PDUs for groups and rows:\n\n");
Packit 022b05
	       dumpGroupPduSizes(f, modv[i]);
Packit 022b05
	       fprintf(f, "\n# size of one-shot row creation PDUs including columns with default values:\n\n");
Packit 022b05
	       dumpFullRowCreatePduSizes(f, modv[i]);
Packit 022b05
	       fprintf(f, "\n# size of one-shot row creation PDUs excluding columns with default values:\n\n");
Packit 022b05
	       dumpSmallRowCreatePduSizes(f, modv[i]);
Packit 022b05
	       fprintf(f, "\n# size of notification PDUs:\n\n");
Packit 022b05
	       dumpNotificationPduSizes(f, modv[i]);
Packit 022b05
	  }
Packit 022b05
     }
Packit 022b05
     
Packit 022b05
     if (fflush(f) || ferror(f)) {
Packit 022b05
	  perror("smidump: write error");
Packit 022b05
	  exit(1);
Packit 022b05
     }
Packit 022b05
     
Packit 022b05
     if (output) {
Packit 022b05
	  fclose(f);
Packit 022b05
     }
Packit 022b05
}
Packit 022b05
Packit 022b05
void
Packit 022b05
initSizes()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "variables", OPT_FLAG, &detail, 0,
Packit 022b05
	  "show detailed information the sizes of variables"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"sizes",
Packit 022b05
	dumpSizes,
Packit 022b05
	SMI_FLAG_NODESCR,
Packit 022b05
	0,
Packit 022b05
	"RFC 3416 PDU sizes excluding message / transport headers",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}