Subject: comments on draft-ietf-disman-remops-mib-04.txt (part 1)

From: Randy Presuhn <[email-masked]>
Date: Tue, 11 May 1999 16:48:08 -0700 (PDT)

Hi -

As a technical contributor, I have a few comments on the current draft,
draft-ietf-disman-remops-mib-04.txt 
This message covers pages 1..25

=========================
Page 2:

OLD:Currently, there exists several enterprise defined MIBs for performing
                          X
NEW:Currently, there exist several enterprise defined MIBs for performing

OLD:both remote ping or traceroute operations.  The purpose of this memo is
    XXXXX
NEW:remote ping or traceroute operations.  The purpose of this memo is

=========================
Page 3:

|Ping is typically used to determine if a path exists between two hosts
|while traceroute shows an actual path.  Ping is usually implemented
|using the InterNet Control Message Protocol (ICMP) "ECHO" facility.  It
|is also possible to implement a ping capability using alternate methods.
|Some of which are:
|
|o   Using the udp echo port (7), if supported.
|
|o   Timing an SNMP query.

references should be added for these

|
|o   Timing an TCP connect attempt.
             X

=========================
Page 3:

...
|negatively effect its performance.  Attempting to connect to an used

is this supposed to read "a used" or "an unused"?

|port can be very unpredictable.  There are tools that attempt to connect
|to a range of TCP ports to test that any receiving server can handle
|erroneous connections attempts.
                     X

=========================
Page 3:

|It also can be important to the management application using a remote
         ^^^^^^
          is

|ping capability to know which method is being used. Different methods
|will yield different response times since the protocol and resulting
|processing will be different.  It is RECOMMENDED that the ping
|capability defined within this memo be implemented using the ICMP Echo
|Facility.

Suggestion:
    1) at a minimum, add an object which reports the kind of ping
       implemented.  Suggestion OBJECT IDENTIFIER syntax, with a
       value carved out for ICMP Echo.
    2) more elaborate (probably overkill) would be to have a
       read-create object in the control table, so different
       tests could employ different mechanisms

|Traceroute is usually implemented by transmitting a series of probe
|packets with increasing time-to-live values.  A probe packet is a UDP
|datagram encapsulated into an IP packet.  Each hop in a path to the
|target (destination) host rejects the probe packet (probe's TTL too
|small) until its time-to-live value becomes large enough for the probe
|to be forwarded.  Some systems use icmp probes instead of udp ones to
|implement traceroute.  In both cases traceroute relies on the probes
|being rejected via an ICMP message to discover the hops taken along a

something is missing in this sentence - the probe's rejection is
detected upon receipt of an ICMP message...

|path to the final destination.  ;p.Implementations of the remote
                                 ???
|traceroute capability as defined within this memo MUST be done using UDP
|packets to a (hopefully) unused port.  ICMP Echo Request packets MUST
|NOT be used.  Many PC implementations do it incorrectly, which, in turn,
|causes intermediate hops to be invisible when the router either refuses
|to send an ICMP TTL expired in response to an incoming ICMP packet or
|simply tosses ICMP echo requests altogether.

Can we nail down the port number, e.g., udp echo?

=========================
Page 4:

OLD:o   An overall architecture, described in RFC 2271 [7].
                                                   ^
NEW:o   An overall architecture, described in RFC 2571 [7].

OLD:    described in RFC 1906 [18], RFC 2272 [8] and RFC 2274 [10].
                                         ^                ^
NEW:    described in RFC 1906 [18], RFC 2572 [8] and RFC 2574 [10].

=========================
Page 5:

OLD:o   A set of fundamental applications described in RFC 2273 [9] and the
                                                            ^
NEW:o   A set of fundamental applications described in RFC 2573 [9] and the
OLD:    view-based access control mechanism described in RFC 2275 [11].
                                                              ^
NEW:    view-based access control mechanism described in RFC 2575 [11].

OLD:This memo specifies a MIB module that is compliant to the SMIv2.  A MIB
                        X          ^      ^^
NEW:This memo specifies MIB modules that are compliant to the SMIv2.  A MIB

|o   DISMAN-PING-MIB
|
|    Enables the ping function at a remote host.
|
|o   DISMAN-TRACEROUTE-MIB
|
|    Enables the traceroute function at a remote host.

