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