RFC 5060

Protocol Independent Multicast MIB

πŸ“… published January 2008, from ietf

RFC 5060: Protocol Independent Multicast MIB πŸŽ€

okay bestie, so this is RFC 5060 and it's a Standards Track doc from the Network Working Group πŸ’– It's dated January 2008 and the main author is R. Sivaramu from Cisco Systems. Co-authors are J. Lingard (Arastra, Inc), D. McWalter (Data Connection Ltd), B. Joshi (Infosys Technologies Ltd), and A. Kessler (Cisco Systems) 🫢 The header doesn't list any RFCs this one obsoletes or updates. The abstract does say it's part of work to obsolete RFC 2934, but it does not obsolete RFC 2934 itself πŸ™ˆ

Status of This Memo ✨

ok so this part is the official vibe check. It's an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements πŸ’… For the standardization state and status, you check the current edition of the "Internet Official Protocol Standards" (STD 1). And yes, distribution of this memo is unlimited 🌈

Abstract πŸ¦‹

this memo defines a chunk of the Management Information Base (MIB), which is the data model network management protocols use on the Internet 🧚 It's all about managed objects for the Protocol Independent Multicast (PIM) family: PIM-SM (Sparse Mode), BIDIR-PIM (Bidirectional), and PIM-DM (Dense Mode). This document is part of work in progress to obsolete RFC 2934, and where the two overlap, this one is the one to use πŸ‘‘ It does not obsolete RFC 2934 though, so don't get it twisted πŸ’€

Table of Contents πŸ“

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
2.  Terminology  . . . . . . . . . . . . . . . . . . . . . . . . .  2
3.  The Internet-Standard Management Framework . . . . . . . . . .  2
4.  Overview . . . . . . . . . . . . . . . . . . . . . . . . . . .  3
5.  Definitions  . . . . . . . . . . . . . . . . . . . . . . . . .  4
6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 82
7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 86
8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 86
9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 86
  9.1.  Normative References . . . . . . . . . . . . . . . . . . . 86
  9.2.  Informative References . . . . . . . . . . . . . . . . . . 87

1. Introduction 🌸

okay so this memo is the MIB for managing the PIM protocols, specifically PIM-SM [RFC4601], BIDIR-PIM [RFC5015], and PIM-DM [RFC3973] πŸ¦‹

this doc is the work-in-progress replacement for RFC 2934 [RFC2934]. RFC 2934 was an experimental MIB module for managing PIM. This one is a re-working of that MIB, with some major glow-ups:

  • This MIB module is independent of IP version. RFC 2934 only did IPv4, so this is a big deal ✨
  • This MIB module supports managing BIDIR-PIM 🫢
  • This MIB module keeps limited support for managing PIM-DM [RFC3973], but that's no longer its main job πŸ™ˆ
  • This MIB module does not support managing PIM-SM v1 πŸ’…
  • This MIB module does not depend on the IPv4 Multicast Routing MIB from RFC 2932 [RFC2932] πŸ”₯
  • This MIB module supports configuring static Rendezvous Points (RPs) πŸ’–
  • This MIB module supports configuring anycast RPs [RFC4610] πŸ‘‘

2. Terminology πŸ’œ

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read the way RFC 2119 [RFC2119] describes them πŸŽ€ those words are the official vocab, so if you see them in caps, they're load-bearing ✨

3. The Internet-Standard Management Framework 🧚

if you want the full tea on the current Internet-Standard Management Framework, go read section 7 of RFC 3410 [RFC3410] πŸ“š

managed objects live in a virtual information store called the Management Information Base, or MIB 🌈 You usually reach them through the Simple Network Management Protocol (SNMP).

objects in the MIB are defined with the Structure of Management Information (SMI). This memo specifies a MIB module that's compliant with SMIv2, which is covered in STD 58, RFC 2578 [RFC2578], STD 58, RFC 2579 [RFC2579], and STD 58, RFC 2580 [RFC2580] πŸ’…

4. Overview πŸ¦‹

this MIB module has the following tables, and honestly each one has its own energy πŸ’–

  1. The PIM Interface Table. It has one row per IP version for each router interface that's running PIM.
  2. The PIM Neighbor Table. It has one row for each of the router's PIM neighbors.
  3. The PIM Neighbor Secondary Address Table. It has one row for each secondary address advertised by each of the router's PIM neighbors.
  4. The PIM (*,G) State Table. It has one row for each group that PIM has (*,G) state for.
  5. The PIM (*,G,I) State Table. It has one row for each group and interface that PIM has interface-specific (*,G) state for.
  6. The PIM (S,G) State Table. It has one row for each source and group that PIM has (S,G) state for.
  7. The PIM (S,G,I) State Table. It has one row for each source, group, and interface that PIM has interface-specific (S,G) state for.
  8. The PIM (S,G,rpt) State Table. It has one row for each source and group that PIM has (S,G,rpt) state for.
  9. The PIM (S,G,rpt,I) State Table. It has one row for each source, group, and interface that PIM has interface-specific (S,G,rpt) state for.
  10. The PIM Bidir DF-Election Table. It has one row per interface for each Rendezvous Point (RP) that has Bidirectional-PIM Designated Forwarder (DF) election state being maintained.
  11. The PIM Static RP Table. It has one row per range of multicast group addresses where a particular configured RP should be used.
  12. The PIM Group Mapping Table. It has one row for each mapping from a multicast group address prefix to the PIM mode and RP address to use for groups inside that prefix, no matter where the group mapping info came from.
  13. The PIM Anycast-RP Set Table. It has one row for each RP inside each Anycast-RP set that the local router is a member of.

this MIB module uses textual conventions from the IF-MIB [RFC2863], the INET-ADDRESS-MIB [RFC4001], and the IANA-RTPROTO-MIB [RTPROTO] 🌸 It also REFERENCEs [RFC3376], [RFC3569], [RFC3618], [RFC3810], [RFC3956], [RFC3973], [RFC4601], [RFC4610], [RFC5015], [RFC5059], and [IPMCAST-MIB], so there's a whole squad of documents behind it 🫢


πŸŽ€ Part 1 of 14 done, bestie! Next up is Section 5 (Definitions), where the actual MIB module lives. It's gonna be a lot, so get your snacks ready πŸ“βœ¨

Okay bestie, first up is the Register Suppression Timer β²οΈπŸ’– It's the chill period where a DR stops sending Register-encapsulated data to the RP once a Register-Stop comes back, and this one object runs the timer on both sides. It's literally the same PIM-SM timer, just exposed to management. πŸ¦‹

pimRegisterSuppressionTime OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The duration of the Register Suppression Timer.  This is
            the period during which a PIM Designated Router (DR) stops
            sending Register-encapsulated data to the Rendezvous Point
            (RP) after receiving a Register-Stop message.  This object
            is used to run timers both at the DR and at the RP.  This
            timer period is called the Register_Suppression_Time in the
            PIM-SM specification.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    REFERENCE "RFC 4601 section 4.11"
    DEFVAL { 60 }
    ::= { pim 15 }

The counting objects come next, and they're giving "how many of these do I have right now" energy πŸ“Šβœ¨ Each Gauge32 just tells you how many entries sit in one of the PIM tables, so pimStarGEntries is the count for pimStarGTable, and so on down the line 🌸

pimStarGEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimStarGTable."
    ::= { pim 16 }

pimStarGIEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimStarGITable."
    ::= { pim 17 }

pimSGEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimSGTable."

    ::= { pim 18 }

pimSGIEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimSGITable."
    ::= { pim 19 }

pimSGRptEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimSGRptTable."
    ::= { pim 20 }

pimSGRptIEntries OBJECT-TYPE
    SYNTAX     Gauge32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of entries in the pimSGRptITable."
    ::= { pim 21 }

Now the Assert stuff πŸ‘€πŸ’… pimOutAsserts and pimInAsserts are both Counter64s, and the sneaky detail is that pimInAsserts counts every router that receives an assert, not just the ones actually fighting over it. Iconic behaviour, honestly πŸ™ˆ Both counters can reset when the management system reinitialises, like after a reboot, so keep that in mind when you're reading the numbers.

pimOutAsserts OBJECT-TYPE
    SYNTAX     Counter64
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of Asserts sent by this router.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.6"
    ::= { pim 22 }

pimInAsserts OBJECT-TYPE
    SYNTAX     Counter64
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of Asserts received by this router.  Asserts
            are multicast to all routers on a network.  This counter is
            incremented by all routers that receive an assert, not only
            those routers that are contesting the assert.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.6"
    ::= { pim 23 }

Next up is the "last assert" group πŸŽ€ These objects remember the most recent assert, which interface it happened on, and the group and source addresses involved. If nothing has happened yet, the interface is zero and the address types are unknown(0). The source address is tricky, because for a (*,G) assert, the source type is unknown(0) too 🧚

pimLastAssertInterface OBJECT-TYPE
    SYNTAX     InterfaceIndexOrZero
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The interface on which this router most recently sent or
            received an assert, or zero if this router has not sent or
            received an assert."
    REFERENCE "RFC 4601 section 4.6"
    ::= { pim 24 }

pimLastAssertGroupAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the multicast group address in the most
            recently sent or received assert.  If this router has not
            sent or received an assert, then this object is set to
            unknown(0)."
    ::= { pim 25 }

pimLastAssertGroupAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The multicast group address in the most recently sent or
            received assert.  The InetAddressType is given by the
            pimLastAssertGroupAddressType object."
    ::= { pim 26 }

pimLastAssertSourceAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the source address in the most recently
            sent or received assert.  If the most recent assert was
            (*,G), or if this router has not sent or received an assert,
            then this object is set to unknown(0)."
    ::= { pim 27 }

pimLastAssertSourceAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The source address in the most recently sent or received
            assert.  The InetAddressType is given by the
            pimLastAssertSourceAddressType object."
    ::= { pim 28 }

Now the notification throttles 🚨 pimNeighborLossNotificationPeriod is the minimum gap between neighbour-loss notifications, and 65535 is basically "never send them" πŸ™…β€β™€οΈ pimNeighborLossCount just ticks up whenever a neighbour timer expires and this router has no other neighbour on that interface with the same IP version and a lower address. It also ticks up every time a pimNeighborLoss notification would be generated, even if the throttle stops it from actually going out πŸ’…

pimNeighborLossNotificationPeriod OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The minimum time that must elapse between pimNeighborLoss
            notifications originated by this router.  The maximum value
            65535 represents an 'infinite' time, in which case, no
            pimNeighborLoss notifications are ever sent.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    DEFVAL { 0 }
    ::= { pim 29 }

pimNeighborLossCount OBJECT-TYPE
    SYNTAX     Counter32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of neighbor loss events that have occurred.

            This counter is incremented when the neighbor timer expires,
            and the router has no other neighbors on the same interface
            with the same IP version and a lower IP address than itself.

            This counter is incremented whenever a pimNeighborLoss
            notification would be generated.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.3.2"
    ::= { pim 30 }

The invalid Register bit is a whole storyline 🎬 pimInvalidRegisterMsgsRcvd counts Register messages that are invalid, which means the destination doesn't match the Group to RP mapping, or the group is in an SSM range but the Register is trying to use ASM. Those conditions can show up briefly while RP mappings are still spreading, so one blip is fine. But if the counter keeps climbing over several minutes, that's a persisting configuration error, so go fix it, bestie πŸ”§ Also, the data inside those invalid Registers gets thrown away πŸ—‘οΈ

The companion objects are super helpful for debugging. pimInvalidRegisterAddressType tells you which address type the next three objects use, and it's unknown(0) until something invalid actually shows up. pimInvalidRegisterOrigin, pimInvalidRegisterGroup, and pimInvalidRegisterRp hold the source, group, and RP from the most recent bad Register πŸ”