"Enables" is not quite the right word; these functions probably exist
and are enabled regardless of whether they may be accessed through SNMP.

=========================
Page 6:

|o   pingResultsTable :li,pingProbeHistoryTable
                      ????

|The object pingMaxConcurrentRequests enable control of the maximum
|number of concurrent requests that an agent implementation is structured
|to support.  It is permissible for an agent to either limit the maximum
|upper range allowed for this object or to implement this object as
|read-only with an implementation limit expressed as its value.

Suggest replacing "is structured to support" with "supports".

OLD:Control Model (RFC 2275 [11], VACM)  and also allows for a management
                        ^
NEW:Control Model (RFC 2575 [11], VACM)  and also allows for a management

|The 3rd and 4th indexes, pingCtlHostAddressType and pingCtlHostAddress,
|specifies the target address (ipv4, ipv6, or an dnsName) for the
|operation.

"specifies" should read "specify"

|The contents of the pingCtlTable is preserved across reIPLs (Initial
|Program Loads) of its agent according the the values of each of the
|pingCtlStorageType objects.

should the conformance material for this object permit implementations
which only allow "volatile"?  (I think so, but don't have strong feelings
on this.)

=========================
Page 7:
|An implementation of this MIB will remove the oldest entry in the
|pingProbeHistoryTable to allow the addition of an new entry once the
|number of rows in the pingProbeHistoryTable reaches the value specified
|by pingCtlMaxRows.  Entries will be removed on the basis of oldest
|pingProbeHistoryTime value first.

How pingProbeHistoryIndex fits into this scheme needs to cleared up.
As I read the current text, an implementation could assign values to
pingProbeHistoryIndex more or less randomly and still conform to the
specification.  This is probably not good.  The other thing that needs
to be nailed down (with the current wording) is what happens when the
clock runs backwards.  I suggest that both of these issues can be 
dealt with by saying that pingProbeHistoryIndex values for a given
test are issued consecutively, starting at 1 and wrapping at 0xffffffff.

Presumably, when a test is started, any old entries for that test
should be deleted first?  

....
|The object traceRouteMaxConcurrentRequests enable control of the maximum
|number of concurrent requests that an agent implementation is structured
|to support.  It is permissible for an agent to either limit the maximum
|upper range allowed for this object or to implement this object as
|read-only with an implementation limit expressed as its value.

suggest "enable" -> "enables",
        "is structured to support" -> "supports".

|A remote traceroute test is started by setting traceRouteCtlAdminStatus
|to up(1).  The associating traceRouteCtlEntry MUST have been created and
|its traceRouteCtlRowStatus set to active(1) prior to starting the test.

Does this intend to say that the SET request for traceRoutCtlAdminStatus
cannot be the same SET request as is used to set the RowStatus to active?

=========================
Page 8:

|minutes and 30 seconds for a default traceroute operation.  Clearly 42
|plus hours is too long to wait for a traceroute operation to complete.

unless using RFC 2549... or inter-planetary networks :-)

|An entry in the traceRouteResultsTable is created for a corresponding

created by ???

|traceRouteCtlEntry once the test defined by this entry is started.  The
|objects traceRouteResultsCurHopCount and traceRouteResultsCurProbeCount
|can be examined to determine how far the current remote traceroute
|operation has reached.

|An implementation of this MIB will remove the oldest entry in the
|traceRouteProbeHistoryTable to allow the addition of an new entry once
|the number of rows in the traceRouteProbeHistoryTable reaches the value
|of traceRouteCtlMaxRows.  Entries will be removed on the basis of oldest
|traceRouteProbeHistoryTime value first.

  1) same issue regarding indexing as for ping history
  2) especially for traceroute, it would be possible for multiple
     entries' timestamps to have the same value, since this
     data type's precision is one-tenth of a second.
  3) this paragraph describes the behaviour of the table in terms
     of an object which will not be present in systems that do
     not support the traceRouteTimeStampGroup.  This is fishy.

=========================
Page 9:

OLD:on lookupRowStatus.  An lookupEntry is initially indexed by
                          X
NEW:on lookupRowStatus.  A lookupEntry is initially indexed by

