Index: lib/libpfctl/libpfctl.h =================================================================== --- lib/libpfctl/libpfctl.h +++ lib/libpfctl/libpfctl.h @@ -99,6 +99,8 @@ uint64_t evaluations; uint64_t packets[2]; uint64_t bytes[2]; + uint32_t last_active_timestamp; + time_t last_active; /* In system clock. */ /* Action */ char qname[PF_QNAME_SIZE]; @@ -171,6 +173,8 @@ uint64_t evaluations; uint64_t packets[2]; uint64_t bytes[2]; + uint32_t last_active_timestamp; + time_t last_active; /* In system clock. */ struct pfi_kif *kif; struct pfctl_anchor *anchor; Index: lib/libpfctl/libpfctl.c =================================================================== --- lib/libpfctl/libpfctl.c +++ lib/libpfctl/libpfctl.c @@ -47,6 +47,7 @@ #include #include #include +#include /* _long_to_time */ #include "libpfctl.h" @@ -479,6 +480,10 @@ pf_nvuint_64_array(nvl, "packets", 2, rule->packets, NULL); pf_nvuint_64_array(nvl, "bytes", 2, rule->bytes, NULL); + if (nvlist_exists_number(nvl, "timestamp")) { + rule->last_active_timestamp = nvlist_get_number(nvl, "timestamp"); + } + rule->os_fingerprint = nvlist_get_number(nvl, "os_fingerprint"); rule->rtableid = nvlist_get_number(nvl, "rtableid"); @@ -609,6 +614,10 @@ rule->bytes[0] = nvlist_get_number(nvl, "bytes-in"); rule->bytes[1] = nvlist_get_number(nvl, "bytes-out"); + if (nvlist_exists_number(nvl, "timestamp")) { + rule->last_active_timestamp = nvlist_get_number(nvl, "timestamp"); + } + strlcpy(rule->qname, nvlist_get_string(nvl, "qname"), PF_QNAME_SIZE); strlcpy(rule->tagname, nvlist_get_string(nvl, "tagname"), PF_TAG_NAME_SIZE); @@ -739,7 +748,7 @@ const char *path, struct pfctl_eth_rule *rule, bool clear, char *anchor_call) { - uint8_t buf[2048]; + uint8_t buf[4096]; struct pfioc_nv nv; nvlist_t *nvl; void *data; Index: sbin/pfctl/pfctl.c =================================================================== --- sbin/pfctl/pfctl.c +++ sbin/pfctl/pfctl.c @@ -1016,6 +1016,14 @@ (unsigned long long)(rule->bytes[0] + rule->bytes[1])); } + if (opts & PF_OPT_VERBOSE2) { + char timestr[30]; + time_t last_active = rule->last_active_timestamp; + bcopy(ctime(&last_active), timestr, sizeof(timestr)); + *strchr(timestr, '\n') = '\0'; + printf(" [ Last Active Timestamp: %d Last Active " + "Time: %s ]\n", rule->last_active_timestamp, timestr); + } } void @@ -1055,6 +1063,14 @@ (unsigned)rule->cuid, (unsigned)rule->cpid, (uintmax_t)rule->states_tot); } + if (opts & PF_OPT_VERBOSE2) { + char timestr[30]; + time_t last_active = rule->last_active_timestamp; + bcopy(ctime(&last_active), timestr, sizeof(timestr)); + *strchr(timestr, '\n') = '\0'; + printf(" [ Last Active Timestamp: %d Last Active " + "Time: %s ]\n", rule->last_active_timestamp, timestr); + } } void Index: sys/net/pfvar.h =================================================================== --- sys/net/pfvar.h +++ sys/net/pfvar.h @@ -654,6 +654,7 @@ counter_u64_t evaluations; counter_u64_t packets[2]; counter_u64_t bytes[2]; + uint32_t timestamp; /* Action */ char qname[PF_QNAME_SIZE]; @@ -693,6 +694,7 @@ struct pf_counter_u64 evaluations; struct pf_counter_u64 packets[2]; struct pf_counter_u64 bytes[2]; + uint32_t timestamp; struct pfi_kkif *kif; struct pf_kanchor *anchor; Index: sys/netpfil/pf/pf.c =================================================================== --- sys/netpfil/pf/pf.c +++ sys/netpfil/pf/pf.c @@ -3941,6 +3941,7 @@ /* Execute action. */ counter_u64_add(r->packets[dir == PF_OUT], 1); counter_u64_add(r->bytes[dir == PF_OUT], m_length(m, NULL)); + r->timestamp = time_uptime; /* Shortcut. Don't tag if we're just going to drop anyway. */ if (r->action == PF_DROP) @@ -7428,6 +7429,7 @@ dirndx = (dir == PF_OUT); pf_counter_u64_add_protected(&r->packets[dirndx], 1); pf_counter_u64_add_protected(&r->bytes[dirndx], pd.tot_len); + r->timestamp = time_uptime; if (a != NULL) { pf_counter_u64_add_protected(&a->packets[dirndx], 1); pf_counter_u64_add_protected(&a->bytes[dirndx], pd.tot_len); Index: sys/netpfil/pf/pf_ioctl.c =================================================================== --- sys/netpfil/pf/pf_ioctl.c +++ sys/netpfil/pf/pf_ioctl.c @@ -2786,7 +2786,7 @@ ERROUT(EBUSY); } - rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK); + rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK | M_ZERO); if (rule == NULL) ERROUT(ENOMEM); Index: sys/netpfil/pf/pf_nv.c =================================================================== --- sys/netpfil/pf/pf_nv.c +++ sys/netpfil/pf/pf_nv.c @@ -687,6 +687,7 @@ pf_krule_to_nvrule(struct pf_krule *rule) { nvlist_t *nvl, *tmp; + struct timeval boottime; nvl = nvlist_create(0); if (nvl == NULL) @@ -738,6 +739,8 @@ nvlist_append_number_array(nvl, "bytes", pf_counter_u64_fetch(&rule->bytes[i])); } + getboottime(&boottime); + nvlist_add_number(nvl, "timestamp", rule->timestamp + boottime.tv_sec); nvlist_add_number(nvl, "os_fingerprint", rule->os_fingerprint); @@ -1046,6 +1049,7 @@ pf_keth_rule_to_nveth_rule(const struct pf_keth_rule *krule) { nvlist_t *nvl, *addr; + struct timeval boottime; nvl = nvlist_create(0); if (nvl == NULL) @@ -1099,6 +1103,8 @@ nvlist_add_number(nvl, "bytes-out", counter_u64_fetch(krule->bytes[1])); + getboottime(&boottime); + nvlist_add_number(nvl, "timestamp", krule->timestamp + boottime.tv_sec); nvlist_add_string(nvl, "qname", krule->qname); nvlist_add_string(nvl, "tagname", krule->tagname);