Subject: Re: <draft-ietf-disman-remops-mib-03.txt> comments

From: Randy Presuhn <[email-masked]>
Date: Thu, 21 Jan 1999 21:09:11 -0800 (PST)

Hi - 

> From: [email-masked]
> To: [email-masked]
> cc: Karl Auerbach <[email-masked]>
> Date: Wed, 13 Jan 1999 10:55:25 -0500
> Subject: <draft-ietf-disman-remops-mib-03.txt> comments
...
> If there are no comments I plan to make these changes in a few days and
> resubmit
> the draft.
...

Are we at the point where I should ask our AD for a MIB quality
reviewer in preparation for a last call?

 -----------------------------------------------------------------------
 Randy Presuhn           Email: [email-masked]     http://www.bmc.com
 Voice: +1 408 616-3100  BMC Software, Inc.           965 Stewart Drive
 Fax:   +1 408 616-3101  Sunnyvale, California 94086  USA
 -----------------------------------------------------------------------
 In accordance with the BMC Communications Systems Use and Security
 Policy, I explicitly state that although my affiliation with BMC may be
 apparent, implied, or provided, my opinions are not necessarily those
 of BMC Software and that all external representations on behalf of
 BMC must first be cleared with a member of "the top management team."
 -----------------------------------------------------------------------

---

From: Bob Stewart <[email-masked]>
Date: Wed, 27 Jan 1999 12:39:07 -0500

>reviewer in preparation for a last call?

My apologies for my negligence in not getting to this sooner.  Here are my
review comments with quotes from draft 3.

>The Lookup operation enables the equivalent of either a gethostbyname()
>or a gethostbyaddr() call being performed at a remote host.  The
>traceroute function provided does not provide the DNS names of the
>intermediate hops.  The Lookup gethostbyname() capability can be used to
>determine the symbolic name of a hop in a traceroute path.  Neither the
>remote ping or traceroute operations accept a DNS name as the address of
>the target host.  The Lookup function gethostbyaddr() can be used prior
>to using a remote ping or traceroute operation in order to determine the
>numeric address of a host.

I know we discussed this some, but I find this approach rather
unsatisfying.  What I'd rather see is address input to the MIB as a
DisplayString that can contain either an IP address in standard dot
notation or a DNS name.  For output I'd supply an object with the IP
address and another with the DNS name.

Then to handle either not wanting lookups or not being able to do them I'd
supply a readonly object that says whether the system can do DNS
translation and an output configuration option that says whether returned
addresses are also to supply their DNS names.

And of course I'd have error codes for being unable to do translations of
input and for not being able to translate a particular input address.

And although I'd no longer need it to support the others, I'd still keep
the DISMAN-LOOKUP-MIB as a handy gadget for dealing with more deficient MIBs.

>3.1  Ping MIB

Since I'm pressed for time and much of the information appeared likely to
be redundant with the DESCRIPTIONs, I skipped the prose.  I figure the
prose should illuminate the MIB definition itself but only in areas not
really appropriate to the actual object definitions, which should stand
alone reasonably well.

>   HostAddress ::= TEXTUAL-CONVENTION
>      STATUS  current
>      DESCRIPTION
>          "The textual convention for specifying a host
>          address.  The type of address can be determined
>          by the octet string length:
>
>                OCTETs    ADDRESS TYPE
>
>                  0       not specified
>                  4          ipv4
>                 16          ipv6"
>      SYNTAX OCTET STRING (SIZE (0..16))

Why not use the standard TDomain and TAddress textual conventions?

>   pingNotifications  OBJECT IDENTIFIER ::= { pingMIB 0 }
>   pingObjects        OBJECT IDENTIFIER ::= { pingMIB 1 }
>   pingConformance    OBJECT IDENTIFIER ::= { pingMIB 2 }

This is an odd structure.  Most MIBs go Objects, Notifications,
Conformance, 1, 2, 3, in the order you usually find them in the file.