|The index element lookupAddressType preceeds lookupAddress and specifies
|the type of address for either performing a gethostbyname or a
|gethostbyaddr call at a remote host.  The value of this index element
|determines whether to invoke either the gethostbyname or the
|gethostbyaddr operation.  Specification of a dnsName(2) implies that
|gethostbyname should be called to return a numeric address.  Use of a
|value of either ipv4(3) or ipv6(4) implies that a gethostbyaddr call
|should occur to return the symbolic name of a remote host.

Should explain what happens for
    1) multi-homed hosts
    2) hosts with multiple DNS names
    3) DNS round-robin scenarios

=========================
Page 10:

OLD:          FROM SNMPv2-SMI                  -- RFC1902
NEW:          FROM SNMPv2-SMI                  -- RFC2578

OLD:          FROM SNMPv2-TC                   -- RFC1903
NEW:          FROM SNMPv2-TC                   -- RFC2579

OLD:          FROM SNMPv2-CONF                 -- RFC1904
NEW:          FROM SNMPv2-CONF                 -- RFC2580

OLD:          FROM SNMP-FRAMEWORK-MIB;         -- RFC2271
NEW:          FROM SNMP-FRAMEWORK-MIB;         -- RFC2571

|      ::= { experimental 84 1 }

Should add comment to IANA requesting allocation at RFC time

=========================
Page 11:

|                none(0)         0        not specified
|                dnsName(2)      1-255    DNS name
|                ipv4(3)         4        ipv4
|                ipv6(4)         16       ipv6"
|      SYNTAX OCTET STRING (SIZE (0..65))

It looks like the upper bound should be 255 rather than 65.

=========================
Page 12:

|   pingMaxConcurrentRequests OBJECT-TYPE
|      SYNTAX      Integer32 (1..100)
|      MAX-ACCESS  read-write
|      STATUS      current
|      DESCRIPTION
|         "The maximum number of concurrent active ping requests
|         that are allowed within an agent implementation."
|      DEFVAL { 10 }
|      ::= { pingObjects 1 }

I don't see any architectural reason to impose a limit of 100 in the
MIB.  There may be reasonable implementation limits, but those are
up to the implementations.

=========================
Page 13:

|         All entries in that table belonging to a particular user will
|         have the same value for this initial index.  For a given user's
|         entries in a particular table, the object identifiers for the
|         information in these entries will have the same subidentifiers
|         (except for the 'column' subidentifier) up to the end of the
|         encoded owner index.  To configure VACM to permit access to this
|         portion of the table, one would create vacmViewTreeFamilyTable
|         entries with the value of vacmViewTreeFamilySubtree including the
|         owner index portion, and vacmViewTreeFamilyMask 'wildcarding' the
|         column subidentifier.  More elaborate configurations are
|         possible."

Cool.  You've just written the framework document.  :-)
Two tiny quibbles:
    1) I'd preface the paragraph with "When used in conjunction with
       such a security policy"
    2) I'd add a parenthetical "or group" after "user".

=========================
Page 14:

|   pingCtlHostAddress OBJECT-TYPE
|      SYNTAX      HostAddress
|      MAX-ACCESS  read-create
|      STATUS      current
|      DESCRIPTION
|          "Specifies the host address to be used at a remote host for
|          performing a ping operation.  The host address type is
|          determined by its octet string length.  Refer to the
|          definition of the TEXTUAL-CONVENTION HostAddress."
|      ::= { pingCtlEntry 4 }

Defval?  Must this be present for row activation?  What if it resolves
to a broadcast or multicast address?

=========================
Page 15:

|   pingCtlAdminStatus OBJECT-TYPE
|      SYNTAX      INTEGER {
|                            up(1),    -- test should be started
|                            down(2)   -- test should be stop
|                          }
|      MAX-ACCESS  read-create
|      STATUS      current
|      DESCRIPTION
|          "Reflects the desired state that a pingCtlEntry should be
|          in:
|
|             up(1)    - Attempt to active the test as defined by
|                        this pingCtlEntry.
|             down(1)  - Deactivate the test as defined by this
|                        pingCtlEntry.
|
|          Refer to the corresponding pingResultsOperStatus to
|          determine the operational state of the test defined by
|          this entry."
|       DEFVAL { down }
|      ::= { pingCtlEntry 8 }