pimInvalidRegisterNotificationPeriod OBJECT-TYPE
    SYNTAX     Unsigned32 (10..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The minimum time that must elapse between
            pimInvalidRegister notifications originated by this router.
            The default value of 65535 represents an 'infinite' time, in
            which case, no pimInvalidRegister notifications are ever
            sent.

            The non-zero minimum allowed value provides resilience
            against propagation of denial-of-service attacks from the
            data and control planes to the network management plane.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    DEFVAL { 65535 }
    ::= { pim 31 }

pimInvalidRegisterMsgsRcvd OBJECT-TYPE
    SYNTAX     Counter32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of invalid PIM Register messages that have been
            received by this device.

            A PIM Register message is invalid if either

            o the destination address of the Register message does not
              match the Group to RP mapping on this device, or

            o this device believes the group address to be within an
              SSM address range, but this Register implies ASM usage.

            These conditions can occur transiently while RP mapping
            changes propagate through the network.  If this counter is
            incremented repeatedly over several minutes, then there is a
            persisting configuration error that requires correction.

            The active Group to RP mapping on this device is specified
            by the object pimGroupMappingPimMode.  If there is no such
            mapping, then the object pimGroupMappingPimMode is absent.
            The RP address contained in the invalid Register is
            pimInvalidRegisterRp.

            Multicast data carried by invalid Register messages is
            discarded.  The discarded data is from a source directly
            connected to pimInvalidRegisterOrigin, and is addressed to
            pimInvalidRegisterGroup.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.4.2, RFC 3569, and
               'IP Multicast MIB' (August 2007) ipMcastSsmRangeTable"
    ::= { pim 32 }

pimInvalidRegisterAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type stored in pimInvalidRegisterOrigin,
            pimInvalidRegisterGroup, and pimInvalidRegisterRp.

            If no invalid Register messages have been received, then
            this object is set to unknown(0)."
    ::= { pim 33 }

pimInvalidRegisterOrigin OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The source address of the last invalid Register message
            received by this device."
    ::= { pim 34 }

pimInvalidRegisterGroup OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The IP multicast group address to which the last invalid
            Register message received by this device was addressed."
    ::= { pim 35 }

pimInvalidRegisterRp OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The RP address to which the last invalid Register message
            received by this device was delivered."
    ::= { pim 36 }

Last one for this part is the invalid Join/Prune throttle πŸ›‘οΈ It works just like the Register one, with the same 10 second floor and the 65535 "never" default. The non-zero minimum is there so denial-of-service traffic coming from the control plane can't flood the management plane with notifications 🌈

pimInvalidJoinPruneNotificationPeriod OBJECT-TYPE
    SYNTAX     Unsigned32 (10..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The minimum time that must elapse between
            pimInvalidJoinPrune notifications originated by this router.
            The default value of 65535 represents an 'infinite' time, in
            which case, no pimInvalidJoinPrune notifications are ever
            sent.

            The non-zero minimum allowed value provides resilience
            against propagation of denial-of-service attacks from the
            control plane to the network management plane.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    DEFVAL { 65535 }
    ::= { pim 37 }

okay so this is where the invalid Join/Prune counters start getting really specific πŸ¦‹ bestie, these are the objects that tell you how many broken Join/Prune messages showed up, who sent them, and what group and RP they were pointing at πŸ’…

pimInvalidJoinPruneMsgsRcvd OBJECT-TYPE
    SYNTAX     Counter32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of invalid PIM Join/Prune messages that have
            been received by this device.

            A PIM Join/Prune message is invalid if either

            o the Group to RP mapping specified by this message does not
              match the Group to RP mapping on this device, or

            o this device believes the group address to be within an
              SSM address range, but this Join/Prune (*,G) or (S,G,rpt)
              implies ASM usage.

            These conditions can occur transiently while RP mapping
            changes propagate through the network.  If this counter is
            incremented repeatedly over several minutes, then there is a
            persisting configuration error that requires correction.

            The active Group to RP mapping on this device is specified
            by the object pimGroupMappingPimMode.  If there is no such
            mapping, then the object pimGroupMappingPimMode is absent.
            The RP address contained in the invalid Join/Prune is
            pimInvalidJoinPruneRp.

            Invalid Join/Prune messages are discarded.  This may result
            in loss of multicast data affecting listeners downstream of
            pimInvalidJoinPruneOrigin, for multicast data addressed to
            pimInvalidJoinPruneGroup.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.5.2, RFC 3569, and
               'IP Multicast MIB' (August 2007) ipMcastSsmRangeTable"
    ::= { pim 38 }

ngl this one is giving "keep an eye on me" energy πŸ‘€ if the counter keeps climbing for several minutes, that's not a glitch, that's a real config problem that needs fixing πŸ”₯ and invalid messages just get thrown out, so downstream listeners might stop getting multicast data they wanted πŸ’€

pimInvalidJoinPruneAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type stored in pimInvalidJoinPruneOrigin,
            pimInvalidJoinPruneGroup, and pimInvalidJoinPruneRp.

            If no invalid Join/Prune messages have been received, this
            object is set to unknown(0)."
    ::= { pim 39 }

this one is the label on the three invalid-join addresses, so you know what kind of address you're looking at 🌸 if nothing invalid has shown up yet, it just sits at unknown(0) 🧚

pimInvalidJoinPruneOrigin OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The source address of the last invalid Join/Prune message
            received by this device."
    ::= { pim 40 }

pimInvalidJoinPruneGroup OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The IP multicast group address carried in the last
            invalid Join/Prune message received by this device."
    ::= { pim 41 }

pimInvalidJoinPruneRp OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The RP address carried in the last invalid Join/Prune
            message received by this device."
    ::= { pim 42 }

so these three are the receipts for the most recent bad message 🧾 origin is who sent it, group is which multicast group it was about, and RP is the rendezvous point it named ✨ it's always just the last one, not a full history, so keep that in mind bestie πŸ’–

pimRPMappingNotificationPeriod OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The minimum time that must elapse between
            pimRPMappingChange notifications originated by this router.
            The default value of 65535 represents an 'infinite' time, in
            which case, no pimRPMappingChange notifications are ever
            sent.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    DEFVAL { 65535 }
    ::= { pim 43 }

this is the throttle for RP mapping change notifications πŸŽ€ 65535 is the default and it basically means "never send them" lol, so if you want alerts, you gotta set a real number πŸ”” the storage type follows pimDeviceConfigStorageType, which is giving main character energy πŸ‘‘

pimRPMappingChangeCount OBJECT-TYPE
    SYNTAX     Counter32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of changes to active RP mappings on this device.

            Information about active RP mappings is available in
            pimGroupMappingTable.  Only changes to active mappings cause
            this counter to be incremented.  That is, changes that
            modify the pimGroupMappingEntry with the highest precedence
            for a group (lowest value of pimGroupMappingPrecedence).

            Such changes may result from manual configuration of this
            device, or from automatic RP mapping discovery methods
            including the PIM Bootstrap Router (BSR) mechanism.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 5059"
    ::= { pim 44 }

this counter only ticks up when the active mapping changes, aka the one with the highest precedence for a group 🫢 that can come from someone typing config by hand or from the BSR doing its discovery thing 🌈

pimInterfaceElectionNotificationPeriod OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The minimum time that must elapse between
            pimInterfaceElection notifications originated by this
            router.  The default value of 65535 represents an 'infinite'
            time, in which case, no pimInterfaceElection notifications
            are ever sent.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    DEFVAL { 65535 }
    ::= { pim 45 }

same vibe as the RP mapping one, but for election notifications πŸ—³οΈ 65535 means no notifications ever, and the storage type again follows pimDeviceConfigStorageType πŸ’œ

pimInterfaceElectionWinCount OBJECT-TYPE
    SYNTAX     Counter32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The number of times this device has been elected DR or DF
            on any interface.

            Elections occur frequently on newly-active interfaces, as
            triggered Hellos establish adjacencies.  This counter is not
            incremented for elections on an interface until the first
            periodic Hello has been sent.  If this router is the DR or
            DF at the time of sending the first periodic Hello after
            interface activation, then this counter is incremented
            (once) at that time.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, for example,
            when the device is rebooted."
    REFERENCE "RFC 4601 section 4.3.2 and RFC 5015 section 3.5.2"
    ::= { pim 46 }

okay this one is lowkey so specific πŸ₯Ή elections happen a lot on brand-new interfaces while triggered Hellos are building adjacencies, but the counter waits until the first periodic Hello goes out before it counts anything πŸ¦‹ and if the router is DR or DF at that moment, it only gets bumped once

pimRefreshInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-write
    STATUS     current
    DESCRIPTION
            "The interval between successive State Refresh messages sent
            by an Originator.  This timer period is called the
            RefreshInterval in the PIM-DM specification.  This object is
            used only by PIM-DM.

            The storage type of this object is determined by
            pimDeviceConfigStorageType."
    REFERENCE "RFC 3973 section 4.8"
    DEFVAL { 60 }
    ::= { pim 47 }

this is the gap between State Refresh messages from an Originator, and it's only used by PIM-DM so don't go looking for it anywhere else 🌸 default is 60 seconds ⏱️ the storage type once again follows pimDeviceConfigStorageType

pimDeviceConfigStorageType OBJECT-TYPE
    SYNTAX      StorageType
    MAX-ACCESS  read-write
    STATUS      current
    DESCRIPTION
            "The storage type used for the global PIM configuration of
            this device, comprised of the objects listed below.  If this
            storage type takes the value 'permanent', write-access to
            the listed objects need not be allowed.

            The objects described by this storage type are:
            pimKeepalivePeriod, pimRegisterSuppressionTime,
            pimNeighborLossNotificationPeriod,
            pimInvalidRegisterNotificationPeriod,
            pimInvalidJoinPruneNotificationPeriod,
            pimRPMappingNotificationPeriod,
            pimInterfaceElectionNotificationPeriod, and
            pimRefreshInterval."
    DEFVAL { nonVolatile }
    ::= { pim 48 }

this is the storage type for the whole global PIM config 🧚 it lists every object that follows it, and if it's 'permanent', write access to those listed objects doesn't have to be allowed πŸ’… default is nonVolatile


now we're entering the PIM Interface Table era πŸŽ€ this is the part where we get into per-interface stuff, so let's go 🫢

--
-- The PIM Interface Table
--

pimInterfaceTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimInterfaceEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the router's PIM interfaces.
            PIM is enabled on all interfaces listed in this table."
    ::= { pim 1 }

pimInterfaceEntry OBJECT-TYPE
    SYNTAX     PimInterfaceEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimInterfaceTable.  This
            entry is preserved on agent restart."
    INDEX      { pimInterfaceIfIndex,
                 pimInterfaceIPVersion }
    ::= { pimInterfaceTable 1 }

PimInterfaceEntry ::= SEQUENCE {
    pimInterfaceIfIndex              InterfaceIndex,
    pimInterfaceIPVersion            InetVersion,
    pimInterfaceAddressType          InetAddressType,
    pimInterfaceAddress              InetAddress,
    pimInterfaceGenerationIDValue    Unsigned32,
    pimInterfaceDR                   InetAddress,
    pimInterfaceDRPriority           Unsigned32,
    pimInterfaceDRPriorityEnabled    TruthValue,
    pimInterfaceHelloInterval        Unsigned32,
    pimInterfaceTrigHelloInterval    Unsigned32,
    pimInterfaceHelloHoldtime        Unsigned32,
    pimInterfaceJoinPruneInterval    Unsigned32,
    pimInterfaceJoinPruneHoldtime    Unsigned32,
    pimInterfaceDFElectionRobustness Unsigned32,
    pimInterfaceLanDelayEnabled      TruthValue,
    pimInterfacePropagationDelay     Unsigned32,
    pimInterfaceOverrideInterval     Unsigned32,
    pimInterfaceEffectPropagDelay    Unsigned32,
    pimInterfaceEffectOverrideIvl    Unsigned32,
    pimInterfaceSuppressionEnabled   TruthValue,
    pimInterfaceBidirCapable         TruthValue,
    pimInterfaceDomainBorder         TruthValue,
    pimInterfaceStubInterface        TruthValue,
    pimInterfacePruneLimitInterval   Unsigned32,
    pimInterfaceGraftRetryInterval   Unsigned32,
    pimInterfaceSRPriorityEnabled    TruthValue,
    pimInterfaceStatus               RowStatus,
    pimInterfaceStorageType          StorageType
}

pimInterfaceIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The ifIndex value of this PIM interface."
    ::= { pimInterfaceEntry 1 }

pimInterfaceIPVersion OBJECT-TYPE
    SYNTAX     InetVersion
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The IP version of this PIM interface.  A physical interface
            may be configured in multiple modes concurrently, e.g., IPv4
            and IPv6; however, the traffic is considered to be logically
            separate."

    ::= { pimInterfaceEntry 2 }

pimInterfaceAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of this PIM interface."
    ::= { pimInterfaceEntry 3 }

pimInterfaceAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary IP address of this router on this PIM
            interface.  The InetAddressType is given by the
            pimInterfaceAddressType object."
    REFERENCE "RFC 4601 sections 4.1.6, 4.3.1-4.3.4, and 4.5.1"
    ::= { pimInterfaceEntry 4 }

pimInterfaceGenerationIDValue OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of the Generation ID this router inserted in the
            last PIM Hello message it sent on this interface."
    REFERENCE "RFC 4601 section 4.3.1"
    ::= { pimInterfaceEntry 5 }

pimInterfaceDR OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary IP address of the Designated Router on this PIM
            interface.  The InetAddressType is given by the
            pimInterfaceAddressType object."
    REFERENCE "RFC 4601 section 4.3"
    ::= { pimInterfaceEntry 6 }

okay bestie, the DR Priority stuff is up next πŸ’– Here's pimInterfaceDRPriority. It's an Unsigned32 you can change on a row, and the default is 1. Whatever number you set goes into the DR Priority option of PIM Hello messages sent on that interface, and higher numbers mean higher priority πŸ‘‘

pimInterfaceDRPriority OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The Designated Router Priority value inserted into the DR
            Priority option in PIM Hello messages transmitted on this
            interface.  Numerically higher values for this object
            indicate higher priorities."
    REFERENCE "RFC 4601 section 4.3.2"
    DEFVAL { 1 }
    ::= { pimInterfaceEntry 7 }

pimInterfaceDRPriorityEnabled OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if all routers on this interface are
            using the DR Priority option."
    REFERENCE "RFC 4601 section 4.3.2"
    ::= { pimInterfaceEntry 8 }

pimInterfaceDRPriorityEnabled is the read-only check πŸ” It comes back TRUE when every router on the interface is using the DR Priority option. Iconic behaviour, honestly πŸ’…

pimInterfaceHelloInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..18000)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The frequency at which PIM Hello messages are transmitted
            on this interface.  This object corresponds to the
            'Hello_Period' timer value defined in the PIM-SM
            specification.  A value of zero represents an 'infinite'
            interval, and indicates that periodic PIM Hello messages
            should not be sent on this interface."
    REFERENCE "RFC 4601 section 9"
    DEFVAL { 30 }
    ::= { pimInterfaceEntry 9 }

pimInterfaceTrigHelloInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..60)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The maximum time before this router sends a triggered PIM
            Hello message on this interface.  This object corresponds to
            the 'Trigered_Hello_Delay' timer value defined in the PIM-SM
            specification.  A value of zero has no special meaning and
            indicates that triggered PIM Hello messages should always be
            sent immediately."
    REFERENCE "RFC 4601 section 4.11"
    DEFVAL { 5 }
    ::= { pimInterfaceEntry 10 }

So pimInterfaceHelloInterval is how often Hello messages go out, in seconds, with a default of 30 ⏱️ Setting it to 0 is the "infinite" vibe, which means no periodic Hellos on that interface πŸ™ˆ pimInterfaceTrigHelloInterval is the max wait before a triggered Hello gets sent, default 5 seconds. A 0 here doesn't mean anything special. It just means triggered Hellos go out right away πŸ¦‹

pimInterfaceHelloHoldtime OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The value set in the Holdtime field of PIM Hello messages
            transmitted on this interface.  A value of 65535 represents
            an 'infinite' holdtime.  Implementations are recommended
            to use a holdtime that is 3.5 times the value of
            pimInterfaceHelloInterval, or 65535 if
            pimInterfaceHelloInterval is set to zero."
    REFERENCE "RFC 4601 sections 4.3.2 and 4.9.2"
    DEFVAL { 105 }
    ::= { pimInterfaceEntry 11 }

pimInterfaceJoinPruneInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..18000)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The frequency at which this router sends PIM Join/Prune
            messages on this PIM interface.  This object corresponds to
            the 't_periodic' timer value defined in the PIM-SM
            specification.  A value of zero represents an 'infinite'
            interval, and indicates that periodic PIM Join/Prune
            messages should not be sent on this interface."
    REFERENCE "RFC 4601 section 4.11"
    DEFVAL { 60 }
    ::= { pimInterfaceEntry 12 }

pimInterfaceJoinPruneHoldtime OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The value inserted into the Holdtime field of a PIM
            Join/Prune message sent on this interface.  A value of 65535
            represents an 'infinite' holdtime.  Implementations are
            recommended to use a holdtime that is 3.5 times the value of
            pimInterfaceJoinPruneInterval, or 65535 if
            pimInterfaceJoinPruneInterval is set to zero.  PIM-DM
            implementations are recommended to use the value of
            pimInterfacePruneLimitInterval."
    REFERENCE "RFC 4601 sections 4.5.3 and 4.9.5"
    DEFVAL { 210 }
    ::= { pimInterfaceEntry 13 }

pimInterfaceHelloHoldtime is the value that goes in the Holdtime field of Hello messages, default 105 ⏳ The doc recommends a holdtime of 3.5 times the Hello interval, or 65535 if that interval is 0. 65535 is also the "infinite" holdtime, so it's giving max patience 🫢 pimInterfaceJoinPruneInterval is the send frequency for Join/Prune messages (default 60 seconds). pimInterfaceJoinPruneHoldtime is the value that goes in the Holdtime field of those Join/Prune messages (default 210). The same 3.5x recommendation shows up here, and PIM-DM folks are pointed at pimInterfacePruneLimitInterval for this one 🌸

pimInterfaceDFElectionRobustness OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The minimum number of PIM DF-Election messages that must be
            lost in order for DF election on this interface to fail."
    DEFVAL { 3 }
    ::= { pimInterfaceEntry 14 }

pimInterfaceLanDelayEnabled OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if all routers on this interface are
            using the LAN Prune Delay option."
    REFERENCE "RFC 4601 sections 4.3.3 and 4.9.2"
    ::= { pimInterfaceEntry 15 }

pimInterfaceDFElectionRobustness is about how many DF-Election messages have to get lost before DF election on the interface fails, and the default is 3 🧠 pimInterfaceLanDelayEnabled is another read-only check that comes back TRUE when every router on the interface is using the LAN Prune Delay option ✨

pimInterfacePropagationDelay OBJECT-TYPE
    SYNTAX     Unsigned32 (0..32767)
    UNITS      "milliseconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The expected propagation delay between PIM routers on this
            network or link.

            This router inserts this value into the Propagation_Delay
            field of the LAN Prune Delay option in the PIM Hello
            messages sent on this interface.  Implementations SHOULD
            enforce a lower bound on the permitted values for this
            object to allow for scheduling and processing delays within
            the local router."
    DEFVAL { 500 }
    ::= { pimInterfaceEntry 16 }

pimInterfaceOverrideInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "milliseconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The value this router inserts into the Override_Interval
            field of the LAN Prune Delay option in the PIM Hello
            messages it sends on this interface.

            When overriding a prune, PIM routers pick a random timer
            duration up to the value of this object.  The more PIM
            routers that are active on a network, the more likely it is
            that the prune will be overridden after a small proportion
            of this time has elapsed.

            The more PIM routers are active on this network, the larger
            this object should be to obtain an optimal spread of prune
            override latencies."
    REFERENCE "RFC 4601 section 4.3.3"
    DEFVAL { 2500 }
    ::= { pimInterfaceEntry 17 }

pimInterfacePropagationDelay is the expected propagation delay between PIM routers on the network or link, in milliseconds, default 500 🌈 The router drops this value into the Propagation_Delay field of the LAN Prune Delay option in its Hellos. The doc says implementations SHOULD enforce a lower bound on what you're allowed to set, so the router has room for its own scheduling and processing delays πŸ“

pimInterfaceOverrideInterval is what gets inserted into the Override_Interval field, default 2500 ms. When a prune is being overridden, routers pick a random timer up to this value. More routers on the network means the prune is more likely to get overridden after just a small chunk of that time, and the doc says a bigger number is better for a nice spread of override latencies when more routers are around πŸŽ€

pimInterfaceEffectPropagDelay OBJECT-TYPE
    SYNTAX     Unsigned32 (0..32767)
    UNITS      "milliseconds"
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The Effective Propagation Delay on this interface.  This
            object is always 500 if pimInterfaceLanDelayEnabled is
            FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimInterfaceEntry 18 }

pimInterfaceEffectOverrideIvl OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "milliseconds"
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The Effective Override Interval on this interface.  This
            object is always 2500 if pimInterfaceLanDelayEnabled is
            FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimInterfaceEntry 19 }

pimInterfaceSuppressionEnabled OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether join suppression is enabled on this interface.
            This object is always TRUE if pimInterfaceLanDelayEnabled is
            FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimInterfaceEntry 20 }

