From 2f5e00be394e786c362da436695591803437df41 Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Mon, 14 Mar 2005 22:16:39 +0000 Subject: [PATCH] Add snmp_pf, a bsnmpd module for monitoring (not managing!) pf firewalls. Currently implemented are most things related to states and interfaces, todo are address tables and altq. I've tried to keep this roughly in sync with a project implementing this for net-snmpd. Reviewed by: harti, dhartmei MFC after: 1 month --- usr.sbin/bsnmpd/modules/Makefile | 3 +- .../bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt | 1230 +++++++++++++++++ usr.sbin/bsnmpd/modules/snmp_pf/Makefile | 15 + usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c | 1170 ++++++++++++++++ usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def | 195 +++ 5 files changed, 2612 insertions(+), 1 deletion(-) create mode 100644 usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt create mode 100644 usr.sbin/bsnmpd/modules/snmp_pf/Makefile create mode 100644 usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c create mode 100644 usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile index 8e8c21596d32..9d59b9e3b566 100644 --- a/usr.sbin/bsnmpd/modules/Makefile +++ b/usr.sbin/bsnmpd/modules/Makefile @@ -8,7 +8,8 @@ _snmp_atm= snmp_atm SUBDIR= ${_snmp_atm} \ snmp_mibII \ - snmp_netgraph + snmp_netgraph \ + snmp_pf INCS= snmpmod.h INCSDIR= ${INCLUDEDIR}/bsnmp diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt new file mode 100644 index 000000000000..72ebdb711676 --- /dev/null +++ b/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt @@ -0,0 +1,1230 @@ +-- +-- ---------------------------------------------------------------------------- +-- "THE BEER-WARE LICENSE" (Revision 42): +-- wrote this file. As long as you retain this notice you +-- can do whatever you want with this stuff. If we meet some day, and you think +-- this stuff is worth it, you can buy me a beer in return. -Philip Paeps +-- ---------------------------------------------------------------------------- +-- +-- $FreeBSD$ +-- + +BEGEMOT-PF-MIB DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, Counter64, Integer32, + TimeTicks, Unsigned32 + FROM SNMPv2-SMI + TruthValue + FROM SNMPv2-TC + begemot + FROM BEGEMOT-MIB; + +begemotPf MODULE-IDENTITY + LAST-UPDATED "200501240000Z" + ORGANIZATION "NixSys BVBA" + CONTACT-INFO + " Philip Paeps + + Postal: NixSys BVBA + Louizastraat 14 + BE-2800 Mechelen + Belgium + + E-Mail: philip@FreeBSD.org" + DESCRIPTION + "The Begemot MIB for the pf packet filter." + + ::= { begemot 200 } + +begemotPfObjects OBJECT IDENTIFIER ::= { begemotPf 1 } + +-- -------------------------------------------------------------------------- + +pfStatus OBJECT IDENTIFIER ::= { begemotPfObjects 1 } +pfCounter OBJECT IDENTIFIER ::= { begemotPfObjects 2 } +pfStateTable OBJECT IDENTIFIER ::= { begemotPfObjects 3 } +pfSrcNodes OBJECT IDENTIFIER ::= { begemotPfObjects 4 } +pfLimits OBJECT IDENTIFIER ::= { begemotPfObjects 5 } +pfTimeouts OBJECT IDENTIFIER ::= { begemotPfObjects 6 } +pfLogInterface OBJECT IDENTIFIER ::= { begemotPfObjects 7 } +pfInterfaces OBJECT IDENTIFIER ::= { begemotPfObjects 8 } +pfTables OBJECT IDENTIFIER ::= { begemotPfObjects 9 } +pfAltq OBJECT IDENTIFIER ::= { begemotPfObjects 10 } + +-- -------------------------------------------------------------------------- + +-- +-- status information +-- + +pfStatusRunning OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "True if pf is currently enabled." + ::= { pfStatus 1 } + +pfStatusRuntime OBJECT-TYPE + SYNTAX TimeTicks + UNITS "1/100th of a Second" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Indicates how long pf has been enabled. If pf is not currently + enabled, indicates how long it has been disabled. If pf has not + been enabled or disabled since the system was started, the value + will be 0." + ::= { pfStatus 2 } + +pfStatusDebug OBJECT-TYPE + SYNTAX INTEGER { none(0), urgent(1), misc(2), loud(3) } + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Indicates the debug level at which pf is running." + ::= { pfStatus 3 } + +pfStatusHostId OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The (unique) host identifier of the machine running pf." + ::= { pfStatus 4 } + +-- -------------------------------------------------------------------------- + +-- +-- counters +-- + +pfCounterMatch OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packets that matched a filter rule." + ::= { pfCounter 1 } + +pfCounterBadOffset OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packets with bad offset." + ::= { pfCounter 2 } + +pfCounterFragment OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of fragmented packets." + ::= { pfCounter 3 } + +pfCounterShort OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of short packets." + ::= { pfCounter 4 } + +pfCounterNormalize OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of normalized packets." + ::= { pfCounter 5 } + +pfCounterMemDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packets dropped due to memory limitations." + ::= { pfCounter 6 } + +-- -------------------------------------------------------------------------- + +-- +-- state table +-- + +pfStateTableCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries in the state table." + ::= { pfStateTable 1 } + +pfStateTableSearches OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of searches against the state table." + ::= { pfStateTable 2 } + +pfStateTableInserts OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries inserted into the state table." + ::= { pfStateTable 3 } + +pfStateTableRemovals OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries removed from the state table." + ::= { pfStateTable 4 } + +-- -------------------------------------------------------------------------- + +-- +-- source nodes +-- + +pfSrcNodesCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries in the source tracking table." + ::= { pfSrcNodes 1 } + +pfSrcNodesSearches OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of searches against the source tracking table." + ::= { pfSrcNodes 2 } + +pfSrcNodesInserts OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries inserted into the source tracking table." + ::= { pfSrcNodes 3 } + +pfSrcNodesRemovals OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of entries removed from the source tracking table." + ::= { pfSrcNodes 4 } + +-- -------------------------------------------------------------------------- + +-- +-- limits +-- + +pfLimitsStates OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum number of 'keep state' rules in the ruleset." + ::= { pfLimits 1 } + +pfLimitsSrcNodes OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum number of 'sticky-address' or 'source-track' rules + in the ruleset." + ::= { pfLimits 2 } + +pfLimitsFrags OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum number of 'scrub' rules in the ruleset." + ::= { pfLimits 3 } + +-- -------------------------------------------------------------------------- + +-- +-- timeouts +-- + +pfTimeoutsTcpFirst OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after the first packet in a connection." + ::= { pfTimeouts 1 } + +pfTimeoutsTcpOpening OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State before the destination host ever sends a packet." + ::= { pfTimeouts 2 } + +pfTimeoutsTcpEstablished OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The fully established state." + ::= { pfTimeouts 3 } + +pfTimeoutsTcpClosing OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after the first FIN has been sent." + ::= { pfTimeouts 4 } + +pfTimeoutsTcpFinWait OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after both FINs have been exchanged and the + connection is closed." + ::= { pfTimeouts 5 } + +pfTimeoutsTcpClosed OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after one endpoint sends an RST." + ::= { pfTimeouts 6 } + +pfTimeoutsUdpFirst OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after the first packet." + ::= { pfTimeouts 7 } + +pfTimeoutsUdpSingle OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State if the source host sends more than one packet but + the destination host has never sent one back." + ::= { pfTimeouts 8 } + +pfTimeoutsUdpMultiple OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State if both hosts have sent packets." + ::= { pfTimeouts 9 } + +pfTimeoutsIcmpFirst OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after the first packet." + ::= { pfTimeouts 10 } + +pfTimeoutsIcmpError OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after an ICMP error came back in response to an + ICMP packet." + ::= { pfTimeouts 11 } + +pfTimeoutsOtherFirst OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State after the first packet." + ::= { pfTimeouts 12 } + +pfTimeoutsOtherSingle OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State if the source host sends more than one packet but + the destination host has never sent one back." + ::= { pfTimeouts 13 } + +pfTimeoutsOtherMultiple OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "State if both hosts have sent packets." + ::= { pfTimeouts 14 } + +pfTimeoutsFragment OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Seconds before an unassembled fragment is expired." + ::= { pfTimeouts 15 } + +pfTimeoutsInterval OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Interval between purging expired states and fragments." + ::= { pfTimeouts 16 } + +pfTimeoutsAdaptiveStart OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "When the number of state entries exceeds this value, + adaptive scaling begins." + ::= { pfTimeouts 17 } + +pfTimeoutsAdaptiveEnd OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "When reaching this number of state entries, all timeout + values become zero, effectively purging all state entries + immediately." + ::= { pfTimeouts 18 } + +pfTimeoutsSrcNode OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Length of time to retain a source tracking entry after + the last state expires." + ::= { pfTimeouts 19 } + +-- -------------------------------------------------------------------------- + +-- +-- log interface +-- + +pfLogInterfaceName OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the interface configured with 'set loginterface'. + If no interface has been configured, the object will be empty." + ::= { pfLogInterface 1 } + +pfLogInterfaceIp4BytesIn OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 bytes passed in on the loginterface." + ::= { pfLogInterface 2 } + +pfLogInterfaceIp4BytesOut OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 bytes passed out on the loginterface." + ::= { pfLogInterface 3 } + +pfLogInterfaceIp4PktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 packets passed in on the loginterface." + ::= { pfLogInterface 4 } + +pfLogInterfaceIp4PktsInDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 packets dropped coming in on the loginterface." + ::= { pfLogInterface 5 } + +pfLogInterfaceIp4PktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 packets passed out on the loginterface." + ::= { pfLogInterface 6 } + +pfLogInterfaceIp4PktsOutDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 packets dropped going out on the loginterface." + ::= { pfLogInterface 7 } + +pfLogInterfaceIp6BytesIn OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 bytes passed in on the loginterface." + ::= { pfLogInterface 8 } + +pfLogInterfaceIp6BytesOut OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 bytes passed out on the loginterface." + ::= { pfLogInterface 9 } + +pfLogInterfaceIp6PktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 packets passed in on the loginterface." + ::= { pfLogInterface 10 } + +pfLogInterfaceIp6PktsInDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 packets dropped coming in on the loginterface." + ::= { pfLogInterface 11 } + +pfLogInterfaceIp6PktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 packets passed out on the loginterface." + ::= { pfLogInterface 12 } + +pfLogInterfaceIp6PktsOutDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 packets dropped going out on the loginterface." + ::= { pfLogInterface 13 } + +-- -------------------------------------------------------------------------- + +-- +-- interfaces +-- + +pfInterfacesIfNumber OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of network interfaces on this system." + ::= { pfInterfaces 1 } + +pfInterfacesIfTable OBJECT-TYPE + SYNTAX SEQUENCE OF PfInterfacesIfEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of network interfaces, indexed on pfInterfacesIfNumber." + ::= { pfInterfaces 2 } + +pfInterfacesIfEntry OBJECT-TYPE + SYNTAX PfInterfacesIfEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the pfInterfacesIfTable containing information + about a particular network interface in the machine." + INDEX { pfInterfacesIfIndex } + ::= { pfInterfacesIfTable 1 } + +PfInterfacesIfEntry ::= SEQUENCE { + pfInterfacesIfIndex Integer32, + pfInterfacesIfDescr OCTET STRING, + pfInterfacesIfType INTEGER, + pfInterfacesIfTZero TimeTicks, + pfInterfacesIfRefsState Unsigned32, + pfInterfacesIfRefsRule Unsigned32, + pfInterfacesIf4BytesInPass Counter64, + pfInterfacesIf4BytesInBlock Counter64, + pfInterfacesIf4BytesOutPass Counter64, + pfInterfacesIf4BytesOutBlock Counter64, + pfInterfacesIf4PktsInPass Counter64, + pfInterfacesIf4PktsInBlock Counter64, + pfInterfacesIf4PktsOutPass Counter64, + pfInterfacesIf4PktsOutBlock Counter64, + pfInterfacesIf6BytesInPass Counter64, + pfInterfacesIf6BytesInBlock Counter64, + pfInterfacesIf6BytesOutPass Counter64, + pfInterfacesIf6BytesOutBlock Counter64, + pfInterfacesIf6PktsInPass Counter64, + pfInterfacesIf6PktsInBlock Counter64, + pfInterfacesIf6PktsOutPass Counter64, + pfInterfacesIf6PktsOutBlock Counter64 +} + +pfInterfacesIfIndex OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A unique value, greater than zero, for each interface." + ::= { pfInterfacesIfEntry 1 } + +pfInterfacesIfDescr OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the interface." + ::= { pfInterfacesIfEntry 2 } + +pfInterfacesIfType OBJECT-TYPE + SYNTAX INTEGER { group(0), instance(1), detached(2) } + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Indicates whether the interface is a group inteface, an + interface instance, or whether it has been removed or + destroyed." + ::= { pfInterfacesIfEntry 3 } + +pfInterfacesIfTZero OBJECT-TYPE + SYNTAX TimeTicks + UNITS "1/100th of a Second" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Time since statistics were last reset or since the + interface was loaded." + ::= { pfInterfacesIfEntry 4 } + +pfInterfacesIfRefsState OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of state and/or source track entries referencing + this interface." + ::= { pfInterfacesIfEntry 5 } + +pfInterfacesIfRefsRule OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of rules referencing this interface." + ::= { pfInterfacesIfEntry 6 } + +pfInterfacesIf4BytesInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 bytes passed coming in on this interface." + ::= { pfInterfacesIfEntry 7 } + +pfInterfacesIf4BytesInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 bytes blocked coming in on this interface." + ::= { pfInterfacesIfEntry 8 } + +pfInterfacesIf4BytesOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 bytes passed going out on this interface." + ::= { pfInterfacesIfEntry 9 } + +pfInterfacesIf4BytesOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 bytes blocked going out on this interface." + ::= { pfInterfacesIfEntry 10 } + +pfInterfacesIf4PktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 packets passed coming in on this interface." + ::= { pfInterfacesIfEntry 11 } + +pfInterfacesIf4PktsInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 packets blocked coming in on this interface." + ::= { pfInterfacesIfEntry 12 } + +pfInterfacesIf4PktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 packets passed going out on this interface." + ::= { pfInterfacesIfEntry 13 } + +pfInterfacesIf4PktsOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv4 packets blocked going out on this interface." + ::= { pfInterfacesIfEntry 14 } + +pfInterfacesIf6BytesInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 bytes passed coming in on this interface." + ::= { pfInterfacesIfEntry 15 } + +pfInterfacesIf6BytesInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 bytes blocked coming in on this interface." + ::= { pfInterfacesIfEntry 16 } + +pfInterfacesIf6BytesOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 bytes passed going out on this interface." + ::= { pfInterfacesIfEntry 17 } + +pfInterfacesIf6BytesOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 bytes blocked going out on this interface." + ::= { pfInterfacesIfEntry 18 } + + +pfInterfacesIf6PktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 packets passed coming in on this interface." + ::= { pfInterfacesIfEntry 19 } + +pfInterfacesIf6PktsInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 packets blocked coming in on this interface." + ::= { pfInterfacesIfEntry 20 } + +pfInterfacesIf6PktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 packets passed going out on this interface." + ::= { pfInterfacesIfEntry 21 } + +pfInterfacesIf6PktsOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of IPv6 packets blocked going out on this interface." + ::= { pfInterfacesIfEntry 22 } + +-- -------------------------------------------------------------------------- + +-- +-- tables +-- + +pfTablesTblNumber OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of tables on this system." + ::= { pfTables 1 } + +pfTablesTblTable OBJECT-TYPE + SYNTAX SEQUENCE OF PfTablesTblEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of tables, index on pfTablesTblIndex." + ::= { pfTables 2 } + +pfTablesTblEntry OBJECT-TYPE + SYNTAX PfTablesTblEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Any entry in the pfTablesTblTable containing information + about a particular table on the system." + INDEX { pfTablesTblIndex } + ::= { pfTablesTblTable 1 } + +PfTablesTblEntry ::= SEQUENCE { + pfTablesTblIndex Integer32, + pfTablesTblDescr OCTET STRING, + pfTablesTblCount Integer32, + pfTablesTblTZero TimeTicks, + pfTablesTblRefsAnchor Integer32, + pfTablesTblRefsRule Integer32, + pfTablesTblEvalMatch Counter64, + pfTablesTblEvalNoMatch Counter64, + pfTablesTblBytesInPass Counter64, + pfTablesTblBytesInBlock Counter64, + pfTablesTblBytesInXPass Counter64, + pfTablesTblBytesOutPass Counter64, + pfTablesTblBytesOutBlock Counter64, + pfTablesTblBytesOutXPass Counter64, + pfTablesTblPktsInPass Counter64, + pfTablesTblPktsInBlock Counter64, + pfTablesTblPktsInXPass Counter64, + pfTablesTblPktsOutPass Counter64, + pfTablesTblPktsOutBlock Counter64, + pfTablesTblPktsOutXPass Counter64 +} + +pfTablesTblIndex OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A unique value, greater than zero, for each table." + ::= { pfTablesTblEntry 1 } + +pfTablesTblDescr OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the table." + ::= { pfTablesTblEntry 2 } + +pfTablesTblCount OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of addresses in the table." + ::= { pfTablesTblEntry 3 } + +pfTablesTblTZero OBJECT-TYPE + SYNTAX TimeTicks + UNITS "1/100th of a Second" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The time passed since the statistics of this table were last + cleared or the time since this table was loaded, whichever is + sooner." + ::= { pfTablesTblEntry 4 } + +pfTablesTblRefsAnchor OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of anchors referencing this table." + ::= { pfTablesTblEntry 5 } + +pfTablesTblRefsRule OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of rules referencing this table." + ::= { pfTablesTblEntry 6 } + +pfTablesTblEvalMatch OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of evaluations returning a match." + ::= { pfTablesTblEntry 7 } + +pfTablesTblEvalNoMatch OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of evaluations not returning a match." + ::= { pfTablesTblEntry 8 } + +pfTablesTblBytesInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes passed in matching the table." + ::= { pfTablesTblEntry 9 } + +pfTablesTblBytesInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes blocked coming in matching the table." + ::= { pfTablesTblEntry 10 } + +pfTablesTblBytesInXPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes statefully passed in where the state + entry refers to the table, but the table no longer contains + the address in question." + ::= { pfTablesTblEntry 11 } + +pfTablesTblBytesOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes passed out matching the table." + ::= { pfTablesTblEntry 12 } + +pfTablesTblBytesOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes blocked going out matching the table." + ::= { pfTablesTblEntry 13 } + +pfTablesTblBytesOutXPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of bytes statefully passed out where the state + entry refers to the table, but the table no longer contains + the address in question." + ::= { pfTablesTblEntry 14 } + +pfTablesTblPktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets passed in matching the table." + ::= { pfTablesTblEntry 15 } + +pfTablesTblPktsInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets blocked coming in matching the table." + ::= { pfTablesTblEntry 16 } + +pfTablesTblPktsInXPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets statefully passed in where the state + entry refers to the table, but the table no longer contains + the address in question." + ::= { pfTablesTblEntry 17 } + +pfTablesTblPktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets passed out matching the table." + ::= { pfTablesTblEntry 18 } + +pfTablesTblPktsOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets blocked going out matching the table." + ::= { pfTablesTblEntry 19 } + +pfTablesTblPktsOutXPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of packets statefully passed out where the state + entry refers to the table, but the table no longer contains + the address in question." + ::= { pfTablesTblEntry 20 } + +pfTablesAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF PfTablesAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of addresses from every table on the system." + ::= { pfTables 3 } + +pfTablesAddrEntry OBJECT-TYPE + SYNTAX PfTablesAddrEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the pfTablesAddrTable containing information + about a particular entry in a table." + INDEX { pfTablesAddrIndex } + ::= { pfTablesAddrTable 1 } + +PfTablesAddrEntry ::= SEQUENCE { + pfTablesAddrIndex Integer32, + pfTablesAddrNet IpAddress, + pfTablesAddrMask Integer32, + pfTablesAddrTZero TimeTicks, + pfTablesAddrBytesInPass Counter64, + pfTablesAddrBytesInBlock Counter64, + pfTablesAddrBytesOutPass Counter64, + pfTablesAddrBytesOutBlock Counter64, + pfTablesAddrPktsInPass Counter64, + pfTablesAddrPktsInBlock Counter64, + pfTablesAddrPktsOutPass Counter64, + pfTablesAddrPktsOutBlock Counter64 +} + +pfTablesAddrIndex OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A unique value, greater than zero, for each address." + ::= { pfTablesAddrEntry 1 } + +pfTablesAddrNet OBJECT-TYPE + SYNTAX IpAddress + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The IP address of this particular table entry." + ::= { pfTablesAddrEntry 2 } + +pfTablesAddrMask OBJECT-TYPE + SYNTAX Integer32 (0..32) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The CIDR netmask of this particular table entry." + ::= { pfTablesAddrEntry 3 } + +pfTablesAddrTZero OBJECT-TYPE + SYNTAX TimeTicks + UNITS "1/100th of a Second" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The time passed since this entry's statistics were last + cleared, or the time passed since this entry was loaded + into the table, whichever is sooner." + ::= { pfTablesAddrEntry 4 } + +pfTablesAddrBytesInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of inbound bytes passed as a result of this entry." + ::= { pfTablesAddrEntry 5 } + +pfTablesAddrBytesInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of inbound bytes blocked as a result of this entry." + ::= { pfTablesAddrEntry 6 } + +pfTablesAddrBytesOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outbound bytes passed as a result of this entry." + ::= { pfTablesAddrEntry 7 } + +pfTablesAddrBytesOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outbound bytes blocked as a result of this entry." + ::= { pfTablesAddrEntry 8 } + +pfTablesAddrPktsInPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of inbound packets passed as a result of this entry." + ::= { pfTablesAddrEntry 9 } + +pfTablesAddrPktsInBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of inbound packets blocked as a result of this entry." + ::= { pfTablesAddrEntry 10 } + +pfTablesAddrPktsOutPass OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outbound packets passed as a result of this entry." + ::= { pfTablesAddrEntry 11 } + +pfTablesAddrPktsOutBlock OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outbound packets blocked as a result of this + entry." + ::= { pfTablesAddrEntry 12 } + +-- -------------------------------------------------------------------------- + +-- +-- Altq information +-- + +pfAltqQueueNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of queues in the active set." + ::= { pfAltq 1 } + +pfAltqQueueTable OBJECT-TYPE + SYNTAX SEQUENCE OF PfAltqQueueEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table containing the rules that are active on this system." + ::= { pfAltq 2 } + +pfAltqQueueEntry OBJECT-TYPE + SYNTAX PfAltqQueueEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the pfAltqQueueTable table." + INDEX { pfAltqQueueIndex } + ::= { pfAltqQueueTable 1 } + +PfAltqQueueEntry ::= SEQUENCE { + pfAltqQueueIndex Integer32, + pfAltqQueueDescr OCTET STRING, + pfAltqQueueParent OCTET STRING, + pfAltqQueueScheduler INTEGER, + pfAltqQueueBandwidth Unsigned32, + pfAltqQueuePriority Integer32, + pfAltqQueueLimit Integer32 +} + +pfAltqQueueIndex OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A unique value, greater than zero, for each queue." + ::= { pfAltqQueueEntry 1 } + +pfAltqQueueDescr OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the queue." + ::= { pfAltqQueueEntry 2 } + +pfAltqQueueParent OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Name of the queue's parent if it has one." + ::= { pfAltqQueueEntry 3 } + +pfAltqQueueScheduler OBJECT-TYPE + SYNTAX INTEGER { cbq(1), hfsc(8), priq(11) } + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Scheduler algorithm implemented by this queue." + ::= { pfAltqQueueEntry 4 } + +pfAltqQueueBandwidth OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Bandwitch assigned to this queue." + ::= { pfAltqQueueEntry 5 } + +pfAltqQueuePriority OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Priority level of the queue." + ::= { pfAltqQueueEntry 6 } + +pfAltqQueueLimit OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum number of packets in the queue." + ::= { pfAltqQueueEntry 7 } + +END diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile new file mode 100644 index 000000000000..18860668f7d9 --- /dev/null +++ b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile @@ -0,0 +1,15 @@ +# $FreeBSD$ +# +# Author: Philip Paeps + +CONTRIB=${.CURDIR}/../../../../contrib/bsnmp + +MOD= pf +SRCS= pf_snmp.c +WARNS?= 6 + +XSYM= begemotPf +DEFS= ${MOD}_tree.def +BMIBS= BEGEMOT-PF-MIB.txt + +.include diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c new file mode 100644 index 000000000000..a7cced3d6b91 --- /dev/null +++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c @@ -0,0 +1,1170 @@ +/*- + * Copyright (c) 2005 Philip Paeps + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "pf_oid.h" +#include "pf_tree.h" + +struct lmodule *module; + +static int dev = -1; +static int started; +static uint32_t pf_tick; + +static struct pf_status pfs; + +enum { IN, OUT }; +enum { IPV4, IPV6 }; +enum { PASS, BLOCK }; + +#define PFI_IFTYPE_GROUP 0 +#define PFI_IFTYPE_INSTANCE 1 +#define PFI_IFTYPE_DETACHED 2 + +struct pfi_entry { + struct pfi_if pfi; + u_int index; + TAILQ_ENTRY(pfi_entry) link; +}; +TAILQ_HEAD(pfi_table, pfi_entry); + +static struct pfi_table pfi_table; +static time_t pfi_table_age; +static int pfi_table_count; + +#define PFI_TABLE_MAXAGE 5 + +struct pft_entry { + struct pfr_tstats pft; + u_int index; + TAILQ_ENTRY(pft_entry) link; +}; +TAILQ_HEAD(pft_table, pft_entry); + +static struct pft_table pft_table; +static time_t pft_table_age; +static int pft_table_count; + +#define PFT_TABLE_MAXAGE 5 + +struct pfq_entry { + struct pf_altq altq; + u_int index; + TAILQ_ENTRY(pfq_entry) link; +}; +TAILQ_HEAD(pfq_table, pfq_entry); + +static struct pfq_table pfq_table; +static time_t pfq_table_age; +static int pfq_table_count; + +#define PFQ_TABLE_MAXAGE 5 + +/* Forward declarations */ +static int pfi_refresh(void); +static int pfq_refresh(void); +static int pfs_refresh(void); +static int pft_refresh(void); +static struct pfi_entry * pfi_table_find(u_int idx); +static struct pfq_entry * pfq_table_find(u_int idx); +static struct pft_entry * pft_table_find(u_int idx); + +int +pf_status(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + time_t runtime; + unsigned char str[128]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if (pfs_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfStatusRunning: + val->v.uint32 = pfs.running; + break; + case LEAF_pfStatusRuntime: + runtime = (pfs.since > 0) ? + time(NULL) - pfs.since : 0; + val->v.uint32 = runtime * 100; + break; + case LEAF_pfStatusDebug: + val->v.uint32 = pfs.debug; + break; + case LEAF_pfStatusHostId: + sprintf(str, "0x%08x", ntohl(pfs.hostid)); + return (string_get(val, str, strlen(str))); + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_counter(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if (pfs_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfCounterMatch: + val->v.counter64 = pfs.counters[PFRES_MATCH]; + break; + case LEAF_pfCounterBadOffset: + val->v.counter64 = pfs.counters[PFRES_BADOFF]; + break; + case LEAF_pfCounterFragment: + val->v.counter64 = pfs.counters[PFRES_FRAG]; + break; + case LEAF_pfCounterShort: + val->v.counter64 = pfs.counters[PFRES_SHORT]; + break; + case LEAF_pfCounterNormalize: + val->v.counter64 = pfs.counters[PFRES_NORM]; + break; + case LEAF_pfCounterMemDrop: + val->v.counter64 = pfs.counters[PFRES_MEMORY]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_statetable(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if (pfs_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfStateTableCount: + val->v.uint32 = pfs.states; + break; + case LEAF_pfStateTableSearches: + val->v.counter64 = + pfs.fcounters[FCNT_STATE_SEARCH]; + break; + case LEAF_pfStateTableInserts: + val->v.counter64 = + pfs.fcounters[FCNT_STATE_INSERT]; + break; + case LEAF_pfStateTableRemovals: + val->v.counter64 = + pfs.fcounters[FCNT_STATE_REMOVALS]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_srcnodes(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if (pfs_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfSrcNodesCount: + val->v.uint32 = pfs.src_nodes; + break; + case LEAF_pfSrcNodesSearches: + val->v.counter64 = + pfs.scounters[SCNT_SRC_NODE_SEARCH]; + break; + case LEAF_pfSrcNodesInserts: + val->v.counter64 = + pfs.scounters[SCNT_SRC_NODE_INSERT]; + break; + case LEAF_pfSrcNodesRemovals: + val->v.counter64 = + pfs.scounters[SCNT_SRC_NODE_REMOVALS]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_limits(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pfioc_limit pl; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + bzero(&pl, sizeof(struct pfioc_limit)); + + switch (which) { + case LEAF_pfLimitsStates: + pl.index = PF_LIMIT_STATES; + break; + case LEAF_pfLimitsSrcNodes: + pl.index = PF_LIMIT_SRC_NODES; + break; + case LEAF_pfLimitsFrags: + pl.index = PF_LIMIT_FRAGS; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + if (ioctl(dev, DIOCGETLIMIT, &pl)) { + syslog(LOG_ERR, "pf_limits(): ioctl(): %s", + strerror(errno)); + return (SNMP_ERR_GENERR); + } + + val->v.uint32 = pl.limit; + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_timeouts(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pfioc_tm pt; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + bzero(&pt, sizeof(struct pfioc_tm)); + + switch (which) { + case LEAF_pfTimeoutsTcpFirst: + pt.timeout = PFTM_TCP_FIRST_PACKET; + break; + case LEAF_pfTimeoutsTcpOpening: + pt.timeout = PFTM_TCP_OPENING; + break; + case LEAF_pfTimeoutsTcpEstablished: + pt.timeout = PFTM_TCP_ESTABLISHED; + break; + case LEAF_pfTimeoutsTcpClosing: + pt.timeout = PFTM_TCP_CLOSING; + break; + case LEAF_pfTimeoutsTcpFinWait: + pt.timeout = PFTM_TCP_FIN_WAIT; + break; + case LEAF_pfTimeoutsTcpClosed: + pt.timeout = PFTM_TCP_CLOSED; + break; + case LEAF_pfTimeoutsUdpFirst: + pt.timeout = PFTM_UDP_FIRST_PACKET; + break; + case LEAF_pfTimeoutsUdpSingle: + pt.timeout = PFTM_UDP_SINGLE; + break; + case LEAF_pfTimeoutsUdpMultiple: + pt.timeout = PFTM_UDP_MULTIPLE; + break; + case LEAF_pfTimeoutsIcmpFirst: + pt.timeout = PFTM_ICMP_FIRST_PACKET; + break; + case LEAF_pfTimeoutsIcmpError: + pt.timeout = PFTM_ICMP_ERROR_REPLY; + break; + case LEAF_pfTimeoutsOtherFirst: + pt.timeout = PFTM_OTHER_FIRST_PACKET; + break; + case LEAF_pfTimeoutsOtherSingle: + pt.timeout = PFTM_OTHER_SINGLE; + break; + case LEAF_pfTimeoutsOtherMultiple: + pt.timeout = PFTM_OTHER_MULTIPLE; + break; + case LEAF_pfTimeoutsFragment: + pt.timeout = PFTM_FRAG; + break; + case LEAF_pfTimeoutsInterval: + pt.timeout = PFTM_INTERVAL; + break; + case LEAF_pfTimeoutsAdaptiveStart: + pt.timeout = PFTM_ADAPTIVE_START; + break; + case LEAF_pfTimeoutsAdaptiveEnd: + pt.timeout = PFTM_ADAPTIVE_END; + break; + case LEAF_pfTimeoutsSrcNode: + pt.timeout = PFTM_SRC_NODE; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + if (ioctl(dev, DIOCGETTIMEOUT, &pt)) { + syslog(LOG_ERR, "pf_timeouts(): ioctl(): %s", + strerror(errno)); + return (SNMP_ERR_GENERR); + } + + val->v.integer = pt.seconds; + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_logif(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + unsigned char str[IFNAMSIZ]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if (pfs_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfLogInterfaceName: + strlcpy(str, pfs.ifname, sizeof str); + return (string_get(val, str, strlen(str))); + case LEAF_pfLogInterfaceIp4BytesIn: + val->v.counter64 = pfs.bcounters[IPV4][IN]; + break; + case LEAF_pfLogInterfaceIp4BytesOut: + val->v.counter64 = pfs.bcounters[IPV4][OUT]; + break; + case LEAF_pfLogInterfaceIp4PktsInPass: + val->v.counter64 = + pfs.pcounters[IPV4][IN][PF_PASS]; + break; + case LEAF_pfLogInterfaceIp4PktsInDrop: + val->v.counter64 = + pfs.pcounters[IPV4][IN][PF_DROP]; + break; + case LEAF_pfLogInterfaceIp4PktsOutPass: + val->v.counter64 = + pfs.pcounters[IPV4][OUT][PF_PASS]; + break; + case LEAF_pfLogInterfaceIp4PktsOutDrop: + val->v.counter64 = + pfs.pcounters[IPV4][OUT][PF_DROP]; + break; + case LEAF_pfLogInterfaceIp6BytesIn: + val->v.counter64 = pfs.bcounters[IPV6][IN]; + break; + case LEAF_pfLogInterfaceIp6BytesOut: + val->v.counter64 = pfs.bcounters[IPV6][OUT]; + break; + case LEAF_pfLogInterfaceIp6PktsInPass: + val->v.counter64 = + pfs.pcounters[IPV6][IN][PF_PASS]; + break; + case LEAF_pfLogInterfaceIp6PktsInDrop: + val->v.counter64 = + pfs.pcounters[IPV6][IN][PF_DROP]; + break; + case LEAF_pfLogInterfaceIp6PktsOutPass: + val->v.counter64 = + pfs.pcounters[IPV6][OUT][PF_PASS]; + break; + case LEAF_pfLogInterfaceIp6PktsOutDrop: + val->v.counter64 = + pfs.pcounters[IPV6][OUT][PF_DROP]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_interfaces(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE) + if (pfi_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfInterfacesIfNumber: + val->v.uint32 = pfi_table_count; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_iftable(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pfi_entry *e = NULL; + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_GETNEXT: + if ((e = NEXT_OBJECT_INT(&pfi_table, + &val->var, sub)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + val->var.len = sub + 1; + val->var.subs[sub] = e->index; + break; + case SNMP_OP_GET: + if (val->var.len - sub != 1) + return (SNMP_ERR_NOSUCHNAME); + if ((e = pfi_table_find(val->var.subs[sub])) == NULL) + return (SNMP_ERR_NOSUCHNAME); + break; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + default: + abort(); + } + + if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE) + pfi_refresh(); + + switch (which) { + case LEAF_pfInterfacesIfDescr: + return (string_get(val, e->pfi.pfif_name, -1)); + case LEAF_pfInterfacesIfType: + val->v.integer = PFI_IFTYPE_INSTANCE; + break; + case LEAF_pfInterfacesIfTZero: + val->v.uint32 = + (time(NULL) - e->pfi.pfif_tzero) * 100; + break; + case LEAF_pfInterfacesIfRefsState: + val->v.uint32 = e->pfi.pfif_states; + break; + case LEAF_pfInterfacesIfRefsRule: + val->v.uint32 = e->pfi.pfif_rules; + break; + case LEAF_pfInterfacesIf4BytesInPass: + val->v.counter64 = + e->pfi.pfif_bytes[IPV4][IN][PASS]; + break; + case LEAF_pfInterfacesIf4BytesInBlock: + val->v.counter64 = + e->pfi.pfif_bytes[IPV4][IN][BLOCK]; + break; + case LEAF_pfInterfacesIf4BytesOutPass: + val->v.counter64 = + e->pfi.pfif_bytes[IPV4][OUT][PASS]; + break; + case LEAF_pfInterfacesIf4BytesOutBlock: + val->v.counter64 = + e->pfi.pfif_bytes[IPV4][OUT][BLOCK]; + break; + case LEAF_pfInterfacesIf4PktsInPass: + val->v.counter64 = + e->pfi.pfif_packets[IPV4][IN][PASS]; + break; + case LEAF_pfInterfacesIf4PktsInBlock: + val->v.counter64 = + e->pfi.pfif_packets[IPV4][IN][BLOCK]; + break; + case LEAF_pfInterfacesIf4PktsOutPass: + val->v.counter64 = + e->pfi.pfif_packets[IPV4][OUT][PASS]; + break; + case LEAF_pfInterfacesIf4PktsOutBlock: + val->v.counter64 = + e->pfi.pfif_packets[IPV4][OUT][BLOCK]; + break; + case LEAF_pfInterfacesIf6BytesInPass: + val->v.counter64 = + e->pfi.pfif_bytes[IPV6][IN][PASS]; + break; + case LEAF_pfInterfacesIf6BytesInBlock: + val->v.counter64 = + e->pfi.pfif_bytes[IPV6][IN][BLOCK]; + break; + case LEAF_pfInterfacesIf6BytesOutPass: + val->v.counter64 = + e->pfi.pfif_bytes[IPV6][OUT][PASS]; + break; + case LEAF_pfInterfacesIf6BytesOutBlock: + val->v.counter64 = + e->pfi.pfif_bytes[IPV6][OUT][BLOCK]; + break; + case LEAF_pfInterfacesIf6PktsInPass: + val->v.counter64 = + e->pfi.pfif_packets[IPV6][IN][PASS]; + break; + case LEAF_pfInterfacesIf6PktsInBlock: + val->v.counter64 = + e->pfi.pfif_packets[IPV6][IN][BLOCK]; + break; + case LEAF_pfInterfacesIf6PktsOutPass: + val->v.counter64 = + e->pfi.pfif_packets[IPV6][OUT][PASS]; + break; + case LEAF_pfInterfacesIf6PktsOutBlock: + val->v.counter64 = + e->pfi.pfif_packets[IPV6][OUT][BLOCK]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); +} + +int +pf_tables(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE) + if (pft_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfTablesTblNumber: + val->v.uint32 = pft_table_count; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_tbltable(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pft_entry *e = NULL; + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_GETNEXT: + if ((e = NEXT_OBJECT_INT(&pft_table, + &val->var, sub)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + val->var.len = sub + 1; + val->var.subs[sub] = e->index; + break; + case SNMP_OP_GET: + if (val->var.len - sub != 1) + return (SNMP_ERR_NOSUCHNAME); + if ((e = pft_table_find(val->var.subs[sub])) == NULL) + return (SNMP_ERR_NOSUCHNAME); + break; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + default: + abort(); + } + + if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE) + pft_refresh(); + + switch (which) { + case LEAF_pfTablesTblDescr: + return (string_get(val, e->pft.pfrts_name, -1)); + case LEAF_pfTablesTblCount: + val->v.integer = e->pft.pfrts_cnt; + break; + case LEAF_pfTablesTblTZero: + val->v.uint32 = + (time(NULL) - e->pft.pfrts_tzero) * 100; + break; + case LEAF_pfTablesTblRefsAnchor: + val->v.integer = + e->pft.pfrts_refcnt[PFR_REFCNT_ANCHOR]; + break; + case LEAF_pfTablesTblRefsRule: + val->v.integer = + e->pft.pfrts_refcnt[PFR_REFCNT_RULE]; + break; + case LEAF_pfTablesTblEvalMatch: + val->v.counter64 = e->pft.pfrts_match; + break; + case LEAF_pfTablesTblEvalNoMatch: + val->v.counter64 = e->pft.pfrts_nomatch; + break; + case LEAF_pfTablesTblBytesInPass: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_PASS]; + break; + case LEAF_pfTablesTblBytesInBlock: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesTblBytesInXPass: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_XPASS]; + break; + case LEAF_pfTablesTblBytesOutPass: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_PASS]; + break; + case LEAF_pfTablesTblBytesOutBlock: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesTblBytesOutXPass: + val->v.counter64 = + e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_XPASS]; + break; + case LEAF_pfTablesTblPktsInPass: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_PASS]; + break; + case LEAF_pfTablesTblPktsInBlock: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesTblPktsInXPass: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_XPASS]; + break; + case LEAF_pfTablesTblPktsOutPass: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_PASS]; + break; + case LEAF_pfTablesTblPktsOutBlock: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesTblPktsOutXPass: + val->v.counter64 = + e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_XPASS]; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); +} + +int +pf_tbladdr(struct snmp_context __unused *ctx, struct snmp_value __unused *val, + u_int __unused sub, u_int __unused vindex, enum snmp_op __unused op) +{ + return (SNMP_ERR_GENERR); +} + +int +pf_altq(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE) + if (pfq_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfAltqQueueNumber: + val->v.uint32 = pfq_table_count; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); + return (SNMP_ERR_GENERR); +} + +int +pf_altqq(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pfq_entry *e = NULL; + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_GETNEXT: + if ((e = NEXT_OBJECT_INT(&pfq_table, + &val->var, sub)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + val->var.len = sub + 1; + val->var.subs[sub] = e->index; + break; + case SNMP_OP_GET: + if (val->var.len - sub != 1) + return (SNMP_ERR_NOSUCHNAME); + if ((e = pfq_table_find(val->var.subs[sub])) == NULL) + return (SNMP_ERR_NOSUCHNAME); + break; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + default: + abort(); + } + + if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE) + pfq_refresh(); + + switch (which) { + case LEAF_pfAltqQueueDescr: + return (string_get(val, e->altq.qname, -1)); + case LEAF_pfAltqQueueParent: + return (string_get(val, e->altq.parent, -1)); + case LEAF_pfAltqQueueScheduler: + val->v.integer = e->altq.scheduler; + break; + case LEAF_pfAltqQueueBandwidth: + val->v.uint32 = e->altq.bandwidth; + break; + case LEAF_pfAltqQueuePriority: + val->v.integer = e->altq.priority; + break; + case LEAF_pfAltqQueueLimit: + val->v.integer = e->altq.qlimit; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); +} + +static struct pfi_entry * +pfi_table_find(u_int idx) +{ + struct pfi_entry *e; + + TAILQ_FOREACH(e, &pfi_table, link) + if (e->index == idx) + return (e); + return (NULL); +} + +static struct pfq_entry * +pfq_table_find(u_int idx) +{ + struct pfq_entry *e; + TAILQ_FOREACH(e, &pfq_table, link) + if (e->index == idx) + return (e); + return (NULL); +} + +static struct pft_entry * +pft_table_find(u_int idx) +{ + struct pft_entry *e; + + TAILQ_FOREACH(e, &pft_table, link) + if (e->index == idx) + return (e); + return (NULL); +} + +static int +pfi_refresh(void) +{ + struct pfioc_iface io; + struct pfi_if *p; + struct pfi_entry *e; + int i, numifs = 1; + + if (started && this_tick <= pf_tick) + return (0); + + while (!TAILQ_EMPTY(&pfi_table)) { + e = TAILQ_FIRST(&pfi_table); + TAILQ_REMOVE(&pfi_table, e, link); + free(e); + } + + bzero(&io, sizeof(io)); + p = malloc(sizeof(struct pfi_if)); + io.pfiio_flags = PFI_FLAG_INSTANCE; + io.pfiio_esize = sizeof(struct pfi_if); + + for (;;) { + p = realloc(p, numifs * sizeof(struct pfi_if)); + io.pfiio_size = numifs; + io.pfiio_buffer = p; + + if (ioctl(dev, DIOCIGETIFACES, &io)) { + syslog(LOG_ERR, "pfi_refresh(): ioctl(): %s", + strerror(errno)); + return (-1); + } + + if (numifs >= io.pfiio_size) + break; + + numifs = io.pfiio_size; + } + + for (i = 0; i < numifs; i++) { + e = malloc(sizeof(struct pfi_entry)); + e->index = i + 1; + memcpy(&e->pfi, p+i, sizeof(struct pfi_if)); + TAILQ_INSERT_TAIL(&pfi_table, e, link); + } + + pfi_table_age = time(NULL); + pfi_table_count = numifs; + pf_tick = this_tick; + + free(p); + return (0); +} + +static int +pfq_refresh(void) +{ + struct pfioc_altq pa; + struct pfq_entry *e; + int i, numqs, ticket; + + if (started && this_tick <= pf_tick) + return (0); + + while (!TAILQ_EMPTY(&pfq_table)) { + e = TAILQ_FIRST(&pfq_table); + TAILQ_REMOVE(&pfq_table, e, link); + free(e); + } + + bzero(&pa, sizeof(pa)); + + if (ioctl(dev, DIOCGETALTQS, &pa)) { + syslog(LOG_ERR, "pfq_refresh: ioctl(DIOCGETALTQS): %s", + strerror(errno)); + return (-1); + } + + numqs = pa.nr; + ticket = pa.ticket; + + for (i = 0; i < numqs; i++) { + e = malloc(sizeof(struct pfq_entry)); + pa.ticket = ticket; + pa.nr = i; + + if (ioctl(dev, DIOCGETALTQ, &pa)) { + syslog(LOG_ERR, "pfq_refresh(): " + "ioctl(DIOCGETALTQ): %s", + strerror(errno)); + return (-1); + } + + if (pa.altq.qid > 0) { + memcpy(&e->altq, &pa.altq, sizeof(struct pf_altq)); + e->index = pa.altq.qid; + pfq_table_count = i; + TAILQ_INSERT_TAIL(&pfq_table, e, link); + } + } + + pfq_table_age = time(NULL); + pf_tick = this_tick; + + return (0); +} + +static int +pfs_refresh(void) +{ + if (started && this_tick <= pf_tick) + return (0); + + bzero(&pfs, sizeof(struct pf_status)); + + if (ioctl(dev, DIOCGETSTATUS, &pfs)) { + syslog(LOG_ERR, "pfs_refresh(): ioctl(): %s", + strerror(errno)); + return (-1); + } + + pf_tick = this_tick; + return (0); +} + +static int +pft_refresh(void) +{ + struct pfioc_table io; + struct pfr_tstats *t; + struct pft_entry *e; + int i, numtbls = 1; + + if (started && this_tick <= pf_tick) + return (0); + + while (!TAILQ_EMPTY(&pft_table)) { + e = TAILQ_FIRST(&pft_table); + TAILQ_REMOVE(&pft_table, e, link); + free(e); + } + + bzero(&io, sizeof(io)); + t = malloc(sizeof(struct pfr_tstats)); + io.pfrio_esize = sizeof(struct pfr_tstats); + + for (;;) { + t = realloc(t, numtbls * sizeof(struct pfr_tstats)); + io.pfrio_size = numtbls; + io.pfrio_buffer = t; + + if (ioctl(dev, DIOCRGETTSTATS, &io)) { + syslog(LOG_ERR, "pft_refresh(): ioctl(): %s", + strerror(errno)); + return (-1); + } + + if (numtbls >= io.pfrio_size) + break; + + numtbls = io.pfrio_size; + } + + for (i = 0; i < numtbls; i++) { + e = malloc(sizeof(struct pfr_tstats)); + e->index = i + 1; + memcpy(&e->pft, t+i, sizeof(struct pfr_tstats)); + TAILQ_INSERT_TAIL(&pft_table, e, link); + } + + pft_table_age = time(NULL); + pft_table_count = numtbls; + pf_tick = this_tick; + + free(t); + return (0); +} + +/* + * Implement the bsnmpd module interface + */ +static int +pf_init(struct lmodule *mod, int __unused argc, char __unused *argv[]) +{ + module = mod; + + if ((dev = open("/dev/pf", O_RDONLY)) == -1) { + syslog(LOG_ERR, "pf_init(): open(): %s\n", + strerror(errno)); + return (-1); + } + + /* Prepare internal state */ + TAILQ_INIT(&pfi_table); + TAILQ_INIT(&pfq_table); + TAILQ_INIT(&pft_table); + + pfi_refresh(); + pfq_refresh(); + pfs_refresh(); + pft_refresh(); + + started = 1; + + return (0); +} + +static int +pf_fini(void) +{ + struct pfi_entry *i1, *i2; + struct pfq_entry *q1, *q2; + struct pft_entry *t1, *t2; + + /* Empty the list of interfaces */ + i1 = TAILQ_FIRST(&pfi_table); + while (i1 != NULL) { + i2 = TAILQ_NEXT(i1, link); + free(i1); + i1 = i2; + } + + /* List of queues */ + q1 = TAILQ_FIRST(&pfq_table); + while (q1 != NULL) { + q2 = TAILQ_NEXT(q1, link); + free(q1); + q1 = q2; + } + + /* And the list of tables */ + t1 = TAILQ_FIRST(&pft_table); + while (t1 != NULL) { + t2 = TAILQ_NEXT(t1, link); + free(t1); + t1 = t2; + } + + close(dev); + return (0); +} + +static void +pf_dump(void) +{ + pfi_refresh(); + pfq_refresh(); + pft_refresh(); + + syslog(LOG_ERR, "Dump: pfi_table_age = %u", + pfi_table_age); + syslog(LOG_ERR, "Dump: pfi_table_count = %d", + pfi_table_count); + + syslog(LOG_ERR, "Dump: pfq_table_age = %u", + pfq_table_age); + syslog(LOG_ERR, "Dump: pfq_table_count = %d", + pfq_table_count); + + syslog(LOG_ERR, "Dump: pft_table_age = %u", + pft_table_age); + + syslog(LOG_ERR, "Dump: pft_table_count = %d", + pft_table_count); +} + +const struct snmp_module config = { + .comment = "This module implements a MIB for the pf packet filter.", + .init = pf_init, + .fini = pf_fini, + .tree = pf_ctree, + .dump = pf_dump, + .tree_size = pf_CTREE_SIZE, +}; diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def b/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def new file mode 100644 index 000000000000..003a3ec9acb9 --- /dev/null +++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def @@ -0,0 +1,195 @@ +# +# Copyright (c) 2005 Philip Paeps +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +(1 internet + (4 private + (1 enterprises + (12325 fokus + (1 begemot + (200 begemotPf + (1 begemotPfObjects + (1 pfStatus + (1 pfStatusRunning INTEGER pf_status GET) + (2 pfStatusRuntime TIMETICKS pf_status GET) + (3 pfStatusDebug INTEGER pf_status GET) + (4 pfStatusHostId OCTETSTRING pf_status GET) + ) + (2 pfCounter + (1 pfCounterMatch COUNTER64 pf_counter GET) + (2 pfCounterBadOffset COUNTER64 pf_counter GET) + (3 pfCounterFragment COUNTER64 pf_counter GET) + (4 pfCounterShort COUNTER64 pf_counter GET) + (5 pfCounterNormalize COUNTER64 pf_counter GET) + (6 pfCounterMemDrop COUNTER64 pf_counter GET) + ) + (3 pfStateTable + (1 pfStateTableCount UNSIGNED32 pf_statetable GET) + (2 pfStateTableSearches COUNTER64 pf_statetable GET) + (3 pfStateTableInserts COUNTER64 pf_statetable GET) + (4 pfStateTableRemovals COUNTER64 pf_statetable GET) + ) + (4 pfSrcNodes + (1 pfSrcNodesCount UNSIGNED32 pf_srcnodes GET) + (2 pfSrcNodesSearches COUNTER64 pf_srcnodes GET) + (3 pfSrcNodesInserts COUNTER64 pf_srcnodes GET) + (4 pfSrcNodesRemovals COUNTER64 pf_srcnodes GET) + ) + (5 pfLimits + (1 pfLimitsStates UNSIGNED32 pf_limits GET) + (2 pfLimitsSrcNodes UNSIGNED32 pf_limits GET) + (3 pfLimitsFrags UNSIGNED32 pf_limits GET) + ) + (6 pfTimeouts + (1 pfTimeoutsTcpFirst INTEGER32 pf_timeouts GET) + (2 pfTimeoutsTcpOpening INTEGER32 pf_timeouts GET) + (3 pfTimeoutsTcpEstablished INTEGER32 pf_timeouts GET) + (4 pfTimeoutsTcpClosing INTEGER32 pf_timeouts GET) + (5 pfTimeoutsTcpFinWait INTEGER32 pf_timeouts GET) + (6 pfTimeoutsTcpClosed INTEGER32 pf_timeouts GET) + (7 pfTimeoutsUdpFirst INTEGER32 pf_timeouts GET) + (8 pfTimeoutsUdpSingle INTEGER32 pf_timeouts GET) + (9 pfTimeoutsUdpMultiple INTEGER32 pf_timeouts GET) + (10 pfTimeoutsIcmpFirst INTEGER32 pf_timeouts GET) + (11 pfTimeoutsIcmpError INTEGER32 pf_timeouts GET) + (12 pfTimeoutsOtherFirst INTEGER32 pf_timeouts GET) + (13 pfTimeoutsOtherSingle INTEGER32 pf_timeouts GET) + (14 pfTimeoutsOtherMultiple INTEGER32 pf_timeouts GET) + (15 pfTimeoutsFragment INTEGER32 pf_timeouts GET) + (16 pfTimeoutsInterval INTEGER32 pf_timeouts GET) + (17 pfTimeoutsAdaptiveStart INTEGER32 pf_timeouts GET) + (18 pfTimeoutsAdaptiveEnd INTEGER32 pf_timeouts GET) + (19 pfTimeoutsSrcNode INTEGER32 pf_timeouts GET) + ) + (7 pfLogInterface + (1 pfLogInterfaceName OCTETSTRING pf_logif GET) + (2 pfLogInterfaceIp4BytesIn COUNTER64 pf_logif GET) + (3 pfLogInterfaceIp4BytesOut COUNTER64 pf_logif GET) + (4 pfLogInterfaceIp4PktsInPass COUNTER64 pf_logif GET) + (5 pfLogInterfaceIp4PktsInDrop COUNTER64 pf_logif GET) + (6 pfLogInterfaceIp4PktsOutPass COUNTER64 pf_logif GET) + (7 pfLogInterfaceIp4PktsOutDrop COUNTER64 pf_logif GET) + (8 pfLogInterfaceIp6BytesIn COUNTER64 pf_logif GET) + (9 pfLogInterfaceIp6BytesOut COUNTER64 pf_logif GET) + (10 pfLogInterfaceIp6PktsInPass COUNTER64 pf_logif GET) + (11 pfLogInterfaceIp6PktsInDrop COUNTER64 pf_logif GET) + (12 pfLogInterfaceIp6PktsOutPass COUNTER64 pf_logif GET) + (13 pfLogInterfaceIp6PktsOutDrop COUNTER64 pf_logif GET) + ) + (8 pfInterfaces + (1 pfInterfacesIfNumber INTEGER32 pf_interfaces GET) + (2 pfInterfacesIfTable + (1 pfInterfacesIfEntry : INTEGER32 pf_iftable + (1 pfInterfacesIfIndex INTEGER32) + (2 pfInterfacesIfDescr OCTETSTRING GET) + (3 pfInterfacesIfType INTEGER GET) + (4 pfInterfacesIfTZero TIMETICKS GET) + (5 pfInterfacesIfRefsState UNSIGNED32 GET) + (6 pfInterfacesIfRefsRule UNSIGNED32 GET) + (7 pfInterfacesIf4BytesInPass COUNTER64 GET) + (8 pfInterfacesIf4BytesInBlock COUNTER64 GET) + (9 pfInterfacesIf4BytesOutPass COUNTER64 GET) + (10 pfInterfacesIf4BytesOutBlock COUNTER64 GET) + (11 pfInterfacesIf4PktsInPass COUNTER64 GET) + (12 pfInterfacesIf4PktsInBlock COUNTER64 GET) + (13 pfInterfacesIf4PktsOutPass COUNTER64 GET) + (14 pfInterfacesIf4PktsOutBlock COUNTER64 GET) + (15 pfInterfacesIf6BytesInPass COUNTER64 GET) + (16 pfInterfacesIf6BytesInBlock COUNTER64 GET) + (17 pfInterfacesIf6BytesOutPass COUNTER64 GET) + (18 pfInterfacesIf6BytesOutBlock COUNTER64 GET) + (19 pfInterfacesIf6PktsInPass COUNTER64 GET) + (20 pfInterfacesIf6PktsInBlock COUNTER64 GET) + (21 pfInterfacesIf6PktsOutPass COUNTER64 GET) + (22 pfInterfacesIf6PktsOutBlock COUNTER64 GET) + ) + ) + ) + (9 pfTables + (1 pfTablesTblNumber INTEGER32 pf_tables GET) + (2 pfTablesTblTable + (1 pfTablesTblEntry : INTEGER32 pf_tbltable + (1 pfTablesTblIndex INTEGER32) + (2 pfTablesTblDescr OCTETSTRING GET) + (3 pfTablesTblCount INTEGER32 GET) + (4 pfTablesTblTZero TIMETICKS GET) + (5 pfTablesTblRefsAnchor INTEGER32 GET) + (6 pfTablesTblRefsRule INTEGER32 GET) + (7 pfTablesTblEvalMatch COUNTER64 GET) + (8 pfTablesTblEvalNoMatch COUNTER64 GET) + (9 pfTablesTblBytesInPass COUNTER64 GET) + (10 pfTablesTblBytesInBlock COUNTER64 GET) + (11 pfTablesTblBytesInXPass COUNTER64 GET) + (12 pfTablesTblBytesOutPass COUNTER64 GET) + (13 pfTablesTblBytesOutBlock COUNTER64 GET) + (14 pfTablesTblBytesOutXPass COUNTER64 GET) + (15 pfTablesTblPktsInPass COUNTER64 GET) + (16 pfTablesTblPktsInBlock COUNTER64 GET) + (17 pfTablesTblPktsInXPass COUNTER64 GET) + (18 pfTablesTblPktsOutPass COUNTER64 GET) + (19 pfTablesTblPktsOutBlock COUNTER64 GET) + (20 pfTablesTblPktsOutXPass COUNTER64 GET) + ) + ) + (3 pfTablesAddrTable + (1 pfTablesAddrEntry : INTEGER32 pf_tbladdr + (1 pfTablesAddrIndex INTEGER32) + (2 pfTablesAddrNet IPADDRESS GET) + (3 pfTablesAddrMask INTEGER32 GET) + (4 pfTablesAddrTZero TIMETICKS GET) + (5 pfTablesAddrBytesInPass COUNTER64 GET) + (6 pfTablesAddrBytesInBlock COUNTER64 GET) + (7 pfTablesAddrBytesOutPass COUNTER64 GET) + (8 pfTablesAddrBytesOutBlock COUNTER64 GET) + (9 pfTablesAddrPktsInPass COUNTER64 GET) + (10 pfTablesAddrPktsInBlock COUNTER64 GET) + (11 pfTablesAddrPktsOutPass COUNTER64 GET) + (12 pfTablesAddrPktsOutBlock COUNTER64 GET) + ) + ) + ) + (10 pfAltq + (1 pfAltqQueueNumber INTEGER32 pf_altq GET) + (2 pfAltqQueueTable + (1 pfAltqQueueEntry : INTEGER32 pf_altqq + (1 pfAltqQueueIndex INTEGER32) + (2 pfAltqQueueDescr OCTETSTRING GET) + (3 pfAltqQueueParent OCTETSTRING GET) + (4 pfAltqQueueScheduler INTEGER GET) + (5 pfAltqQueueBandwidth UNSIGNED32 GET) + (6 pfAltqQueuePriority INTEGER32 GET) + (7 pfAltqQueueLimit INTEGER32 GET) + ) + ) + ) + ) + ) + ) + ) + ) + ) +)