"active" -> "activate"
It sounds like "up" and "down" are really not the right labels for
these values.

=========================
Page 16:
|   pingCtlMaxRows OBJECT-TYPE
|      SYNTAX      Integer32 (0..1500)
|      MAX-ACCESS  read-create
|      STATUS      current
|      DESCRIPTION
|          "The maximum number of entries allowed in the
|          pingProbeHistoryTable.  An implementation of this
|          MIB will remove the oldest entry in the
|          pingProbeHistoryTable to allow the addition of an
|          new entry once the number of rows in the
|          pingProbeHistoryTable reaches this value.
|          Entries will be removed on the basis of oldest
|          pingProbeHistoryTime value first.
|
|          A value of 0 for this object disables creation of
|          pingProbeHistoryTable entries."
|      DEFVAL      { 50 }
|      ::= { pingCtlEntry 11 }

Since implementations are not required to have pingProbeHistoryTime,
this DESCRIPTION needs to be fixed to only refer to the age of the
rows.

=========================
Page 18:

|   pingCtlRowStatus OBJECT-TYPE
...

What objects in row must have values for transition to active?

=========================
Page 19:
|   pingResultsOperStatus OBJECT-TYPE
...
|      SYNTAX      INTEGER {
|                            up(1),    -- test is in progress
|                            down(2)   -- test has stopped
|                          }
|      MAX-ACCESS  read-only
|      STATUS      current
|      DESCRIPTION
|          "Reflects the operational state of an pingCtlEntry:
|
|             up(1)    - Test is active.
|             down(1)  - Test has stopped."
|      ::= { pingResultsEntry 1 }

What good is this object?  

|   pingResultsMinRtt OBJECT-TYPE

units?

|   pingResultsMaxRtt OBJECT-TYPE

units?

|    pingResultsAverageRtt OBJECT-TYPE

units?

|    pingResultsProbeResponses OBJECT-TYPE

units?

=========================
Page 20:

|    pingResultsSentProbes OBJECT-TYPE
|      SYNTAX      Counter32
|      MAX-ACCESS  read-only
|      STATUS      current
|      DESCRIPTION
|          "The value of this object reflects the number of probes sent
|          for the corresponding pingCtlEntry and pingResultsEntry."
|      ::= { pingResultsEntry 7 }

units?  is this zero-based, or is it an ordinary counter?

|    pingResultsRttSumOfSquares OBJECT-TYPE
|      SYNTAX      Unsigned32
|      MAX-ACCESS  read-only
|      STATUS      current
|      DESCRIPTION
|          "This object contains the sum of all ping responses received.
|          Its purpose is to enable standard deviation calculation."
|      ::= { pingResultsEntry 8 }

units?  the description doesn't match the name

|   pingResultsLastGoodProbe OBJECT-TYPE
|      SYNTAX      DateAndTime
|      MAX-ACCESS  read-only
|      STATUS      current
|      DESCRIPTION
|          "Date and time was the last response was received for a probe."
|      ::= { pingResultsEntry 9 }

value if none?

|   pingProbeHistoryTable OBJECT-TYPE
|      SYNTAX      SEQUENCE OF PingProbeHistoryEntry
|      MAX-ACCESS  not-accessible
|      STATUS      current
|      DESCRIPTION
|          "Defines a table for storing the results of a ping
|          operation.  Entries in this table is limited by

"Entries" -> "The number of entries for a given <owner,test> pair"

|          the value of the corresponding pingCtlMaxRows
|          object.
|
|          An implementation of this MIB will remove the oldest
|          entry in the pingProbeHistoryTable to allow the
|          addition of an new entry once the number of rows in
|          the pingProbeHistoryTable reaches the value specified
|          by pingCtlMaxRows.  Entries will be removed on the
|          basis of oldest pingProbeHistoryTime value first."

pingProbeHistoryTime is not required for all implementations, so
the description of the table should not depend on it.

=========================
Page 21:
|   pingProbeHistoryEntry OBJECT-TYPE

This object's description duplicates the table.  Seems silly.

|   pingProbeHistoryIndex OBJECT-TYPE
|      SYNTAX      Unsigned32 (1..'ffffffff'h)
|      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 2 instance
 
