1143611Sphilip/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 4143611Sphilip * Copyright (c) 2005 Philip Paeps <philip@FreeBSD.org> 5143611Sphilip * All rights reserved. 6143611Sphilip * 7143611Sphilip * Redistribution and use in source and binary forms, with or without 8143611Sphilip * modification, are permitted provided that the following conditions 9143611Sphilip * are met: 10143611Sphilip * 1. Redistributions of source code must retain the above copyright 11143611Sphilip * notice, this list of conditions and the following disclaimer. 12143611Sphilip * 2. Redistributions in binary form must reproduce the above copyright 13143611Sphilip * notice, this list of conditions and the following disclaimer in the 14143611Sphilip * documentation and/or other materials provided with the distribution. 15143611Sphilip * 16143611Sphilip * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17143611Sphilip * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18143611Sphilip * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19143611Sphilip * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20143611Sphilip * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21143611Sphilip * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22143611Sphilip * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23143611Sphilip * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24143611Sphilip * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25143611Sphilip * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26143611Sphilip * SUCH DAMAGE. 27143611Sphilip * 28143611Sphilip * $FreeBSD: stable/11/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c 357523 2020-02-04 19:46:29Z dim $ 29143611Sphilip */ 30143611Sphilip 31216294Ssyrinx#include <sys/queue.h> 32143611Sphilip#include <bsnmp/snmpmod.h> 33143611Sphilip 34143611Sphilip#include <net/pfvar.h> 35143611Sphilip#include <sys/ioctl.h> 36143611Sphilip 37143611Sphilip#include <errno.h> 38143611Sphilip#include <fcntl.h> 39143626Sphilip#include <stdint.h> 40143611Sphilip#include <stdio.h> 41143611Sphilip#include <stdlib.h> 42143611Sphilip#include <string.h> 43143611Sphilip#include <syslog.h> 44143611Sphilip#include <unistd.h> 45143611Sphilip 46143611Sphilip#include "pf_oid.h" 47143611Sphilip#include "pf_tree.h" 48143611Sphilip 49143611Sphilipstruct lmodule *module; 50143611Sphilip 51143611Sphilipstatic int dev = -1; 52143611Sphilipstatic int started; 53146531Sphilipstatic uint64_t pf_tick; 54143611Sphilip 55143611Sphilipstatic struct pf_status pfs; 56143611Sphilip 57143611Sphilipenum { IN, OUT }; 58143611Sphilipenum { IPV4, IPV6 }; 59143611Sphilipenum { PASS, BLOCK }; 60143611Sphilip 61143611Sphilip#define PFI_IFTYPE_GROUP 0 62143611Sphilip#define PFI_IFTYPE_INSTANCE 1 63143611Sphilip#define PFI_IFTYPE_DETACHED 2 64143611Sphilip 65143611Sphilipstruct pfi_entry { 66171173Smlaier struct pfi_kif pfi; 67143611Sphilip u_int index; 68143611Sphilip TAILQ_ENTRY(pfi_entry) link; 69143611Sphilip}; 70143611SphilipTAILQ_HEAD(pfi_table, pfi_entry); 71143611Sphilip 72143611Sphilipstatic struct pfi_table pfi_table; 73143611Sphilipstatic time_t pfi_table_age; 74143611Sphilipstatic int pfi_table_count; 75143611Sphilip 76143611Sphilip#define PFI_TABLE_MAXAGE 5 77143611Sphilip 78143611Sphilipstruct pft_entry { 79143611Sphilip struct pfr_tstats pft; 80143611Sphilip u_int index; 81143611Sphilip TAILQ_ENTRY(pft_entry) link; 82143611Sphilip}; 83143611SphilipTAILQ_HEAD(pft_table, pft_entry); 84143611Sphilip 85143611Sphilipstatic struct pft_table pft_table; 86143611Sphilipstatic time_t pft_table_age; 87143611Sphilipstatic int pft_table_count; 88143611Sphilip 89143611Sphilip#define PFT_TABLE_MAXAGE 5 90143611Sphilip 91205607Ssyrinxstruct pfa_entry { 92205607Ssyrinx struct pfr_astats pfas; 93205607Ssyrinx u_int index; 94205607Ssyrinx TAILQ_ENTRY(pfa_entry) link; 95205607Ssyrinx}; 96205607SsyrinxTAILQ_HEAD(pfa_table, pfa_entry); 97205607Ssyrinx 98205607Ssyrinxstatic struct pfa_table pfa_table; 99205607Ssyrinxstatic time_t pfa_table_age; 100205607Ssyrinxstatic int pfa_table_count; 101205607Ssyrinx 102205607Ssyrinx#define PFA_TABLE_MAXAGE 5 103205607Ssyrinx 104143611Sphilipstruct pfq_entry { 105143611Sphilip struct pf_altq altq; 106143611Sphilip u_int index; 107143611Sphilip TAILQ_ENTRY(pfq_entry) link; 108143611Sphilip}; 109143611SphilipTAILQ_HEAD(pfq_table, pfq_entry); 110143611Sphilip 111143611Sphilipstatic struct pfq_table pfq_table; 112143611Sphilipstatic time_t pfq_table_age; 113143611Sphilipstatic int pfq_table_count; 114143611Sphilip 115152970Sphilipstatic int altq_enabled = 0; 116152970Sphilip 117143611Sphilip#define PFQ_TABLE_MAXAGE 5 118143611Sphilip 119205280Ssyrinxstruct pfl_entry { 120205280Ssyrinx char name[MAXPATHLEN + PF_RULE_LABEL_SIZE]; 121205280Ssyrinx u_int64_t evals; 122205280Ssyrinx u_int64_t bytes[2]; 123205280Ssyrinx u_int64_t pkts[2]; 124205280Ssyrinx u_int index; 125205280Ssyrinx TAILQ_ENTRY(pfl_entry) link; 126205280Ssyrinx}; 127205280SsyrinxTAILQ_HEAD(pfl_table, pfl_entry); 128205280Ssyrinx 129205280Ssyrinxstatic struct pfl_table pfl_table; 130205280Ssyrinxstatic time_t pfl_table_age; 131205280Ssyrinxstatic int pfl_table_count; 132205280Ssyrinx 133205280Ssyrinx#define PFL_TABLE_MAXAGE 5 134205280Ssyrinx 135143611Sphilip/* Forward declarations */ 136143611Sphilipstatic int pfi_refresh(void); 137143611Sphilipstatic int pfq_refresh(void); 138143611Sphilipstatic int pfs_refresh(void); 139143611Sphilipstatic int pft_refresh(void); 140205607Ssyrinxstatic int pfa_refresh(void); 141205280Ssyrinxstatic int pfl_refresh(void); 142143611Sphilipstatic struct pfi_entry * pfi_table_find(u_int idx); 143143611Sphilipstatic struct pfq_entry * pfq_table_find(u_int idx); 144143611Sphilipstatic struct pft_entry * pft_table_find(u_int idx); 145205607Ssyrinxstatic struct pfa_entry * pfa_table_find(u_int idx); 146205280Ssyrinxstatic struct pfl_entry * pfl_table_find(u_int idx); 147143611Sphilip 148152970Sphilipstatic int altq_is_enabled(int pfdevice); 149152970Sphilip 150143611Sphilipint 151143611Sphilippf_status(struct snmp_context __unused *ctx, struct snmp_value *val, 152143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 153143611Sphilip{ 154143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 155143611Sphilip time_t runtime; 156143611Sphilip unsigned char str[128]; 157143611Sphilip 158143611Sphilip if (op == SNMP_OP_SET) 159143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 160143611Sphilip 161143611Sphilip if (op == SNMP_OP_GET) { 162143611Sphilip if (pfs_refresh() == -1) 163143611Sphilip return (SNMP_ERR_GENERR); 164143611Sphilip 165143611Sphilip switch (which) { 166143611Sphilip case LEAF_pfStatusRunning: 167143611Sphilip val->v.uint32 = pfs.running; 168143611Sphilip break; 169143611Sphilip case LEAF_pfStatusRuntime: 170143611Sphilip runtime = (pfs.since > 0) ? 171143611Sphilip time(NULL) - pfs.since : 0; 172143611Sphilip val->v.uint32 = runtime * 100; 173143611Sphilip break; 174143611Sphilip case LEAF_pfStatusDebug: 175143611Sphilip val->v.uint32 = pfs.debug; 176143611Sphilip break; 177143611Sphilip case LEAF_pfStatusHostId: 178143611Sphilip sprintf(str, "0x%08x", ntohl(pfs.hostid)); 179143611Sphilip return (string_get(val, str, strlen(str))); 180143611Sphilip 181143611Sphilip default: 182143611Sphilip return (SNMP_ERR_NOSUCHNAME); 183143611Sphilip } 184143611Sphilip 185143611Sphilip return (SNMP_ERR_NOERROR); 186143611Sphilip } 187143611Sphilip 188143611Sphilip abort(); 189143611Sphilip} 190143611Sphilip 191143611Sphilipint 192143611Sphilippf_counter(struct snmp_context __unused *ctx, struct snmp_value *val, 193143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 194143611Sphilip{ 195143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 196143611Sphilip 197143611Sphilip if (op == SNMP_OP_SET) 198143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 199143611Sphilip 200143611Sphilip if (op == SNMP_OP_GET) { 201143611Sphilip if (pfs_refresh() == -1) 202143611Sphilip return (SNMP_ERR_GENERR); 203143611Sphilip 204143611Sphilip switch (which) { 205143611Sphilip case LEAF_pfCounterMatch: 206143611Sphilip val->v.counter64 = pfs.counters[PFRES_MATCH]; 207143611Sphilip break; 208143611Sphilip case LEAF_pfCounterBadOffset: 209143611Sphilip val->v.counter64 = pfs.counters[PFRES_BADOFF]; 210143611Sphilip break; 211143611Sphilip case LEAF_pfCounterFragment: 212143611Sphilip val->v.counter64 = pfs.counters[PFRES_FRAG]; 213143611Sphilip break; 214143611Sphilip case LEAF_pfCounterShort: 215143611Sphilip val->v.counter64 = pfs.counters[PFRES_SHORT]; 216143611Sphilip break; 217143611Sphilip case LEAF_pfCounterNormalize: 218143611Sphilip val->v.counter64 = pfs.counters[PFRES_NORM]; 219143611Sphilip break; 220143611Sphilip case LEAF_pfCounterMemDrop: 221143611Sphilip val->v.counter64 = pfs.counters[PFRES_MEMORY]; 222143611Sphilip break; 223143611Sphilip 224143611Sphilip default: 225143611Sphilip return (SNMP_ERR_NOSUCHNAME); 226143611Sphilip } 227143611Sphilip 228143611Sphilip return (SNMP_ERR_NOERROR); 229143611Sphilip } 230143611Sphilip 231143611Sphilip abort(); 232143611Sphilip} 233143611Sphilip 234143611Sphilipint 235143611Sphilippf_statetable(struct snmp_context __unused *ctx, struct snmp_value *val, 236143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 237143611Sphilip{ 238143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 239143611Sphilip 240143611Sphilip if (op == SNMP_OP_SET) 241143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 242143611Sphilip 243143611Sphilip if (op == SNMP_OP_GET) { 244143611Sphilip if (pfs_refresh() == -1) 245143611Sphilip return (SNMP_ERR_GENERR); 246143611Sphilip 247143611Sphilip switch (which) { 248143611Sphilip case LEAF_pfStateTableCount: 249143611Sphilip val->v.uint32 = pfs.states; 250143611Sphilip break; 251143611Sphilip case LEAF_pfStateTableSearches: 252143611Sphilip val->v.counter64 = 253143611Sphilip pfs.fcounters[FCNT_STATE_SEARCH]; 254143611Sphilip break; 255143611Sphilip case LEAF_pfStateTableInserts: 256143611Sphilip val->v.counter64 = 257143611Sphilip pfs.fcounters[FCNT_STATE_INSERT]; 258143611Sphilip break; 259143611Sphilip case LEAF_pfStateTableRemovals: 260143611Sphilip val->v.counter64 = 261143611Sphilip pfs.fcounters[FCNT_STATE_REMOVALS]; 262143611Sphilip break; 263143611Sphilip 264143611Sphilip default: 265143611Sphilip return (SNMP_ERR_NOSUCHNAME); 266143611Sphilip } 267143611Sphilip 268143611Sphilip return (SNMP_ERR_NOERROR); 269143611Sphilip } 270143611Sphilip 271143611Sphilip abort(); 272143611Sphilip} 273143611Sphilip 274143611Sphilipint 275143611Sphilippf_srcnodes(struct snmp_context __unused *ctx, struct snmp_value *val, 276143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 277143611Sphilip{ 278143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 279143611Sphilip 280143611Sphilip if (op == SNMP_OP_SET) 281143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 282143611Sphilip 283143611Sphilip if (op == SNMP_OP_GET) { 284143611Sphilip if (pfs_refresh() == -1) 285143611Sphilip return (SNMP_ERR_GENERR); 286143611Sphilip 287143611Sphilip switch (which) { 288143611Sphilip case LEAF_pfSrcNodesCount: 289143611Sphilip val->v.uint32 = pfs.src_nodes; 290143611Sphilip break; 291143611Sphilip case LEAF_pfSrcNodesSearches: 292143611Sphilip val->v.counter64 = 293143611Sphilip pfs.scounters[SCNT_SRC_NODE_SEARCH]; 294143611Sphilip break; 295143611Sphilip case LEAF_pfSrcNodesInserts: 296143611Sphilip val->v.counter64 = 297143611Sphilip pfs.scounters[SCNT_SRC_NODE_INSERT]; 298143611Sphilip break; 299143611Sphilip case LEAF_pfSrcNodesRemovals: 300143611Sphilip val->v.counter64 = 301143611Sphilip pfs.scounters[SCNT_SRC_NODE_REMOVALS]; 302143611Sphilip break; 303143611Sphilip 304143611Sphilip default: 305143611Sphilip return (SNMP_ERR_NOSUCHNAME); 306143611Sphilip } 307143611Sphilip 308143611Sphilip return (SNMP_ERR_NOERROR); 309143611Sphilip } 310143611Sphilip 311143611Sphilip abort(); 312143611Sphilip} 313143611Sphilip 314143611Sphilipint 315143611Sphilippf_limits(struct snmp_context __unused *ctx, struct snmp_value *val, 316143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 317143611Sphilip{ 318143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 319143611Sphilip struct pfioc_limit pl; 320143611Sphilip 321143611Sphilip if (op == SNMP_OP_SET) 322143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 323143611Sphilip 324143611Sphilip if (op == SNMP_OP_GET) { 325143611Sphilip bzero(&pl, sizeof(struct pfioc_limit)); 326143611Sphilip 327143611Sphilip switch (which) { 328143611Sphilip case LEAF_pfLimitsStates: 329143611Sphilip pl.index = PF_LIMIT_STATES; 330143611Sphilip break; 331143611Sphilip case LEAF_pfLimitsSrcNodes: 332143611Sphilip pl.index = PF_LIMIT_SRC_NODES; 333143611Sphilip break; 334143611Sphilip case LEAF_pfLimitsFrags: 335143611Sphilip pl.index = PF_LIMIT_FRAGS; 336143611Sphilip break; 337143611Sphilip 338143611Sphilip default: 339143611Sphilip return (SNMP_ERR_NOSUCHNAME); 340143611Sphilip } 341143611Sphilip 342143611Sphilip if (ioctl(dev, DIOCGETLIMIT, &pl)) { 343143611Sphilip syslog(LOG_ERR, "pf_limits(): ioctl(): %s", 344143611Sphilip strerror(errno)); 345143611Sphilip return (SNMP_ERR_GENERR); 346143611Sphilip } 347143611Sphilip 348143611Sphilip val->v.uint32 = pl.limit; 349143611Sphilip 350143611Sphilip return (SNMP_ERR_NOERROR); 351143611Sphilip } 352143611Sphilip 353143611Sphilip abort(); 354143611Sphilip} 355143611Sphilip 356143611Sphilipint 357143611Sphilippf_timeouts(struct snmp_context __unused *ctx, struct snmp_value *val, 358143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 359143611Sphilip{ 360143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 361143611Sphilip struct pfioc_tm pt; 362143611Sphilip 363143611Sphilip if (op == SNMP_OP_SET) 364143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 365143611Sphilip 366143611Sphilip if (op == SNMP_OP_GET) { 367143611Sphilip bzero(&pt, sizeof(struct pfioc_tm)); 368143611Sphilip 369143611Sphilip switch (which) { 370143611Sphilip case LEAF_pfTimeoutsTcpFirst: 371143611Sphilip pt.timeout = PFTM_TCP_FIRST_PACKET; 372143611Sphilip break; 373143611Sphilip case LEAF_pfTimeoutsTcpOpening: 374143611Sphilip pt.timeout = PFTM_TCP_OPENING; 375143611Sphilip break; 376143611Sphilip case LEAF_pfTimeoutsTcpEstablished: 377143611Sphilip pt.timeout = PFTM_TCP_ESTABLISHED; 378143611Sphilip break; 379143611Sphilip case LEAF_pfTimeoutsTcpClosing: 380143611Sphilip pt.timeout = PFTM_TCP_CLOSING; 381143611Sphilip break; 382143611Sphilip case LEAF_pfTimeoutsTcpFinWait: 383143611Sphilip pt.timeout = PFTM_TCP_FIN_WAIT; 384143611Sphilip break; 385143611Sphilip case LEAF_pfTimeoutsTcpClosed: 386143611Sphilip pt.timeout = PFTM_TCP_CLOSED; 387143611Sphilip break; 388143611Sphilip case LEAF_pfTimeoutsUdpFirst: 389143611Sphilip pt.timeout = PFTM_UDP_FIRST_PACKET; 390143611Sphilip break; 391143611Sphilip case LEAF_pfTimeoutsUdpSingle: 392143611Sphilip pt.timeout = PFTM_UDP_SINGLE; 393143611Sphilip break; 394143611Sphilip case LEAF_pfTimeoutsUdpMultiple: 395143611Sphilip pt.timeout = PFTM_UDP_MULTIPLE; 396143611Sphilip break; 397143611Sphilip case LEAF_pfTimeoutsIcmpFirst: 398143611Sphilip pt.timeout = PFTM_ICMP_FIRST_PACKET; 399143611Sphilip break; 400143611Sphilip case LEAF_pfTimeoutsIcmpError: 401143611Sphilip pt.timeout = PFTM_ICMP_ERROR_REPLY; 402143611Sphilip break; 403143611Sphilip case LEAF_pfTimeoutsOtherFirst: 404143611Sphilip pt.timeout = PFTM_OTHER_FIRST_PACKET; 405143611Sphilip break; 406143611Sphilip case LEAF_pfTimeoutsOtherSingle: 407143611Sphilip pt.timeout = PFTM_OTHER_SINGLE; 408143611Sphilip break; 409143611Sphilip case LEAF_pfTimeoutsOtherMultiple: 410143611Sphilip pt.timeout = PFTM_OTHER_MULTIPLE; 411143611Sphilip break; 412143611Sphilip case LEAF_pfTimeoutsFragment: 413143611Sphilip pt.timeout = PFTM_FRAG; 414143611Sphilip break; 415143611Sphilip case LEAF_pfTimeoutsInterval: 416143611Sphilip pt.timeout = PFTM_INTERVAL; 417143611Sphilip break; 418143611Sphilip case LEAF_pfTimeoutsAdaptiveStart: 419143611Sphilip pt.timeout = PFTM_ADAPTIVE_START; 420143611Sphilip break; 421143611Sphilip case LEAF_pfTimeoutsAdaptiveEnd: 422143611Sphilip pt.timeout = PFTM_ADAPTIVE_END; 423143611Sphilip break; 424143611Sphilip case LEAF_pfTimeoutsSrcNode: 425143611Sphilip pt.timeout = PFTM_SRC_NODE; 426143611Sphilip break; 427143611Sphilip 428143611Sphilip default: 429143611Sphilip return (SNMP_ERR_NOSUCHNAME); 430143611Sphilip } 431143611Sphilip 432143611Sphilip if (ioctl(dev, DIOCGETTIMEOUT, &pt)) { 433143611Sphilip syslog(LOG_ERR, "pf_timeouts(): ioctl(): %s", 434143611Sphilip strerror(errno)); 435143611Sphilip return (SNMP_ERR_GENERR); 436143611Sphilip } 437143611Sphilip 438143611Sphilip val->v.integer = pt.seconds; 439143611Sphilip 440143611Sphilip return (SNMP_ERR_NOERROR); 441143611Sphilip } 442143611Sphilip 443143611Sphilip abort(); 444143611Sphilip} 445143611Sphilip 446143611Sphilipint 447143611Sphilippf_logif(struct snmp_context __unused *ctx, struct snmp_value *val, 448143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 449143611Sphilip{ 450143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 451143611Sphilip unsigned char str[IFNAMSIZ]; 452143611Sphilip 453143611Sphilip if (op == SNMP_OP_SET) 454143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 455143611Sphilip 456143611Sphilip if (op == SNMP_OP_GET) { 457143611Sphilip if (pfs_refresh() == -1) 458143611Sphilip return (SNMP_ERR_GENERR); 459143611Sphilip 460143611Sphilip switch (which) { 461143611Sphilip case LEAF_pfLogInterfaceName: 462143611Sphilip strlcpy(str, pfs.ifname, sizeof str); 463143611Sphilip return (string_get(val, str, strlen(str))); 464143611Sphilip case LEAF_pfLogInterfaceIp4BytesIn: 465143611Sphilip val->v.counter64 = pfs.bcounters[IPV4][IN]; 466143611Sphilip break; 467143611Sphilip case LEAF_pfLogInterfaceIp4BytesOut: 468143611Sphilip val->v.counter64 = pfs.bcounters[IPV4][OUT]; 469143611Sphilip break; 470143611Sphilip case LEAF_pfLogInterfaceIp4PktsInPass: 471143611Sphilip val->v.counter64 = 472143611Sphilip pfs.pcounters[IPV4][IN][PF_PASS]; 473143611Sphilip break; 474143611Sphilip case LEAF_pfLogInterfaceIp4PktsInDrop: 475143611Sphilip val->v.counter64 = 476143611Sphilip pfs.pcounters[IPV4][IN][PF_DROP]; 477143611Sphilip break; 478143611Sphilip case LEAF_pfLogInterfaceIp4PktsOutPass: 479143611Sphilip val->v.counter64 = 480143611Sphilip pfs.pcounters[IPV4][OUT][PF_PASS]; 481143611Sphilip break; 482143611Sphilip case LEAF_pfLogInterfaceIp4PktsOutDrop: 483143611Sphilip val->v.counter64 = 484143611Sphilip pfs.pcounters[IPV4][OUT][PF_DROP]; 485143611Sphilip break; 486143611Sphilip case LEAF_pfLogInterfaceIp6BytesIn: 487143611Sphilip val->v.counter64 = pfs.bcounters[IPV6][IN]; 488143611Sphilip break; 489143611Sphilip case LEAF_pfLogInterfaceIp6BytesOut: 490143611Sphilip val->v.counter64 = pfs.bcounters[IPV6][OUT]; 491143611Sphilip break; 492143611Sphilip case LEAF_pfLogInterfaceIp6PktsInPass: 493143611Sphilip val->v.counter64 = 494143611Sphilip pfs.pcounters[IPV6][IN][PF_PASS]; 495143611Sphilip break; 496143611Sphilip case LEAF_pfLogInterfaceIp6PktsInDrop: 497143611Sphilip val->v.counter64 = 498143611Sphilip pfs.pcounters[IPV6][IN][PF_DROP]; 499143611Sphilip break; 500143611Sphilip case LEAF_pfLogInterfaceIp6PktsOutPass: 501143611Sphilip val->v.counter64 = 502143611Sphilip pfs.pcounters[IPV6][OUT][PF_PASS]; 503143611Sphilip break; 504143611Sphilip case LEAF_pfLogInterfaceIp6PktsOutDrop: 505143611Sphilip val->v.counter64 = 506143611Sphilip pfs.pcounters[IPV6][OUT][PF_DROP]; 507143611Sphilip break; 508143611Sphilip 509143611Sphilip default: 510143611Sphilip return (SNMP_ERR_NOSUCHNAME); 511143611Sphilip } 512143611Sphilip 513143611Sphilip return (SNMP_ERR_NOERROR); 514143611Sphilip } 515143611Sphilip 516143611Sphilip abort(); 517143611Sphilip} 518143611Sphilip 519143611Sphilipint 520143611Sphilippf_interfaces(struct snmp_context __unused *ctx, struct snmp_value *val, 521143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 522143611Sphilip{ 523143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 524143611Sphilip 525143611Sphilip if (op == SNMP_OP_SET) 526143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 527143611Sphilip 528143611Sphilip if (op == SNMP_OP_GET) { 529143611Sphilip if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE) 530143611Sphilip if (pfi_refresh() == -1) 531143611Sphilip return (SNMP_ERR_GENERR); 532143611Sphilip 533143611Sphilip switch (which) { 534143611Sphilip case LEAF_pfInterfacesIfNumber: 535143611Sphilip val->v.uint32 = pfi_table_count; 536143611Sphilip break; 537143611Sphilip 538143611Sphilip default: 539143611Sphilip return (SNMP_ERR_NOSUCHNAME); 540143611Sphilip } 541143611Sphilip 542143611Sphilip return (SNMP_ERR_NOERROR); 543143611Sphilip } 544143611Sphilip 545143611Sphilip abort(); 546143611Sphilip} 547143611Sphilip 548143611Sphilipint 549143611Sphilippf_iftable(struct snmp_context __unused *ctx, struct snmp_value *val, 550143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 551143611Sphilip{ 552143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 553143611Sphilip struct pfi_entry *e = NULL; 554143611Sphilip 555205312Ssyrinx if ((time(NULL) - pfi_table_age) > PFI_TABLE_MAXAGE) 556205312Ssyrinx pfi_refresh(); 557205312Ssyrinx 558143611Sphilip switch (op) { 559143611Sphilip case SNMP_OP_SET: 560143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 561143611Sphilip case SNMP_OP_GETNEXT: 562143611Sphilip if ((e = NEXT_OBJECT_INT(&pfi_table, 563143611Sphilip &val->var, sub)) == NULL) 564143611Sphilip return (SNMP_ERR_NOSUCHNAME); 565143611Sphilip val->var.len = sub + 1; 566143611Sphilip val->var.subs[sub] = e->index; 567143611Sphilip break; 568143611Sphilip case SNMP_OP_GET: 569143611Sphilip if (val->var.len - sub != 1) 570143611Sphilip return (SNMP_ERR_NOSUCHNAME); 571143611Sphilip if ((e = pfi_table_find(val->var.subs[sub])) == NULL) 572143611Sphilip return (SNMP_ERR_NOSUCHNAME); 573143611Sphilip break; 574143611Sphilip 575143611Sphilip case SNMP_OP_COMMIT: 576143611Sphilip case SNMP_OP_ROLLBACK: 577143611Sphilip default: 578143611Sphilip abort(); 579143611Sphilip } 580143611Sphilip 581143611Sphilip switch (which) { 582143611Sphilip case LEAF_pfInterfacesIfDescr: 583171173Smlaier return (string_get(val, e->pfi.pfik_name, -1)); 584143611Sphilip case LEAF_pfInterfacesIfType: 585143611Sphilip val->v.integer = PFI_IFTYPE_INSTANCE; 586143611Sphilip break; 587143611Sphilip case LEAF_pfInterfacesIfTZero: 588143611Sphilip val->v.uint32 = 589171173Smlaier (time(NULL) - e->pfi.pfik_tzero) * 100; 590143611Sphilip break; 591143611Sphilip case LEAF_pfInterfacesIfRefsRule: 592240233Sglebius val->v.uint32 = e->pfi.pfik_rulerefs; 593143611Sphilip break; 594143611Sphilip case LEAF_pfInterfacesIf4BytesInPass: 595143611Sphilip val->v.counter64 = 596171173Smlaier e->pfi.pfik_bytes[IPV4][IN][PASS]; 597143611Sphilip break; 598143611Sphilip case LEAF_pfInterfacesIf4BytesInBlock: 599143611Sphilip val->v.counter64 = 600171173Smlaier e->pfi.pfik_bytes[IPV4][IN][BLOCK]; 601143611Sphilip break; 602143611Sphilip case LEAF_pfInterfacesIf4BytesOutPass: 603143611Sphilip val->v.counter64 = 604171173Smlaier e->pfi.pfik_bytes[IPV4][OUT][PASS]; 605143611Sphilip break; 606143611Sphilip case LEAF_pfInterfacesIf4BytesOutBlock: 607143611Sphilip val->v.counter64 = 608171173Smlaier e->pfi.pfik_bytes[IPV4][OUT][BLOCK]; 609143611Sphilip break; 610143611Sphilip case LEAF_pfInterfacesIf4PktsInPass: 611143611Sphilip val->v.counter64 = 612171173Smlaier e->pfi.pfik_packets[IPV4][IN][PASS]; 613143611Sphilip break; 614143611Sphilip case LEAF_pfInterfacesIf4PktsInBlock: 615143611Sphilip val->v.counter64 = 616171173Smlaier e->pfi.pfik_packets[IPV4][IN][BLOCK]; 617143611Sphilip break; 618143611Sphilip case LEAF_pfInterfacesIf4PktsOutPass: 619143611Sphilip val->v.counter64 = 620171173Smlaier e->pfi.pfik_packets[IPV4][OUT][PASS]; 621143611Sphilip break; 622143611Sphilip case LEAF_pfInterfacesIf4PktsOutBlock: 623143611Sphilip val->v.counter64 = 624171173Smlaier e->pfi.pfik_packets[IPV4][OUT][BLOCK]; 625143611Sphilip break; 626143611Sphilip case LEAF_pfInterfacesIf6BytesInPass: 627143611Sphilip val->v.counter64 = 628171173Smlaier e->pfi.pfik_bytes[IPV6][IN][PASS]; 629143611Sphilip break; 630143611Sphilip case LEAF_pfInterfacesIf6BytesInBlock: 631143611Sphilip val->v.counter64 = 632171173Smlaier e->pfi.pfik_bytes[IPV6][IN][BLOCK]; 633143611Sphilip break; 634143611Sphilip case LEAF_pfInterfacesIf6BytesOutPass: 635143611Sphilip val->v.counter64 = 636171173Smlaier e->pfi.pfik_bytes[IPV6][OUT][PASS]; 637143611Sphilip break; 638143611Sphilip case LEAF_pfInterfacesIf6BytesOutBlock: 639143611Sphilip val->v.counter64 = 640171173Smlaier e->pfi.pfik_bytes[IPV6][OUT][BLOCK]; 641143611Sphilip break; 642143611Sphilip case LEAF_pfInterfacesIf6PktsInPass: 643143611Sphilip val->v.counter64 = 644171173Smlaier e->pfi.pfik_packets[IPV6][IN][PASS]; 645143611Sphilip break; 646143611Sphilip case LEAF_pfInterfacesIf6PktsInBlock: 647143611Sphilip val->v.counter64 = 648171173Smlaier e->pfi.pfik_packets[IPV6][IN][BLOCK]; 649143611Sphilip break; 650143611Sphilip case LEAF_pfInterfacesIf6PktsOutPass: 651143611Sphilip val->v.counter64 = 652171173Smlaier e->pfi.pfik_packets[IPV6][OUT][PASS]; 653143611Sphilip break; 654143611Sphilip case LEAF_pfInterfacesIf6PktsOutBlock: 655310901Sngie val->v.counter64 = 656171173Smlaier e->pfi.pfik_packets[IPV6][OUT][BLOCK]; 657143611Sphilip break; 658143611Sphilip 659143611Sphilip default: 660143611Sphilip return (SNMP_ERR_NOSUCHNAME); 661143611Sphilip } 662143611Sphilip 663143611Sphilip return (SNMP_ERR_NOERROR); 664143611Sphilip} 665143611Sphilip 666143611Sphilipint 667143611Sphilippf_tables(struct snmp_context __unused *ctx, struct snmp_value *val, 668143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 669143611Sphilip{ 670143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 671143611Sphilip 672143611Sphilip if (op == SNMP_OP_SET) 673143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 674143611Sphilip 675143611Sphilip if (op == SNMP_OP_GET) { 676143611Sphilip if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE) 677143611Sphilip if (pft_refresh() == -1) 678143611Sphilip return (SNMP_ERR_GENERR); 679143611Sphilip 680143611Sphilip switch (which) { 681143611Sphilip case LEAF_pfTablesTblNumber: 682143611Sphilip val->v.uint32 = pft_table_count; 683143611Sphilip break; 684143611Sphilip 685143611Sphilip default: 686143611Sphilip return (SNMP_ERR_NOSUCHNAME); 687143611Sphilip } 688143611Sphilip 689143611Sphilip return (SNMP_ERR_NOERROR); 690143611Sphilip } 691143611Sphilip 692143611Sphilip abort(); 693143611Sphilip} 694143611Sphilip 695143611Sphilipint 696143611Sphilippf_tbltable(struct snmp_context __unused *ctx, struct snmp_value *val, 697143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 698143611Sphilip{ 699143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 700143611Sphilip struct pft_entry *e = NULL; 701143611Sphilip 702205312Ssyrinx if ((time(NULL) - pft_table_age) > PFT_TABLE_MAXAGE) 703205312Ssyrinx pft_refresh(); 704205312Ssyrinx 705143611Sphilip switch (op) { 706143611Sphilip case SNMP_OP_SET: 707143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 708143611Sphilip case SNMP_OP_GETNEXT: 709143611Sphilip if ((e = NEXT_OBJECT_INT(&pft_table, 710143611Sphilip &val->var, sub)) == NULL) 711143611Sphilip return (SNMP_ERR_NOSUCHNAME); 712143611Sphilip val->var.len = sub + 1; 713143611Sphilip val->var.subs[sub] = e->index; 714143611Sphilip break; 715143611Sphilip case SNMP_OP_GET: 716143611Sphilip if (val->var.len - sub != 1) 717143611Sphilip return (SNMP_ERR_NOSUCHNAME); 718143611Sphilip if ((e = pft_table_find(val->var.subs[sub])) == NULL) 719143611Sphilip return (SNMP_ERR_NOSUCHNAME); 720143611Sphilip break; 721143611Sphilip 722143611Sphilip case SNMP_OP_COMMIT: 723143611Sphilip case SNMP_OP_ROLLBACK: 724143611Sphilip default: 725143611Sphilip abort(); 726143611Sphilip } 727143611Sphilip 728143611Sphilip switch (which) { 729143611Sphilip case LEAF_pfTablesTblDescr: 730143611Sphilip return (string_get(val, e->pft.pfrts_name, -1)); 731143611Sphilip case LEAF_pfTablesTblCount: 732143611Sphilip val->v.integer = e->pft.pfrts_cnt; 733143611Sphilip break; 734143611Sphilip case LEAF_pfTablesTblTZero: 735143611Sphilip val->v.uint32 = 736143611Sphilip (time(NULL) - e->pft.pfrts_tzero) * 100; 737143611Sphilip break; 738143611Sphilip case LEAF_pfTablesTblRefsAnchor: 739143611Sphilip val->v.integer = 740143611Sphilip e->pft.pfrts_refcnt[PFR_REFCNT_ANCHOR]; 741143611Sphilip break; 742143611Sphilip case LEAF_pfTablesTblRefsRule: 743143611Sphilip val->v.integer = 744143611Sphilip e->pft.pfrts_refcnt[PFR_REFCNT_RULE]; 745143611Sphilip break; 746143611Sphilip case LEAF_pfTablesTblEvalMatch: 747143611Sphilip val->v.counter64 = e->pft.pfrts_match; 748143611Sphilip break; 749143611Sphilip case LEAF_pfTablesTblEvalNoMatch: 750143611Sphilip val->v.counter64 = e->pft.pfrts_nomatch; 751143611Sphilip break; 752143611Sphilip case LEAF_pfTablesTblBytesInPass: 753143611Sphilip val->v.counter64 = 754143611Sphilip e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_PASS]; 755143611Sphilip break; 756143611Sphilip case LEAF_pfTablesTblBytesInBlock: 757143611Sphilip val->v.counter64 = 758143611Sphilip e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_BLOCK]; 759143611Sphilip break; 760143611Sphilip case LEAF_pfTablesTblBytesInXPass: 761143611Sphilip val->v.counter64 = 762143611Sphilip e->pft.pfrts_bytes[PFR_DIR_IN][PFR_OP_XPASS]; 763143611Sphilip break; 764143611Sphilip case LEAF_pfTablesTblBytesOutPass: 765143611Sphilip val->v.counter64 = 766143611Sphilip e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_PASS]; 767143611Sphilip break; 768143611Sphilip case LEAF_pfTablesTblBytesOutBlock: 769143611Sphilip val->v.counter64 = 770143611Sphilip e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_BLOCK]; 771143611Sphilip break; 772143611Sphilip case LEAF_pfTablesTblBytesOutXPass: 773143611Sphilip val->v.counter64 = 774143611Sphilip e->pft.pfrts_bytes[PFR_DIR_OUT][PFR_OP_XPASS]; 775143611Sphilip break; 776143611Sphilip case LEAF_pfTablesTblPktsInPass: 777143611Sphilip val->v.counter64 = 778143611Sphilip e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_PASS]; 779143611Sphilip break; 780143611Sphilip case LEAF_pfTablesTblPktsInBlock: 781143611Sphilip val->v.counter64 = 782143611Sphilip e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_BLOCK]; 783143611Sphilip break; 784143611Sphilip case LEAF_pfTablesTblPktsInXPass: 785143611Sphilip val->v.counter64 = 786143611Sphilip e->pft.pfrts_packets[PFR_DIR_IN][PFR_OP_XPASS]; 787143611Sphilip break; 788143611Sphilip case LEAF_pfTablesTblPktsOutPass: 789143611Sphilip val->v.counter64 = 790143611Sphilip e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_PASS]; 791143611Sphilip break; 792143611Sphilip case LEAF_pfTablesTblPktsOutBlock: 793143611Sphilip val->v.counter64 = 794143611Sphilip e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_BLOCK]; 795143611Sphilip break; 796143611Sphilip case LEAF_pfTablesTblPktsOutXPass: 797143611Sphilip val->v.counter64 = 798143611Sphilip e->pft.pfrts_packets[PFR_DIR_OUT][PFR_OP_XPASS]; 799143611Sphilip break; 800143611Sphilip 801143611Sphilip default: 802143611Sphilip return (SNMP_ERR_NOSUCHNAME); 803143611Sphilip } 804143611Sphilip 805143611Sphilip return (SNMP_ERR_NOERROR); 806143611Sphilip} 807143611Sphilip 808143611Sphilipint 809143611Sphilippf_tbladdr(struct snmp_context __unused *ctx, struct snmp_value __unused *val, 810143611Sphilip u_int __unused sub, u_int __unused vindex, enum snmp_op __unused op) 811143611Sphilip{ 812205607Ssyrinx asn_subid_t which = val->var.subs[sub - 1]; 813205607Ssyrinx struct pfa_entry *e = NULL; 814205607Ssyrinx 815205607Ssyrinx if ((time(NULL) - pfa_table_age) > PFA_TABLE_MAXAGE) 816205607Ssyrinx pfa_refresh(); 817205607Ssyrinx 818205607Ssyrinx switch (op) { 819205607Ssyrinx case SNMP_OP_SET: 820205607Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 821205607Ssyrinx case SNMP_OP_GETNEXT: 822205607Ssyrinx if ((e = NEXT_OBJECT_INT(&pfa_table, 823205607Ssyrinx &val->var, sub)) == NULL) 824205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 825205607Ssyrinx val->var.len = sub + 1; 826205607Ssyrinx val->var.subs[sub] = e->index; 827205607Ssyrinx break; 828205607Ssyrinx case SNMP_OP_GET: 829205607Ssyrinx if (val->var.len - sub != 1) 830205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 831205607Ssyrinx if ((e = pfa_table_find(val->var.subs[sub])) == NULL) 832205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 833205607Ssyrinx break; 834205607Ssyrinx 835205607Ssyrinx case SNMP_OP_COMMIT: 836205607Ssyrinx case SNMP_OP_ROLLBACK: 837205607Ssyrinx default: 838205607Ssyrinx abort(); 839205607Ssyrinx } 840205607Ssyrinx 841205607Ssyrinx switch (which) { 842205607Ssyrinx case LEAF_pfTablesAddrNetType: 843205607Ssyrinx if (e->pfas.pfras_a.pfra_af == AF_INET) 844205607Ssyrinx val->v.integer = pfTablesAddrNetType_ipv4; 845205607Ssyrinx else if (e->pfas.pfras_a.pfra_af == AF_INET6) 846205607Ssyrinx val->v.integer = pfTablesAddrNetType_ipv6; 847205607Ssyrinx else 848205607Ssyrinx return (SNMP_ERR_GENERR); 849205607Ssyrinx break; 850205607Ssyrinx case LEAF_pfTablesAddrNet: 851205607Ssyrinx if (e->pfas.pfras_a.pfra_af == AF_INET) { 852205607Ssyrinx return (string_get(val, 853205607Ssyrinx (u_char *)&e->pfas.pfras_a.pfra_ip4addr, 4)); 854205607Ssyrinx } else if (e->pfas.pfras_a.pfra_af == AF_INET6) 855205607Ssyrinx return (string_get(val, 856205607Ssyrinx (u_char *)&e->pfas.pfras_a.pfra_ip6addr, 16)); 857205607Ssyrinx else 858205607Ssyrinx return (SNMP_ERR_GENERR); 859205607Ssyrinx break; 860205607Ssyrinx case LEAF_pfTablesAddrPrefix: 861205607Ssyrinx val->v.integer = (int32_t) e->pfas.pfras_a.pfra_net; 862205607Ssyrinx break; 863205607Ssyrinx case LEAF_pfTablesAddrTZero: 864205607Ssyrinx val->v.uint32 = 865205607Ssyrinx (time(NULL) - e->pfas.pfras_tzero) * 100; 866205607Ssyrinx break; 867205607Ssyrinx case LEAF_pfTablesAddrBytesInPass: 868205607Ssyrinx val->v.counter64 = 869205607Ssyrinx e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_PASS]; 870205607Ssyrinx break; 871205607Ssyrinx case LEAF_pfTablesAddrBytesInBlock: 872205607Ssyrinx val->v.counter64 = 873205607Ssyrinx e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_BLOCK]; 874205607Ssyrinx break; 875205607Ssyrinx case LEAF_pfTablesAddrBytesOutPass: 876205607Ssyrinx val->v.counter64 = 877205607Ssyrinx e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_PASS]; 878205607Ssyrinx break; 879205607Ssyrinx case LEAF_pfTablesAddrBytesOutBlock: 880205607Ssyrinx val->v.counter64 = 881205607Ssyrinx e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_BLOCK]; 882205607Ssyrinx break; 883205607Ssyrinx case LEAF_pfTablesAddrPktsInPass: 884205607Ssyrinx val->v.counter64 = 885205607Ssyrinx e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_PASS]; 886205607Ssyrinx break; 887205607Ssyrinx case LEAF_pfTablesAddrPktsInBlock: 888205607Ssyrinx val->v.counter64 = 889205607Ssyrinx e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_BLOCK]; 890205607Ssyrinx break; 891205607Ssyrinx case LEAF_pfTablesAddrPktsOutPass: 892205607Ssyrinx val->v.counter64 = 893205607Ssyrinx e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_PASS]; 894205607Ssyrinx break; 895205607Ssyrinx case LEAF_pfTablesAddrPktsOutBlock: 896205607Ssyrinx val->v.counter64 = 897205607Ssyrinx e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_BLOCK]; 898205607Ssyrinx break; 899205607Ssyrinx default: 900205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 901205607Ssyrinx } 902205607Ssyrinx 903205607Ssyrinx return (SNMP_ERR_NOERROR); 904143611Sphilip} 905143611Sphilip 906143611Sphilipint 907143611Sphilippf_altq(struct snmp_context __unused *ctx, struct snmp_value *val, 908143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 909143611Sphilip{ 910143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 911143611Sphilip 912205607Ssyrinx if (!altq_enabled) 913205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 914152970Sphilip 915143611Sphilip if (op == SNMP_OP_SET) 916143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 917143611Sphilip 918143611Sphilip if (op == SNMP_OP_GET) { 919143611Sphilip if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE) 920143611Sphilip if (pfq_refresh() == -1) 921143611Sphilip return (SNMP_ERR_GENERR); 922143611Sphilip 923143611Sphilip switch (which) { 924143611Sphilip case LEAF_pfAltqQueueNumber: 925143611Sphilip val->v.uint32 = pfq_table_count; 926143611Sphilip break; 927143611Sphilip 928143611Sphilip default: 929143611Sphilip return (SNMP_ERR_NOSUCHNAME); 930143611Sphilip } 931143611Sphilip 932143611Sphilip return (SNMP_ERR_NOERROR); 933143611Sphilip } 934143611Sphilip 935143611Sphilip abort(); 936143611Sphilip return (SNMP_ERR_GENERR); 937310901Sngie} 938143611Sphilip 939143611Sphilipint 940143611Sphilippf_altqq(struct snmp_context __unused *ctx, struct snmp_value *val, 941143611Sphilip u_int sub, u_int __unused vindex, enum snmp_op op) 942143611Sphilip{ 943143611Sphilip asn_subid_t which = val->var.subs[sub - 1]; 944143611Sphilip struct pfq_entry *e = NULL; 945143611Sphilip 946205607Ssyrinx if (!altq_enabled) 947205607Ssyrinx return (SNMP_ERR_NOSUCHNAME); 948152970Sphilip 949205312Ssyrinx if ((time(NULL) - pfq_table_age) > PFQ_TABLE_MAXAGE) 950205312Ssyrinx pfq_refresh(); 951205312Ssyrinx 952143611Sphilip switch (op) { 953143611Sphilip case SNMP_OP_SET: 954143611Sphilip return (SNMP_ERR_NOT_WRITEABLE); 955143611Sphilip case SNMP_OP_GETNEXT: 956143611Sphilip if ((e = NEXT_OBJECT_INT(&pfq_table, 957143611Sphilip &val->var, sub)) == NULL) 958143611Sphilip return (SNMP_ERR_NOSUCHNAME); 959143611Sphilip val->var.len = sub + 1; 960143611Sphilip val->var.subs[sub] = e->index; 961143611Sphilip break; 962143611Sphilip case SNMP_OP_GET: 963143611Sphilip if (val->var.len - sub != 1) 964143611Sphilip return (SNMP_ERR_NOSUCHNAME); 965143611Sphilip if ((e = pfq_table_find(val->var.subs[sub])) == NULL) 966143611Sphilip return (SNMP_ERR_NOSUCHNAME); 967143611Sphilip break; 968143611Sphilip 969143611Sphilip case SNMP_OP_COMMIT: 970143611Sphilip case SNMP_OP_ROLLBACK: 971143611Sphilip default: 972143611Sphilip abort(); 973143611Sphilip } 974143611Sphilip 975143611Sphilip switch (which) { 976143611Sphilip case LEAF_pfAltqQueueDescr: 977143611Sphilip return (string_get(val, e->altq.qname, -1)); 978143611Sphilip case LEAF_pfAltqQueueParent: 979143611Sphilip return (string_get(val, e->altq.parent, -1)); 980143611Sphilip case LEAF_pfAltqQueueScheduler: 981143611Sphilip val->v.integer = e->altq.scheduler; 982143611Sphilip break; 983143611Sphilip case LEAF_pfAltqQueueBandwidth: 984143611Sphilip val->v.uint32 = e->altq.bandwidth; 985143611Sphilip break; 986143611Sphilip case LEAF_pfAltqQueuePriority: 987143611Sphilip val->v.integer = e->altq.priority; 988143611Sphilip break; 989143611Sphilip case LEAF_pfAltqQueueLimit: 990143611Sphilip val->v.integer = e->altq.qlimit; 991143611Sphilip break; 992310901Sngie 993143611Sphilip default: 994143611Sphilip return (SNMP_ERR_NOSUCHNAME); 995143611Sphilip } 996143611Sphilip 997143611Sphilip return (SNMP_ERR_NOERROR); 998205280Ssyrinx} 999143611Sphilip 1000205280Ssyrinxint 1001205280Ssyrinxpf_labels(struct snmp_context __unused *ctx, struct snmp_value *val, 1002205280Ssyrinx u_int sub, u_int __unused vindex, enum snmp_op op) 1003205280Ssyrinx{ 1004205280Ssyrinx asn_subid_t which = val->var.subs[sub - 1]; 1005205280Ssyrinx 1006205280Ssyrinx if (op == SNMP_OP_SET) 1007205280Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1008205280Ssyrinx 1009205280Ssyrinx if (op == SNMP_OP_GET) { 1010205280Ssyrinx if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE) 1011205280Ssyrinx if (pfl_refresh() == -1) 1012205280Ssyrinx return (SNMP_ERR_GENERR); 1013205280Ssyrinx 1014205280Ssyrinx switch (which) { 1015205280Ssyrinx case LEAF_pfLabelsLblNumber: 1016205280Ssyrinx val->v.uint32 = pfl_table_count; 1017205280Ssyrinx break; 1018205280Ssyrinx 1019205280Ssyrinx default: 1020205280Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1021205280Ssyrinx } 1022205280Ssyrinx 1023205280Ssyrinx return (SNMP_ERR_NOERROR); 1024205280Ssyrinx } 1025205280Ssyrinx 1026205280Ssyrinx abort(); 1027205280Ssyrinx return (SNMP_ERR_GENERR); 1028205280Ssyrinx} 1029205280Ssyrinx 1030205280Ssyrinxint 1031205280Ssyrinxpf_lbltable(struct snmp_context __unused *ctx, struct snmp_value *val, 1032205280Ssyrinx u_int sub, u_int __unused vindex, enum snmp_op op) 1033205280Ssyrinx{ 1034205280Ssyrinx asn_subid_t which = val->var.subs[sub - 1]; 1035205280Ssyrinx struct pfl_entry *e = NULL; 1036205280Ssyrinx 1037205312Ssyrinx if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE) 1038205312Ssyrinx pfl_refresh(); 1039205312Ssyrinx 1040205280Ssyrinx switch (op) { 1041205280Ssyrinx case SNMP_OP_SET: 1042205280Ssyrinx return (SNMP_ERR_NOT_WRITEABLE); 1043205280Ssyrinx case SNMP_OP_GETNEXT: 1044205280Ssyrinx if ((e = NEXT_OBJECT_INT(&pfl_table, 1045205280Ssyrinx &val->var, sub)) == NULL) 1046205280Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1047205280Ssyrinx val->var.len = sub + 1; 1048205280Ssyrinx val->var.subs[sub] = e->index; 1049205280Ssyrinx break; 1050205280Ssyrinx case SNMP_OP_GET: 1051205280Ssyrinx if (val->var.len - sub != 1) 1052205280Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1053205280Ssyrinx if ((e = pfl_table_find(val->var.subs[sub])) == NULL) 1054205280Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1055205280Ssyrinx break; 1056205280Ssyrinx 1057205280Ssyrinx case SNMP_OP_COMMIT: 1058205280Ssyrinx case SNMP_OP_ROLLBACK: 1059205280Ssyrinx default: 1060205280Ssyrinx abort(); 1061205280Ssyrinx } 1062205280Ssyrinx 1063205280Ssyrinx switch (which) { 1064205280Ssyrinx case LEAF_pfLabelsLblName: 1065205280Ssyrinx return (string_get(val, e->name, -1)); 1066205280Ssyrinx case LEAF_pfLabelsLblEvals: 1067205280Ssyrinx val->v.counter64 = e->evals; 1068205280Ssyrinx break; 1069205280Ssyrinx case LEAF_pfLabelsLblBytesIn: 1070205280Ssyrinx val->v.counter64 = e->bytes[IN]; 1071205280Ssyrinx break; 1072205280Ssyrinx case LEAF_pfLabelsLblBytesOut: 1073205280Ssyrinx val->v.counter64 = e->bytes[OUT]; 1074205280Ssyrinx break; 1075205280Ssyrinx case LEAF_pfLabelsLblPktsIn: 1076205280Ssyrinx val->v.counter64 = e->pkts[IN]; 1077205280Ssyrinx break; 1078205280Ssyrinx case LEAF_pfLabelsLblPktsOut: 1079205280Ssyrinx val->v.counter64 = e->pkts[OUT]; 1080205280Ssyrinx break; 1081205280Ssyrinx default: 1082205280Ssyrinx return (SNMP_ERR_NOSUCHNAME); 1083205280Ssyrinx } 1084205280Ssyrinx 1085205280Ssyrinx return (SNMP_ERR_NOERROR); 1086205280Ssyrinx} 1087205280Ssyrinx 1088143611Sphilipstatic struct pfi_entry * 1089143611Sphilippfi_table_find(u_int idx) 1090143611Sphilip{ 1091143611Sphilip struct pfi_entry *e; 1092143611Sphilip 1093143611Sphilip TAILQ_FOREACH(e, &pfi_table, link) 1094143611Sphilip if (e->index == idx) 1095143611Sphilip return (e); 1096143611Sphilip return (NULL); 1097143611Sphilip} 1098143611Sphilip 1099143611Sphilipstatic struct pfq_entry * 1100143611Sphilippfq_table_find(u_int idx) 1101143611Sphilip{ 1102143611Sphilip struct pfq_entry *e; 1103205280Ssyrinx 1104143611Sphilip TAILQ_FOREACH(e, &pfq_table, link) 1105143611Sphilip if (e->index == idx) 1106143611Sphilip return (e); 1107143611Sphilip return (NULL); 1108143611Sphilip} 1109143611Sphilip 1110143611Sphilipstatic struct pft_entry * 1111143611Sphilippft_table_find(u_int idx) 1112143611Sphilip{ 1113143611Sphilip struct pft_entry *e; 1114143611Sphilip 1115143611Sphilip TAILQ_FOREACH(e, &pft_table, link) 1116143611Sphilip if (e->index == idx) 1117143611Sphilip return (e); 1118143611Sphilip return (NULL); 1119143611Sphilip} 1120143611Sphilip 1121205607Ssyrinxstatic struct pfa_entry * 1122205607Ssyrinxpfa_table_find(u_int idx) 1123205607Ssyrinx{ 1124205607Ssyrinx struct pfa_entry *e; 1125205607Ssyrinx 1126205607Ssyrinx TAILQ_FOREACH(e, &pfa_table, link) 1127205607Ssyrinx if (e->index == idx) 1128205607Ssyrinx return (e); 1129205607Ssyrinx return (NULL); 1130205607Ssyrinx} 1131205607Ssyrinx 1132205280Ssyrinxstatic struct pfl_entry * 1133205280Ssyrinxpfl_table_find(u_int idx) 1134205280Ssyrinx{ 1135205280Ssyrinx struct pfl_entry *e; 1136205280Ssyrinx 1137205280Ssyrinx TAILQ_FOREACH(e, &pfl_table, link) 1138205280Ssyrinx if (e->index == idx) 1139205280Ssyrinx return (e); 1140205280Ssyrinx 1141205280Ssyrinx return (NULL); 1142205280Ssyrinx} 1143205280Ssyrinx 1144143611Sphilipstatic int 1145143611Sphilippfi_refresh(void) 1146143611Sphilip{ 1147143611Sphilip struct pfioc_iface io; 1148171173Smlaier struct pfi_kif *p = NULL; 1149143611Sphilip struct pfi_entry *e; 1150143611Sphilip int i, numifs = 1; 1151143611Sphilip 1152143611Sphilip if (started && this_tick <= pf_tick) 1153143611Sphilip return (0); 1154143611Sphilip 1155143611Sphilip while (!TAILQ_EMPTY(&pfi_table)) { 1156143611Sphilip e = TAILQ_FIRST(&pfi_table); 1157143611Sphilip TAILQ_REMOVE(&pfi_table, e, link); 1158143611Sphilip free(e); 1159143611Sphilip } 1160143611Sphilip 1161143611Sphilip bzero(&io, sizeof(io)); 1162171173Smlaier io.pfiio_esize = sizeof(struct pfi_kif); 1163143611Sphilip 1164143611Sphilip for (;;) { 1165171173Smlaier p = reallocf(p, numifs * sizeof(struct pfi_kif)); 1166149571Sphilip if (p == NULL) { 1167149571Sphilip syslog(LOG_ERR, "pfi_refresh(): reallocf() numifs=%d: %s", 1168149571Sphilip numifs, strerror(errno)); 1169149571Sphilip goto err2; 1170149571Sphilip } 1171143611Sphilip io.pfiio_size = numifs; 1172143611Sphilip io.pfiio_buffer = p; 1173143611Sphilip 1174143611Sphilip if (ioctl(dev, DIOCIGETIFACES, &io)) { 1175143611Sphilip syslog(LOG_ERR, "pfi_refresh(): ioctl(): %s", 1176143611Sphilip strerror(errno)); 1177149571Sphilip goto err2; 1178143611Sphilip } 1179143611Sphilip 1180143611Sphilip if (numifs >= io.pfiio_size) 1181143611Sphilip break; 1182143611Sphilip 1183143611Sphilip numifs = io.pfiio_size; 1184143611Sphilip } 1185143611Sphilip 1186143611Sphilip for (i = 0; i < numifs; i++) { 1187143611Sphilip e = malloc(sizeof(struct pfi_entry)); 1188149571Sphilip if (e == NULL) 1189149571Sphilip goto err1; 1190143611Sphilip e->index = i + 1; 1191171173Smlaier memcpy(&e->pfi, p+i, sizeof(struct pfi_kif)); 1192143611Sphilip TAILQ_INSERT_TAIL(&pfi_table, e, link); 1193143611Sphilip } 1194143611Sphilip 1195143611Sphilip pfi_table_age = time(NULL); 1196143611Sphilip pfi_table_count = numifs; 1197143611Sphilip pf_tick = this_tick; 1198143611Sphilip 1199143611Sphilip free(p); 1200143611Sphilip return (0); 1201149571Sphilip 1202149571Sphiliperr1: 1203149571Sphilip while (!TAILQ_EMPTY(&pfi_table)) { 1204149571Sphilip e = TAILQ_FIRST(&pfi_table); 1205149571Sphilip TAILQ_REMOVE(&pfi_table, e, link); 1206149571Sphilip free(e); 1207149571Sphilip } 1208149571Sphiliperr2: 1209149571Sphilip free(p); 1210149571Sphilip return(-1); 1211143611Sphilip} 1212143611Sphilip 1213143611Sphilipstatic int 1214143611Sphilippfq_refresh(void) 1215143611Sphilip{ 1216143611Sphilip struct pfioc_altq pa; 1217143611Sphilip struct pfq_entry *e; 1218143611Sphilip int i, numqs, ticket; 1219143611Sphilip 1220143611Sphilip if (started && this_tick <= pf_tick) 1221143611Sphilip return (0); 1222143611Sphilip 1223143611Sphilip while (!TAILQ_EMPTY(&pfq_table)) { 1224143611Sphilip e = TAILQ_FIRST(&pfq_table); 1225143611Sphilip TAILQ_REMOVE(&pfq_table, e, link); 1226143611Sphilip free(e); 1227143611Sphilip } 1228143611Sphilip 1229143611Sphilip bzero(&pa, sizeof(pa)); 1230310901Sngie 1231143611Sphilip if (ioctl(dev, DIOCGETALTQS, &pa)) { 1232143611Sphilip syslog(LOG_ERR, "pfq_refresh: ioctl(DIOCGETALTQS): %s", 1233143611Sphilip strerror(errno)); 1234143611Sphilip return (-1); 1235143611Sphilip } 1236143611Sphilip 1237143611Sphilip numqs = pa.nr; 1238143611Sphilip ticket = pa.ticket; 1239143611Sphilip 1240143611Sphilip for (i = 0; i < numqs; i++) { 1241143611Sphilip e = malloc(sizeof(struct pfq_entry)); 1242149571Sphilip if (e == NULL) { 1243149571Sphilip syslog(LOG_ERR, "pfq_refresh(): " 1244149571Sphilip "malloc(): %s", 1245149571Sphilip strerror(errno)); 1246149571Sphilip goto err; 1247149571Sphilip } 1248143611Sphilip pa.ticket = ticket; 1249143611Sphilip pa.nr = i; 1250143611Sphilip 1251143611Sphilip if (ioctl(dev, DIOCGETALTQ, &pa)) { 1252143611Sphilip syslog(LOG_ERR, "pfq_refresh(): " 1253143611Sphilip "ioctl(DIOCGETALTQ): %s", 1254143611Sphilip strerror(errno)); 1255149571Sphilip goto err; 1256143611Sphilip } 1257143611Sphilip 1258143611Sphilip if (pa.altq.qid > 0) { 1259143611Sphilip memcpy(&e->altq, &pa.altq, sizeof(struct pf_altq)); 1260143611Sphilip e->index = pa.altq.qid; 1261143611Sphilip pfq_table_count = i; 1262179476Sphilip INSERT_OBJECT_INT_LINK_INDEX(e, &pfq_table, link, index); 1263143611Sphilip } 1264143611Sphilip } 1265310901Sngie 1266143611Sphilip pfq_table_age = time(NULL); 1267143611Sphilip pf_tick = this_tick; 1268143611Sphilip 1269143611Sphilip return (0); 1270149571Sphiliperr: 1271149571Sphilip free(e); 1272149571Sphilip while (!TAILQ_EMPTY(&pfq_table)) { 1273149571Sphilip e = TAILQ_FIRST(&pfq_table); 1274149571Sphilip TAILQ_REMOVE(&pfq_table, e, link); 1275149571Sphilip free(e); 1276149571Sphilip } 1277149571Sphilip return(-1); 1278143611Sphilip} 1279143611Sphilip 1280143611Sphilipstatic int 1281143611Sphilippfs_refresh(void) 1282143611Sphilip{ 1283143611Sphilip if (started && this_tick <= pf_tick) 1284143611Sphilip return (0); 1285143611Sphilip 1286143611Sphilip bzero(&pfs, sizeof(struct pf_status)); 1287143611Sphilip 1288143611Sphilip if (ioctl(dev, DIOCGETSTATUS, &pfs)) { 1289143611Sphilip syslog(LOG_ERR, "pfs_refresh(): ioctl(): %s", 1290143611Sphilip strerror(errno)); 1291143611Sphilip return (-1); 1292143611Sphilip } 1293143611Sphilip 1294143611Sphilip pf_tick = this_tick; 1295143611Sphilip return (0); 1296143611Sphilip} 1297143611Sphilip 1298143611Sphilipstatic int 1299143611Sphilippft_refresh(void) 1300143611Sphilip{ 1301143611Sphilip struct pfioc_table io; 1302149571Sphilip struct pfr_tstats *t = NULL; 1303143611Sphilip struct pft_entry *e; 1304143611Sphilip int i, numtbls = 1; 1305143611Sphilip 1306143611Sphilip if (started && this_tick <= pf_tick) 1307143611Sphilip return (0); 1308143611Sphilip 1309143611Sphilip while (!TAILQ_EMPTY(&pft_table)) { 1310143611Sphilip e = TAILQ_FIRST(&pft_table); 1311143611Sphilip TAILQ_REMOVE(&pft_table, e, link); 1312143611Sphilip free(e); 1313143611Sphilip } 1314143611Sphilip 1315143611Sphilip bzero(&io, sizeof(io)); 1316143611Sphilip io.pfrio_esize = sizeof(struct pfr_tstats); 1317143611Sphilip 1318143611Sphilip for (;;) { 1319149571Sphilip t = reallocf(t, numtbls * sizeof(struct pfr_tstats)); 1320149571Sphilip if (t == NULL) { 1321149571Sphilip syslog(LOG_ERR, "pft_refresh(): reallocf() numtbls=%d: %s", 1322149571Sphilip numtbls, strerror(errno)); 1323149571Sphilip goto err2; 1324149571Sphilip } 1325143611Sphilip io.pfrio_size = numtbls; 1326143611Sphilip io.pfrio_buffer = t; 1327143611Sphilip 1328143611Sphilip if (ioctl(dev, DIOCRGETTSTATS, &io)) { 1329143611Sphilip syslog(LOG_ERR, "pft_refresh(): ioctl(): %s", 1330143611Sphilip strerror(errno)); 1331149571Sphilip goto err2; 1332143611Sphilip } 1333143611Sphilip 1334143611Sphilip if (numtbls >= io.pfrio_size) 1335143611Sphilip break; 1336143611Sphilip 1337143611Sphilip numtbls = io.pfrio_size; 1338143611Sphilip } 1339143611Sphilip 1340143611Sphilip for (i = 0; i < numtbls; i++) { 1341200122Ssyrinx e = malloc(sizeof(struct pft_entry)); 1342149571Sphilip if (e == NULL) 1343149571Sphilip goto err1; 1344143611Sphilip e->index = i + 1; 1345143611Sphilip memcpy(&e->pft, t+i, sizeof(struct pfr_tstats)); 1346143611Sphilip TAILQ_INSERT_TAIL(&pft_table, e, link); 1347143611Sphilip } 1348143611Sphilip 1349143611Sphilip pft_table_age = time(NULL); 1350143611Sphilip pft_table_count = numtbls; 1351143611Sphilip pf_tick = this_tick; 1352143611Sphilip 1353143611Sphilip free(t); 1354143611Sphilip return (0); 1355149571Sphiliperr1: 1356149571Sphilip while (!TAILQ_EMPTY(&pft_table)) { 1357149571Sphilip e = TAILQ_FIRST(&pft_table); 1358149571Sphilip TAILQ_REMOVE(&pft_table, e, link); 1359149571Sphilip free(e); 1360149571Sphilip } 1361149571Sphiliperr2: 1362149571Sphilip free(t); 1363149571Sphilip return(-1); 1364143611Sphilip} 1365143611Sphilip 1366205280Ssyrinxstatic int 1367205607Ssyrinxpfa_table_addrs(u_int sidx, struct pfr_table *pt) 1368205607Ssyrinx{ 1369205607Ssyrinx struct pfioc_table io; 1370205607Ssyrinx struct pfr_astats *t = NULL; 1371205607Ssyrinx struct pfa_entry *e; 1372205607Ssyrinx int i, numaddrs = 1; 1373205607Ssyrinx 1374205607Ssyrinx if (pt == NULL) 1375205607Ssyrinx return (-1); 1376205607Ssyrinx 1377205607Ssyrinx memset(&io, 0, sizeof(io)); 1378205607Ssyrinx strlcpy(io.pfrio_table.pfrt_name, pt->pfrt_name, 1379205607Ssyrinx sizeof(io.pfrio_table.pfrt_name)); 1380205607Ssyrinx 1381205607Ssyrinx for (;;) { 1382205607Ssyrinx t = reallocf(t, numaddrs * sizeof(struct pfr_astats)); 1383205607Ssyrinx if (t == NULL) { 1384205607Ssyrinx syslog(LOG_ERR, "pfa_table_addrs(): reallocf(): %s", 1385205607Ssyrinx strerror(errno)); 1386205607Ssyrinx numaddrs = -1; 1387205607Ssyrinx goto error; 1388205607Ssyrinx } 1389205607Ssyrinx 1390205607Ssyrinx memset(t, 0, sizeof(*t)); 1391205607Ssyrinx io.pfrio_size = numaddrs; 1392205607Ssyrinx io.pfrio_buffer = t; 1393205607Ssyrinx io.pfrio_esize = sizeof(struct pfr_astats); 1394205607Ssyrinx 1395205607Ssyrinx if (ioctl(dev, DIOCRGETASTATS, &io)) { 1396205607Ssyrinx syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s", 1397205607Ssyrinx pt->pfrt_name, strerror(errno)); 1398205607Ssyrinx numaddrs = -1; 1399205607Ssyrinx break; 1400205607Ssyrinx } 1401205607Ssyrinx 1402205607Ssyrinx if (numaddrs >= io.pfrio_size) 1403205607Ssyrinx break; 1404205607Ssyrinx 1405205607Ssyrinx numaddrs = io.pfrio_size; 1406205607Ssyrinx } 1407205607Ssyrinx 1408205607Ssyrinx for (i = 0; i < numaddrs; i++) { 1409205607Ssyrinx if ((t + i)->pfras_a.pfra_af != AF_INET && 1410205607Ssyrinx (t + i)->pfras_a.pfra_af != AF_INET6) { 1411205607Ssyrinx numaddrs = i; 1412205607Ssyrinx break; 1413205607Ssyrinx } 1414205607Ssyrinx 1415205607Ssyrinx e = (struct pfa_entry *)malloc(sizeof(struct pfa_entry)); 1416205607Ssyrinx if (e == NULL) { 1417205607Ssyrinx syslog(LOG_ERR, "pfa_table_addrs(): malloc(): %s", 1418205607Ssyrinx strerror(errno)); 1419205607Ssyrinx numaddrs = -1; 1420205607Ssyrinx break; 1421205607Ssyrinx } 1422205607Ssyrinx e->index = sidx + i; 1423205607Ssyrinx memcpy(&e->pfas, t + i, sizeof(struct pfr_astats)); 1424205607Ssyrinx TAILQ_INSERT_TAIL(&pfa_table, e, link); 1425205607Ssyrinx } 1426205607Ssyrinx 1427205607Ssyrinx free(t); 1428205607Ssyrinxerror: 1429205607Ssyrinx return (numaddrs); 1430205607Ssyrinx} 1431205607Ssyrinx 1432205607Ssyrinxstatic int 1433205607Ssyrinxpfa_refresh(void) 1434205607Ssyrinx{ 1435205607Ssyrinx struct pfioc_table io; 1436205607Ssyrinx struct pfr_table *pt = NULL, *it = NULL; 1437205607Ssyrinx struct pfa_entry *e; 1438205607Ssyrinx int i, numtbls = 1, cidx, naddrs; 1439205607Ssyrinx 1440205607Ssyrinx if (started && this_tick <= pf_tick) 1441205607Ssyrinx return (0); 1442205607Ssyrinx 1443205607Ssyrinx while (!TAILQ_EMPTY(&pfa_table)) { 1444205607Ssyrinx e = TAILQ_FIRST(&pfa_table); 1445205607Ssyrinx TAILQ_REMOVE(&pfa_table, e, link); 1446205607Ssyrinx free(e); 1447205607Ssyrinx } 1448205607Ssyrinx 1449205607Ssyrinx memset(&io, 0, sizeof(io)); 1450205607Ssyrinx io.pfrio_esize = sizeof(struct pfr_table); 1451205607Ssyrinx 1452205607Ssyrinx for (;;) { 1453205607Ssyrinx pt = reallocf(pt, numtbls * sizeof(struct pfr_table)); 1454205607Ssyrinx if (pt == NULL) { 1455205607Ssyrinx syslog(LOG_ERR, "pfa_refresh(): reallocf() %s", 1456205607Ssyrinx strerror(errno)); 1457205607Ssyrinx return (-1); 1458205607Ssyrinx } 1459205607Ssyrinx memset(pt, 0, sizeof(*pt)); 1460205607Ssyrinx io.pfrio_size = numtbls; 1461205607Ssyrinx io.pfrio_buffer = pt; 1462205607Ssyrinx 1463205607Ssyrinx if (ioctl(dev, DIOCRGETTABLES, &io)) { 1464205607Ssyrinx syslog(LOG_ERR, "pfa_refresh(): ioctl(): %s", 1465205607Ssyrinx strerror(errno)); 1466205607Ssyrinx goto err2; 1467205607Ssyrinx } 1468205607Ssyrinx 1469205607Ssyrinx if (numtbls >= io.pfrio_size) 1470205607Ssyrinx break; 1471205607Ssyrinx 1472205607Ssyrinx numtbls = io.pfrio_size; 1473205607Ssyrinx } 1474205607Ssyrinx 1475205607Ssyrinx cidx = 1; 1476205607Ssyrinx 1477205607Ssyrinx for (it = pt, i = 0; i < numtbls; it++, i++) { 1478205607Ssyrinx /* 1479205607Ssyrinx * Skip the table if not active - ioctl(DIOCRGETASTATS) will 1480205607Ssyrinx * return ESRCH for this entry anyway. 1481205607Ssyrinx */ 1482205607Ssyrinx if (!(it->pfrt_flags & PFR_TFLAG_ACTIVE)) 1483205607Ssyrinx continue; 1484205607Ssyrinx 1485205607Ssyrinx if ((naddrs = pfa_table_addrs(cidx, it)) < 0) 1486205607Ssyrinx goto err1; 1487205607Ssyrinx 1488205607Ssyrinx cidx += naddrs; 1489205607Ssyrinx } 1490205607Ssyrinx 1491205607Ssyrinx pfa_table_age = time(NULL); 1492205607Ssyrinx pfa_table_count = cidx; 1493205607Ssyrinx pf_tick = this_tick; 1494205607Ssyrinx 1495205607Ssyrinx free(pt); 1496205607Ssyrinx return (0); 1497205607Ssyrinxerr1: 1498205607Ssyrinx while (!TAILQ_EMPTY(&pfa_table)) { 1499205607Ssyrinx e = TAILQ_FIRST(&pfa_table); 1500205607Ssyrinx TAILQ_REMOVE(&pfa_table, e, link); 1501205607Ssyrinx free(e); 1502205607Ssyrinx } 1503205607Ssyrinx 1504205607Ssyrinxerr2: 1505205607Ssyrinx free(pt); 1506205607Ssyrinx return (-1); 1507205607Ssyrinx} 1508205607Ssyrinx 1509205607Ssyrinxstatic int 1510205280Ssyrinxpfl_scan_ruleset(const char *path) 1511205280Ssyrinx{ 1512205280Ssyrinx struct pfioc_rule pr; 1513205280Ssyrinx struct pfl_entry *e; 1514205280Ssyrinx u_int32_t nr, i; 1515205280Ssyrinx 1516205280Ssyrinx bzero(&pr, sizeof(pr)); 1517205280Ssyrinx strlcpy(pr.anchor, path, sizeof(pr.anchor)); 1518205280Ssyrinx pr.rule.action = PF_PASS; 1519205280Ssyrinx if (ioctl(dev, DIOCGETRULES, &pr)) { 1520205280Ssyrinx syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULES): %s", 1521205280Ssyrinx strerror(errno)); 1522205280Ssyrinx goto err; 1523205280Ssyrinx } 1524205280Ssyrinx 1525205280Ssyrinx for (nr = pr.nr, i = 0; i < nr; i++) { 1526205280Ssyrinx pr.nr = i; 1527205280Ssyrinx if (ioctl(dev, DIOCGETRULE, &pr)) { 1528205280Ssyrinx syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULE):" 1529205280Ssyrinx " %s", strerror(errno)); 1530205280Ssyrinx goto err; 1531205280Ssyrinx } 1532205280Ssyrinx 1533205280Ssyrinx if (pr.rule.label[0]) { 1534205280Ssyrinx e = (struct pfl_entry *)malloc(sizeof(*e)); 1535205280Ssyrinx if (e == NULL) 1536205280Ssyrinx goto err; 1537205280Ssyrinx 1538205280Ssyrinx strlcpy(e->name, path, sizeof(e->name)); 1539205280Ssyrinx if (path[0]) 1540205280Ssyrinx strlcat(e->name, "/", sizeof(e->name)); 1541205280Ssyrinx strlcat(e->name, pr.rule.label, sizeof(e->name)); 1542205280Ssyrinx 1543205280Ssyrinx e->evals = pr.rule.evaluations; 1544205280Ssyrinx e->bytes[IN] = pr.rule.bytes[IN]; 1545205280Ssyrinx e->bytes[OUT] = pr.rule.bytes[OUT]; 1546205280Ssyrinx e->pkts[IN] = pr.rule.packets[IN]; 1547205280Ssyrinx e->pkts[OUT] = pr.rule.packets[OUT]; 1548205280Ssyrinx e->index = ++pfl_table_count; 1549205280Ssyrinx 1550205280Ssyrinx TAILQ_INSERT_TAIL(&pfl_table, e, link); 1551205280Ssyrinx } 1552205280Ssyrinx } 1553205280Ssyrinx 1554205280Ssyrinx return (0); 1555205280Ssyrinx 1556205280Ssyrinxerr: 1557205280Ssyrinx return (-1); 1558205280Ssyrinx} 1559205280Ssyrinx 1560205280Ssyrinxstatic int 1561205280Ssyrinxpfl_walk_rulesets(const char *path) 1562205280Ssyrinx{ 1563205280Ssyrinx struct pfioc_ruleset prs; 1564205280Ssyrinx char newpath[MAXPATHLEN]; 1565205280Ssyrinx u_int32_t nr, i; 1566205280Ssyrinx 1567205280Ssyrinx if (pfl_scan_ruleset(path)) 1568205280Ssyrinx goto err; 1569205280Ssyrinx 1570205280Ssyrinx bzero(&prs, sizeof(prs)); 1571205280Ssyrinx strlcpy(prs.path, path, sizeof(prs.path)); 1572205280Ssyrinx if (ioctl(dev, DIOCGETRULESETS, &prs)) { 1573205280Ssyrinx syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESETS): %s", 1574205280Ssyrinx strerror(errno)); 1575205280Ssyrinx goto err; 1576205280Ssyrinx } 1577205280Ssyrinx 1578205280Ssyrinx for (nr = prs.nr, i = 0; i < nr; i++) { 1579205280Ssyrinx prs.nr = i; 1580205280Ssyrinx if (ioctl(dev, DIOCGETRULESET, &prs)) { 1581205280Ssyrinx syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESET):" 1582205280Ssyrinx " %s", strerror(errno)); 1583205280Ssyrinx goto err; 1584205280Ssyrinx } 1585205280Ssyrinx 1586205280Ssyrinx if (strcmp(prs.name, PF_RESERVED_ANCHOR) == 0) 1587205280Ssyrinx continue; 1588205280Ssyrinx 1589205280Ssyrinx strlcpy(newpath, path, sizeof(newpath)); 1590205280Ssyrinx if (path[0]) 1591205280Ssyrinx strlcat(newpath, "/", sizeof(newpath)); 1592205280Ssyrinx 1593205280Ssyrinx strlcat(newpath, prs.name, sizeof(newpath)); 1594205280Ssyrinx if (pfl_walk_rulesets(newpath)) 1595205280Ssyrinx goto err; 1596205280Ssyrinx } 1597205280Ssyrinx 1598205280Ssyrinx return (0); 1599205280Ssyrinx 1600205280Ssyrinxerr: 1601205280Ssyrinx return (-1); 1602205280Ssyrinx} 1603205280Ssyrinx 1604205280Ssyrinxstatic int 1605205280Ssyrinxpfl_refresh(void) 1606205280Ssyrinx{ 1607205280Ssyrinx struct pfl_entry *e; 1608205280Ssyrinx 1609205280Ssyrinx if (started && this_tick <= pf_tick) 1610205280Ssyrinx return (0); 1611205280Ssyrinx 1612205280Ssyrinx while (!TAILQ_EMPTY(&pfl_table)) { 1613205280Ssyrinx e = TAILQ_FIRST(&pfl_table); 1614205280Ssyrinx TAILQ_REMOVE(&pfl_table, e, link); 1615205280Ssyrinx free(e); 1616205280Ssyrinx } 1617205280Ssyrinx pfl_table_count = 0; 1618205280Ssyrinx 1619205280Ssyrinx if (pfl_walk_rulesets("")) 1620205280Ssyrinx goto err; 1621205280Ssyrinx 1622205280Ssyrinx pfl_table_age = time(NULL); 1623205280Ssyrinx pf_tick = this_tick; 1624205280Ssyrinx 1625205280Ssyrinx return (0); 1626205280Ssyrinx 1627205280Ssyrinxerr: 1628205280Ssyrinx while (!TAILQ_EMPTY(&pfl_table)) { 1629205280Ssyrinx e = TAILQ_FIRST(&pfl_table); 1630205280Ssyrinx TAILQ_REMOVE(&pfl_table, e, link); 1631205280Ssyrinx free(e); 1632205280Ssyrinx } 1633205280Ssyrinx pfl_table_count = 0; 1634205280Ssyrinx 1635205280Ssyrinx return (-1); 1636205280Ssyrinx} 1637205280Ssyrinx 1638143611Sphilip/* 1639152970Sphilip * check whether altq support is enabled in kernel 1640152970Sphilip */ 1641152970Sphilip 1642152970Sphilipstatic int 1643152970Sphilipaltq_is_enabled(int pfdev) 1644152970Sphilip{ 1645310902Sngie struct pfioc_altq pa; 1646152970Sphilip 1647152970Sphilip errno = 0; 1648310902Sngie if (ioctl(pfdev, DIOCGETALTQS, &pa)) { 1649310902Sngie if (errno == ENODEV) { 1650152970Sphilip syslog(LOG_INFO, "No ALTQ support in kernel\n" 1651152970Sphilip "ALTQ related functions disabled\n"); 1652310902Sngie return (0); 1653357523Sdim } else { 1654310902Sngie syslog(LOG_ERR, "DIOCGETALTQS returned an error: %s", 1655152970Sphilip strerror(errno)); 1656152970Sphilip return (-1); 1657357523Sdim } 1658310902Sngie } 1659310902Sngie return (1); 1660152970Sphilip} 1661152970Sphilip 1662152970Sphilip/* 1663143611Sphilip * Implement the bsnmpd module interface 1664143611Sphilip */ 1665143611Sphilipstatic int 1666143611Sphilippf_init(struct lmodule *mod, int __unused argc, char __unused *argv[]) 1667143611Sphilip{ 1668143611Sphilip module = mod; 1669143611Sphilip 1670143611Sphilip if ((dev = open("/dev/pf", O_RDONLY)) == -1) { 1671143611Sphilip syslog(LOG_ERR, "pf_init(): open(): %s\n", 1672143611Sphilip strerror(errno)); 1673143611Sphilip return (-1); 1674143611Sphilip } 1675143611Sphilip 1676152970Sphilip if ((altq_enabled = altq_is_enabled(dev)) == -1) { 1677152970Sphilip syslog(LOG_ERR, "pf_init(): altq test failed"); 1678152970Sphilip return (-1); 1679152970Sphilip } 1680310901Sngie 1681143611Sphilip /* Prepare internal state */ 1682143611Sphilip TAILQ_INIT(&pfi_table); 1683143611Sphilip TAILQ_INIT(&pfq_table); 1684143611Sphilip TAILQ_INIT(&pft_table); 1685205607Ssyrinx TAILQ_INIT(&pfa_table); 1686205280Ssyrinx TAILQ_INIT(&pfl_table); 1687143611Sphilip 1688143611Sphilip pfi_refresh(); 1689152970Sphilip if (altq_enabled) { 1690152970Sphilip pfq_refresh(); 1691152970Sphilip } 1692152970Sphilip 1693143611Sphilip pfs_refresh(); 1694143611Sphilip pft_refresh(); 1695205607Ssyrinx pfa_refresh(); 1696205280Ssyrinx pfl_refresh(); 1697143611Sphilip 1698143611Sphilip started = 1; 1699143611Sphilip 1700143611Sphilip return (0); 1701143611Sphilip} 1702143611Sphilip 1703143611Sphilipstatic int 1704143611Sphilippf_fini(void) 1705143611Sphilip{ 1706143611Sphilip struct pfi_entry *i1, *i2; 1707143611Sphilip struct pfq_entry *q1, *q2; 1708143611Sphilip struct pft_entry *t1, *t2; 1709205607Ssyrinx struct pfa_entry *a1, *a2; 1710205280Ssyrinx struct pfl_entry *l1, *l2; 1711143611Sphilip 1712143611Sphilip /* Empty the list of interfaces */ 1713143611Sphilip i1 = TAILQ_FIRST(&pfi_table); 1714143611Sphilip while (i1 != NULL) { 1715143611Sphilip i2 = TAILQ_NEXT(i1, link); 1716143611Sphilip free(i1); 1717143611Sphilip i1 = i2; 1718143611Sphilip } 1719143611Sphilip 1720143611Sphilip /* List of queues */ 1721143611Sphilip q1 = TAILQ_FIRST(&pfq_table); 1722143611Sphilip while (q1 != NULL) { 1723143611Sphilip q2 = TAILQ_NEXT(q1, link); 1724143611Sphilip free(q1); 1725143611Sphilip q1 = q2; 1726143611Sphilip } 1727143611Sphilip 1728205280Ssyrinx /* List of tables */ 1729143611Sphilip t1 = TAILQ_FIRST(&pft_table); 1730143611Sphilip while (t1 != NULL) { 1731143611Sphilip t2 = TAILQ_NEXT(t1, link); 1732143611Sphilip free(t1); 1733143611Sphilip t1 = t2; 1734143611Sphilip } 1735143611Sphilip 1736205607Ssyrinx /* List of table addresses */ 1737205607Ssyrinx a1 = TAILQ_FIRST(&pfa_table); 1738205607Ssyrinx while (a1 != NULL) { 1739205607Ssyrinx a2 = TAILQ_NEXT(a1, link); 1740205607Ssyrinx free(a1); 1741205607Ssyrinx a1 = a2; 1742205607Ssyrinx } 1743205607Ssyrinx 1744205280Ssyrinx /* And the list of labeled filter rules */ 1745205280Ssyrinx l1 = TAILQ_FIRST(&pfl_table); 1746205280Ssyrinx while (l1 != NULL) { 1747205280Ssyrinx l2 = TAILQ_NEXT(l1, link); 1748205280Ssyrinx free(l1); 1749205280Ssyrinx l1 = l2; 1750205280Ssyrinx } 1751205280Ssyrinx 1752143611Sphilip close(dev); 1753143611Sphilip return (0); 1754143611Sphilip} 1755143611Sphilip 1756143611Sphilipstatic void 1757143611Sphilippf_dump(void) 1758143611Sphilip{ 1759143611Sphilip pfi_refresh(); 1760152970Sphilip if (altq_enabled) { 1761152970Sphilip pfq_refresh(); 1762152970Sphilip } 1763143611Sphilip pft_refresh(); 1764205607Ssyrinx pfa_refresh(); 1765205280Ssyrinx pfl_refresh(); 1766143611Sphilip 1767143654Sphilip syslog(LOG_ERR, "Dump: pfi_table_age = %jd", 1768143654Sphilip (intmax_t)pfi_table_age); 1769143611Sphilip syslog(LOG_ERR, "Dump: pfi_table_count = %d", 1770143611Sphilip pfi_table_count); 1771310901Sngie 1772143654Sphilip syslog(LOG_ERR, "Dump: pfq_table_age = %jd", 1773143654Sphilip (intmax_t)pfq_table_age); 1774143611Sphilip syslog(LOG_ERR, "Dump: pfq_table_count = %d", 1775143611Sphilip pfq_table_count); 1776143611Sphilip 1777143654Sphilip syslog(LOG_ERR, "Dump: pft_table_age = %jd", 1778143654Sphilip (intmax_t)pft_table_age); 1779143611Sphilip syslog(LOG_ERR, "Dump: pft_table_count = %d", 1780143611Sphilip pft_table_count); 1781205280Ssyrinx 1782205607Ssyrinx syslog(LOG_ERR, "Dump: pfa_table_age = %jd", 1783205607Ssyrinx (intmax_t)pfa_table_age); 1784205607Ssyrinx syslog(LOG_ERR, "Dump: pfa_table_count = %d", 1785205607Ssyrinx pfa_table_count); 1786205607Ssyrinx 1787205280Ssyrinx syslog(LOG_ERR, "Dump: pfl_table_age = %jd", 1788205280Ssyrinx (intmax_t)pfl_table_age); 1789205280Ssyrinx syslog(LOG_ERR, "Dump: pfl_table_count = %d", 1790205280Ssyrinx pfl_table_count); 1791143611Sphilip} 1792143611Sphilip 1793143611Sphilipconst struct snmp_module config = { 1794143611Sphilip .comment = "This module implements a MIB for the pf packet filter.", 1795143611Sphilip .init = pf_init, 1796143611Sphilip .fini = pf_fini, 1797143611Sphilip .tree = pf_ctree, 1798143611Sphilip .dump = pf_dump, 1799143611Sphilip .tree_size = pf_CTREE_SIZE, 1800143611Sphilip}; 1801