New DRAFT of accounting MIB

nevil@ccu1.aukuni.ac.nz Sun, 07 February 1993 23:56 UTC

Received: from ietf.nri.reston.va.us by IETF.CNRI.Reston.VA.US id aa05527; 7 Feb 93 18:56 EST
Received: from CNRI.RESTON.VA.US by IETF.CNRI.Reston.VA.US id aa05521; 7 Feb 93 18:56 EST
Received: from wugate.wustl.edu by CNRI.Reston.VA.US id aa21484; 7 Feb 93 18:56 EST
Received: by wugate.wustl.edu (5.65c+/WUSTL-0.3) with SMTP id AA24065; Sun, 7 Feb 1993 17:53:40 -0600
Message-Id: <199302072353.AA24065@wugate.wustl.edu>
Date: Mon, 08 Feb 1993 12:55:02 -0000
Sender: ietf-archive-request@IETF.CNRI.Reston.VA.US
From: nevil@ccu1.aukuni.ac.nz
X-Orig-Sender: "ONC List Processor V0.2" <listserv@wugate.wustl.edu>
Reply-To: accounting-wg@wugate.wustl.edu
To: accounting-wg@wugate.wustl.edu
Errors-To: accounting-wg-errors@wugate.wustl.edu
Subject: New DRAFT of accounting MIB

G'day!  It's taken quite some time to produce it, but I've sent out the
draft of my current version of the MIB.  Herewith the m4 source of it,
perhaps Buz could check that his MIB compiler will accept it.

I'm working on the implementation now, and will have it ready to talk about
in July.  Alas I'm not going to be able to get to Columbus in March.

As far as keeping the Internet Accounting group alive, what do I/we need
to do?

Cheers, Nevil

+----------------------------------------------------------------------------+
|  Nevil Brownlee:        n.brownlee@auckland.ac.nz         Deputy Director  |
|     Phone: 64 9 373 7599 x8941    Computer Centre, University of Auckland  |
|     FAX:   64 9 373 7425         Private Bag 92019, Auckland, New Zealand  |
+----------------------------------------------------------------------------+

-- 
-- Internet Accounting MIB $Revision: 2.0 $
-- $Principal-Author: cbrooks $
-- $Current-Author: nbrownlee @

-- Internet Accounting MIB
-- This following text defines an initial SNMP MIB for Internet Accounting.
-- For additional details, see RFC 1272, "Internet Accounting: Background",
-- C. Mills, D. Hirsch, and G. Ruth, and the Internet Draft
-- "Internet Accounting Architecture", Mills, Laube, and Ruth.

define(Object,
$1 OBJECT-TYPE
    SYNTAX  $2
    ACCESS  $3
    STATUS  $4
    DESCRIPTION
	$5
    ::= { $6 $7 }
)dnl
define(ObjectIndex,
$1 OBJECT-TYPE
    SYNTAX  $2
    ACCESS  $3
    STATUS  $4
    DESCRIPTION
	$5
    INDEX  $6
    ::= { $7 $8 }
)dnl
define(ObjectDefval,
$1 OBJECT-TYPE
    SYNTAX  $2
    ACCESS  $3
    STATUS  $4
    DESCRIPTION
	$5
    DEFVAL $6
    ::= { $7 $8 }
)dnl

define(IncX,`incr(X) define(`X',eval(X + 1))')dnl
define(IncY,`incr(Y) define(`Y',eval(Y + 1))')dnl
define(IncZ,`eval(Z * 2) define(`Z',eval(Z * 2))')dnl

ACCOUNTING-MIB DEFINITIONS ::= BEGIN

IMPORTS experimental, OBJECT-TYPE, ObjectName, Counter, Gauge,
    NetworkAddress, TimeTicks  FROM RFC1155-SMI
	TRAP-TYPE FROM RFC1215;

internet-accounting OBJECT IDENTIFIER ::= { experimental 99 }

control		OBJECT IDENTIFIER ::= { internet-accounting 1 }

flowdata	OBJECT IDENTIFIER ::= { internet-accounting 2 }

ruledata	OBJECT IDENTIFIER ::= { internet-accounting 3 }