pimInterfaceBidirCapable OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if all routers on this interface are
            using the Bidirectional-PIM Capable option."
    REFERENCE "RFC 5015 section 3.2 and 3.7.4"
    ::= { pimInterfaceEntry 21 }

These four are the read-only "what's actually happening" objects πŸ‘€ pimInterfaceEffectPropagDelay is the Effective Propagation Delay, and it's always 500 whenever pimInterfaceLanDelayEnabled is FALSE. pimInterfaceEffectOverrideIvl is the Effective Override Interval, and it's always 2500 in that same FALSE situation πŸ’… pimInterfaceSuppressionEnabled says whether join suppression is on, and it's always TRUE when LAN delay is FALSE. pimInterfaceBidirCapable comes back TRUE when every router on the interface is using the Bidirectional-PIM Capable option πŸ¦‹

pimInterfaceDomainBorder OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "Whether or not this interface is a PIM domain border.  This
            includes acting as a border for PIM Bootstrap Router (BSR)
            messages, if the BSR mechanism is in use."
    DEFVAL { false }
    ::= { pimInterfaceEntry 22 }

pimInterfaceStubInterface OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "Whether this interface is a 'stub interface'.  If this
            object is set to TRUE, then no PIM packets are sent out this
            interface, and any received PIM packets are ignored.

            Setting this object to TRUE is a security measure for
            interfaces towards untrusted hosts.  This allows an
            interface to be configured for use with IGMP (Internet Group
            Management Protocol) or MLD (Multicast Listener Discovery)
            only, which protects the PIM router from forged PIM messages
            on the interface.

            To communicate with other PIM routers using this interface,
            this object must remain set to FALSE.

            Changing the value of this object while the interface is
            operational causes PIM to be disabled and then re-enabled on
            this interface."
    REFERENCE "RFC 3376, RFC 3810"
    DEFVAL { false }
    ::= { pimInterfaceEntry 23 }

pimInterfaceDomainBorder is a yes/no for whether the interface is a PIM domain border, and it defaults to false 🚧 It also covers acting as a border for PIM Bootstrap Router messages, but only if the BSR mechanism is in use.

⚠️ pimInterfaceStubInterface is the security one, so pay attention bestie πŸ”’ When it's TRUE, no PIM packets go out this interface and any received PIM packets get ignored. The doc calls this a security measure for interfaces facing untrusted hosts, since you can use the interface just for IGMP or MLD and the router is protected from forged PIM messages. If you want to talk to other PIM routers over this interface, it has to stay FALSE. Also, changing it while the interface is running turns PIM off and back on again on that interface 😭
pimInterfacePruneLimitInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The minimum interval that must transpire between two
            successive Prunes sent by a router.  This object corresponds
            to the 't_limit' timer value defined in the PIM-DM
            specification.  This object is used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.8"
    DEFVAL { 60 }
    ::= { pimInterfaceEntry 24 }

pimInterfaceGraftRetryInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    UNITS      "seconds"
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The minimum interval that must transpire between two
            successive Grafts sent by a router.  This object corresponds
            to the 'Graft_Retry_Period' timer value defined in the
            PIM-DM specification.  This object is used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.8"
    DEFVAL { 3 }
    ::= { pimInterfaceEntry 25 }

pimInterfaceSRPriorityEnabled OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if all routers on this interface are
            using the State Refresh option.  This object is used only by
            PIM-DM."
    ::= { pimInterfaceEntry 26 }

These next ones are PIM-DM territory 🌊 pimInterfacePruneLimitInterval is the minimum gap between two successive Prunes from a router, default 60 seconds, and it's the t_limit timer. pimInterfaceGraftRetryInterval is the minimum gap between two successive Grafts, default 3 seconds, and it's the Graft_Retry_Period timer. pimInterfaceSRPriorityEnabled is a read-only TRUE when every router on the interface is using the State Refresh option, and it's also PIM-DM only πŸ’œ

pimInterfaceStatus OBJECT-TYPE
    SYNTAX     RowStatus
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The status of this entry.  Creating the entry enables PIM
            on the interface; destroying the entry disables PIM on the
            interface.

            This status object can be set to active(1) without setting
            any other columnar objects in this entry.

            All writeable objects in this entry can be modified when the
            status of this entry is active(1)."
    ::= { pimInterfaceEntry 27 }

pimInterfaceStorageType OBJECT-TYPE
    SYNTAX      StorageType
    MAX-ACCESS  read-create
    STATUS      current
    DESCRIPTION
            "The storage type for this row.  Rows having the value
            'permanent' need not allow write-access to any columnar
            objects in the row."
    DEFVAL { nonVolatile }
    ::= { pimInterfaceEntry 28 }

--
-- The PIM Neighbor Table
--

And here's the row lifecycle πŸŽ€ pimInterfaceStatus is the switch for the whole entry. Creating the entry turns PIM on for the interface, and destroying it turns PIM off. You can set it to active(1) without touching any other column in the entry, and once it's active, every writeable object in the entry can be changed πŸ¦‹ Last one is pimInterfaceStorageType, the storage type for the row, defaulting to nonVolatile. Rows marked 'permanent' don't need to allow write access to any of their columns 🌸

okay so this is the neighbor table bestie, where the router keeps track of who it's vibing with 🫢✨

pimNeighborTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimNeighborEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the router's PIM neighbors."
    ::= { pim 2 }

pimNeighborEntry OBJECT-TYPE
    SYNTAX     PimNeighborEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimNeighborTable."
    INDEX      { pimNeighborIfIndex,
                 pimNeighborAddressType,
                 pimNeighborAddress }
    ::= { pimNeighborTable 1 }

PimNeighborEntry ::= SEQUENCE {
    pimNeighborIfIndex              InterfaceIndex,
    pimNeighborAddressType          InetAddressType,
    pimNeighborAddress              InetAddress,
    pimNeighborGenerationIDPresent  TruthValue,
    pimNeighborGenerationIDValue    Unsigned32,
    pimNeighborUpTime               TimeTicks,
    pimNeighborExpiryTime           TimeTicks,
    pimNeighborDRPriorityPresent    TruthValue,
    pimNeighborDRPriority           Unsigned32,
    pimNeighborLanPruneDelayPresent TruthValue,
    pimNeighborTBit                 TruthValue,
    pimNeighborPropagationDelay     Unsigned32,
    pimNeighborOverrideInterval     Unsigned32,
    pimNeighborBidirCapable         TruthValue,
    pimNeighborSRCapable            TruthValue
}

pimNeighborIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The value of ifIndex for the interface used to reach this
            PIM neighbor."
    ::= { pimNeighborEntry 1 }

pimNeighborAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of this PIM neighbor."
    ::= { pimNeighborEntry 2 }

pimNeighborAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The primary IP address of this PIM neighbor.  The
            InetAddressType is given by the pimNeighborAddressType
            object."
    ::= { pimNeighborEntry 3 }

pimNeighborGenerationIDPresent OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if this neighbor is using the Generation
            ID option."
    REFERENCE "RFC 4601 section 4.3.1"
    ::= { pimNeighborEntry 4 }

pimNeighborGenerationIDValue OBJECT-TYPE

    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of the Generation ID from the last PIM Hello
            message received from this neighbor.  This object is always
            zero if pimNeighborGenerationIDPresent is FALSE."
    REFERENCE "RFC 4601 section 4.3.1"
    ::= { pimNeighborEntry 5 }

pimNeighborUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this PIM neighbor (last) became a neighbor
            of the local router."
    ::= { pimNeighborEntry 6 }

pimNeighborExpiryTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The minimum time remaining before this PIM neighbor will
            time out.  The value zero indicates that this PIM neighbor
            will never time out."
    ::= { pimNeighborEntry 7 }

pimNeighborDRPriorityPresent OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if this neighbor is using the DR Priority
            option."
    REFERENCE "RFC 4601 section 4.3.2"
    ::= { pimNeighborEntry 8 }

pimNeighborDRPriority OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of the Designated Router Priority from the last
            PIM Hello message received from this neighbor.  This object
            is always zero if pimNeighborDRPriorityPresent is FALSE."
    REFERENCE "RFC 4601 section 4.3.2"
    ::= { pimNeighborEntry 9 }

pimNeighborLanPruneDelayPresent OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if this neighbor is using the LAN Prune
            Delay option."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimNeighborEntry 10 }

pimNeighborTBit OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the T bit was set in the LAN Prune Delay option
            received from this neighbor.  The T bit specifies the
            ability of the neighbor to disable join suppression.  This
            object is always TRUE if pimNeighborLanPruneDelayPresent is
            FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimNeighborEntry 11 }

pimNeighborPropagationDelay OBJECT-TYPE
    SYNTAX     Unsigned32 (0..32767)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of the Propagation_Delay field of the LAN Prune
            Delay option received from this neighbor.  This object is
            always zero if pimNeighborLanPruneDelayPresent is FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimNeighborEntry 12 }

pimNeighborOverrideInterval OBJECT-TYPE
    SYNTAX     Unsigned32 (0..65535)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of the Override_Interval field of the LAN Prune
            Delay option received from this neighbor.  This object is
            always zero if pimNeighborLanPruneDelayPresent is FALSE."
    REFERENCE "RFC 4601 section 4.3.3"
    ::= { pimNeighborEntry 13 }

pimNeighborBidirCapable OBJECT-TYPE

    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if this neighbor is using the
            Bidirectional-PIM Capable option."
    REFERENCE "RFC 5015 section 3.2 and 3.7.4"
    ::= { pimNeighborEntry 14 }

pimNeighborSRCapable OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Evaluates to TRUE if this neighbor is using the State
            Refresh Capable option.  This object is used only by
            PIM-DM."
    REFERENCE "RFC 3973 section 4.3.4"
    ::= { pimNeighborEntry 15 }

next up is the secondary address table, which is basically the neighbor's extra addresses hanging off the main one 🌸

--
-- The PIM Neighbor Secondary Address Table
--

pimNbrSecAddressTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimNbrSecAddressEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the secondary addresses
            advertised by each PIM neighbor (on a subset of the rows of
            the pimNeighborTable defined above)."
    REFERENCE "RFC 4601 section 4.3.4"
    ::= { pim 3 }

pimNbrSecAddressEntry OBJECT-TYPE
    SYNTAX     PimNbrSecAddressEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimNbrSecAddressTable."
    INDEX      { pimNbrSecAddressIfIndex,
                 pimNbrSecAddressType,
                 pimNbrSecAddressPrimary,
                 pimNbrSecAddress }
    ::= { pimNbrSecAddressTable 1 }

PimNbrSecAddressEntry ::= SEQUENCE {

    pimNbrSecAddressIfIndex InterfaceIndex,
    pimNbrSecAddressType    InetAddressType,
    pimNbrSecAddressPrimary InetAddress,
    pimNbrSecAddress        InetAddress
}

pimNbrSecAddressIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The value of ifIndex for the interface used to reach this
            PIM neighbor."
    ::= { pimNbrSecAddressEntry 1 }

pimNbrSecAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of this PIM neighbor."
    ::= { pimNbrSecAddressEntry 2 }

pimNbrSecAddressPrimary OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The primary IP address of this PIM neighbor.  The
            InetAddressType is given by the pimNbrSecAddressType
            object."
    ::= { pimNbrSecAddressEntry 3 }

pimNbrSecAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The secondary IP address of this PIM neighbor.  The
            InetAddressType is given by the pimNbrSecAddressType
            object."
    ::= { pimNbrSecAddressEntry 4 }

and now we're on to the (*,G) state table, the non-interface-specific stuff that PIM is tracking, so it's giving main character energy πŸ‘‘πŸ¦‹

--
-- The PIM (*,G) State Table
--

pimStarGTable OBJECT-TYPE

    SYNTAX     SEQUENCE OF PimStarGEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the non-interface specific
            (*,G) state that PIM has."
    REFERENCE "RFC 4601 section 4.1.3"
    ::= { pim 4 }

pimStarGEntry OBJECT-TYPE
    SYNTAX     PimStarGEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimStarGTable."
    INDEX      { pimStarGAddressType,
                 pimStarGGrpAddress }
    ::= { pimStarGTable 1 }

PimStarGEntry ::= SEQUENCE {
    pimStarGAddressType             InetAddressType,
    pimStarGGrpAddress              InetAddress,
    pimStarGUpTime                  TimeTicks,
    pimStarGPimMode                 PimMode,
    pimStarGRPAddressType           InetAddressType,
    pimStarGRPAddress               InetAddress,
    pimStarGPimModeOrigin           PimGroupMappingOriginType,
    pimStarGRPIsLocal               TruthValue,
    pimStarGUpstreamJoinState       INTEGER,
    pimStarGUpstreamJoinTimer       TimeTicks,
    pimStarGUpstreamNeighborType    InetAddressType,
    pimStarGUpstreamNeighbor        InetAddress,
    pimStarGRPFIfIndex              InterfaceIndexOrZero,
    pimStarGRPFNextHopType          InetAddressType,
    pimStarGRPFNextHop              InetAddress,
    pimStarGRPFRouteProtocol        IANAipRouteProtocol,
    pimStarGRPFRouteAddress         InetAddress,
    pimStarGRPFRoutePrefixLength    InetAddressPrefixLength,
    pimStarGRPFRouteMetricPref      Unsigned32,
    pimStarGRPFRouteMetric          Unsigned32
}

pimStarGAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of this multicast group."

    ::= { pimStarGEntry 1 }

pimStarGGrpAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The multicast group address.  The InetAddressType is given
            by the pimStarGAddressType object."
    ::= { pimStarGEntry 2 }

pimStarGUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimStarGEntry 3 }

pimStarGPimMode OBJECT-TYPE
    SYNTAX     PimMode { asm(3), bidir(4) }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether this entry represents an ASM (Any Source Multicast,
            used with PIM-SM) or BIDIR-PIM group."
    ::= { pimStarGEntry 4 }

pimStarGRPAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the Rendezvous Point (RP), or
            unknown(0) if the RP address is unknown."
    ::= { pimStarGEntry 5 }

pimStarGRPAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address of the Rendezvous Point (RP) for the group.
            The InetAddressType is given by the pimStarGRPAddressType."
    ::= { pimStarGEntry 6 }

Picking up right where the (,G) table left off: the RPF info for the RP, then the wonderful (,G,I) per-interface table πŸ¦‹

pimStarGPimModeOrigin OBJECT-TYPE
    SYNTAX     PimGroupMappingOriginType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The mechanism by which the PIM mode and RP for the group
            were learned."
    ::= { pimStarGEntry 7 }

pimStarGRPIsLocal OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router is the RP for the group."
    ::= { pimStarGEntry 8 }