>   pingSpinLock OBJECT-TYPE
>      SYNTAX      TestAndIncr
>      MAX-ACCESS  read-write
>      STATUS      current
>      DESCRIPTION
>         "An advisory lock used to allow cooperating
>         ping applications to coordinate their
>         use of the pingPingTable.
>
>         This object should be used when an application seeks to create
>         an new entry or alter an existing entry in the
>         pingTable.  A management implementation MAY utilize
>         the pingSpinLock to serialize its changes or additions.
>         Its usage is NOT REQUIRED."
>      ::= { pingObjects 1 }

Why is this necessary?  That's supposed to be covered by RowStatus.

>   pingEntry OBJECT-TYPE
>      SYNTAX      PingEntry
>      MAX-ACCESS  not-accessible
>      STATUS      current
>      DESCRIPTION
>          "Defines an entry in the pingTable."
>      INDEX {
>               pingOwnerIndex,
>               pingHostAddress
>             }
>      ::= { pingTable 1 }

This form of indexing requires the use of OwnerIndex to distinguish
different users pinging the same place and precludes an individual user
with only one Owner name from having multiple entries for the same place.

Is that intentional?

It's probably OK for an individual to be limited to one per destination,
although I'm not sure.  It's more questionable to force use of the Owner
name to distinguish that situation where you'd otherwise just use 0-length
Owner names.

This could be resolved either by using an integer as the index or providing
one as an additional index.

Or maybe it's good enough as it is.  I just want to make sure this is
considered.

>   pingOwnerIndex OBJECT-TYPE

Mmmpphhhlllggggg.

>   pingResultsProbeIndex OBJECT-TYPE
>      SYNTAX      Integer32 (1..15)
>      MAX-ACCESS  not-accessible
>      STATUS      current
>      DESCRIPTION
>          "An entry in this table is created when the results of
>          a ping probe is determined.  The initial instance
>          identifier value identifies the pingEntry
>          that a probe result (pingResultsEntry) belongs
>          to."
>      ::= { pingResultsEntry 1 }