"is" -> "are"

|          identifier index values identifies the pingCtlEntry

"identifies" -> "identify"

|          that a probe result (pingProbeHistoryEntry) belongs
|          to."
|      ::= { pingProbeHistoryEntry 1 }

are these index values carved out in any particular order?
do they wrap?

=========================
Page 22:

|   pingProbeHistoryLastReplyCode OBJECT-TYPE
|      SYNTAX      Integer32
|      MAX-ACCESS  read-only
|      STATUS      current
|      DESCRIPTION
|          "The last implementation method specific reply code received.
|          If the ICMP Echo capability is being used then a successful
|          probe ends when an ICMP response is received that contains
|          the code ICMP_ECHOREPLY(0)."

Otherwise, what value will this have?

OLD:          "Timestamp for when this probe results was determined."
NEW:          "Timestamp for when this probe result was determined."

 -----------------------------------------------------------------------
 Randy Presuhn           [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
 -----------------------------------------------------------------------
 Any relationship between my opinions and BMC's is coincidental.
 -----------------------------------------------------------------------

---

From: Randy Presuhn <[email-masked]>
Date: Thu, 27 May 1999 15:46:18 -0700 (PDT)

Hi -

> From: [email-masked]
> To: Randy Presuhn <[email-masked]>
> cc: [email-masked]
> Date: Sat, 22 May 1999 12:09:51 -0400
> Subject: Re: comments on draft-ietf-disman-remops-mib-04.txt (part 1)
...
> For the first I added a reference to RFC 862. For the second do you have
> something in mind?

No, but there are some subtleties to using SNMP for response time
calculations.

> This has come up several times in the past so its time to get it over
> with. What I have added is the following:
> 
>       pingImplementationTypeDomains      OBJECT IDENTIFIER ::= { pingMIB 3 }
> 
>       pingIcmpEcho OBJECT-IDENTITY
>          STATUS      current
>          DESCRIPTION
>              "Indicates that an implementation is using the InterNet
>              Control Message Protocol (ICMP) 'ECHO' facility."
>          ::= { pingImplementationTypeDomains 1 }
> 
>       pingUdpEcho OBJECT-IDENTITY
>          STATUS      current
>          DESCRIPTION
>              "Indicates that an implementation is using the udp echo
>              port (7)."
>          REFERENCE
>              "RFC 862, 'Echo Protocol'."
>          ::= { pingImplementationTypeDomains 2 }
> 
>       pingSnmpQuery OBJECT-IDENTITY
>          STATUS      current
>          DESCRIPTION
>              "Indicates that an implementation is an SNMP query to
>              calculate a round trip time."
>          ::= { pingImplementationTypeDomains 3 }
> 
>       pingTcpConnectionAttempt OBJECT-IDENTITY
>          STATUS      current
>          DESCRIPTION
>              "Indicates that an implementation is attempting to
>              connect to a TCP port in order to calculate a round
>              trip time."
>          ::= { pingImplementationTypeDomains 4 }

that's enough to make me happy

> I then added a read-create object, pingCtlType, of the OBJECT IDENTIFIER
> TEXTUAL CONVENTION to administer reporting/usage. I then added:
> 
>         OBJECT pingCtlType
>         MIN-ACCESS  read-only
>         DESCRIPTION
>             "Write access is not required.  In addition, the only
>             value that MUST be enabled for this object is
>             pingIcmpEcho."

instead of "enabled", I'd suggest "supported by an implementation".

> Does this now mean I need to add an IANA section and pull the above setting
> out into a proposed IANA administered MIB?

We need to say whether we're expecting IANA to handle future registrations
beneath the pingImplementationTypeDomains arc, and, if so, what kind
of approval process we envision.  I don't think that there's much value
in setting up a registration authority for this; if folks need new ping
types, they can always do so in their enterprise space.

...
> The BSD version of traceroute uses 4096. This is what the defval for
> traceRouteCtlPort is set to. I checked the IANA port assignment page and
> saw that 4096 isn't reserved for traceroute. It looks like 33434 is. Are
> there any objects to using 33434?  Hope not since I've already changed
> the MIB!

Karl addressed this.

...
> Don't think so.  I would prefer letting pingCtlMaxRows determine this.

Perhaps a couple words to this effect in the document?

> No.

Then we need to clarify. :-)