pimStarGUpstreamJoinState OBJECT-TYPE
    SYNTAX     INTEGER {
                  notJoined (1),
                  joined (2)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router should join the RP tree for the
            group.  This corresponds to the state of the upstream (*,G)
            state machine in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.5.6"
    ::= { pimStarGEntry 9 }

pimStarGUpstreamJoinTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router next sends a
            periodic (*,G) Join message on pimStarGRPFIfIndex.  This
            timer is called the (*,G) Upstream Join Timer in the PIM-SM
            specification.  This object is zero if the timer is not
            running."
    REFERENCE "RFC 4601 section 4.10"
    ::= { pimStarGEntry 10 }

pimStarGUpstreamNeighborType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary address type of the upstream neighbor, or
            unknown(0) if the upstream neighbor address is unknown or is
            not a PIM neighbor."
    ::= { pimStarGEntry 11 }

pimStarGUpstreamNeighbor OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary address of the neighbor on pimStarGRPFIfIndex
            that the local router is sending periodic (*,G) Join
            messages to.  The InetAddressType is given by the
            pimStarGUpstreamNeighborType object.  This address is called
            RPF'(*,G) in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.1.6"
    ::= { pimStarGEntry 12 }

pimStarGRPFIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndexOrZero
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of ifIndex for the Reverse Path Forwarding
            (RPF) interface towards the RP, or zero if the RPF
            interface is unknown."
    ::= { pimStarGEntry 13 }

pimStarGRPFNextHopType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the RPF next hop towards the RP, or
            unknown(0) if the RPF next hop is unknown."
    ::= { pimStarGEntry 14 }

pimStarGRPFNextHop OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address of the RPF next hop towards the RP.  The
            InetAddressType is given by the pimStarGRPFNextHopType
            object.  This address is called MRIB.next_hop(RP(G))
            in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.5.5"
    ::= { pimStarGEntry 15 }

pimStarGRPFRouteProtocol OBJECT-TYPE
    SYNTAX     IANAipRouteProtocol
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The routing mechanism via which the route used to find the
            RPF interface towards the RP was learned."
    ::= { pimStarGEntry 16 }

pimStarGRPFRouteAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The IP address that, when combined with the corresponding
            value of pimStarGRPFRoutePrefixLength, identifies the route
            used to find the RPF interface towards the RP.  The
            InetAddressType is given by the pimStarGRPFNextHopType
            object.

            This address object is only significant up to
            pimStarGRPFRoutePrefixLength bits.  The remainder of the
            address bits are zero."
    ::= { pimStarGEntry 17 }

pimStarGRPFRoutePrefixLength OBJECT-TYPE
    SYNTAX     InetAddressPrefixLength
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The prefix length that, when combined with the
            corresponding value of pimStarGRPFRouteAddress, identifies
            the route used to find the RPF interface towards the RP.
            The InetAddressType is given by the pimStarGRPFNextHopType
            object."
    ::= { pimStarGEntry 18 }

pimStarGRPFRouteMetricPref OBJECT-TYPE
    SYNTAX     Unsigned32 (0..2147483647)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The metric preference of the route used to find the RPF
            interface towards the RP."
    ::= { pimStarGEntry 19 }

pimStarGRPFRouteMetric OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The routing metric of the route used to find the RPF
            interface towards the RP."
    ::= { pimStarGEntry 20 }

The PIM (*,G,I) State Table

Okay, so this is where the per-interface stuff lives 🌸 It's giving "one row for every interface that (*,G) cares about," and the index is basically the group address type, the group address, and the ifIndex. Iconic, honestly πŸ’…

--
-- The PIM (*,G,I) State Table
--

pimStarGITable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimStarGIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the interface-specific (*,G)
            state that PIM has."
    REFERENCE "RFC 4601 section 4.1.3"
    ::= { pim 5 }

pimStarGIEntry OBJECT-TYPE
    SYNTAX     PimStarGIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimStarGITable."
    INDEX      { pimStarGAddressType,
                 pimStarGGrpAddress,
                 pimStarGIIfIndex }
    ::= { pimStarGITable 1 }

PimStarGIEntry ::= SEQUENCE {
    pimStarGIIfIndex                 InterfaceIndex,
    pimStarGIUpTime                  TimeTicks,
    pimStarGILocalMembership         TruthValue,
    pimStarGIJoinPruneState          INTEGER,
    pimStarGIPrunePendingTimer       TimeTicks,
    pimStarGIJoinExpiryTimer         TimeTicks,
    pimStarGIAssertState             INTEGER,
    pimStarGIAssertTimer             TimeTicks,
    pimStarGIAssertWinnerAddressType InetAddressType,
    pimStarGIAssertWinnerAddress     InetAddress,
    pimStarGIAssertWinnerMetricPref  Unsigned32,
    pimStarGIAssertWinnerMetric      Unsigned32
}

pimStarGIIfIndex OBJECT-TYPE

    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The ifIndex of the interface that this entry corresponds
            to."
    ::= { pimStarGIEntry 1 }

pimStarGIUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimStarGIEntry 2 }

pimStarGILocalMembership OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router has (*,G) local membership on this
            interface (resulting from a mechanism such as IGMP or MLD).
            This corresponds to local_receiver_include(*,G,I) in the
            PIM-SM specification."
    REFERENCE "RFC 3376, RFC 3810, and RFC 4601 section 4.1.6"
    ::= { pimStarGIEntry 3 }