actiondata	OBJECT IDENTIFIER ::= { internet-accounting 4 }

GroupMask ::= OCTET STRING (SIZE (1))


-- The AddressTuple construct:
-- In future might have any address for any layer in the protocol
-- stack (session, presentation, application).  The intent here is to
-- represent the fact that the address tuple field can contain from 1
-- 1 to 9 attributes.

-- AddressTuple ::= SEQUENCE {
--    interface	       [0] INTEGER OPTIONAL,		-- interface

--    adjacent_type    [1] AddressType OPTIONAL,	-- adjacent
--    adjacent_address [2] NetWork_Address OPTIONAL,
--    adjacent_mask    [3] NetWork_Address OPTIONAL,

--    peer_type        [4] AddressType OPTIONAL,	-- peer
--    peer_address     [5] NetWork_Address OPTIONAL,
--    peer_mask	       [6] NetWork_Address OPTIONAL,

--    subscriber_id    [7] OCTET STRING OPTIONAL	-- subscriber
--    subscriber_mask  [8] OCTET STRING OPTIONAL
--    }

-- Within an address tuple the mask attributes are used to specify
-- which parts of the addresses must match exactly when address tuples
-- are compared.  For example peer_type = ipaddress, peer_address =
-- 130.216.0.0, peer_mask = 255.255.0.0 would match any peer address
-- representing an IP interface within network 130.216.

-- The Network Address construct:
-- The intent here is that this address type represent a choice of N-1
-- layer addresses based on the protocol layer at which accounting is
-- done.  For example, if accounting is being performed at the
-- presentation level, then this address might be a session layer
-- address; if done at the transport level it might be an IP address.
-- The level at which accounting is done is the "peer" level, N.

-- In the following, "adjacent" means the level below the current level.
-- For IP, the adjacent layer address might be the ethernet or 802 MAC
-- layer address.  A better encoding convention may be needed so that
-- addresses at any layer can be specified unambiguously.

-- NetWorkAddress ::= CHOICE {
--     adjacentLayerAddress  [1] IMPLICIT OCTET STRING,
--     ipAddress	     [2] IMPLICIT IpAddress,
--     nsapAddress	     [3] IMPLICIT OCTET STRING,
--     idprAddress	     [4] IMPLICIT OCTET STRING,
--     decnetAddress	     [5] IMPLICIT OCTET STRING
--     }

-- The AddressType type:
-- The intent of this type is to indicate the type of address
-- that is being recorded.  This would probably be encoded as a
-- tag in the above NetworkAddress type if using full ASN.1.  Instead
-- we explicitly call it out as a separate value, and instantiate it
-- as a separate field.

AddressType ::= INTEGER {
	adjacentlayer(1), ipaddress(2), nsapaddress(3),
	idpraddress(4), decnetaddress(5),
	ipxnetaddress(6), appletalkaddress(7)
	}


--
-- The Control Group
--

Object(highWaterMark,
    INTEGER (0..100),
    read-write,
    mandatory,
	`"A value expressed as a percent, interpreted by the meter as an
	indication of when to send a trap indicating that the management
	station should increase the polling interval.  Values of 0% or
	100% disable the checking represented by this variable."',
    control,
    1)

Object(floodMark,
    INTEGER (0..100),
    read-write,
    mandatory,
	`"A value expressed as a percent, interpreted by the meter as
	an indication of how full the flow record table should become
	before the meter should panic and start dumping the contents of
	the flow table to the management station in raw form.
	0% or 100% disables the checking represented by this variable."',
    control,
    2)

ObjectDefval(inactivityTimeout,
    INTEGER,
    read-write,
    mandatory,
	`"The time in seconds since the last packet seen (and the last
	report) after which the flow may be terminated."',
	{ 600 } -- 10 minutes,
    control,
    3)

ObjectDefval(maxLifetime,
    INTEGER,
    read-write,
    mandatory,
	`"A value in seconds interpreted by the meter as the maximum
	lifetime of a flow.  N.B: Interpretation of this value by the
	meter is optional."',
    { 3600 } -- 1 hour,
    control,
    4)