...
> For gethostbyaddr is pretty easy, just return the h_name ("official name of
> the host") from the hostent struct that is returned.  For gethostbyname its
> somewhat more complicated.  We could go with returning just the first
> address pointed to by the h_addr_list in the hostent or I will have to created
> a results table for addresses and have the whole list returned. If we did this
> then for gethostbyaddr I would return the alias list as pointed to by h_aliases.
> Suggestions?
> 
> Explain what you mean here.

I think Karl's comments addressed this.

...
> Yes. I've added the following:
> 
>      A value for this object MUST be set prior to transitioning
>      its corresponding pingCtlEntry to active(1) via
>      pingCtlRowStatus.
> 
> I have added invalidHostAddress(11) to the OperationResponseStatus TC.
> Broadcast and multicast addresses are not supported.

Does "prior to" include the case of "in the same SetRequest"?  We need
to be really clear on this.

...
> In what way is activation of a test here different than starting or
> stopping an interface?

My point was that we should probably explain why a management system
would take this object's value into account in evaluating data from the
other columns of this row in this table.

...
> > ...is this zero-based, or is it an ordinary counter?
> 
> What do you mean by zero-based?

Is the value of this counter meaningful on its own, or are only the
differences between samples of interest?  I think the intent was that
a single Get of this data would yield useful information.  That is not
true of ordinary counters.

...
> How about NO SUCH OBJECT?
...

possible, though I prefer '0000000000000000'H

---

From: [email-masked]
Date: Fri, 28 May 1999 08:18:48 -0400

Karl,

>It is fairly important to be able to adjust the destination port -- nobody
>can guarantee that 33434 will not be in use by some application on the
>target host.  And if it is, the last hop won't necessarily be visible as
>the packet would be gobbled up by the application rather than rejected
>with the ICMP port unreachable as is typical when doing tracerouts.  (All
>intermediate hops should get ICMP Time-Exceeded messages, but the last
>typically gets an ICMP port unreachable, unless the port is actually
>reachable because it is in use.)

>Also, given some newer "caching" and L4 routing/switching devices, the
>path taken by various packets will depend on the destination port number
>(as well as on the TOS bits in the IP header.)  So having the ability to
>look at per-port (and per-TOS setting) routing is something that is
>becomming increasingly useful.

traceRouteCtlPort is a read-write (create) object. It now has a default value
of the IANA assigned reserved port for traceroute. It can be changed with
a SNMP set request.

>> >|gethostbyaddr call at a remote host.

>I haven't been following the discussion on this, but I do hope that one
>can control whether one is fetching an A record, an MX record, or
>whatever.

Based upon Randy's comments I thought that I would create a results table that
would contain either the h_name and h_alais fields for a address lookup
(gethostbyaddr) or the h_addr_list content for a name lookup (gethostbyname).
The LOOKUP-MIB is not intended to be a DNS MIB.

>And when one is trying to diagnose DNS problems, one typically wants to
>know things like whether one passed through a CNAME record.

>Also, is the gethostbyaddr() function stop when it hits the PTR record or
>does it continue the resolution to make sure that it maps back to an set
>of A records, at least one of which contains the initial IP address?

>(Of course how DNS looks at any point is typically dependent on what
>server one is pointing to for any particular query.  That's why it is
>often interesting to do a query using a local resolver and then do it by
>brute force by tracking down, non-recursivly, from the roots.)

There is already a DNS-SERVER-MIB (RFC 1611) and a DNS-RESOLVER-MIB (RFC 1612).
The LOOKUP-MIB is structured to provide remote access to gethostbyname and
gethostbyaddr functions. These functions don't return the kind of information
you are referring to.

>A lot of "caching" stuff in the net plays with DNS to distribute traffic
>among a number of servers.  This can actually get pretty complicated when
>we talk about some of boxes that revector traffic off to different DNS
>servers depending on the IP source address.  (And the different DNS
>servers would, in turn return results which are presumably topolologically
>proximate to the querier.)

OK, I understand what this is now but consider this out of scope for the
LOOKUP-MIB.

Ken