pimStarGIJoinPruneState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  join (2),
                  prunePending (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The state resulting from (*,G) Join/Prune messages
            received on this interface.  This corresponds to the state
            of the downstream per-interface (*,G) state machine in the
            PIM-SM specification."
    REFERENCE "RFC 4601 section 4.5.2"
    ::= { pimStarGIEntry 4 }

pimStarGIPrunePendingTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router acts on a (*,G)
            Prune message received on this interface, during which the
            router is waiting to see whether another downstream router
            will override the Prune message.  This timer is called the
            (*,G) Prune-Pending Timer in the PIM-SM specification.  This
            object is zero if the timer is not running."
    REFERENCE "RFC 4601 section 4.5.1"
    ::= { pimStarGIEntry 5 }

pimStarGIJoinExpiryTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before (*,G) Join state for this
            interface expires.  This timer is called the (*,G) Join
            Expiry Timer in the PIM-SM specification.  This object is
            zero if the timer is not running.  A value of 'FFFFFFFF'h
            indicates an infinite expiry time."
    REFERENCE "RFC 4601 section 4.10"
    ::= { pimStarGIEntry 6 }

pimStarGIAssertState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  iAmAssertWinner (2),
                  iAmAssertLoser (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The (*,G) Assert state for this interface.  This
            corresponds to the state of the per-interface (*,G) Assert
            state machine in the PIM-SM specification.  If
            pimStarGPimMode is 'bidir', this object must be 'noInfo'."
    REFERENCE "RFC 4601 section 4.6.2"
    ::= { pimStarGIEntry 7 }

pimStarGIAssertTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimStarGIAssertState is 'iAmAssertWinner', this is the
            time remaining before the local router next sends a (*,G)
            Assert message on this interface.  If pimStarGIAssertState
            is 'iAmAssertLoser', this is the time remaining before the
            (*,G) Assert state expires.  If pimStarGIAssertState is
            'noInfo', this is zero.  This timer is called the (*,G)
            Assert Timer in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.6.2"
    ::= { pimStarGIEntry 8 }

pimStarGIAssertWinnerAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimStarGIAssertState is 'iAmAssertLoser', this is the
            address type of the assert winner; otherwise, this object is
            unknown(0)."
    ::= { pimStarGIEntry 9 }

pimStarGIAssertWinnerAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimStarGIAssertState is 'iAmAssertLoser', this is the
            address of the assert winner.  The InetAddressType is given
            by the pimStarGIAssertWinnerAddressType object."
    ::= { pimStarGIEntry 10 }

pimStarGIAssertWinnerMetricPref OBJECT-TYPE
    SYNTAX     Unsigned32 (0..2147483647)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimStarGIAssertState is 'iAmAssertLoser', this is the
            metric preference of the route to the RP advertised by the
            assert winner; otherwise, this object is zero."
    ::= { pimStarGIEntry 11 }

pimStarGIAssertWinnerMetric OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimStarGIAssertState is 'iAmAssertLoser', this is the
            routing metric of the route to the RP advertised by the
            assert winner; otherwise, this object is zero."
    ::= { pimStarGIEntry 12 }

--
-- The PIM (S,G) State Table
--

Okay that's the whole (*,G,I) table, bestie πŸ§šπŸ’œ Next up is the (S,G) table, and I'm lowkey so ready 🫢✨

Okay bestie, we're back in the (S,G) state table and it's giving main character energy πŸ’– Here's the whole table, entry, and object lineup, with every field, index, and reference exactly as it's written πŸŽ€

pimSGTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimSGEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the non-interface specific
            (S,G) state that PIM has."
    REFERENCE "RFC 4601 section 4.1.4"
    ::= { pim 6 }

pimSGEntry OBJECT-TYPE
    SYNTAX     PimSGEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimSGTable."
    INDEX      { pimSGAddressType,
                 pimSGGrpAddress,
                 pimSGSrcAddress }
    ::= { pimSGTable 1 }

PimSGEntry ::= SEQUENCE {
    pimSGAddressType               InetAddressType,
    pimSGGrpAddress                InetAddress,
    pimSGSrcAddress                InetAddress,
    pimSGUpTime                    TimeTicks,
    pimSGPimMode                   PimMode,
    pimSGUpstreamJoinState         INTEGER,
    pimSGUpstreamJoinTimer         TimeTicks,
    pimSGUpstreamNeighbor          InetAddress,
    pimSGRPFIfIndex                InterfaceIndexOrZero,
    pimSGRPFNextHopType            InetAddressType,
    pimSGRPFNextHop                InetAddress,
    pimSGRPFRouteProtocol          IANAipRouteProtocol,
    pimSGRPFRouteAddress           InetAddress,
    pimSGRPFRoutePrefixLength      InetAddressPrefixLength,
    pimSGRPFRouteMetricPref        Unsigned32,
    pimSGRPFRouteMetric            Unsigned32,
    pimSGSPTBit                    TruthValue,
    pimSGKeepaliveTimer            TimeTicks,
    pimSGDRRegisterState           INTEGER,
    pimSGDRRegisterStopTimer       TimeTicks,
    pimSGRPRegisterPMBRAddressType InetAddressType,
    pimSGRPRegisterPMBRAddress     InetAddress,
    pimSGUpstreamPruneState        INTEGER,
    pimSGUpstreamPruneLimitTimer   TimeTicks,
    pimSGOriginatorState           INTEGER,
    pimSGSourceActiveTimer         TimeTicks,
    pimSGStateRefreshTimer         TimeTicks
}

pimSGAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of the source and multicast group for this
            entry."
    ::= { pimSGEntry 1 }

pimSGGrpAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The multicast group address for this entry.  The
            InetAddressType is given by the pimSGAddressType object."
    ::= { pimSGEntry 2 }

pimSGSrcAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The source address for this entry.  The InetAddressType is
            given by the pimSGAddressType object."
    ::= { pimSGEntry 3 }

pimSGUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimSGEntry 4 }

pimSGPimMode OBJECT-TYPE
    SYNTAX     PimMode { ssm(2), asm(3) }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether pimSGGrpAddress is an SSM (Source Specific
            Multicast, used with PIM-SM) or ASM (Any Source Multicast,
            used with PIM-SM) group."

    REFERENCE "RFC 4601 section 4.5.2, RFC 3569, and
               'IP Multicast MIB' (August 2007) ipMcastSsmRangeTable"
    ::= { pimSGEntry 5 }

pimSGUpstreamJoinState OBJECT-TYPE
    SYNTAX     INTEGER {
                  notJoined (1),
                  joined (2)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router should join the shortest-path tree
            for the source and group represented by this entry.  This
            corresponds to the state of the upstream (S,G) state machine
            in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.5.7"
    ::= { pimSGEntry 6 }

pimSGUpstreamJoinTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router next sends a
            periodic (S,G) Join message on pimSGRPFIfIndex.  This timer
            is called the (S,G) Upstream Join Timer in the PIM-SM
            specification.  This object is zero if the timer is not
            running."
    REFERENCE "RFC 4601 sections 4.10 and 4.11"
    ::= { pimSGEntry 7 }

pimSGUpstreamNeighbor OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary address of the neighbor on pimSGRPFIfIndex that
            the local router is sending periodic (S,G) Join messages to.
            This is zero if the RPF next hop is unknown or is not a
            PIM neighbor.  The InetAddressType is given by the
            pimSGAddressType object.  This address is called RPF'(S,G)
            in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.1.6"
    ::= { pimSGEntry 8 }

pimSGRPFIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndexOrZero
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The value of ifIndex for the RPF interface towards the
            source, or zero if the RPF interface is unknown."
    ::= { pimSGEntry 9 }

pimSGRPFNextHopType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the RPF next hop towards the source, or
            unknown(0) if the RPF next hop is unknown."
    ::= { pimSGEntry 10 }

pimSGRPFNextHop OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address of the RPF next hop towards the source.  The
            InetAddressType is given by the pimSGRPFNextHopType.  This
            address is called MRIB.next_hop(S) in the PIM-SM
            specification."
    REFERENCE "RFC 4601 section 4.5.5"
    ::= { pimSGEntry 11 }

pimSGRPFRouteProtocol OBJECT-TYPE
    SYNTAX     IANAipRouteProtocol
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The routing mechanism via which the route used to find the
            RPF interface towards the source was learned."
    ::= { pimSGEntry 12 }

pimSGRPFRouteAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The IP address that, when combined with the corresponding
            value of pimSGRPFRoutePrefixLength, identifies the route
            used to find the RPF interface towards the source.  The
            InetAddressType is given by the pimSGRPFNextHopType object.

            This address object is only significant up to
            pimSGRPFRoutePrefixLength bits.  The remainder of the
            address bits are zero."
    ::= { pimSGEntry 13 }

pimSGRPFRoutePrefixLength OBJECT-TYPE
    SYNTAX     InetAddressPrefixLength
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The prefix length that, when combined with the
            corresponding value of pimSGRPFRouteAddress, identifies the
            route used to find the RPF interface towards the source.
            The InetAddressType is given by the pimSGRPFNextHopType
            object."
    ::= { pimSGEntry 14 }

pimSGRPFRouteMetricPref OBJECT-TYPE
    SYNTAX     Unsigned32 (0..2147483647)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The metric preference of the route used to find the RPF
            interface towards the source."
    ::= { pimSGEntry 15 }

pimSGRPFRouteMetric OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The routing metric of the route used to find the RPF
            interface towards the source."
    ::= { pimSGEntry 16 }

pimSGSPTBit OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the SPT bit is set; and therefore whether
            forwarding is taking place on the shortest-path tree."
    ::= { pimSGEntry 17 }

pimSGKeepaliveTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION

            "The time remaining before this (S,G) state expires, in
            the absence of explicit (S,G) local membership or (S,G)
            Join messages received to maintain it.  This timer is
            called the (S,G) Keepalive Timer in the PIM-SM
            specification."
    REFERENCE "RFC 4601 section 4.1.4"
    ::= { pimSGEntry 18 }

pimSGDRRegisterState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  join (2),
                  joinPending (3),
                  prune (4)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router should encapsulate (S,G) data
            packets in Register messages and send them to the RP.  This
            corresponds to the state of the per-(S,G) Register state
            machine in the PIM-SM specification.  This object is always
            'noInfo' unless pimSGPimMode is 'asm'."
    REFERENCE "RFC 4601 section 4.4.1"
    ::= { pimSGEntry 19 }

pimSGDRRegisterStopTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGDRRegisterState is 'prune', this is the time
            remaining before the local router sends a Null-Register
            message to the RP.  If pimSGDRRegisterState is
            'joinPending', this is the time remaining before the local
            router resumes encapsulating data packets and sending them
            to the RP.  Otherwise, this is zero.  This timer is called
            the Register-Stop Timer in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.4"
    ::= { pimSGEntry 20 }

pimSGRPRegisterPMBRAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The address type of the first PIM Multicast Border Router
            to send a Register message with the Border bit set.  This
            object is unknown(0) if the local router is not the RP for
            the group."
    ::= { pimSGEntry 21 }

pimSGRPRegisterPMBRAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The IP address of the first PIM Multicast Border Router to
            send a Register message with the Border bit set.  The
            InetAddressType is given by the
            pimSGRPRegisterPMBRAddressType object."
    ::= { pimSGEntry 22 }

pimSGUpstreamPruneState OBJECT-TYPE
    SYNTAX     INTEGER {
                  forwarding (1),
                  ackpending (2),
                  pruned (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router has pruned itself from the tree.
            This corresponds to the state of the upstream prune (S,G)
            state machine in the PIM-DM specification.  This object is
            used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.4.1"
    ::= { pimSGEntry 23 }

pimSGUpstreamPruneLimitTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router may send a (S,G)
            Prune message on pimSGRPFIfIndex.  This timer is called the
            (S,G) Prune Limit Timer in the PIM-DM specification.  This
            object is zero if the timer is not running.  This object is
            used only by PIM-DM."
    REFERENCE "RFC 2973 section 4.8"
    ::= { pimSGEntry 24 }

Okay bestie, we're picking up with the PIM-DM originator stuff, and honestly it's giving main character energy πŸ’…βœ¨

pimSGOriginatorState OBJECT-TYPE
    SYNTAX     INTEGER {
                  notOriginator (1),
                  originator (2)

               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the router is an originator for an (S,G) message
            flow.  This corresponds to the state of the per-(S,G)
            Originator state machine in the PIM-DM specification.  This
            object is used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.5.2"
    ::= { pimSGEntry 25 }

pimSGSourceActiveTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGOriginatorState is 'originator', this is the time
            remaining before the local router reverts to a notOriginator
            state.  Otherwise, this is zero.  This timer is called the
            Source Active Timer in the PIM-DM specification.  This
            object is used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.8"
    ::= { pimSGEntry 26 }

pimSGStateRefreshTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGOriginatorState is 'originator', this is the time
            remaining before the local router sends a State Refresh
            message.  Otherwise, this is zero.  This timer is called the
            State Refresh Timer in the PIM-DM specification.  This
            object is used only by PIM-DM."
    REFERENCE "RFC 3973 section 4.8"
    ::= { pimSGEntry 27 }

Next up is the (S,G,I) table, which is the interface-specific state, so every entry is basically its own little world 🌸

--
-- The PIM (S,G,I) State Table
--

pimSGITable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimSGIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the interface-specific (S,G)
            state that PIM has."

    REFERENCE "RFC 4601 section 4.1.4"
    ::= { pim 7 }

pimSGIEntry OBJECT-TYPE
    SYNTAX     PimSGIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimSGITable."
    INDEX      { pimSGAddressType,
                 pimSGGrpAddress,
                 pimSGSrcAddress,
                 pimSGIIfIndex }
    ::= { pimSGITable 1 }

PimSGIEntry ::= SEQUENCE {
    pimSGIIfIndex                 InterfaceIndex,
    pimSGIUpTime                  TimeTicks,
    pimSGILocalMembership         TruthValue,
    pimSGIJoinPruneState          INTEGER,
    pimSGIPrunePendingTimer       TimeTicks,
    pimSGIJoinExpiryTimer         TimeTicks,
    pimSGIAssertState             INTEGER,
    pimSGIAssertTimer             TimeTicks,
    pimSGIAssertWinnerAddressType InetAddressType,
    pimSGIAssertWinnerAddress     InetAddress,
    pimSGIAssertWinnerMetricPref  Unsigned32,
    pimSGIAssertWinnerMetric      Unsigned32
}

pimSGIIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The ifIndex of the interface that this entry corresponds
            to."
    ::= { pimSGIEntry 1 }

pimSGIUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimSGIEntry 2 }

pimSGILocalMembership OBJECT-TYPE

    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router has (S,G) local membership on this
            interface (resulting from a mechanism such as IGMP or MLD).
            This corresponds to local_receiver_include(S,G,I) in the
            PIM-SM specification."
    REFERENCE "RFC 3376, RFC 3810, RFC 4601 sections 4.1.6, 4.6.1, and
              4.6.2"
    ::= { pimSGIEntry 3 }

pimSGIJoinPruneState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  join (2),
                  prunePending (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The state resulting from (S,G) Join/Prune messages
            received on this interface.  This corresponds to the state
            of the downstream per-interface (S,G) state machine in the
            PIM-SM and PIM-DM specification."
    REFERENCE "RFC 4601 section 4.5.3 and RFC 3973 section 4.4.2"
    ::= { pimSGIEntry 4 }

pimSGIPrunePendingTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router acts on an (S,G)
            Prune message received on this interface, during which the
            router is waiting to see whether another downstream router
            will override the Prune message.  This timer is called the
            (S,G) Prune-Pending Timer in the PIM-SM specification.  This
            object is zero if the timer is not running."
    REFERENCE "RFC 4601 sections 4.5.3 and 4.5.4"
    ::= { pimSGIEntry 5 }

pimSGIJoinExpiryTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before (S,G) Join state for this
            interface expires.  This timer is called the (S,G) Join
            Expiry Timer in the PIM-SM specification.  This object is
            zero if the timer is not running.  A value of 'FFFFFFFF'h
            indicates an infinite expiry time.  This timer is called the
            (S,G) Prune Timer in the PIM-DM specification."
    REFERENCE "RFC 4601 section 4.10 and RFC 3973 section 4.8"
    ::= { pimSGIEntry 6 }

pimSGIAssertState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  iAmAssertWinner (2),
                  iAmAssertLoser (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The (S,G) Assert state for this interface.  This
            corresponds to the state of the per-interface (S,G) Assert
            state machine in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.6.1"
    ::= { pimSGIEntry 7 }

pimSGIAssertTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGIAssertState is 'iAmAssertWinner', this is the time
            remaining before the local router next sends a (S,G) Assert
            message on this interface.  If pimSGIAssertState is
            'iAmAssertLoser', this is the time remaining before the
            (S,G) Assert state expires.  If pimSGIAssertState is
            'noInfo', this is zero.  This timer is called the (S,G)
            Assert Timer in the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.6.1"
    ::= { pimSGIEntry 8 }

pimSGIAssertWinnerAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGIAssertState is 'iAmAssertLoser', this is the
            address type of the assert winner; otherwise, this object is
            unknown(0)."
    ::= { pimSGIEntry 9 }

pimSGIAssertWinnerAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGIAssertState is 'iAmAssertLoser', this is the
            address of the assert winner.  The InetAddressType is given
            by the pimSGIAssertWinnerAddressType object."
    ::= { pimSGIEntry 10 }

pimSGIAssertWinnerMetricPref OBJECT-TYPE
    SYNTAX     Unsigned32 (0..2147483647)
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGIAssertState is 'iAmAssertLoser', this is the
            metric preference of the route to the source advertised by
            the assert winner; otherwise, this object is zero."
    ::= { pimSGIEntry 11 }

pimSGIAssertWinnerMetric OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "If pimSGIAssertState is 'iAmAssertLoser', this is the
            routing metric of the route to the source advertised by the
            assert winner; otherwise, this object is zero."
    ::= { pimSGIEntry 12 }

Now the (S,G,rpt) table, the non-interface-specific one. It's the RP-tree side of the story and it's so dramatic πŸŽ€πŸ”₯

--
-- The PIM (S,G,rpt) State Table
--

pimSGRptTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimSGRptEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the non-interface specific
            (S,G,rpt) state that PIM has."
    REFERENCE "RFC 4601 section 4.1.5"
    ::= { pim 8 }

pimSGRptEntry OBJECT-TYPE
    SYNTAX     PimSGRptEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimSGRptTable."
    INDEX      { pimStarGAddressType,
                 pimStarGGrpAddress,
                 pimSGRptSrcAddress }
    ::= { pimSGRptTable 1 }

PimSGRptEntry ::= SEQUENCE {
    pimSGRptSrcAddress             InetAddress,
    pimSGRptUpTime                 TimeTicks,
    pimSGRptUpstreamPruneState     INTEGER,
    pimSGRptUpstreamOverrideTimer  TimeTicks
}

pimSGRptSrcAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The source address for this entry.  The InetAddressType is
            given by the pimStarGAddressType object."
    ::= { pimSGRptEntry 1 }

pimSGRptUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimSGRptEntry 2 }

pimSGRptUpstreamPruneState OBJECT-TYPE
    SYNTAX     INTEGER {
                  rptNotJoined (1),
                  pruned (2),
                  notPruned (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router should prune the source off the RP
            tree.  This corresponds to the state of the upstream
            (S,G,rpt) state machine for triggered messages in the PIM-SM
            specification."
    REFERENCE "RFC 4601 section 4.5.9"
    ::= { pimSGRptEntry 3 }

pimSGRptUpstreamOverrideTimer OBJECT-TYPE

    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router sends a
            triggered (S,G,rpt) Join message on pimStarGRPFIfIndex.
            This timer is called the (S,G,rpt) Upstream Override Timer
            in the PIM-SM specification.  This object is zero if the
            timer is not running."
    REFERENCE "RFC 4601 section 4.5.9"
    ::= { pimSGRptEntry 4 }

Last stretch for this part: the (S,G,rpt,I) table, which is the interface-specific version of the RP-tree state. We're almost through the pile πŸ¦‹

--
-- The PIM (S,G,rpt,I) State Table
--

pimSGRptITable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimSGRptIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the interface-specific
            (S,G,rpt) state that PIM has."
    REFERENCE "RFC 4601 section 4.1.5"
    ::= { pim 9 }

pimSGRptIEntry OBJECT-TYPE
    SYNTAX     PimSGRptIEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimSGRptITable."
    INDEX      { pimStarGAddressType,
                 pimStarGGrpAddress,
                 pimSGRptSrcAddress,
                 pimSGRptIIfIndex }
    ::= { pimSGRptITable 1 }

PimSGRptIEntry ::= SEQUENCE {
    pimSGRptIIfIndex            InterfaceIndex,
    pimSGRptIUpTime             TimeTicks,
    pimSGRptILocalMembership    TruthValue,
    pimSGRptIJoinPruneState     INTEGER,
    pimSGRptIPrunePendingTimer  TimeTicks,
    pimSGRptIPruneExpiryTimer   TimeTicks
}

pimSGRptIIfIndex OBJECT-TYPE

    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The ifIndex of the interface that this entry corresponds
            to."
    ::= { pimSGRptIEntry 1 }

pimSGRptIUpTime OBJECT-TYPE is up next, and it's giving table vibes πŸŽ€

pimSGRptIUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since this entry was created by the local router."
    ::= { pimSGRptIEntry 2 }

pimSGRptILocalMembership OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether the local router has both (*,G) include local
            membership and (S,G) exclude local membership on this
            interface (resulting from a mechanism such as IGMP or MLD).
            This corresponds to local_receiver_exclude(S,G,I) in the
            PIM-SM specification."
    REFERENCE "RFC 3376, RFC 3810, RFC 4601 section 4.1.6"
    ::= { pimSGRptIEntry 3 }

pimSGRptIJoinPruneState OBJECT-TYPE
    SYNTAX     INTEGER {
                  noInfo (1),
                  prune (2),
                  prunePending (3)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The state resulting from (S,G,rpt) Join/Prune messages
            received on this interface.  This corresponds to the state
            of the downstream per-interface (S,G,rpt) state machine in
            the PIM-SM specification."
    REFERENCE "RFC 4601 section 4.5.4"
    ::= { pimSGRptIEntry 4 }

pimSGRptIPrunePendingTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before the local router starts pruning
            this source off the RP tree.  This timer is called the
            (S,G,rpt) Prune-Pending Timer in the PIM-SM specification.
            This object is zero if the timer is not running."
    REFERENCE "RFC 4601 section 4.5.4"
    ::= { pimSGRptIEntry 5 }

pimSGRptIPruneExpiryTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time remaining before (S,G,rpt) Prune state for this
            interface expires.  This timer is called the (S,G,rpt)
            Prune Expiry Timer in the PIM-SM specification.  This object
            is zero if the timer is not running.  A value of 'FFFFFFFF'h
            indicates an infinite expiry time."
    REFERENCE "RFC 4601 section 4.5.4"
    ::= { pimSGRptIEntry 6 }

Okay bestie, now we're entering the PIM Bidir DF-Election Table πŸ’…βœ¨ This one tracks who wins the Designated Forwarder race for each RP and interface. Iconic behaviour, honestly πŸ‘‘

--
-- The PIM Bidir DF-Election Table
--

pimBidirDFElectionTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimBidirDFElectionEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing the per-RP Designated
            Forwarder (DF) Election state for each interface for all the
            RPs in BIDIR mode."
    REFERENCE "RFC 5015 section 3.5"
    ::= { pim 10 }

pimBidirDFElectionEntry OBJECT-TYPE
    SYNTAX     PimBidirDFElectionEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimBidirDFElectionTable."
    INDEX      { pimBidirDFElectionAddressType,
                 pimBidirDFElectionRPAddress,
                 pimBidirDFElectionIfIndex }
    ::= { pimBidirDFElectionTable 1 }

PimBidirDFElectionEntry ::= SEQUENCE {
    pimBidirDFElectionAddressType       InetAddressType,
    pimBidirDFElectionRPAddress         InetAddress,
    pimBidirDFElectionIfIndex           InterfaceIndex,
    pimBidirDFElectionWinnerAddressType InetAddressType,
    pimBidirDFElectionWinnerAddress     InetAddress,
    pimBidirDFElectionWinnerUpTime      TimeTicks,
    pimBidirDFElectionWinnerMetricPref  Unsigned32,
    pimBidirDFElectionWinnerMetric      Unsigned32,
    pimBidirDFElectionState             INTEGER,
    pimBidirDFElectionStateTimer        TimeTicks
}

pimBidirDFElectionAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of the RP for which the DF state is being
            maintained."
    ::= { pimBidirDFElectionEntry 1 }

pimBidirDFElectionRPAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The IP address of the RP for which the DF state is being
            maintained.  The InetAddressType is given by the
            pimBidirDFElectionAddressType object."
    ::= { pimBidirDFElectionEntry 2 }

pimBidirDFElectionIfIndex OBJECT-TYPE
    SYNTAX     InterfaceIndex
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The value of ifIndex for the interface for which the DF
            state is being maintained."
    ::= { pimBidirDFElectionEntry 3 }

pimBidirDFElectionWinnerAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary address type of the winner of the DF Election
            process.  A value of unknown(0) indicates there is currently
            no DF."
    ::= { pimBidirDFElectionEntry 4 }

pimBidirDFElectionWinnerAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The primary IP address of the winner of the DF Election
            process.  The InetAddressType is given by the
            pimBidirDFElectionWinnerAddressType object."
    ::= { pimBidirDFElectionEntry 5 }

pimBidirDFElectionWinnerUpTime OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The time since the current winner (last) became elected as
            the DF for this RP."
    ::= { pimBidirDFElectionEntry 6 }

pimBidirDFElectionWinnerMetricPref OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The metric preference advertised by the DF Winner, or zero
            if there is currently no DF."
    ::= { pimBidirDFElectionEntry 7 }

pimBidirDFElectionWinnerMetric OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The metric advertised by the DF Winner, or zero if there is
            currently no DF."
    ::= { pimBidirDFElectionEntry 8 }

pimBidirDFElectionState OBJECT-TYPE
    SYNTAX     INTEGER {
                  dfOffer(1),
                  dfLose(2),
                  dfWinner(3),
                  dfBackoff(4)
               }
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The state of this interface with respect to DF-Election for
            this RP.  The states correspond to the ones defined in the
            BIDIR-PIM specification."
    REFERENCE "RFC 5015 section 3.5.3.1"
    ::= { pimBidirDFElectionEntry 9 }

pimBidirDFElectionStateTimer OBJECT-TYPE
    SYNTAX     TimeTicks
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The minimum time remaining after which the local router
            will expire the current DF state represented by
            pimBidirDFElectionState."
    ::= { pimBidirDFElectionEntry 10 }

Last stop for this part: the PIM Static RP Table 🌸 This is where you manually tell the router which RP to use for which group range, and yes, it's a whole vibe with overrides and prefix lengths 🧚

--
-- The PIM Static RP Table
--

pimStaticRPTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimStaticRPEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "This table is used to manage static configuration of RPs.

            If the group prefixes configured for two or more rows in
            this table overlap, the row with the greatest value of
            pimStaticRPGrpPrefixLength is used for the overlapping
            range."
    REFERENCE "RFC 4601 section 3.7"
    ::= { pim 11 }

pimStaticRPEntry OBJECT-TYPE
    SYNTAX     PimStaticRPEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimStaticRPTable.  This
            entry is preserved on agent restart."
    INDEX      { pimStaticRPAddressType,
                 pimStaticRPGrpAddress,
                 pimStaticRPGrpPrefixLength }
    ::= { pimStaticRPTable 1 }

PimStaticRPEntry ::= SEQUENCE {
    pimStaticRPAddressType      InetAddressType,
    pimStaticRPGrpAddress       InetAddress,
    pimStaticRPGrpPrefixLength  InetAddressPrefixLength,
    pimStaticRPRPAddress        InetAddress,
    pimStaticRPPimMode          PimMode,
    pimStaticRPOverrideDynamic  TruthValue,
    pimStaticRPPrecedence       Unsigned32,
    pimStaticRPRowStatus        RowStatus,
    pimStaticRPStorageType      StorageType
}

pimStaticRPAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of this entry."
    ::= { pimStaticRPEntry 1 }

pimStaticRPGrpAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The multicast group address that, when combined with
            pimStaticRPGrpPrefixLength, gives the group prefix for this
            entry.  The InetAddressType is given by the
            pimStaticRPAddressType object.

            This address object is only significant up to
            pimStaticRPGrpPrefixLength bits.  The remainder of the
            address bits are zero.  This is especially important for
            this index field, which is part of the index of this entry.
            Any non-zero bits would signify an entirely different
            entry."
    ::= { pimStaticRPEntry 2 }

pimStaticRPGrpPrefixLength OBJECT-TYPE
    SYNTAX     InetAddressPrefixLength (4..128)
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The multicast group prefix length that, when combined
            with pimStaticRPGrpAddress, gives the group prefix for this
            entry.  The InetAddressType is given by the
            pimStaticRPAddressType object.  If pimStaticRPAddressType is
            'ipv4' or 'ipv4z', this object must be in the range 4..32.

            If pimStaticRPGrpAddressType is 'ipv6' or 'ipv6z', this
            object must be in the range 8..128."
    ::= { pimStaticRPEntry 3 }

pimStaticRPRPAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The IP address of the RP to be used for groups within this
            group prefix.  The InetAddressType is given by the
            pimStaticRPAddressType object."
    ::= { pimStaticRPEntry 4 }

pimStaticRPPimMode OBJECT-TYPE
    SYNTAX     PimMode { ssm(2), asm(3), bidir(4) }
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The PIM mode to be used for groups in this group prefix.

            If this object is set to ssm(2), then pimStaticRPRPAddress
            must be set to zero.  No RP operations are ever possible for
            PIM Mode SSM."
    REFERENCE "RFC 4601 section 3.7, RFC 3569, and
               'IP Multicast MIB' (August 2007) ipMcastSsmRangeTable"
    DEFVAL { asm }
    ::= { pimStaticRPEntry 5 }

pimStaticRPOverrideDynamic OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "Whether this static RP configuration will override other
            group mappings in this group prefix.  If this object is
            TRUE, then it will override:

            -  RP information learned dynamically for groups in this
            group prefix.

            -  RP information configured in pimStaticRPTable with
            pimStaticRPOverrideDynamic set to FALSE.

            See pimGroupMappingTable for details."
    DEFVAL { false }
    ::= { pimStaticRPEntry 6 }

okay the static RP precedence knob is SO specific πŸ’… this is where you get to fine-tune which config wins, lowkey iconic πŸŽ€

pimStaticRPPrecedence OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The value for pimGroupMappingPrecedence to be used for this
            static RP configuration.  This allows fine control over
            which configuration is overridden by this static
            configuration.

            If pimStaticRPOverrideDynamic is set to TRUE, all dynamic RP
            configuration is overridden by this static configuration,
            whatever the value of this object.

            The absolute values of this object have a significance only
            on the local router and do not need to be coordinated with
            other routers.  A setting of this object may have different
            effects when applied to other routers.

            Do not use this object unless fine control of static RP
            behavior on the local router is required."
    ::= { pimStaticRPEntry 7 }

pimStaticRPRowStatus OBJECT-TYPE
    SYNTAX     RowStatus
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The status of this row, by which rows in this table can
            be created and destroyed.

            This status object cannot be set to active(1) before a valid
            value has been written to pimStaticRPRPAddress.

            All writeable objects in this entry can be modified when the
            status of this entry is active(1)."
    ::= { pimStaticRPEntry 8 }

pimStaticRPStorageType OBJECT-TYPE
    SYNTAX      StorageType
    MAX-ACCESS  read-create
    STATUS      current
    DESCRIPTION
            "The storage type for this row.  Rows having the value
            'permanent' need not allow write-access to any columnar
            objects in the row."
    DEFVAL { nonVolatile }
    ::= { pimStaticRPEntry 9 }

ok next up is the Anycast-RP Set table, where the router has to know if it's part of a set. the description literally warns about a Register loop, so pay attention πŸ‘€

--
-- The PIM Anycast-RP Set Table
--

pimAnycastRPSetTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimAnycastRPSetEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "This table is used to manage Anycast-RP via PIM Register
            messages, as opposed to via other protocols such as MSDP
            (Multicast Source Discovery Protocol).

            Entries must be configured in this table if and only if the
            local router is a member of one or more Anycast-RP sets,
            that is, one or more Anycast-RP addresses are assigned to
            the local router.  Note that if using static RP
            configuration, this is in addition to, not instead of, the
            pimStaticRPTable entries that must be configured for the
            Anycast-RPs.

            The set of rows with the same values of both
            pimAnycastRPSetAddressType and pimAnycastRPSetAnycastAddress
            corresponds to the Anycast-RP set for that Anycast-RP
            address.

            When an Anycast-RP set configuration is active, one entry
            per pimAnycastRPSetAnycastAddress corresponds to the local
            router.  The local router is identified by the
            pimAnycastRpSetLocalRouter object.  That entry determines
            the source address used by the local router when forwarding
            PIM Register messages within the Anycast-RP set."
    REFERENCE "RFC 4610, RFC 3618"
    ::= { pim 12 }

pimAnycastRPSetEntry OBJECT-TYPE
    SYNTAX     PimAnycastRPSetEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry corresponds to a single router within a particular
            Anycast-RP set.  This entry is preserved on agent restart."
    INDEX      { pimAnycastRPSetAddressType,
                 pimAnycastRPSetAnycastAddress,
                 pimAnycastRPSetRouterAddress }
    ::= { pimAnycastRPSetTable 1 }

PimAnycastRPSetEntry ::= SEQUENCE {

    pimAnycastRPSetAddressType     InetAddressType,
    pimAnycastRPSetAnycastAddress  InetAddress,
    pimAnycastRPSetRouterAddress   InetAddress,
    pimAnycastRPSetLocalRouter     TruthValue,
    pimAnycastRPSetRowStatus       RowStatus,
    pimAnycastRPSetStorageType     StorageType
}

pimAnycastRPSetAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of the Anycast-RP address and router
            address."
    ::= { pimAnycastRPSetEntry 1 }

pimAnycastRPSetAnycastAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The Anycast-RP address.  The InetAddressType is given by
            the pimAnycastRPSetAddressType object."
    ::= { pimAnycastRPSetEntry 2 }

pimAnycastRPSetRouterAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address of a router that is a member of the Anycast-RP
            set.  The InetAddressType is given by the
            pimAnycastRPSetAddressType object.

            This address differs from pimAnycastRPSetAnycastAddress.
            Equal values for these two addresses in a single entry are
            not permitted.  That would cause a Register loop."
    ::= { pimAnycastRPSetEntry 3 }

pimAnycastRPSetLocalRouter OBJECT-TYPE
    SYNTAX     TruthValue
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "Whether this entry corresponds to the local router."
    ::= { pimAnycastRPSetEntry 4 }

pimAnycastRPSetRowStatus OBJECT-TYPE
    SYNTAX     RowStatus
    MAX-ACCESS read-create
    STATUS     current
    DESCRIPTION
            "The status of this row, by which rows in this table can
            be created and destroyed.

            This status object can be set to active(1) without setting
            any other columnar objects in this entry.

            All writeable objects in this entry can be modified when the
            status of this entry is active(1)."
    ::= { pimAnycastRPSetEntry 5 }

pimAnycastRPSetStorageType OBJECT-TYPE
    SYNTAX      StorageType
    MAX-ACCESS  read-create
    STATUS      current
    DESCRIPTION
            "The storage type for this row.  Rows having the value
            'permanent' need not allow write-access to any columnar
            objects in the row."
    DEFVAL { nonVolatile }
    ::= { pimAnycastRPSetEntry 6 }

last stop this part: the Group Mapping table, which is basically the algorithm that decides which group uses which RP and PIM mode 🧠 it's so detailed it's giving tax form energy, but it's SO good

--
-- The PIM Group Mapping Table
--

pimGroupMappingTable OBJECT-TYPE
    SYNTAX     SEQUENCE OF PimGroupMappingEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The (conceptual) table listing mappings from multicast
            group prefixes to the PIM mode and RP address to use for
            groups within that group prefix.

            Rows in this table are created for a variety of reasons,
            indicated by the value of the pimGroupMappingOrigin object.

            -  Rows with a pimGroupMappingOrigin value of 'fixed' are
               created automatically by the router at startup, to
               correspond to the well-defined prefixes of link-local and
               unroutable group addresses.  These rows are never
               destroyed.

            -  Rows with a pimGroupMappingOrigin value of 'embedded' are
               created by the router to correspond to group prefixes
               that are to be treated as being in Embedded-RP format.

            -  Rows with a pimGroupMappingOrigin value of 'configRp' are
               created and destroyed as a result of rows in the
               pimStaticRPTable being created and destroyed.

            -  Rows with a pimGroupMappingOrigin value of 'configSsm'
               are created and destroyed as a result of configuration of
               SSM address ranges to the local router.

            -  Rows with a pimGroupMappingOrigin value of 'bsr' are
               created as a result of running the PIM Bootstrap Router
               (BSR) mechanism.  If the local router is not the elected
               BSR, these rows are created to correspond to group
               prefixes in the PIM Bootstrap messages received from the
               elected BSR.  If the local router is the elected BSR,
               these rows are created to correspond to group prefixes in
               the PIM Bootstrap messages that the local router sends.
               In either case, these rows are destroyed when the group
               prefixes are timed out by the BSR mechanism.

            -  Rows with a pimGroupMappingOrigin value of 'other' are
               created and destroyed according to some other mechanism
               not specified here.

            Given the collection of rows in this table at any point in
            time, the PIM mode and RP address to use for a particular
            group is determined using the following algorithm.

            1. From the set of all rows, the subset whose group prefix
               contains the group in question are selected.

            2. If there are no such rows, then the group mapping is
               undefined.

            3. If there are multiple selected rows, and a subset is
               defined by pimStaticRPTable (pimGroupMappingOrigin value
               of 'configRp') with pimStaticRPOverrideDynamic set to
               TRUE, then this subset is selected.

            4. From the selected subset of rows, the subset that have
               the greatest value of pimGroupMappingGrpPrefixLength are
               selected.

            5. If there are still multiple selected rows, the subset
               that has the highest precedence (the lowest numerical
               value for pimGroupMappingPrecedence) is selected.

            6. If there are still multiple selected rows, the row
               selected is implementation dependent; the implementation
               might or might not apply the PIM hash function to select
               the row.

            7. The group mode to use is given by the value of
               pimGroupMappingPimMode from the single selected row; the
               RP to use is given by the value of
               pimGroupMappingRPAddress, unless pimGroupMappingOrigin is
               'embedded', in which case, the RP is extracted from the
               group address in question."
    REFERENCE "RFC 4601 section 3.7, RFC 3956, and RFC 4610"
    ::= { pim 13 }

pimGroupMappingEntry OBJECT-TYPE
    SYNTAX     PimGroupMappingEntry
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "An entry (conceptual row) in the pimGroupMappingTable."
    INDEX      { pimGroupMappingOrigin,
                 pimGroupMappingAddressType,
                 pimGroupMappingGrpAddress,
                 pimGroupMappingGrpPrefixLength,
                 pimGroupMappingRPAddressType,
                 pimGroupMappingRPAddress }
    ::= { pimGroupMappingTable 1 }

PimGroupMappingEntry ::= SEQUENCE {
    pimGroupMappingOrigin           PimGroupMappingOriginType,
    pimGroupMappingAddressType      InetAddressType,
    pimGroupMappingGrpAddress       InetAddress,
    pimGroupMappingGrpPrefixLength  InetAddressPrefixLength,
    pimGroupMappingRPAddressType    InetAddressType,
    pimGroupMappingRPAddress        InetAddress,
    pimGroupMappingPimMode          PimMode,
    pimGroupMappingPrecedence       Unsigned32
}

pimGroupMappingOrigin OBJECT-TYPE
    SYNTAX     PimGroupMappingOriginType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The mechanism by which this group mapping was learned."
    ::= { pimGroupMappingEntry 1 }

pimGroupMappingAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of the IP multicast group prefix."
    ::= { pimGroupMappingEntry 2 }

okay bestie, the group mapping table is about to get SO real πŸ’…

pimGroupMappingGrpAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The IP multicast group address that, when combined with
            pimGroupMappingGrpPrefixLength, gives the group prefix for
            this mapping.  The InetAddressType is given by the
            pimGroupMappingAddressType object.

            This address object is only significant up to
            pimGroupMappingGrpPrefixLength bits.  The remainder of the
            address bits are zero.  This is especially important for
            this index field, which is part of the index of this entry.
            Any non-zero bits would signify an entirely different
            entry."
    ::= { pimGroupMappingEntry 3 }

ngl the "remainder bits are zero" part is giving index energy πŸ¦‹ any stray non-zero bit and it's literally a whole different entry, no cap πŸ™ˆ

pimGroupMappingGrpPrefixLength OBJECT-TYPE
    SYNTAX     InetAddressPrefixLength (4..128)
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The multicast group prefix length that, when combined
            with pimGroupMappingGrpAddress, gives the group prefix for
            this mapping.  The InetAddressType is given by the
            pimGroupMappingAddressType object.  If
            pimGroupMappingAddressType is 'ipv4' or 'ipv4z', this
            object must be in the range 4..32.  If
            pimGroupMappingAddressType is 'ipv6' or 'ipv6z', this object
            must be in the range 8..128."
    ::= { pimGroupMappingEntry 4 }

so the prefix length has to match the address family: IPv4 gets 4..32, IPv6 gets 8..128 🌸 bestie, be precise with your ranges!

pimGroupMappingRPAddressType OBJECT-TYPE
    SYNTAX     InetAddressType
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The address type of the RP to be used for groups within
            this group prefix, or unknown(0) if no RP is to be used or
            if the RP address is unknown.  This object must be
            unknown(0) if pimGroupMappingPimMode is ssm(2), or if
            pimGroupMappingOrigin is embedded(6)."
    ::= { pimGroupMappingEntry 5 }

the SSM and embedded-origin rule is so specific it's iconic 😭 if you're in ssm(2) or embedded(6), the RP address type has to be unknown(0), full stop πŸ’…

pimGroupMappingRPAddress OBJECT-TYPE
    SYNTAX     InetAddress (SIZE (0|4|8|16|20))
    MAX-ACCESS not-accessible
    STATUS     current
    DESCRIPTION
            "The IP address of the RP to be used for groups within this
            group prefix.  The InetAddressType is given by the
            pimGroupMappingRPAddressType object."
    ::= { pimGroupMappingEntry 6 }

pimGroupMappingPimMode OBJECT-TYPE
    SYNTAX     PimMode
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The PIM mode to be used for groups in this group prefix."
    ::= { pimGroupMappingEntry 7 }

pimGroupMappingPrecedence OBJECT-TYPE
    SYNTAX     Unsigned32
    MAX-ACCESS read-only
    STATUS     current
    DESCRIPTION
            "The precedence of this row, used in the algorithm that
            determines which row applies to a given group address
            (described above).  Numerically higher values for this
            object indicate lower precedences, with the value zero
            denoting the highest precedence.

            The absolute values of this object have a significance only
            on the local router and do not need to be coordinated with
            other routers."
    ::= { pimGroupMappingEntry 8 }

precedence goes the opposite way from what you'd expect: bigger number means lower priority, and zero is the VIP πŸ‘‘ and the numbers only matter on your own router, so no group chat coordination needed 🫢


--
-- PIM Notifications
--

pimNeighborLoss NOTIFICATION-TYPE
    OBJECTS { pimNeighborUpTime }
    STATUS     current
    DESCRIPTION
            "A pimNeighborLoss notification signifies the loss of an
            adjacency with a neighbor.  This notification should be
            generated when the neighbor timer expires, and the router
            has no other neighbors on the same interface with the same
            IP version and a lower IP address than itself.

            This notification is generated whenever the counter
            pimNeighborLossCount is incremented, subject
            to the rate limit specified by
            pimNeighborLossNotificationPeriod."
    REFERENCE "RFC 4601 section 4.3.2"
    ::= { pimNotifications 1 }

pimInvalidRegister NOTIFICATION-TYPE
    OBJECTS { pimGroupMappingPimMode,
              pimInvalidRegisterAddressType,
              pimInvalidRegisterOrigin,
              pimInvalidRegisterGroup,
              pimInvalidRegisterRp
            }
    STATUS      current
    DESCRIPTION
            "A pimInvalidRegister notification signifies that an invalid
            PIM Register message was received by this device.

            This notification is generated whenever the counter
            pimInvalidRegisterMsgsRcvd is incremented, subject to the
            rate limit specified by
            pimInvalidRegisterNotificationPeriod."
    REFERENCE "RFC 4601 section 4.4.2"
    ::= { pimNotifications 2 }

pimInvalidJoinPrune NOTIFICATION-TYPE
    OBJECTS { pimGroupMappingPimMode,
              pimInvalidJoinPruneAddressType,
              pimInvalidJoinPruneOrigin,
              pimInvalidJoinPruneGroup,
              pimInvalidJoinPruneRp,
              pimNeighborUpTime
            }
    STATUS      current
    DESCRIPTION
            "A pimInvalidJoinPrune notification signifies that an
            invalid PIM Join/Prune message was received by this device.

            This notification is generated whenever the counter
            pimInvalidJoinPruneMsgsRcvd is incremented, subject to the
            rate limit specified by
            pimInvalidJoinPruneNotificationPeriod."

    REFERENCE "RFC 4601 section 4.5.2"
    ::= { pimNotifications 3 }

pimRPMappingChange NOTIFICATION-TYPE
    OBJECTS { pimGroupMappingPimMode,
              pimGroupMappingPrecedence
            }
    STATUS      current
    DESCRIPTION
            "A pimRPMappingChange notification signifies a change to the
            active RP mapping on this device.

            This notification is generated whenever the counter
            pimRPMappingChangeCount is incremented, subject to the
            rate limit specified by
            pimRPMappingChangeNotificationPeriod."
    ::= { pimNotifications 4 }

pimInterfaceElection NOTIFICATION-TYPE
    OBJECTS { pimInterfaceAddressType,
              pimInterfaceAddress }
    STATUS      current
    DESCRIPTION
            "A pimInterfaceElection notification signifies that a new DR
            or DF has been elected on a network.

            This notification is generated whenever the counter
            pimInterfaceElectionWinCount is incremented, subject to the
            rate limit specified by
            pimInterfaceElectionNotificationPeriod."
    REFERENCE "RFC 4601 section 4.3.2 and RFC 5015 section 3.5.2"
    ::= { pimNotifications 5 }

the notifications are where the drama happens πŸ”₯ neighbor loss, invalid registers, invalid join/prunes, RP mapping changes and DR/DF elections, and each one has its own rate limit so the alarms don't go off nonstop πŸ’€

--
-- Conformance Information
--

pimMIBConformance OBJECT IDENTIFIER ::= { pimStdMIB 2 }
pimMIBCompliances OBJECT IDENTIFIER ::= { pimMIBConformance 1 }
pimMIBGroups      OBJECT IDENTIFIER ::= { pimMIBConformance 2 }

--
-- Compliance Statements
--

pimMIBComplianceAsm MODULE-COMPLIANCE
    STATUS  current
    DESCRIPTION

             "The compliance statement for routers which are running
             PIM-SM (Sparse Mode)."
    MODULE  -- this module
    MANDATORY-GROUPS { pimTopologyGroup,
                       pimSsmGroup,
                       pimRPConfigGroup,
                       pimSmGroup }

      GROUP   pimNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimTuningParametersGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimRouterStatisticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimAnycastRpGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimStaticRPPrecedenceGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationObjects
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDiagnosticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDeviceStorageGroup
      DESCRIPTION
          "This group is optional."

    ::= { pimMIBCompliances 1 }

pimMIBComplianceBidir MODULE-COMPLIANCE
    STATUS  current
    DESCRIPTION
            "The compliance statement for routers which are running
            Bidir-PIM."
    MODULE  -- this module
    MANDATORY-GROUPS { pimTopologyGroup,
                       pimRPConfigGroup,
                       pimSmGroup,
                       pimBidirGroup }

      GROUP   pimNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimTuningParametersGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimRouterStatisticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimAnycastRpGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimStaticRPPrecedenceGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationObjects
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDiagnosticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDeviceStorageGroup
      DESCRIPTION
          "This group is optional."

    ::= { pimMIBCompliances 2 }

pimMIBComplianceSsm MODULE-COMPLIANCE

    STATUS  current
    DESCRIPTION
            "The compliance statement for routers which are running
             PIM SSM (Source Specific Multicast)."
    MODULE  -- this module
    MANDATORY-GROUPS { pimTopologyGroup,
                       pimSsmGroup }

      GROUP   pimNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimTuningParametersGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimRouterStatisticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationObjects
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDiagnosticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDeviceStorageGroup
      DESCRIPTION
          "This group is optional."

    ::= { pimMIBCompliances 3 }

pimMIBComplianceDm MODULE-COMPLIANCE
    STATUS  current
    DESCRIPTION
            "The compliance statement for routers which are running
            PIM-DM (Dense Mode)."
    MODULE  -- this module
    MANDATORY-GROUPS { pimTopologyGroup,
                       pimSsmGroup,
                       pimRPConfigGroup,
                       pimSmGroup,
                       pimDmGroup }

      GROUP   pimNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimTuningParametersGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimRouterStatisticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimAnycastRpGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimStaticRPPrecedenceGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationObjects
      DESCRIPTION
          "This group is optional."

      GROUP   pimNetMgmtNotificationGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDiagnosticsGroup
      DESCRIPTION
          "This group is optional."

      GROUP   pimDeviceStorageGroup
      DESCRIPTION
          "This group is optional."

    ::= { pimMIBCompliances 4 }

--
-- Units of Conformance
--

the compliance statements are where every router type gets to pick its lane 🌈 SM, Bidir, SSM and DM each list their mandatory groups, and everything else is optional, which is so chill πŸ¦‹βœ¨

okay so the actual bundles are here, bestie πŸŽ€ each OBJECT-GROUP is a little squad of objects that go together, and the NOTIFICATION-GROUPs are the notification crews πŸ¦‹ pimTopologyGroup is the read-only local topology crew, and pimSmGroup and pimBidirGroup both have the "also required" energy πŸ’…

pimTopologyGroup OBJECT-GROUP
    OBJECTS { pimInterfaceAddressType,
              pimInterfaceAddress,
              pimInterfaceGenerationIDValue,
              pimInterfaceDR,
              pimInterfaceDRPriorityEnabled,
              pimInterfaceHelloHoldtime,
              pimInterfaceJoinPruneHoldtime,
              pimInterfaceLanDelayEnabled,
              pimInterfaceEffectPropagDelay,
              pimInterfaceEffectOverrideIvl,
              pimInterfaceSuppressionEnabled,
              pimInterfaceBidirCapable,
              pimNeighborGenerationIDPresent,
              pimNeighborGenerationIDValue,
              pimNeighborUpTime,
              pimNeighborExpiryTime,
              pimNeighborDRPriorityPresent,
              pimNeighborDRPriority,
              pimNeighborLanPruneDelayPresent,
              pimNeighborTBit,
              pimNeighborPropagationDelay,
              pimNeighborOverrideInterval,
              pimNeighborBidirCapable,
              pimNbrSecAddress
            }
    STATUS  current
    DESCRIPTION
            "A collection of read-only objects used to report local PIM
            topology."
    ::= { pimMIBGroups 1 }

pimNotificationGroup NOTIFICATION-GROUP
    NOTIFICATIONS { pimNeighborLoss }
    STATUS  current
    DESCRIPTION
            "A collection of notifications for signaling important PIM
            events."
    ::= { pimMIBGroups 2 }

pimTuningParametersGroup OBJECT-GROUP
    OBJECTS { pimKeepalivePeriod,
              pimRegisterSuppressionTime,
              pimInterfaceDRPriority,
              pimInterfaceHelloInterval,
              pimInterfaceTrigHelloInterval,
              pimInterfaceJoinPruneInterval,
              pimInterfacePropagationDelay,
              pimInterfaceOverrideInterval,
              pimInterfaceDomainBorder,
              pimInterfaceStubInterface,
              pimInterfaceStatus,
              pimInterfaceStorageType
            }
    STATUS  current
    DESCRIPTION
            "A collection of writeable objects used to configure PIM
            behavior and to tune performance."
    ::= { pimMIBGroups 3 }

pimRouterStatisticsGroup OBJECT-GROUP
    OBJECTS { pimStarGEntries,
              pimStarGIEntries,
              pimSGEntries,
              pimSGIEntries,
              pimSGRptEntries,
              pimSGRptIEntries
            }
    STATUS  current
    DESCRIPTION
            "A collection of statistics global to the PIM router."
    ::= { pimMIBGroups 4 }

pimSsmGroup OBJECT-GROUP
    OBJECTS { pimSGUpTime,
              pimSGPimMode,
              pimSGUpstreamJoinState,
              pimSGUpstreamJoinTimer,
              pimSGUpstreamNeighbor,
              pimSGRPFIfIndex,
              pimSGRPFNextHopType,
              pimSGRPFNextHop,
              pimSGRPFRouteProtocol,
              pimSGRPFRouteAddress,
              pimSGRPFRoutePrefixLength,
              pimSGRPFRouteMetricPref,
              pimSGRPFRouteMetric,
              pimSGSPTBit,
              pimSGKeepaliveTimer,
              pimSGDRRegisterState,
              pimSGDRRegisterStopTimer,
              pimSGRPRegisterPMBRAddressType,
              pimSGRPRegisterPMBRAddress,
              pimSGIUpTime,
              pimSGILocalMembership,
              pimSGIJoinPruneState,
              pimSGIPrunePendingTimer,
              pimSGIJoinExpiryTimer,
              pimSGIAssertState,
              pimSGIAssertTimer,
              pimSGIAssertWinnerAddressType,
              pimSGIAssertWinnerAddress,
              pimSGIAssertWinnerMetricPref,
              pimSGIAssertWinnerMetric
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support management of PIM
            routers running the PIM SSM (Source Specific Multicast)
            protocol, in PIM mode SM (Sparse Mode)."
    ::= { pimMIBGroups 5 }

pimRPConfigGroup OBJECT-GROUP
    OBJECTS { pimStaticRPRPAddress,
              pimStaticRPPimMode,
              pimStaticRPOverrideDynamic,
              pimStaticRPRowStatus,
              pimStaticRPStorageType,
              pimGroupMappingPimMode,
              pimGroupMappingPrecedence
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support configuration of RPs
            (Rendezvous Points) and Group Mappings."
    ::= { pimMIBGroups 6 }

pimSmGroup OBJECT-GROUP
    OBJECTS { pimStarGUpTime,
              pimStarGPimMode,
              pimStarGRPAddressType,
              pimStarGRPAddress,
              pimStarGPimModeOrigin,
              pimStarGRPIsLocal,
              pimStarGUpstreamJoinState,
              pimStarGUpstreamJoinTimer,
              pimStarGUpstreamNeighborType,
              pimStarGUpstreamNeighbor,
              pimStarGRPFIfIndex,
              pimStarGRPFNextHopType,
              pimStarGRPFNextHop,
              pimStarGRPFRouteProtocol,
              pimStarGRPFRouteAddress,
              pimStarGRPFRoutePrefixLength,
              pimStarGRPFRouteMetricPref,
              pimStarGRPFRouteMetric,
              pimStarGIUpTime,
              pimStarGILocalMembership,
              pimStarGIJoinPruneState,
              pimStarGIPrunePendingTimer,
              pimStarGIJoinExpiryTimer,
              pimStarGIAssertState,
              pimStarGIAssertTimer,
              pimStarGIAssertWinnerAddressType,
              pimStarGIAssertWinnerAddress,
              pimStarGIAssertWinnerMetricPref,
              pimStarGIAssertWinnerMetric,
              pimSGRptUpTime,
              pimSGRptUpstreamPruneState,
              pimSGRptUpstreamOverrideTimer,
              pimSGRptIUpTime,
              pimSGRptILocalMembership,
              pimSGRptIJoinPruneState,
              pimSGRptIPrunePendingTimer,
              pimSGRptIPruneExpiryTimer
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support management of PIM
            routers running PIM-SM (Sparse Mode).  The groups
            pimSsmGroup and pimRPConfigGroup are also required."
    ::= { pimMIBGroups 7 }

pimBidirGroup OBJECT-GROUP
    OBJECTS { pimInterfaceDFElectionRobustness,
              pimBidirDFElectionWinnerAddressType,
              pimBidirDFElectionWinnerAddress,
              pimBidirDFElectionWinnerUpTime,
              pimBidirDFElectionWinnerMetricPref,
              pimBidirDFElectionWinnerMetric,
              pimBidirDFElectionState,
              pimBidirDFElectionStateTimer
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support management of PIM
            routers running BIDIR mode.  The groups pimSsmGroup,
            pimSmGroup and pimRPConfigGroup are also required."
    ::= { pimMIBGroups 8 }

pimAnycastRpGroup OBJECT-GROUP
    OBJECTS { pimAnycastRPSetLocalRouter,
              pimAnycastRPSetRowStatus,
              pimAnycastRPSetStorageType
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support management of the PIM
            Anycast-RP mechanism."
    ::= { pimMIBGroups 9 }

pimStaticRPPrecedenceGroup OBJECT-GROUP
    OBJECTS { pimStaticRPPrecedence }
    STATUS  current
    DESCRIPTION
            "A collection of objects to allow fine control of
            interactions between static RP configuration and
            dynamically acquired group to RP mappings."
    ::= { pimMIBGroups 10 }

pimNetMgmtNotificationObjects OBJECT-GROUP
    OBJECTS { pimInvalidRegisterNotificationPeriod,
              pimInvalidRegisterMsgsRcvd,
              pimInvalidRegisterAddressType,
              pimInvalidRegisterOrigin,
              pimInvalidRegisterGroup,
              pimInvalidRegisterRp,
              pimInvalidJoinPruneNotificationPeriod,
              pimInvalidJoinPruneMsgsRcvd,
              pimInvalidJoinPruneAddressType,
              pimInvalidJoinPruneOrigin,
              pimInvalidJoinPruneGroup,
              pimInvalidJoinPruneRp,
              pimRPMappingNotificationPeriod,
              pimRPMappingChangeCount,
              pimInterfaceElectionNotificationPeriod,
              pimInterfaceElectionWinCount
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects to support notification of PIM
            network management events."
    ::= { pimMIBGroups 11 }

pimNetMgmtNotificationGroup NOTIFICATION-GROUP
    NOTIFICATIONS { pimInvalidRegister,
                    pimInvalidJoinPrune,
                    pimRPMappingChange,
                    pimInterfaceElection
                  }
    STATUS  current
    DESCRIPTION
            "A collection of notifications for signaling PIM network
            management events."

    ::= { pimMIBGroups 12 }

pimDiagnosticsGroup OBJECT-GROUP
    OBJECTS { pimInAsserts,
              pimOutAsserts,
              pimLastAssertInterface,
              pimLastAssertGroupAddressType,
              pimLastAssertGroupAddress,
              pimLastAssertSourceAddressType,
              pimLastAssertSourceAddress,
              pimNeighborLossNotificationPeriod,
              pimNeighborLossCount
            }
    STATUS  current
    DESCRIPTION
            "Objects providing additional diagnostics related to a PIM
            router."
    ::= { pimMIBGroups 13 }

pimDmGroup OBJECT-GROUP
    OBJECTS {
              pimRefreshInterval,
              pimInterfacePruneLimitInterval,
              pimInterfaceGraftRetryInterval,
              pimInterfaceSRPriorityEnabled,
              pimNeighborSRCapable,
              pimSGUpstreamPruneState,
              pimSGUpstreamPruneLimitTimer,
              pimSGOriginatorState,
              pimSGSourceActiveTimer,
              pimSGStateRefreshTimer
            }
    STATUS  current
    DESCRIPTION
            "A collection of objects required for management of PIM
            Dense Mode (PIM-DM) function.  The groups pimSsmGroup and
            pimSmGroup are also required."
    REFERENCE "RFC 3973"
    ::= { pimMIBGroups 14 }

pimDeviceStorageGroup OBJECT-GROUP
    OBJECTS { pimDeviceConfigStorageType
            }
    STATUS  current
    DESCRIPTION
            "An object that specifies the volatility of global PIM
            configuration settings on this device."
    ::= { pimMIBGroups 15 }

END

6. Security Considerations πŸ”βœ¨

okay so there are a bunch of management objects in this MIB module with a MAX-ACCESS of read-write and/or read-create, and bestie, these can be sensitive or vulnerable depending on the network. SET operations in a non-secure environment without proper protection can seriously mess with network operations 😭. Here are the tables and objects and why they're sensitive:

The following tables and objects could be used to change multicast routing behavior in a way that stops, disrupts, or subverts services the network provides, including (but definitely not limited to) multicast data traffic delivery 🚨. Like, attacks could be set up to push nominated multicast data streams through a nominated location, and the sources or listeners would have no idea it's happening πŸ’€.

pimKeepalivePeriod pimRegisterSuppressionTime
pimNeighborLossNotificationPeriod
pimInvalidRegisterNotificationPeriod
pimInvalidJoinPruneNotificationPeriod pimRPMappingNotificationPeriod
pimInterfaceElectionNotificationPeriod pimRefreshInterval
pimInterfaceTable pimInterfaceEntry pimInterfaceIfIndex
pimInterfaceIPVersion pimInterfaceHelloInterval
pimInterfaceTrigHelloInterval pimInterfaceJoinPruneInterval
pimInterfaceDFElectionRobustness pimInterfaceHelloHoldtime
pimInterfaceJoinPruneHoldtime pimInterfacePropagationDelay
pimInterfaceOverrideInterval pimInterfaceDRPriority
pimInterfaceDomainBorder pimInterfaceStatus pimInterfaceStubInterface
pimInterfacePruneLimitInterval pimStaticRPTable pimStaticRPEntry
pimStaticRPAddressType pimStaticRPGrpAddress
pimStaticRPGrpPrefixLength pimStaticRPRPAddress pimStaticRPPimMode
pimStaticRPOverrideDynamic pimStaticRPRowStatus pimStaticRPPrecedence
pimAnycastRPSetTable pimAnycastRPSetEntry pimAnycastRPSetAddressType
pimAnycastRPSetAnycastAddress pimAnycastRPSetRouterAddress

Some of the readable objects in this MIB module (aka objects with a MAX-ACCESS other than not-accessible) can also be sensitive or vulnerable in some network environments πŸ‘€. So it's super important to control even GET and/or NOTIFY access to these objects, and possibly even encrypt their values when they're sent over the network via SNMP πŸ”’. Here's the list of tables and objects and their sensitivity/vulnerability:

The following tables and objects could be used to figure out the topology, disposition, and composition of the network πŸ—ΊοΈ. That info can be commercially sensitive, and it can also be used to prep for attacks, including any of the ones described above πŸ™ˆ.

The following tables and objects may also be used to tell whether multicast data is flowing through the network, or has flowed recently 🌊. They can also reveal where senders and recipients sit in the network. An attacker can run 'traffic analysis' on this data, and honestly, the stuff traffic analysis reveals can be as damaging as fully knowing the data being transported 😱.

pimKeepalivePeriod pimRegisterSuppressionTime pimStarGEntries
pimStarGIEntries pimSGEntries pimSGIEntries pimSGRptEntries
pimSGRptIEntries pimOutAsserts pimInAsserts pimLastAssertInterface
pimLastAssertGroupAddressType pimLastAssertGroupAddress
pimLastAssertSourceAddressType pimLastAssertSourceAddress
pimNeighborLossNotificationPeriod pimNeighborLossCount
pimInvalidRegisterNotificationPeriod pimInvalidRegisterMsgsRcvd
pimInvalidRegisterAddressType pimInvalidRegisterOrigin
pimInvalidRegisterGroup pimInvalidRegisterRp
pimInvalidJoinPruneNotificationPeriod pimInvalidJoinPruneMsgsRcvd
pimInvalidJoinPruneAddressType pimInvalidJoinPruneOrigin
pimInvalidJoinPruneGroup pimInvalidJoinPruneRp
pimRPMappingNotificationPeriod pimRPMappingChangeCount
pimInterfaceElectionNotificationPeriod pimInterfaceElectionWinCount
pimRefreshInterval pimInterfaceTable pimInterfaceEntry
pimInterfaceIfIndex pimInterfaceIPVersion pimInterfaceAddressType
pimInterfaceAddress pimInterfaceDR pimInterfaceHelloInterval
pimInterfaceTrigHelloInterval pimInterfaceJoinPruneInterval
pimInterfaceDFElectionRobustness pimInterfaceHelloHoldtime
pimInterfaceJoinPruneHoldtime pimInterfacePropagationDelay
pimInterfaceOverrideInterval pimInterfaceGenerationIDValue
pimInterfaceDRPriority pimInterfaceLanDelayEnabled
pimInterfaceEffectPropagDelay pimInterfaceEffectOverrideIvl
pimInterfaceSuppressionEnabled pimInterfaceBidirCapable
pimInterfaceDRPriorityEnabled pimInterfaceDomainBorder
pimInterfaceStatus pimInterfaceStubInterface
pimInterfacePruneLimitInterval pimInterfaceSRPriorityEnabled
pimNeighborTable pimNeighborEntry pimNeighborIfIndex
pimNeighborAddressType pimNeighborAddress pimNeighborUpTime
pimNeighborExpiryTime pimNeighborLanPruneDelayPresent
pimNeighborPropagationDelay pimNeighborOverrideInterval
pimNeighborTBit pimNeighborGenerationIDPresent
pimNeighborGenerationIDValue pimNeighborBidirCapable
pimNeighborDRPriorityPresent pimNeighborDRPriority
pimNeighborSRCapable pimNbrSecAddressTable pimNbrSecAddressEntry
pimNbrSecAddressIfIndex pimNbrSecAddressType pimNbrSecAddressPrimary
pimNbrSecAddress pimStarGTable pimStarGEntry pimStarGAddressType
pimStarGGrpAddress pimStarGUpTime pimStarGPimMode
pimStarGRPAddressType pimStarGRPAddress pimStarGPimModeOrigin
pimStarGRPIsLocal pimStarGUpstreamJoinState pimStarGUpstreamJoinTimer
pimStarGUpstreamNeighborType pimStarGUpstreamNeighbor
pimStarGRPFIfIndex pimStarGRPFNextHopType pimStarGRPFNextHop
pimStarGRPFRouteProtocol pimStarGRPFRouteAddress
pimStarGRPFRoutePrefixLength pimStarGRPFRouteMetricPref
pimStarGRPFRouteMetric pimStarGITable pimStarGIEntry pimStarGIIfIndex
pimStarGIUpTime pimStarGILocalMembership pimStarGIJoinPruneState
pimStarGIPrunePendingTimer pimStarGIJoinExpiryTimer
pimStarGIAssertState pimStarGIAssertTimer
pimStarGIAssertWinnerAddressType pimStarGIAssertWinnerAddress
pimStarGIAssertWinnerMetricPref pimStarGIAssertWinnerMetric
pimSGTable pimSGEntry pimSGAddressType pimSGGrpAddress
pimSGSrcAddress pimSGUpTime pimSGPimMode pimSGUpstreamJoinState
pimSGUpstreamJoinTimer pimSGUpstreamNeighbor pimSGRPFIfIndex
pimSGRPFNextHopType pimSGRPFNextHop pimSGRPFRouteProtocol
pimSGRPFRouteAddress pimSGRPFRoutePrefixLength
pimSGRPFRouteMetricPref pimSGRPFRouteMetric pimSGSPTBit
pimSGKeepaliveTimer pimSGDRRegisterState pimSGDRRegisterStopTimer
pimSGRPRegisterPMBRAddressType pimSGRPRegisterPMBRAddress
pimSGUpstreamPruneState pimSGUpstreamPruneLimitTimer
pimSGOriginatorState pimSGSourceActiveTimer pimSGStateRefreshTimer
pimSGITable pimSGIEntry pimSGIIfIndex pimSGIUpTime
pimSGILocalMembership pimSGIJoinPruneState pimSGIPrunePendingTimer
pimSGIJoinExpiryTimer pimSGIAssertState pimSGIAssertTimer
pimSGIAssertWinnerAddressType pimSGIAssertWinnerAddress
pimSGIAssertWinnerMetricPref pimSGIAssertWinnerMetric pimSGRptTable
pimSGRptEntry pimSGRptSrcAddress pimSGRptUpTime
pimSGRptUpstreamPruneState pimSGRptUpstreamOverrideTimer
pimSGRptITable pimSGRptIEntry pimSGRptIIfIndex pimSGRptIUpTime
pimSGRptILocalMembership pimSGRptIJoinPruneState
pimSGRptIPrunePendingTimer pimSGRptIPruneExpiryTimer
pimBidirDFElectionTable pimBidirDFElectionEntry
pimBidirDFElectionAddressType pimBidirDFElectionRPAddress
pimBidirDFElectionIfIndex pimBidirDFElectionWinnerAddressType
pimBidirDFElectionWinnerAddress pimBidirDFElectionWinnerUpTime
pimBidirDFElectionWinnerMetricPref pimBidirDFElectionWinnerMetric
pimBidirDFElectionState pimBidirDFElectionStateTimer pimStaticRPTable
pimStaticRPEntry pimStaticRPAddressType pimStaticRPGrpAddress
pimStaticRPGrpPrefixLength pimStaticRPRPAddress pimStaticRPPimMode
pimStaticRPOverrideDynamic pimStaticRPRowStatus pimStaticRPPrecedence
pimAnycastRPSetTable pimAnycastRPSetEntry pimAnycastRPSetAddressType
pimAnycastRPSetAnycastAddress pimAnycastRPSetRouterAddress
pimAnycastRPSetRowStatus pimAnycastRPSetLocalRouter
pimGroupMappingTable pimGroupMappingEntry pimGroupMappingOrigin
pimGroupMappingAddressType pimGroupMappingGrpAddress
pimGroupMappingGrpPrefixLength pimGroupMappingRPAddress
pimGroupMappingPimMode pimGroupMappingPrecedence
⚠️ There is also a specific danger tied to the notification pimInvalidRegister. It's originated by devices that receive an incorrect unicast-encapsulated multicast data packet, and that poses a clear risk of propagating a DoS (Denial of Service) attack from the data or control plane into the network management plane 😱. These are the steps taken to guard against it:
  1. The notification is disabled by default. The writeable field pimInvalidRegisterNotificationPeriod must be set in order to enable it.
  2. The syntax of pimInvalidRegisterNotificationPeriod prevents any given device from originating the notification more frequently than once every 10 seconds.
  3. The counter pimInvalidRegisterMsgsRcvd provides equivalent function to the notification. Management applications are encouraged to monitor this counter in preference to enabling the notification πŸ“Š.

The same measures are taken for pimInvalidJoinPrune 🫢, though since this notification can only arise as a result of unroutable control packets, the risk isn't as acute πŸ’….

SNMP versions prior to SNMPv3 did not include adequate security 😬. Even if the network itself is secure (for example by using IPsec), there's still no control over who on that secure network is allowed to access and GET/SET (read/change/create/delete) the objects in this MIB module πŸ™ˆ.

It is RECOMMENDED that implementers consider the security features provided by the SNMPv3 framework (see [RFC3410], section 8), including full support for the SNMPv3 cryptographic mechanisms (for authentication and privacy) πŸ”βœ¨.

Further, deployment of SNMP versions prior to SNMPv3 is NOT RECOMMENDED. Instead, it is RECOMMENDED to deploy SNMPv3 and to enable cryptographic security πŸ›‘οΈ. It is then a customer/operator responsibility to make sure the SNMP entity giving access to an instance of this MIB module is properly configured, so the objects are only accessible to those principals (users) who have legitimate rights to GET or SET (change/create/delete) them πŸ‘‘.


7. IANA Considerations πŸŽ€

PIM-STD-MIB is rooted under the mib-2 subtree. IANA has assigned { mib-2 157 } to the PIM-STD-MIB module specified in this document πŸ¦‹.

8. Acknowledgements πŸ’–

This MIB module is based on the original work in RFC 2934 [RFC2934] by K. McCloghrie, D. Farinacci, D. Thaler, and W. Fenner, and it has been updated based on feedback from the IETF's Protocol Independent Multicast (PIM) Working Group 🫢.

Jonathan Nicholas was the editor of early versions of this document, and contributed the objects for management of PIM-DM 🧚.

9. References πŸ“š

9.1. Normative References ✨

okay bestie, these are the docs you have to read before this one makes sense πŸ“š no cap, the whole spec leans on them πŸ’…

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. πŸ”‘ the origin of those MUST/SHOULD key words, iconic ✨
  • [RFC2578] McCloghrie, K., Ed., Perkins, D., Ed., and J. Schoenwaelder, Ed., "Structure of Management Information Version 2 (SMIv2)", STD 58, RFC 2578, April 1999. 🧱 the SMIv2 foundation
  • [RFC2579] McCloghrie, K., Ed., Perkins, D., Ed., and J. Schoenwaelder, Ed., "Textual Conventions for SMIv2", STD 58, RFC 2579, April 1999. πŸŽ€ the textual conventions companion
  • [RFC2580] McCloghrie, K., Perkins, D., and J. Schoenwaelder, "Conformance Statements for SMIv2", STD 58, RFC 2580, April 1999. 🫢 how you prove you're compliant
  • [RFC2863] McCloghrie, K. and F. Kastenholz, "The Interfaces Group MIB", RFC 2863, June 2000. πŸ”Œ interfaces, obsessed
  • [RFC3973] Adams, A., Nicholas, J., and W. Siadak, "Protocol Independent Multicast - Dense Mode (PIM-DM): Protocol Specification (Revised)", RFC 3973, January 2005. 🌊 PIM-DM, the flood-happy one
  • [RFC4001] Daniele, M., Haberman, B., Routhier, S., and J. Schoenwaelder, "Textual Conventions for Internet Network Addresses", RFC 4001, February 2005. 🌐 address textual conventions
  • [RFC4601] Fenner, B., Handley, M., Holbrook, H., and I. Kouvelas, "Protocol Independent Multicast - Sparse Mode (PIM-SM): Protocol Specification (Revised)", RFC 4601, August 2006. 🎯 PIM-SM, the main character of this whole doc πŸ‘‘
  • [RFC4610] Farinacci, D. and Y. Cai, "Anycast-RP Using Protocol Independent Multicast (PIM)", RFC 4610, August 2006. πŸͺž Anycast-RP with PIM
  • [RFC5015] Handley, M., Kouvelas, I., Speakman, T., and L. Vicisano, "Bidirectional Protocol Independent Multicast (BIDIR-PIM)", RFC 5015, October 2007. ↔️ BIDIR-PIM, two-way vibes
  • [RFC5059] Bhaskar, N., Gall, A., Lingard, L., and S. Venaas, "Bootstrap Router (BSR) Mechanism for PIM", RFC 5059, January 2008. πŸ₯Ύ the BSR mechanism for PIM
  • [RTPROTO] IANA, "IP Route Protocol MIB", September 2000, http://www.iana.org/assignments/ianaiprouteprotocol-mib. πŸ“‹ the IANA registry, so it's giving official

9.2. Informative References 🌸

these ones are the extra reading 🧚 helpful context, not strictly required, but I'm obsessed with them tbh

  • [IPMCAST-MIB] McWalter, D., "IP Multicast MIB", Work in Progress, August 2007. 🚧 still a draft, so it's a work in progress
  • [RFC2932] McCloghrie, K., Farinacci, D., and D. Thaler, "IPv4 Multicast Routing MIB", RFC 2932, October 2000. πŸ—ΊοΈ IPv4 multicast routing MIB
  • [RFC2934] McCloghrie, K., Farinacci, D., Thaler, D., and B. Fenner, "Protocol Independent Multicast MIB for IPv4", RFC 2934, October 2000. πŸ“Š the PIM MIB for IPv4
  • [RFC3376] Cain, B., Deering, S., Kouvelas, I., Fenner, B., and A. Thyagarajan, "Internet Group Management Protocol, Version 3", RFC 3376, October 2002. πŸ‘₯ IGMPv3, group chat for hosts πŸ’¬
  • [RFC3410] Case, J., Mundy, R., Partain, D., and B. Stewart, "Introduction and Applicability Statements for Internet-Standard Management Framework", RFC 3410, December 2002. 🧭 the management framework intro
  • [RFC3569] Bhattacharyya, S., "An Overview of Source-Specific Multicast (SSM)", RFC 3569, July 2003. πŸŽ™οΈ SSM overview, a single speaker vibe
  • [RFC3618] Fenner, B. and D. Meyer, "Multicast Source Discovery Protocol (MSDP)", RFC 3618, October 2003. πŸ“‘ MSDP, source discovery
  • [RFC3810] Vida, R. and L. Costa, "Multicast Listener Discovery Version 2 (MLDv2) for IPv6", RFC 3810, June 2004. πŸ‘‚ MLDv2, the IPv6 listener
  • [RFC3956] Savola, P. and B. Haberman, "Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast Address", RFC 3956, November 2004. πŸͺ‘ stitching the RP address into an IPv6 multicast address, so clever 🧠

Authors' Addresses πŸŽ€

meet the squad who wrote this 🫢 here's how to reach them, emails included πŸ’Œ

Raghava Sivaramu
Cisco Systems
425 E. Tasman Drive
San Jose, CA  95134
USA

EMail: raghava@cisco.com


James Lingard
Arastra, Inc
P.O. Box 10905
Palo Alto, CA  94303
USA

EMail: jchl@arastra.com


David McWalter
Data Connection Ltd
100 Church Street
Enfield  EN2 6BQ
United Kingdom

EMail: dmcw@dataconnection.com


Bharat Joshi
Infosys Technologies Ltd
Electronic City
Bangalore  560 100
India

EMail: bharat_joshi@infosys.com


Andrew Kessler
Cisco Systems
425 E. Tasman Drive
San Jose, CA  95134
USA

EMail: kessler@cisco.com

Copyright (C) The IETF Trust (2008). 🌈

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. πŸ’–

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. πŸ™ˆ

Intellectual Property πŸ¦‹

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. πŸ€·β€β™€οΈ Info on how RFC documents handle rights lives in BCP 78 and BCP 79, so go read those if you're curious πŸ“–

Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be found in the IETF on-line IPR repository at http://www.ietf.org/ipr. πŸ—‚οΈ basically the receipts drawer 🧾

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. 🌿 If you spot one, send the info to ietf-ipr@ietf.org βœ‰οΈ you're literally helping everyone πŸ«ΆπŸ‘‘

πŸ“¦ where this page comes from