Object(flowPriorityGroupMask,
    GroupMask,
    read-write,
    mandatory,
	`"Tells the meter which flows are considered critical.  Flows can
	be indentified as belonging to one of 8 groups."',
    control,
    5)

ObjectDefval(flowRoutingMask,
    GroupMask,
    read-write,
    mandatory,
	`"Sent to the meter indicating that a normal report of indicated
	flows should be made (i.e. any flow whose rule indicates that
	it has a bit set which is set in the mask)."',
    { '0'h },
    control,
    6)

Object(flowRecoveryTrigger,
    INTEGER,
    read-write,
    mandatory,
	`"Writing into this variable acknowledges reciept of any
	recoverable flowRecords by the collector."',
    control,
    7)

Object(flowSamplingRate,
    `SEQUENCE OF FlowSamplingRate',
    not-accessible,
    mandatory,
	`"One for each interface.  The paramater N for statistical counting.
	Set to zero to count every packet on this interface.  Set to N to
	count 1/Nth of the packets from this interface.  A meter should
	choose its own algorithm to introduce variance into the sampling
	so that exactly every Nth packet is not counted.  A sampling rate
	of 1 yields a normal counter."',
    control,
    8)

FlowSamplingRate ::= SEQUENCE { rate INTEGER }


--
-- The Flow Table
--

-- This is a table kept by a meter, with one entry for every flow
-- currently being accounted for.

-- The variables kept for each flow comprise:
--	Housekeeping information for the flow.
--	The flow's "counters", i.e. its octet and PDU counts for each
--		direction, and its first and last packet times.
--	The flow's "keys", i.e. the information used to distinguish
--		packets for this particular flow.

-- Each flow has at least one key, but "aggregate" flows may have more
-- than one key.  Every key is associated with a single flow, and every
-- PDU matching a key is counted in its associated flow's counters.

-- Each packet which arrives at a meter is examined, and values for all
-- the "key" variables are extracted and assembled into a "packet key".
-- The set of current keys is searched to see whether this flow has
-- already been seen.  If it has, the packet is simply counted;
-- if not, the rules are consulted to create a new flow in which this
-- packet may be counted.  Once a flow has been created in this way a
-- collector will have to read the flow's key data just once.  After
-- that the collector needs ony to read the flow's counts from time to
-- time.

-- Each key has two AddressTuples, one for each of its end points.
-- Flows are bidirectional and have two sets of counters, one for each
-- of the two possible directions.  Since we may be accounting for
-- packets observed in transit along a network segment the choice of
-- "to" and "from" direction is arbitrary.  To avoid confusion we
-- define a canonical form for a key as follows ..

-- The key's two addresses are compared, field by field, using unsigned
-- arithmetic, in the order they appear in the AddressTuple construct.
-- The address which compares greater is the key's "high" address,
-- the other is its "low" address.  Flow directions are called "up"
-- (low address to high) and "down" (high address to low).
-- In the special case where the address tuples are equal all packets
-- are counted in the "up" direction's counters.

-- From time to time a collector may sweep the flow table so as collect
-- counts.  To reduce the number of SNMP requests required to do this,
-- two further tables provide alternative windows into the flow table.

-- The Creation Table allows a collector to find the first entry created
-- after a specified time, then make successive getnext requests to find
-- all other entries created since that time.  Similarly, the Activity Table
-- allows a collector to find all the entries last counted after a specified
-- time.  Note that it is not sensible for the meter to keep the Activity
-- Table in LastTime order, since that would result in very active flows
-- being counted many times during the same collection.

-- This scheme allows multiple collectors to independently use the same
-- meter; the collectors do not have to be synchronised and they may use
-- different collection intervals.

-- A meter may reclaim the memory space used by flows (or keys) for which
-- no packets have been seen for an interval longer than the 
-- inactivityTimeout.  
-- The meter may reuse flow indexes for flows thus reclaimed.

acctFlowTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF AcctFlowEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	"The list of all flows being kept for
	accounting purposes on this system."
    ::= { flowdata 1 }

acctFlowEntry OBJECT-TYPE
    SYNTAX  AcctFlowEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	"The flow record for a particular flow."
	INDEX { acctFlowIndex }
    ::= { acctFlowTable 1 }

AcctFlowEntry ::= SEQUENCE {
    acctFlowIndex		 INTEGER,
    acctFlowGroupMask		 GroupMask,
    acctFlowStatus		 INTEGER,

    acctFlowLowInterface	 INTEGER,	-- Low AddressTuple
    acctFlowLowAdjacentType	 AddressType,
    acctFlowLowAdjacentAddress	 OCTET STRING,
    acctFlowLowAdjacentMask	 OCTET STRING,
    acctFlowLowPeerType		 AddressType,
    acctFlowLowPeerAddress	 OCTET STRING,
    acctFlowLowPeerMask		 OCTET STRING,
    acctFlowLowSubscriberID	 OCTET STRING,
    acctFlowLowSubscriberMask	 OCTET STRING,

    acctFlowHighInterface	 INTEGER,	-- High AddressTuple
    acctFlowHighAdjacentType	 AddressType,
    acctFlowHighAdjacentAddress	 OCTET STRING,
    acctFlowHighAdjacentMask	 OCTET STRING,
    acctFlowHighPeerType	 AddressType,
    acctFlowHighPeerAddress	 OCTET STRING,
    acctFlowHighPeerMask	 OCTET STRING,
    acctFlowHighSubscriberID	 OCTET STRING,
    acctFlowHighSubscriberMask	 OCTET STRING,

    acctFlowSubscriberID	 OCTET STRING,	-- Other key info
    acctFlowSessionID		 INTEGER,

    acctFlowType		 INTEGER,	-- Counters
    acctFlowActiveKeys		 INTEGER,
    acctFlowPDUScale		 INTEGER,
    acctFlowOctetScale		 INTEGER,

    acctFlowUpOctets		 Counter,	-- Low-to-High
    acctFlowUpPDUs		 Counter,
    acctFlowDownOctets		 Counter,	-- High-to-Low
    acctFlowDownPDUs		 Counter,

    acctFlowFirstTime		 TimeTicks,
    acctFlowLastTime		 TimeTicks
    }

define(`X',0)
Object(acctFlowIndex,
    INTEGER,
    read-only,
    mandatory,
	"The bucket number for this flow.  The different values for this
	variable need not be consecutive.",
    acctFlowEntry,
    IncX)

Object(acctFlowGroupMask,
    GroupMask,
    read-only,
    mandatory,
	"The group mask for this flow.",
    acctFlowEntry,
    IncX)

Object(acctFlowStatus,
    `INTEGER { valid(1), invalid(2) }',
    read-only,
    mandatory,
	`"Status of this flow.  Allows all table rows to be collected
	via a table sweep, whilst throwing out all flows that are
	invalid."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowInterface,
    INTEGER,
    read-only,
    mandatory,
	`"Index of the interface associated with the Low address for this
	flow.  This value is one of the values contained in the ifIndex
	field of the interfaces table."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowAdjacentType,
    AddressType,
    read-only,
    mandatory,
	`"Address type of the adjacent Low address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowAdjacentAddress,
    OCTET STRING -- actually NetworkAddress,
    read-only,
    mandatory,
	`"Address of the adjacent device on the path for the Low
	address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowAdjacentMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the adjacent Low address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowPeerType,
    AddressType,
    read-only,
    mandatory,
	`"Address type of the peer Low address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowPeerAddress,
    OCTET STRING -- actually NetworkAddress,
    read-only,
    mandatory,
	`"Address of the peer device for the Low address of this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowPeerMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the peer Low address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`"Subscriber ID associated with the Low address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowLowSubscriberMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the Low Subsccriber ID for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighInterface,
    INTEGER,
    read-only,
    mandatory,
	`"Index of the interface associated with the High address for
	this flow.  This value is one of the values contained in the
	ifIndex field of the interfaces table."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighAdjacentType,
    AddressType,
    read-only,
    mandatory,
	`"Address type of the adjacent High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighAdjacent,
    OCTET STRING,
    read-only,
    mandatory,
	`"Address of the adjacent device on the path for the High
	address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighAdjacentMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the adjacent High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighPeerType,
    AddressType,
    read-only,
    mandatory,
	`"Address type of the peer High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighPeerMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the peer High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighPeerAddress,
    OCTET STRING,
    read-only,
    mandatory,
	`"Address of the peer device for the High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`"Subscriber ID associated with the High address for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowHighSubscriberMask,
    OCTET STRING,
    read-only,
    mandatory,
	`"1-bits in this mask indicate which bits must match when
	comparing the High Subsccriber ID for this flow."',
    acctFlowEntry,
    IncX)

Object(acctFlowSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`"Subscriber ID for this flow, not associated with flow direction."',
    acctFlowEntry,
    IncX)

Object(acctFlowSessionID,
    OCTET STRING,
    read-only,
    mandatory,
	`"Session ID for this flow.  Such an ID might be allocated by a
	network access server to distinguish a series of sessions between
	the same pair of addresses, which would otherwise appear to be
	parts of the same accounting flow"',
    acctFlowEntry,
    IncX)

Object(acctFlowType,
    `INTEGER { null(1), aggregate(2), count(3), tally(4) }',
    read-only,
    mandatory,
	`"Type of flow.  Details are given for acctRuleAction (below)."',
    acctFlowEntry,
    IncX)

Object(acctFlowActiveKeys,
    INTEGER,
    read-only,
    mandatory,
	`"Number of keys in the key set belonging to this flow.  Will
	always be 1 for count and tally flows; may be greater than 1
	for aggregate flows"',
    acctFlowEntry,
    IncX)

Object(acctFlowPDUScale,
    INTEGER (1..127),
    read-only,
    mandatory,
	`"The scale factor applied to this particular flow.  Indicates
	that number of bits to left shift the value of the PDU counters
	to obtain the actual values."',
    acctFlowEntry,
    IncX)

Object(acctFlowOctetScale,
    INTEGER (1..127),
    read-only,
    mandatory,
	`"The scale factor applied to this particular flow.  Indicates
	that number of bits to left shift the value of the octet
	counters to obtain the actual values."',
    acctFlowEntry,
    IncX)

Object(acctFlowUpOctets,
    Counter,
    read-only,
    mandatory,
	`"The count of octets flowing from low to high address and
	being delivered to the protocol level being metered.  In the
	case of IP, this would count the number ofoctets delivered to
	the IP level."',
    acctFlowEntry,
    IncX)

Object(acctFlowUpPDUs,
    Counter,
    read-only,
    mandatory,
	`"The count of protocol packets flowing from low to high address
	and being delivered to the protocol level being metered.
	In the case of IP, for example, this would count the IP packets
	delivered to the IP protocol level."',
    acctFlowEntry,
    IncX)

Object(acctFlowDownOctets,
    Counter,
    read-only,
    mandatory,
	`"The count of octets flowing from high to low address and
	being delivered to the protocol level being metered."',
    acctFlowEntry,
    IncX)

Object(acctFlowDownPDUs,
    Counter,
    read-only,
    mandatory,
	`"The count of protocol packets flowing from high to low address
	and being delivered to the protocol level being metered.
	In the case of IP, for example, this would count the IP packets
	delivered to the IP protocol level."',
    acctFlowEntry,
    IncX)

Object(acctFlowFirstTime,
    Timeticks,
    read-only,
    mandatory,
	"The time at which the flow was first entered in the table",
    acctFlowEntry,
    IncX)

Object(acctFlowLastTime,
    Timeticks,
    read-only,
    mandatory,
	`"The last time this flow had activity, i.e. the time of arrival
	of the last PDU belonging to this flow."',
    acctFlowEntry,
    IncX)


--
-- The Creation Table
--

acctCreationTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF AcctCreationEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	`"Window into  theFlow Table.  Allows a collector to find all 
	flows wich were created after a given time."'
    ::= { flowdata 2 }

acctCreationEntry OBJECT-TYPE
    SYNTAX  AcctCreationEntry
    ACCESS  not-accessible
    STATUS   mandatory
    DESCRIPTION
	`"The Creation Entry for a particular flow."'
    INDEX { acctCreationFirstTime, acctCreationIndex }
    ::= { acctCreationTable 1 }

AcctCreationEntry ::= SEQUENCE {
    acctCreationFirstTime	 TimeTicks,
    acctCreationIndex		 INTEGER,

    acctCreationStatus		 INTEGER,

    acctCreationFlowIndex	 INTEGER
    }

define(`X',0)
Object(acctCreationFirstTime,
    TimeTicks,
    read-only,
    mandatory,
	`"Time this flow was first counted.  Copy of acctFlowFirstTime."',
    acctCreationEntry,
    IncX)

Object(acctCreationIndex,
    INTEGER,
    read-only,
    mandatory,
	`"Index for the Creation Table.  Distinguishes flows with same
	acctFlowFirstTime.'",
    acctCreationEntry,
    IncX)

Object(acctCreationStatus,
    `INTEGER { valid(1), invalid(2) }',
    read-only,
    mandatory,
	`"Status of this Creation Entry.  Allows all table rows
	to be collected via a table sweep, whilst throwing out
	all flows that are invalid."',
    acctCreationEntry,
    IncX)

Object(acctCreationFlowIndex,
    INTEGER,
    read-only,
    mandatory,
	`"Index of this flow in Flow Table."',
    acctCreationEntry,
    IncX)


--
-- The Activity Table
--

acctActivityTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF AcctActivityEntry
    ACCESS  not-accessible
    STATUS   mandatory
    DESCRIPTION
	`"Window into the Flow Table.  Allows a collector to find all
	flows wich were last used after a given time."'
    ::= { flowdata 3 }

acctActivityEntry OBJECT-TYPE
    SYNTAX  AcctActivityEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	    `"The Activity Entry for a particular flow."'
    INDEX { acctActivityLastTime, acctActivityIndex }
    ::= { acctActivityTable 1 }

AcctActivityEntry ::= SEQUENCE {
    acctActivityLastTime	 TimeTicks,
    acctActivityIndex		 INTEGER,

    acctActivityStatus		 INTEGER,

    acctActivityFlowIndex	 INTEGER
    }

define(`X',0)
Object(acctActivityLastTime,
    TimeTicks,
    read-only,
    mandatory,
	`"Most recent time this flow was counted.  Copy of acctFlowLastTime."',
    acctActivityEntry,
    IncX)

Object(acctActivityIndex,
    INTEGER,
    read-only,
    mandatory,
	`"Index to the Activity Table.  Distinguishes flows with same
	acctFlowFirstTime."',
    acctActivityEntry,
    IncX)

Object(acctActivityGroupMask,
    GroupMask,
    read-only,
    mandatory,
	"The group mask for this Activity Entry.",
    acctActivityEntry,
    IncX)

Object(acctActivityFlowIndex,
    INTEGER,
    read-only,
    mandatory,
	`"Index of this flow in Flow Table."',
    acctActivityEntry,
    IncX)


--
-- The Rule Table
--

-- The semantics of the rule table are such that implementations must
-- consider how to effect the atomic creation or reset of the entire rule
-- table.  One possible implemenation might include the use  of a
-- "shadow" rule table and a control variable.  All changes to the rule
-- table would be made to the shadow table instead, until the control
-- variable was set to a value such that contents of the shadow table
-- would atomically replace the contents of the actual rule table

acctRuleTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF AcctRuleEntry
    ACCESS  not-accessible
    STATUS   mandatory
    DESCRIPTION
	    `"The list of rules used to determine the
	granularity of accounting data."'
    ::= { ruledata 1 }

acctRuleEntry OBJECT-TYPE
    SYNTAX  AcctRuleEntry
    ACCESS  not-accessible
    STATUS   mandatory
    DESCRIPTION
	    "The rule record itself."
    INDEX { acctRuleIndex }
    ::= { acctRuleTable 1 }

define(`X',0)dnl
AcctRuleEntry ::= SEQUENCE {
    acctRuleIndex		 INTEGER,
    acctRuleSelector		 INTEGER,	 -- what to select on
    acctRuleMask		 OCTET STRING,	 -- mask value
    acctRuleMatchedValue	 OCTET STRING,	 -- matched value
    acctRuleAction 		 INTEGER,	 -- action to take
    acctRuleJumpIndex		 INTEGER	 -- where to go
    }

Object(acctRuleIndex,
    INTEGER,
    read-write,
    mandatory,
	`"The `index' into the Rule table.  N.B: These values must be
	consecutive, given the fall-through semantics of processing
	the table"',
    acctRuleEntry,
    IncX)

define(`Y',0)
Object(acctRuleSelector,
    `INTEGER { null(IncY),

--	FlowGroupMask(IncY), FlowStatus(IncY),

	FlowLowInterface(IncY),
	FlowLowAdjacentType(IncY), FlowLowAdjacentAddress(IncY),
--	FlowLowAdjacentMask(IncY),
	FlowLowPeerType(IncY), FlowLowPeerAddress(IncY),
--	FlowLowPeerMask(IncY),
	FlowLowSubscriberID(IncY),
--	FlowLowSubscriberMask(IncY),

	FlowHighInterface(IncY),
	FlowHighAdjacentType(IncY), FlowHighAdjacentAddress(IncY),
--	FlowHighAdjacentMask(IncY),
	FlowHighPeerType(IncY),	FlowHighPeerAddress(IncY),
--	FlowHighPeerMask(IncY),
	FlowHighSubscriberID(IncY),
--	FlowHighSubscriberMask(IncY),

	FlowSubscriberID(IncY), FlowSessionID(IncY),

--	FlowType(IncY), FlowActiveKeys(IncY)
--	FlowPDUScale(IncY), FlowOctetScale(IncY)
	}',
    read-write,
    mandatory,
	`"Defines the source of the value to match."',
    acctRuleEntry,
    IncX)

Object(acctRuleMask,
    OCTET STRING,
    read-write,
    mandatory,
	`"The initial mask used to compute the desired value, encoded
	as an OCTET STRING."',
    acctRuleEntry,
    IncX)

Object(acctRuleMatchedValue,
    OCTET STRING,
    read-write,
    mandatory,
	`"The resulting value to be matched for equality.
	Specifically, if the attribute chosen by the acctRuleSelector
	logically ANDed with the mask specified by the acctRuleMask
	equals the value specified in the acctRuleMatchedValue, then
	continue processing the table entry based on the action
	specified by the acctRuleAction entry.  Otherwise, proceed to
	the next entry in the rule table."',
    acctRuleEntry,
    IncX)

Object(acctRuleAction,
    `INTEGER { goto(1), aggregate(2), count(3), tally(4), ignore(5) }',
    read-write,
    mandatory,
	`"The action to be taken if there is a match between this rule
	and the PDU being considered.
	If goto(1) then remember the`index' for this rule, then use its 
	acctRuleJumpIndex as the `index' of the next rule to be matched.
	If aggregate(2), create an aggregate flowEntry using values
	from acctAction[acctRuleJumpIndex] (should it not exist already),
	create a key using values from the PDU and masks from
	the matched rules, add this to the collection of keys searched
	for incoming packets and arrange for packets matching this key
	to be counted in the aggregate flowEntry.
	If count(3), create a new flowEntry using values from the PDU
	and masks from the matched rules.
	If tally(4), create a new flowEntry using values from the PDU
	and masks from acctAction[acctRuleJumpIndex].  Note that for a
	tally the rule- masks must be less specific than the action- masks.
	If ignore(5), the search is stopped and the PDU is ignored.
	Ignore should be used very carefully, since every ignored packet
	requires a sequential search through the rules!"',
    acctRuleEntry,
    IncX)

Object(acctRuleJumpIndex,
    INTEGER,
    read-write,
    mandatory,
	`"An `index' into the Rule table.  Where to restart the search.
	Must take on one of the values allowed for acctRuleIndex."',
    acctRuleEntry,
    IncX)


--
-- The Action Table
--

acctActionTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF AcctActionEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	`"The list of values used to create flowEntries for flows
	matching entries in the rule table (above)."'
    ::= { actiondata 1 }

acctActionEntry OBJECT-TYPE
    SYNTAX  AcctActionEntry
    ACCESS  not-accessible
    STATUS  mandatory
    DESCRIPTION
	"The rule action record."
    INDEX { acctActionIndex }
    ::= { acctActionTable 1 }

define(`X',0)dnl
AcctActionEntry ::= SEQUENCE {
    acctActionIndex			INTEGER,
    acctActionGroupMask 		GroupMask,
    acctActionStatus 			INTEGER,

    acctActionLowInterface		INTEGER,	-- Low AddressTuple
    acctActionLowAdjacentType		AddressType,
    acctActionLowAdjacentAddress	OCTET STRING,
    acctActionLowAdjacentMask		OCTET STRING,
    acctActionLowPeerType		AddressType,
    acctActionLowPeerAddress		OCTET STRING,
    acctActionLowPeerMask		OCTET STRING,
    acctActionLowSubscriberID		OCTET STRING,
    acctActionLowSubscriberMask		OCTET STRING,

    acctActionHighInterface		INTEGER,	-- High AddressTuple
    acctActionHighAdjacentType		AddressType,
    acctActionHighAdjacentAddress	OCTET STRING,
    acctActionHighAdjacentMask		OCTET STRING,
    acctActionHighPeerType		AddressType,
    acctActionHighPeerAddress		OCTET STRING,
    acctActionHighPeerMask		OCTET STRING,
    acctActionHighSubscriberID		OCTET STRING,
    acctActionHighSubscriberMask	OCTET STRING,

    acctActionSubscriberID		OCTET STRING,	-- Other Key info
    acctActionSessionID			INTEGER,

    acctActionPDUScale			INTEGER,
    acctActionOctetScale		INTEGER,

    acctActionCountType 		INTEGER
    }

Object(acctActionIndex,
    INTEGER,
    read-write,
    mandatory,
	`"The `index' into the Action table."',
    acctActionEntry,
    IncX)

Object(acctActionCountType,
    `INTEGER { normal(2), hop-weighted(3), charge-weighted(4) }',
    read-write,
    mandatory,
	`"Type of count information called for by this action table entry.
	A normal count counts packets and bytes.  A hop weighted count sums
	packet*hop and byte*hop product.  A charge-weighted count uses a
	multiplier proportional to charge to destination instead of hopcount
	to destination.  Other values for CountType are reserved for future
	use."',
    acctActionEntry,
    IncX)

-- The rest of the variables in acctActionEntry provide values for the
-- corresponding variables in acctFlowEntry.  For their descriptions please
-- refer to their definitions in acctFlowEntry.

Object(acctActionGroupMask,
    GroupMask,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowInterface,
    INTEGER,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowAdjacentType,
    AddressType,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowAdjacentAddress,
    OCTET STRING -- actually NetworkAddress,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowAdjacentMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowPeerType,
    AddressType,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowPeerAddress,
    OCTET STRING -- actually NetworkAddress,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowPeerMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionLowSubscriberMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighInterface,
    INTEGER,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighAdjacentType,
    AddressType,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighAdjacent,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighAdjacentMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighPeerType,
    AddressType,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighPeerMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighPeerAddress,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionHighSubscriberMask,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionSubscriberID,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionSessionID,
    OCTET STRING,
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionPDUScale,
    INTEGER (1..127),
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)

Object(acctActionOctetScale,
    INTEGER (1..127),
    read-only,
    mandatory,
	`""',
    acctActionEntry,
    IncX)


--
-- Internet Accounting Traps
--

declareDataLoss TRAP-TYPE
    ENTERPRISE { internet-accounting }
    DESCRIPTION
	"Sent by the meter to the management host to
	indicate that usage data is being lost."
    ::= 1

declareHighWater TRAP-TYPE
    ENTERPRISE { internet-accounting }
    VARIABLES { highWaterMark }
    DESCRIPTION
	"Sent by the meter to the management host to
	indicate that the high water mark has been exceeded.
	This should be interpreted by the management host as a
	request to increase the polling interval.  N.B: this
	trap is optional.  Meters are not required to implement
	this trap; management hosts are not required to
	increase increase their polling period."
    ::= 2

declareFlood TRAP-TYPE
    ENTERPRISE { internet-accounting }
    DESCRIPTION
	"This trap contains, as part of the trap body, Internet
	Accounting flow records.  The assumption here is that
	these flow records will be send as Opaque values, allowing
	an escape to more detailed ASN.1 types."
    ::= 3

END