I figured out that this is intended to allow multiple runs of the same
entry and have distinguished results (assuming I'm right).  I didn't find
either the object descriptors or the DESCRIPTIONs helpful in that effort.

>   pingResultsResponse OBJECT-TYPE
>      SYNTAX      Integer32
>      MAX-ACCESS  read-only
>      STATUS      current
>      DESCRIPTION
>          "The result of the ping operation made by a remote host
>              >=0  Round-trip response time in milliseconds.
>              -1   Internal error.
>              -2   ICMP echo request timed out.
>              -3   Unknown destination address.
>              -4   No route to host.
>              -5   Interface inactive to host.
>              -6   Failed to resolve host name.
>              -7   pingMaxConcurrentRequests limit reached."
>      ::= { pingResultsEntry 2 }

Hmmm.  "Failed to resolve host name."  Part of my suggestion is here.
Vestigial, but here.

This format for results sort of gives me heartburn.  I'd have a nice, neat
enumeration for the completion status and a separate object for the
response time, and perhaps additional objects for more detail.  The Cisco
Ping MIB, which has been in use for some time, has messages sent, messages
received, and minimum, average, and maximum round trip time.

As long as we're doing this we might as well do it up right.

>  END
>  DISMAN-TRACEROUTE-MIB DEFINITIONS ::= BEGIN

I think I'd at least put a few blank lines between these, and perhaps give
each one its own numbered subsection.

>   traceRouteNotifications  OBJECT IDENTIFIER ::= { traceRouteMIB 0 }
>   traceRouteObjects        OBJECT IDENTIFIER ::= { traceRouteMIB 1 }
>   traceRouteConformance    OBJECT IDENTIFIER ::= { traceRouteMIB 2 }

See previous comment.  Please assume comments for the Ping MIB that fit
this one are generic.  The three MIBs should be especially consistent among
themselves.

>   traceRouteByPassRouteTable OBJECT-TYPE
>      SYNTAX TruthValue
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>         "The purpose of this object is optionally enable
>         bypassing the route table.  If enabled bypass the
>         normal routing tables and send directly to a
>         host on an attached network.  If the host
>         is not on a directly-attached network, an
>         error is returned.  This option can be
>         used to ping a local host through an
>         interface that has no route through it
>         (e.g., after the interface was dropped by
>         routed)."
>      DEFVAL { false }
>      ::= { traceRouteEntry 3 }

Can we assume that all systems can do this?

>   traceRoutePacketSize OBJECT-TYPE
>      SYNTAX      Integer32 (0..65507)
>      UNITS       "octets"
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Specifies the size of the data portion of a traceroute
>          request in octets.  A traceroute request is essentially
>          transmitted by encoding a UDP datagram into a
>          IP packet. So subtracting the size of a UDP header
>          (8 octets) and the size of a IP header (20 octets)
>          yields a maximum of 65507 octets."
>      DEFVAL { 0 }
>      ::= { traceRouteEntry 4 }

I'd call this DataSize to make it clear.  Retrofit to previous MIB as
appropriate.

>   traceRouteProbesPerHop OBJECT-TYPE
>      SYNTAX      Integer32 (1..10)
>      UNITS       "count"
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Specifies the number of times to reissue a traceroute
>          request with the same time-to-live (TTL) value."
>      DEFVAL { 3 }
>      ::= { traceRouteEntry 6 }

I also just noticed UNITS "count".  That's not units, that's what it does.
The UNITS is "probes".  Apply this comment throughout the MIBs, as I notice
the same problem in following objects.

I like using UNITS, and these MIBs aren't consistent about it.

>   traceRouteTos OBJECT-TYPE
>      SYNTAX      Integer32 (0..255)
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Specifies the value to store in the TOS OCTET in
>          the IP probe packet that is transmitted as the
>          traceroute request.  The value must be a decimal
>          integer in the range 0 to 255.  This option can be
>          used to see if different types-of-service result
>          in different paths.  Not all values of TOS are
>          legal or meaningful.  TOS is often not supported
>          by IP implementations.  Useful values are probably
>          '16' (low delay) and '8' (high throughput)."
>      DEFVAL { 0 }
>      ::= { traceRouteEntry 9 }

This needs a REFERENCE for the defined values.

>   traceRouteSourceAddress OBJECT-TYPE
>      SYNTAX      HostAddress
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Use the specified IP address
>          (which must be given as an IP number, not a hostname)
>          as the source address in outgoing probe packets. On
>          hosts with more than one IP address, this option can
>          be used to force the source address to be something
>          other than the IP address of the interface the probe
>          packet is sent on. If the IP address is not one of this
>          machine's interface addresses, an error is returned and
>          nothing is sent."
>      DEFVAL { ''H }
>      ::= { traceRouteEntry 10 }

Again can we assume this capability?

>   traceRouteInterfaceName OBJECT-TYPE
>      SYNTAX      OCTET STRING (SIZE(0..32))
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Setting this object to an interface's name prior
>          to starting a remote traceroute operation directs
>          the traceroute probes to be transmitted over the
>          specified interface."
>      DEFVAL { ''H }
>      ::= { traceRouteEntry 11 }

Huh?  What interface name?  The usual (although sometimes broken)
convention is to use ifIndex.  The alternative, which hasn't caught on,
might be to use ifAlias.  If this is referring to an ifTable object, use
the name in the DESCRIPTION.  If it isn't, it's not well-defined enough to use.

>   traceRouteMiscOptions OBJECT-TYPE
>      SYNTAX      Utf8String (SIZE(0..64))
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Enables an application to specify implementation
>          dependent options."
>      DEFVAL { ''H }
>      ::= { traceRouteEntry 12 }

Eeeeeeeek.  Ummmm.  Maybe.  If we've got this Utf8String to use like this,
why are we using SnmpAdminString for comments in other MIBs?

>   traceRouteMaxFailures OBJECT-TYPE
>      SYNTAX      Integer32 (1..255)
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "The value of this object indicates the maximum number
>          of consecutive timeouts allowed before terminating
>          a remote traceroute request.  A value of 255 (maximum
>          hop count) indicate that the function of terminating
>          a remote traceroute request when a number of successive
>          timeouts are detected is disabled."
>      DEFVAL { 5 }
>      ::= { traceRouteEntry 13 }

Does a value of 1 mean that it fails on the first timeout?  If so, then
that number wasn't allowed before terminating.  It caused termination.  So
it seems the DESCRIPTION needs to be more clear and the number range from
0..255.  Is 255 not a usable number for some reason?  If it is usable, I
suggest -1 as the indicator not to count timeouts.

>   traceRouteCurHopCount OBJECT-TYPE
>      SYNTAX      Integer32 (1..255)
>      MAX-ACCESS  read-only
>      STATUS      current
>      DESCRIPTION
>          "Reflects the current TTL value for an remote
>          traceroute operation.  Maximum TTL value is
>          determined by traceRouteMaxTtl."
>      ::= { traceRouteEntry 15 }

Let's call it TTL or hop count, not mix the two terms.

Perhaps this should be a Gauge32.  Since it's read-only it doesn't really
need a limit.

>   traceRouteCurProbeCount OBJECT-TYPE
>      SYNTAX      Integer32 (1..10)
>      MAX-ACCESS  read-only
>      STATUS      current
>      DESCRIPTION
>          "Reflects the current probe count for an remote
>          traceroute operation.  The maximum probe count
>          is determined by traceRouteProbesPerHop."
>      ::= { traceRouteEntry 16 }

Another Gauge32 candidate.  The limit seems rather small, which I should
have said back at the definition for traceRouteProbesPerHop.

>  END
>  DISMAN-LOOKUP-MIB DEFINITIONS ::= BEGIN

Same comments as before about providing a gap in the document and other
previous comments that can apply to all three MIBs.

>      DESCRIPTION
>          "The Lookup MIB (DISMAN-LOOKUP-MIB) enables determination
>          of either the name corresponding to a host address or of
>          the address associated with a host name at a remote host
>          via use of the SNMP protocol,"
>      ::= { experimental 84 3 }

"SNMP protocol" is redundant in itself as is telling me a MIB is for such use.

Things that are redundant bother me, especially when they're repetitive or
said multiple times.

>   lookupEntry OBJECT-TYPE
>      SYNTAX      LookupEntry
>      MAX-ACCESS  not-accessible
>      STATUS      current
>      DESCRIPTION
>          "Defines an entry in the lookupTable."
>      INDEX {
>               lookupOwnerIndex
>            }
>      ::= { lookupTable 1 }

I tried to be quiet about owner indexing, but now it's gone to the extreme.
 It's not only being used for security purposes but to keep a given owner
from having more than one outstanding request.  I'm not convinced that's
good.  Multiple users may share the same named view and legitimately have
multiple requests at the same time.

We're using this technique despite not taking the time to understand it and
write it down as a common reference.

>   lookupCtl OBJECT-TYPE
>      SYNTAX      INTEGER {
>                         getHostByName(1),
>                         getHostByAddr(2)
>                       }
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "The value of this object determines whether the
>          getHostByName or the getHostByAddr resolver function
>          will be invoked at a remote host."
>      ::= { lookupEntry 2 }

This parameter is not necessary (so I won't mention multiple changes if it
were).  See below.

>   lookupAddress OBJECT-TYPE
>      SYNTAX      HostAddress
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Specifies the address used for a getHostByAddr Lookup
>          operation at a remote host."
>      ::= { lookupEntry 5 }
>
>   lookupDnsName OBJECT-TYPE
>      SYNTAX      DnsName
>      MAX-ACCESS  read-create
>      STATUS      current
>      DESCRIPTION
>          "Specifies the address used for a getHostByName Lookup
>          operation at a remote host."
>      ::= { lookupEntry 6 }

This would work nicely with one read-create input object and two output
objects.  The input parameter of type DisplayString (or similar) is either
a domain name or an IP address.  It's easy to parse that string and know
which you have.

Then you have two mutually exclusive, read-only output objects.  One is
type IpAddress (or I suppose HostAddress or two objects for TDomain and
TAddress), the other is type DnsName.  You instantiate whichever is
appropriate depending on the input.

Functionally the MIBs look pretty good.  Most of what I had to say is for
simplification or reasonable flexibility and power and for polish.

	Bob