diff -ur /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt ./BEGEMOT-PF-MIB.txt --- /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/BEGEMOT-PF-MIB.txt 2009-12-02 22:05:06.000000000 +0200 +++ ./BEGEMOT-PF-MIB.txt 2009-12-10 20:45:37.000000000 +0200 @@ -17,11 +17,13 @@ FROM SNMPv2-SMI TruthValue FROM SNMPv2-TC + InetAddress, InetAddressType, InetAddressPrefixLength + FROM INET-ADDRESS-MIB begemot FROM BEGEMOT-MIB; begemotPf MODULE-IDENTITY - LAST-UPDATED "200501240000Z" + LAST-UPDATED "200912100000Z" ORGANIZATION "NixSys BVBA" CONTACT-INFO " Philip Paeps @@ -34,6 +36,19 @@ E-Mail: philip@FreeBSD.org" DESCRIPTION "The Begemot MIB for the pf packet filter." + REVISION "200912100000Z" + DESCRIPTION + "Added support for retrieving counters of labeled + pf filter rules via pfLabelspfLabels subtree." + REVISION "200912050000Z" + DESCRIPTION + "Modified pfTablesAddrEntry to support IPv6 + addresses - added pfTablesAddrNetType column + and modified type of pfTablesAddrNet to + InetAddress." + REVISION "200501240000Z" + DESCRIPTION + "Initial revision." ::= { begemot 200 } @@ -51,7 +66,7 @@ pfInterfaces OBJECT IDENTIFIER ::= { begemotPfObjects 8 } pfTables OBJECT IDENTIFIER ::= { begemotPfObjects 9 } pfAltq OBJECT IDENTIFIER ::= { begemotPfObjects 10 } - +pfLabels OBJECT IDENTIFIER ::= { begemotPfObjects 11 } -- -------------------------------------------------------------------------- -- @@ -1017,8 +1032,9 @@ PfTablesAddrEntry ::= SEQUENCE { pfTablesAddrIndex Integer32, - pfTablesAddrNet IpAddress, - pfTablesAddrMask Integer32, + pfTablesAddrNetType InetAddressType, + pfTablesAddrNet InetAddress, + pfTablesAddrPrefix InetAddressPrefixLength, pfTablesAddrTZero TimeTicks, pfTablesAddrBytesInPass Counter64, pfTablesAddrBytesInBlock Counter64, @@ -1038,21 +1054,29 @@ "A unique value, greater than zero, for each address." ::= { pfTablesAddrEntry 1 } +pfTablesAddrNetType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The type of address in the corresponding pfTablesAddrNet object." + ::= { pfTablesAddrEntry 2 } + pfTablesAddrNet OBJECT-TYPE - SYNTAX IpAddress + SYNTAX InetAddress MAX-ACCESS read-only STATUS current DESCRIPTION "The IP address of this particular table entry." - ::= { pfTablesAddrEntry 2 } + ::= { pfTablesAddrEntry 3 } -pfTablesAddrMask OBJECT-TYPE - SYNTAX Integer32 (0..32) +pfTablesAddrPrefix OBJECT-TYPE + SYNTAX InetAddressPrefixLength MAX-ACCESS read-only STATUS current DESCRIPTION - "The CIDR netmask of this particular table entry." - ::= { pfTablesAddrEntry 3 } + "The network address prefix of this particular table entry." + ::= { pfTablesAddrEntry 4 } pfTablesAddrTZero OBJECT-TYPE SYNTAX TimeTicks @@ -1063,7 +1087,7 @@ "The time passed since this entry's statistics were last cleared, or the time passed since this entry was loaded into the table, whichever is sooner." - ::= { pfTablesAddrEntry 4 } + ::= { pfTablesAddrEntry 5 } pfTablesAddrBytesInPass OBJECT-TYPE SYNTAX Counter64 @@ -1071,7 +1095,7 @@ STATUS current DESCRIPTION "The number of inbound bytes passed as a result of this entry." - ::= { pfTablesAddrEntry 5 } + ::= { pfTablesAddrEntry 6 } pfTablesAddrBytesInBlock OBJECT-TYPE SYNTAX Counter64 @@ -1079,7 +1103,7 @@ STATUS current DESCRIPTION "The number of inbound bytes blocked as a result of this entry." - ::= { pfTablesAddrEntry 6 } + ::= { pfTablesAddrEntry 7 } pfTablesAddrBytesOutPass OBJECT-TYPE SYNTAX Counter64 @@ -1087,7 +1111,7 @@ STATUS current DESCRIPTION "The number of outbound bytes passed as a result of this entry." - ::= { pfTablesAddrEntry 7 } + ::= { pfTablesAddrEntry 8 } pfTablesAddrBytesOutBlock OBJECT-TYPE SYNTAX Counter64 @@ -1095,7 +1119,7 @@ STATUS current DESCRIPTION "The number of outbound bytes blocked as a result of this entry." - ::= { pfTablesAddrEntry 8 } + ::= { pfTablesAddrEntry 9 } pfTablesAddrPktsInPass OBJECT-TYPE SYNTAX Counter64 @@ -1103,7 +1127,7 @@ STATUS current DESCRIPTION "The number of inbound packets passed as a result of this entry." - ::= { pfTablesAddrEntry 9 } + ::= { pfTablesAddrEntry 10 } pfTablesAddrPktsInBlock OBJECT-TYPE SYNTAX Counter64 @@ -1111,7 +1135,7 @@ STATUS current DESCRIPTION "The number of inbound packets blocked as a result of this entry." - ::= { pfTablesAddrEntry 10 } + ::= { pfTablesAddrEntry 11 } pfTablesAddrPktsOutPass OBJECT-TYPE SYNTAX Counter64 @@ -1119,7 +1143,7 @@ STATUS current DESCRIPTION "The number of outbound packets passed as a result of this entry." - ::= { pfTablesAddrEntry 11 } + ::= { pfTablesAddrEntry 12 } pfTablesAddrPktsOutBlock OBJECT-TYPE SYNTAX Counter64 @@ -1128,7 +1152,7 @@ DESCRIPTION "The number of outbound packets blocked as a result of this entry." - ::= { pfTablesAddrEntry 12 } + ::= { pfTablesAddrEntry 13 } -- -------------------------------------------------------------------------- @@ -1227,4 +1251,103 @@ "Maximum number of packets in the queue." ::= { pfAltqQueueEntry 7 } +-- -------------------------------------------------------------------------- + +-- +-- +-- Labeled filter rules statistics +-- + +pfLabelsLblNumber OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of labeled filter rules on this system." + ::= { pfLabels 1 } + +pfLabelsLblTable OBJECT-TYPE + SYNTAX SEQUENCE OF PfLabelsLblEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of filter rules, index on pfLabelsLblIndex." + ::= { pfLabels 2 } + +pfLabelsLblEntry OBJECT-TYPE + SYNTAX PfLabelsLblEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Any entry in the pfLabelsLblTable containing information + about a particular filter rule on the system." + INDEX { pfLabelsLblIndex } + ::= { pfLabelsLblTable 1 } + +PfLabelsLblEntry ::= SEQUENCE { + pfLabelsLblIndex Integer32, + pfLabelsLblName OCTET STRING, + pfLabelsLblEvals Counter64, + pfLabelsLblBytesIn Counter64, + pfLabelsLblBytesOut Counter64, + pfLabelsLblPktsIn Counter64, + pfLabelsLblPktsOut Counter64 +} + +pfLabelsLblIndex OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A unique value, greater than zero, for each label." + ::= { pfLabelsLblEntry 1 } + +pfLabelsLblName OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the rule label." + ::= { pfLabelsLblEntry 2 } + +pfLabelsLblEvals OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of rule evaluations." + ::= { pfLabelsLblEntry 3 } + +pfLabelsLblBytesIn OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of incoming bytes matched by the rule." + ::= { pfLabelsLblEntry 4 } + +pfLabelsLblBytesOut OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outgoing bytes matched by the rule." + ::= { pfLabelsLblEntry 5 } + +pfLabelsLblPktsIn OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of incoming packets matched by the rule." + ::= { pfLabelsLblEntry 6 } + +pfLabelsLblPktsOut OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of outgoing packets matched by the rule." + ::= { pfLabelsLblEntry 7 } + END diff -ur /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/Makefile ./Makefile --- /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/Makefile 2009-12-02 22:05:06.000000000 +0200 +++ ./Makefile 2009-12-10 18:07:10.000000000 +0200 @@ -4,6 +4,7 @@ MOD= pf SRCS= pf_snmp.c +CFLAGS+= -DSNMPTREE_TYPES WARNS?= 6 XSYM= begemotPf diff -ur /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c ./pf_snmp.c --- /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c 2009-12-11 10:28:13.000000000 +0200 +++ ./pf_snmp.c 2009-12-11 11:44:03.000000000 +0200 @@ -84,6 +84,18 @@ static int pft_table_count; #define PFT_TABLE_MAXAGE 5 +struct pfa_entry { + struct pfr_astats pfas; + u_int index; + TAILQ_ENTRY(pfa_entry) link; +}; +TAILQ_HEAD(pfa_table, pfa_entry); + +static struct pfa_table pfa_table; +static time_t pfa_table_age; +static int pfa_table_count; + +#define PFA_TABLE_MAXAGE 5 struct pfq_entry { struct pf_altq altq; @@ -100,14 +112,34 @@ #define PFQ_TABLE_MAXAGE 5 +struct pfl_entry { + char name[MAXPATHLEN + PF_RULE_LABEL_SIZE]; + u_int64_t evals; + u_int64_t bytes[2]; + u_int64_t pkts[2]; + u_int index; + TAILQ_ENTRY(pfl_entry) link; +}; +TAILQ_HEAD(pfl_table, pfl_entry); + +static struct pfl_table pfl_table; +static time_t pfl_table_age; +static int pfl_table_count; + +#define PFL_TABLE_MAXAGE 5 + /* Forward declarations */ static int pfi_refresh(void); static int pfq_refresh(void); static int pfs_refresh(void); static int pft_refresh(void); +static int pfa_refresh(void); +static int pfl_refresh(void); static struct pfi_entry * pfi_table_find(u_int idx); static struct pfq_entry * pfq_table_find(u_int idx); static struct pft_entry * pft_table_find(u_int idx); +static struct pfa_entry * pfa_table_find(u_int idx); +static struct pfl_entry * pfl_table_find(u_int idx); static int altq_is_enabled(int pfdevice); @@ -773,10 +805,103 @@ } int -pf_tbladdr(struct snmp_context __unused *ctx, struct snmp_value __unused *val, - u_int __unused sub, u_int __unused vindex, enum snmp_op __unused op) +pf_tbladdr(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) { - return (SNMP_ERR_GENERR); + asn_subid_t which = val->var.subs[sub - 1]; + struct pfa_entry *e = NULL; + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_GETNEXT: + if ((e = NEXT_OBJECT_INT(&pfa_table, + &val->var, sub)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + val->var.len = sub + 1; + val->var.subs[sub] = e->index; + break; + case SNMP_OP_GET: + if (val->var.len - sub != 1) + return (SNMP_ERR_NOSUCHNAME); + if ((e = pfa_table_find(val->var.subs[sub])) == NULL) + return (SNMP_ERR_NOSUCHNAME); + break; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + default: + abort(); + } + + if ((time(NULL) - pft_table_age) > PFA_TABLE_MAXAGE) + pfa_refresh(); + + switch (which) { + case LEAF_pfTablesAddrNetType: + /* XXX: FIXME!!! */ + if (e->pfas.pfras_a.pfra_af == AF_INET) + val->v.integer = pfTablesAddrNetType_ipv4; + else if (e->pfas.pfras_a.pfra_af == AF_INET6) + val->v.integer = pfTablesAddrNetType_ipv6; + else + return (SNMP_ERR_GENERR); + break; + case LEAF_pfTablesAddrNet: + /* XXX: FIXME!!! */ + if (e->pfas.pfras_a.pfra_af == AF_INET) { + return (string_get(val, + (u_char *)&e->pfas.pfras_a.pfra_ip4addr, 4)); + } else if (e->pfas.pfras_a.pfra_af == AF_INET6) + return (string_get(val, + (u_char *)&e->pfas.pfras_a.pfra_ip6addr, 16)); + else + return (SNMP_ERR_GENERR); + break; + case LEAF_pfTablesAddrPrefix: + val->v.integer = (int32_t) e->pfas.pfras_a.pfra_net; + break; + case LEAF_pfTablesAddrTZero: + val->v.uint32 = + (time(NULL) - e->pfas.pfras_tzero) * 100; + break; + case LEAF_pfTablesAddrBytesInPass: + val->v.counter64 = + e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_PASS]; + break; + case LEAF_pfTablesAddrBytesInBlock: + val->v.counter64 = + e->pfas.pfras_bytes[PFR_DIR_IN][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesAddrBytesOutPass: + val->v.counter64 = + e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_PASS]; + break; + case LEAF_pfTablesAddrBytesOutBlock: + val->v.counter64 = + e->pfas.pfras_bytes[PFR_DIR_OUT][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesAddrPktsInPass: + val->v.counter64 = + e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_PASS]; + break; + case LEAF_pfTablesAddrPktsInBlock: + val->v.counter64 = + e->pfas.pfras_packets[PFR_DIR_IN][PFR_OP_BLOCK]; + break; + case LEAF_pfTablesAddrPktsOutPass: + val->v.counter64 = + e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_PASS]; + break; + case LEAF_pfTablesAddrPktsOutBlock: + val->v.counter64 = + e->pfas.pfras_packets[PFR_DIR_OUT][PFR_OP_BLOCK]; + break; + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); } int @@ -785,9 +910,8 @@ { asn_subid_t which = val->var.subs[sub - 1]; - if (!altq_enabled) { - return (SNMP_ERR_NOERROR); - } + if (!altq_enabled) + return (SNMP_ERR_NOSUCHNAME); if (op == SNMP_OP_SET) return (SNMP_ERR_NOT_WRITEABLE); @@ -820,9 +944,8 @@ asn_subid_t which = val->var.subs[sub - 1]; struct pfq_entry *e = NULL; - if (!altq_enabled) { - return (SNMP_ERR_NOERROR); - } + if (!altq_enabled) + return (SNMP_ERR_NOSUCHNAME); switch (op) { case SNMP_OP_SET: @@ -875,6 +998,93 @@ return (SNMP_ERR_NOERROR); } +int +pf_labels(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + + if (op == SNMP_OP_SET) + return (SNMP_ERR_NOT_WRITEABLE); + + if (op == SNMP_OP_GET) { + if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE) + if (pfl_refresh() == -1) + return (SNMP_ERR_GENERR); + + switch (which) { + case LEAF_pfLabelsLblNumber: + val->v.uint32 = pfl_table_count; + break; + + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +int +pf_lbltable(struct snmp_context __unused *ctx, struct snmp_value *val, + u_int sub, u_int __unused vindex, enum snmp_op op) +{ + asn_subid_t which = val->var.subs[sub - 1]; + struct pfl_entry *e = NULL; + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_GETNEXT: + if ((e = NEXT_OBJECT_INT(&pfl_table, + &val->var, sub)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + val->var.len = sub + 1; + val->var.subs[sub] = e->index; + break; + case SNMP_OP_GET: + if (val->var.len - sub != 1) + return (SNMP_ERR_NOSUCHNAME); + if ((e = pfl_table_find(val->var.subs[sub])) == NULL) + return (SNMP_ERR_NOSUCHNAME); + break; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + default: + abort(); + } + + if ((time(NULL) - pfl_table_age) > PFL_TABLE_MAXAGE) + pfl_refresh(); + + switch (which) { + case LEAF_pfLabelsLblName: + return (string_get(val, e->name, -1)); + case LEAF_pfLabelsLblEvals: + val->v.counter64 = e->evals; + break; + case LEAF_pfLabelsLblBytesIn: + val->v.counter64 = e->bytes[IN]; + break; + case LEAF_pfLabelsLblBytesOut: + val->v.counter64 = e->bytes[OUT]; + break; + case LEAF_pfLabelsLblPktsIn: + val->v.counter64 = e->pkts[IN]; + break; + case LEAF_pfLabelsLblPktsOut: + val->v.counter64 = e->pkts[OUT]; + break; + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); +} + static struct pfi_entry * pfi_table_find(u_int idx) { @@ -890,6 +1100,7 @@ pfq_table_find(u_int idx) { struct pfq_entry *e; + TAILQ_FOREACH(e, &pfq_table, link) if (e->index == idx) return (e); @@ -907,6 +1118,29 @@ return (NULL); } +static struct pfa_entry * +pfa_table_find(u_int idx) +{ + struct pfa_entry *e; + + TAILQ_FOREACH(e, &pfa_table, link) + if (e->index == idx) + return (e); + return (NULL); +} + +static struct pfl_entry * +pfl_table_find(u_int idx) +{ + struct pfl_entry *e; + + TAILQ_FOREACH(e, &pfl_table, link) + if (e->index == idx) + return (e); + + return (NULL); +} + static int pfi_refresh(void) { @@ -1129,6 +1363,268 @@ return(-1); } +static int +pfa_table_addrs(u_int sidx, struct pfr_table *pt) +{ + struct pfioc_table io; + struct pfr_astats *t = NULL; + struct pfa_entry *e; + int i, numaddrs = 1; + + if (pt == NULL) + return (-1); + + memset(&io, 0, sizeof(io)); + strlcpy(io.pfrio_table.pfrt_name, pt->pfrt_name, sizeof(pt->pfrt_name)); + + for (;;) { + t = reallocf(t, numaddrs * sizeof(struct pfr_astats)); + if (t == NULL) { + syslog(LOG_ERR, "pfa_table_addrs(): reallocf(): %s", + strerror(errno)); + numaddrs = -1; + break; + } + + memset(t, 0, sizeof(*t)); + io.pfrio_size = numaddrs; + io.pfrio_buffer = t; + io.pfrio_esize = sizeof(struct pfr_astats); + + if (ioctl(dev, DIOCRGETASTATS, &io)) { + syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s", + pt->pfrt_name, strerror(errno)); + numaddrs = -1; + break; + } + + if (numaddrs >= io.pfrio_size) + break; + + numaddrs = io.pfrio_size; + } + + for (i = 0; i < numaddrs; i++) { + if ((e = malloc(sizeof(struct pfa_entry))) == NULL) { + syslog(LOG_ERR, "pfa_table_addrs(): reallocf(): %s", + strerror(errno)); + numaddrs = -1; + break; + } + e->index = sidx + i; + memcpy(&e->pfas, t + i, sizeof(struct pfr_astats)); + TAILQ_INSERT_TAIL(&pfa_table, e, link); + } + + free(t); + return (numaddrs); +} + +static int +pfa_refresh(void) +{ + struct pfioc_table io; + struct pfr_table *pt = NULL, *it = NULL; + struct pfa_entry *e; + int i, numtbls = 1, cidx, naddrs; + + if (started && this_tick <= pf_tick) + return (0); + + while (!TAILQ_EMPTY(&pfa_table)) { + e = TAILQ_FIRST(&pfa_table); + TAILQ_REMOVE(&pfa_table, e, link); + free(e); + } + + bzero(&io, sizeof(io)); + io.pfrio_esize = sizeof(struct pfr_table); + + for (;;) { + pt = reallocf(pt, numtbls * sizeof(struct pfr_table)); + if (pt == NULL) { + syslog(LOG_ERR, "pfa_refresh(): reallocf() %s", + strerror(errno)); + goto err2; + } + bzero(pt, sizeof(*pt)); + io.pfrio_size = numtbls; + io.pfrio_buffer = pt; + + if (ioctl(dev, DIOCRGETTABLES, &io)) { + syslog(LOG_ERR, "pfa_refresh(): ioctl(): %s", + strerror(errno)); + goto err2; + } + + if (numtbls >= io.pfrio_size) + break; + + numtbls = io.pfrio_size; + } + + cidx = 1; + + for (it = pt, i = 0; i < numtbls; it++, i++) { + /* + * Skip the table if not active - ioctl(DIOCRGETASTATS) will + * return ESRCH for this entry anyway. + */ + if (!(it->pfrt_flags & PFR_TFLAG_ACTIVE)) + continue; + + if ((naddrs = pfa_table_addrs(cidx, it)) < 0) + goto err1; + + cidx += naddrs; + } + + pfa_table_age = time(NULL); + pfa_table_count = cidx; + pf_tick = this_tick; + + free(pt); + return (0); +err1: + while (!TAILQ_EMPTY(&pfa_table)) { + e = TAILQ_FIRST(&pfa_table); + TAILQ_REMOVE(&pfa_table, e, link); + free(e); + } +err2: + free(pt); + return (-1); +} + +static int +pfl_scan_ruleset(const char *path) +{ + struct pfioc_rule pr; + struct pfl_entry *e; + u_int32_t nr, i; + + bzero(&pr, sizeof(pr)); + strlcpy(pr.anchor, path, sizeof(pr.anchor)); + pr.rule.action = PF_PASS; + if (ioctl(dev, DIOCGETRULES, &pr)) { + syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULES): %s", + strerror(errno)); + goto err; + } + + for (nr = pr.nr, i = 0; i < nr; i++) { + pr.nr = i; + if (ioctl(dev, DIOCGETRULE, &pr)) { + syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULE):" + " %s", strerror(errno)); + goto err; + } + + if (pr.rule.label[0]) { + e = (struct pfl_entry *)malloc(sizeof(*e)); + if (e == NULL) + goto err; + + strlcpy(e->name, path, sizeof(e->name)); + if (path[0]) + strlcat(e->name, "/", sizeof(e->name)); + strlcat(e->name, pr.rule.label, sizeof(e->name)); + + e->evals = pr.rule.evaluations; + e->bytes[IN] = pr.rule.bytes[IN]; + e->bytes[OUT] = pr.rule.bytes[OUT]; + e->pkts[IN] = pr.rule.packets[IN]; + e->pkts[OUT] = pr.rule.packets[OUT]; + e->index = ++pfl_table_count; + + TAILQ_INSERT_TAIL(&pfl_table, e, link); + } + } + + return (0); + +err: + return (-1); +} + +static int +pfl_walk_rulesets(const char *path) +{ + struct pfioc_ruleset prs; + char newpath[MAXPATHLEN]; + u_int32_t nr, i; + + if (pfl_scan_ruleset(path)) + goto err; + + bzero(&prs, sizeof(prs)); + strlcpy(prs.path, path, sizeof(prs.path)); + if (ioctl(dev, DIOCGETRULESETS, &prs)) { + syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESETS): %s", + strerror(errno)); + goto err; + } + + for (nr = prs.nr, i = 0; i < nr; i++) { + prs.nr = i; + if (ioctl(dev, DIOCGETRULESET, &prs)) { + syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESET):" + " %s", strerror(errno)); + goto err; + } + + if (strcmp(prs.name, PF_RESERVED_ANCHOR) == 0) + continue; + + strlcpy(newpath, path, sizeof(newpath)); + if (path[0]) + strlcat(newpath, "/", sizeof(newpath)); + + strlcat(newpath, prs.name, sizeof(newpath)); + if (pfl_walk_rulesets(newpath)) + goto err; + } + + return (0); + +err: + return (-1); +} + +static int +pfl_refresh(void) +{ + struct pfl_entry *e; + + if (started && this_tick <= pf_tick) + return (0); + + while (!TAILQ_EMPTY(&pfl_table)) { + e = TAILQ_FIRST(&pfl_table); + TAILQ_REMOVE(&pfl_table, e, link); + free(e); + } + pfl_table_count = 0; + + if (pfl_walk_rulesets("")) + goto err; + + pfl_table_age = time(NULL); + pf_tick = this_tick; + + return (0); + +err: + while (!TAILQ_EMPTY(&pfl_table)) { + e = TAILQ_FIRST(&pfl_table); + TAILQ_REMOVE(&pfl_table, e, link); + free(e); + } + pfl_table_count = 0; + + return (-1); +} + /* * check whether altq support is enabled in kernel */ @@ -1175,6 +1671,8 @@ TAILQ_INIT(&pfi_table); TAILQ_INIT(&pfq_table); TAILQ_INIT(&pft_table); + TAILQ_INIT(&pfa_table); + TAILQ_INIT(&pfl_table); pfi_refresh(); if (altq_enabled) { @@ -1183,6 +1681,8 @@ pfs_refresh(); pft_refresh(); + pfa_refresh(); + pfl_refresh(); started = 1; @@ -1195,6 +1695,8 @@ struct pfi_entry *i1, *i2; struct pfq_entry *q1, *q2; struct pft_entry *t1, *t2; + struct pfa_entry *a1, *a2; + struct pfl_entry *l1, *l2; /* Empty the list of interfaces */ i1 = TAILQ_FIRST(&pfi_table); @@ -1212,7 +1714,7 @@ q1 = q2; } - /* And the list of tables */ + /* List of tables */ t1 = TAILQ_FIRST(&pft_table); while (t1 != NULL) { t2 = TAILQ_NEXT(t1, link); @@ -1220,6 +1722,22 @@ t1 = t2; } + /* List of table addresses */ + a1 = TAILQ_FIRST(&pfa_table); + while (a1 != NULL) { + a2 = TAILQ_NEXT(a1, link); + free(a1); + a1 = a2; + } + + /* And the list of labeled filter rules */ + l1 = TAILQ_FIRST(&pfl_table); + while (l1 != NULL) { + l2 = TAILQ_NEXT(l1, link); + free(l1); + l1 = l2; + } + close(dev); return (0); } @@ -1232,6 +1750,8 @@ pfq_refresh(); } pft_refresh(); + pfa_refresh(); + pfl_refresh(); syslog(LOG_ERR, "Dump: pfi_table_age = %jd", (intmax_t)pfi_table_age); @@ -1245,9 +1765,18 @@ syslog(LOG_ERR, "Dump: pft_table_age = %jd", (intmax_t)pft_table_age); - syslog(LOG_ERR, "Dump: pft_table_count = %d", pft_table_count); + + syslog(LOG_ERR, "Dump: pfa_table_age = %jd", + (intmax_t)pfa_table_age); + syslog(LOG_ERR, "Dump: pfa_table_count = %d", + pfa_table_count); + + syslog(LOG_ERR, "Dump: pfl_table_age = %jd", + (intmax_t)pfl_table_age); + syslog(LOG_ERR, "Dump: pfl_table_count = %d", + pfl_table_count); } const struct snmp_module config = { diff -ur /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def ./pf_tree.def --- /home/shteryana/svn-fbsd/usr.sbin/bsnmpd/modules/snmp_pf/pf_tree.def 2009-12-02 22:05:06.000000000 +0200 +++ ./pf_tree.def 2009-12-10 20:53:25.000000000 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005 Philip Paeps +# Copyright (c) 2009 Philip Paeps # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,9 +34,9 @@ (200 begemotPf (1 begemotPfObjects (1 pfStatus - (1 pfStatusRunning INTEGER pf_status GET) + (1 pfStatusRunning ENUM ( 1 true 2 false ) pf_status GET) (2 pfStatusRuntime TIMETICKS pf_status GET) - (3 pfStatusDebug INTEGER pf_status GET) + (3 pfStatusDebug ENUM ( 0 none 1 urgent 2 misc 3 loud ) pf_status GET) (4 pfStatusHostId OCTETSTRING pf_status GET) ) (2 pfCounter @@ -106,7 +106,7 @@ (1 pfInterfacesIfEntry : INTEGER32 pf_iftable (1 pfInterfacesIfIndex INTEGER32) (2 pfInterfacesIfDescr OCTETSTRING GET) - (3 pfInterfacesIfType INTEGER GET) + (3 pfInterfacesIfType ENUM ( 0 group 1 instance 2 detached ) GET) (4 pfInterfacesIfTZero TIMETICKS GET) (5 pfInterfacesIfRefsState UNSIGNED32 GET) (6 pfInterfacesIfRefsRule UNSIGNED32 GET) @@ -158,17 +158,18 @@ (3 pfTablesAddrTable (1 pfTablesAddrEntry : INTEGER32 pf_tbladdr (1 pfTablesAddrIndex INTEGER32) - (2 pfTablesAddrNet IPADDRESS GET) - (3 pfTablesAddrMask INTEGER32 GET) - (4 pfTablesAddrTZero TIMETICKS GET) - (5 pfTablesAddrBytesInPass COUNTER64 GET) - (6 pfTablesAddrBytesInBlock COUNTER64 GET) - (7 pfTablesAddrBytesOutPass COUNTER64 GET) - (8 pfTablesAddrBytesOutBlock COUNTER64 GET) - (9 pfTablesAddrPktsInPass COUNTER64 GET) - (10 pfTablesAddrPktsInBlock COUNTER64 GET) - (11 pfTablesAddrPktsOutPass COUNTER64 GET) - (12 pfTablesAddrPktsOutBlock COUNTER64 GET) + (2 pfTablesAddrNetType ENUM ( 0 unknown 1 ipv4 2 ipv6) GET) + (3 pfTablesAddrNet OCTETSTRING | InetAddress GET) + (4 pfTablesAddrPrefix UNSIGNED32 GET) + (5 pfTablesAddrTZero TIMETICKS GET) + (6 pfTablesAddrBytesInPass COUNTER64 GET) + (7 pfTablesAddrBytesInBlock COUNTER64 GET) + (8 pfTablesAddrBytesOutPass COUNTER64 GET) + (9 pfTablesAddrBytesOutBlock COUNTER64 GET) + (10 pfTablesAddrPktsInPass COUNTER64 GET) + (11 pfTablesAddrPktsInBlock COUNTER64 GET) + (12 pfTablesAddrPktsOutPass COUNTER64 GET) + (13 pfTablesAddrPktsOutBlock COUNTER64 GET) ) ) ) @@ -179,13 +180,27 @@ (1 pfAltqQueueIndex INTEGER32) (2 pfAltqQueueDescr OCTETSTRING GET) (3 pfAltqQueueParent OCTETSTRING GET) - (4 pfAltqQueueScheduler INTEGER GET) + (4 pfAltqQueueScheduler ENUM ( 1 cbq 8 hfsc 11 priq ) GET) (5 pfAltqQueueBandwidth UNSIGNED32 GET) (6 pfAltqQueuePriority INTEGER32 GET) (7 pfAltqQueueLimit INTEGER32 GET) ) ) ) + (11 pfLabels + (1 pfLabelsLblNumber INTEGER32 pf_labels GET) + (2 pfLabelsLblTable + (1 pfLabelsLblEntry : INTEGER pf_lbltable + (1 pfLabelsLblIndex INTEGER) + (2 pfLabelsLblName OCTETSTRING GET) + (3 pfLabelsLblEvals COUNTER64 GET) + (4 pfLabelsLblBytesIn COUNTER64 GET) + (5 pfLabelsLblBytesOut COUNTER64 GET) + (6 pfLabelsLblPktsIn COUNTER64 GET) + (7 pfLabelsLblPktsOut COUNTER64 GET) + ) + ) + ) ) ) )