pfctl: Use DIOCGETSTATESNV
Migrate to using the new nvlist-based DIOCGETSTATESNV call to obtain the states list. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D30244
This commit is contained in:
parent
0592a4c83d
commit
bc94129147
@ -627,6 +627,179 @@ pfctl_nv_add_state_cmp(nvlist_t *nvl, const char *name,
|
|||||||
nvlist_add_nvlist(nvl, name, nv);
|
nvlist_add_nvlist(nvl, name, nv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pf_nvstate_scrub_to_state_scrub(const nvlist_t *nvl,
|
||||||
|
struct pfctl_state_scrub *scrub)
|
||||||
|
{
|
||||||
|
bzero(scrub, sizeof(*scrub));
|
||||||
|
|
||||||
|
scrub->timestamp = nvlist_get_bool(nvl, "timestamp");
|
||||||
|
scrub->ttl = nvlist_get_number(nvl, "ttl");
|
||||||
|
scrub->ts_mod = nvlist_get_number(nvl, "ts_mod");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pf_nvstate_peer_to_state_peer(const nvlist_t *nvl,
|
||||||
|
struct pfctl_state_peer *peer)
|
||||||
|
{
|
||||||
|
bzero(peer, sizeof(*peer));
|
||||||
|
|
||||||
|
if (nvlist_exists_nvlist(nvl, "scrub")) {
|
||||||
|
peer->scrub = malloc(sizeof(*peer->scrub));
|
||||||
|
pf_nvstate_scrub_to_state_scrub(
|
||||||
|
nvlist_get_nvlist(nvl, "scrub"),
|
||||||
|
peer->scrub);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->seqlo = nvlist_get_number(nvl, "seqlo");
|
||||||
|
peer->seqhi = nvlist_get_number(nvl, "seqhi");
|
||||||
|
peer->seqdiff = nvlist_get_number(nvl, "seqdiff");
|
||||||
|
peer->max_win = nvlist_get_number(nvl, "max_win");
|
||||||
|
peer->mss = nvlist_get_number(nvl, "mss");
|
||||||
|
peer->state = nvlist_get_number(nvl, "state");
|
||||||
|
peer->wscale = nvlist_get_number(nvl, "wscale");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pf_nvstate_key_to_state_key(const nvlist_t *nvl, struct pfctl_state_key *key)
|
||||||
|
{
|
||||||
|
const nvlist_t * const *tmp;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
bzero(key, sizeof(*key));
|
||||||
|
|
||||||
|
tmp = nvlist_get_nvlist_array(nvl, "addr", &count);
|
||||||
|
assert(count == 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
pf_nvaddr_to_addr(tmp[i], &key->addr[i]);
|
||||||
|
|
||||||
|
pf_nvuint_16_array(nvl, "port", 2, key->port, NULL);
|
||||||
|
|
||||||
|
key->af = nvlist_get_number(nvl, "af");
|
||||||
|
key->proto = nvlist_get_number(nvl, "proto");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pf_nvstate_to_state(const nvlist_t *nvl, struct pfctl_state *s)
|
||||||
|
{
|
||||||
|
bzero(s, sizeof(*s));
|
||||||
|
|
||||||
|
s->id = nvlist_get_number(nvl, "id");
|
||||||
|
s->creatorid = nvlist_get_number(nvl, "creatorid");
|
||||||
|
s->direction = nvlist_get_number(nvl, "direction");
|
||||||
|
|
||||||
|
pf_nvstate_peer_to_state_peer(nvlist_get_nvlist(nvl, "src"), &s->src);
|
||||||
|
pf_nvstate_peer_to_state_peer(nvlist_get_nvlist(nvl, "dst"), &s->dst);
|
||||||
|
|
||||||
|
pf_nvstate_key_to_state_key(nvlist_get_nvlist(nvl, "stack_key"),
|
||||||
|
&s->key[0]);
|
||||||
|
pf_nvstate_key_to_state_key(nvlist_get_nvlist(nvl, "wire_key"),
|
||||||
|
&s->key[1]);
|
||||||
|
|
||||||
|
strlcpy(s->ifname, nvlist_get_string(nvl, "ifname"),
|
||||||
|
sizeof(s->ifname));
|
||||||
|
|
||||||
|
pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "rt_addr"), &s->rt_addr);
|
||||||
|
s->rule = nvlist_get_number(nvl, "rule");
|
||||||
|
s->anchor = nvlist_get_number(nvl, "anchor");
|
||||||
|
s->nat_rule = nvlist_get_number(nvl, "nat_rule");
|
||||||
|
s->creation = nvlist_get_number(nvl, "creation");
|
||||||
|
s->expire = nvlist_get_number(nvl, "expire");
|
||||||
|
|
||||||
|
pf_nvuint_64_array(nvl, "packets", 2, s->packets, NULL);
|
||||||
|
pf_nvuint_64_array(nvl, "bytes", 2, s->bytes, NULL);
|
||||||
|
|
||||||
|
s->log = nvlist_get_number(nvl, "log");
|
||||||
|
s->state_flags = nvlist_get_number(nvl, "state_flags");
|
||||||
|
s->timeout = nvlist_get_number(nvl, "timeout");
|
||||||
|
s->sync_flags = nvlist_get_number(nvl, "sync_flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pfctl_get_states(int dev, struct pfctl_states *states)
|
||||||
|
{
|
||||||
|
struct pfioc_nv nv;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
const nvlist_t * const *slist;
|
||||||
|
size_t found_count;
|
||||||
|
|
||||||
|
bzero(states, sizeof(*states));
|
||||||
|
TAILQ_INIT(&states->states);
|
||||||
|
|
||||||
|
/* Just enough to get a number, and we'll grow from there. */
|
||||||
|
nv.data = malloc(64);
|
||||||
|
nv.len = nv.size = 64;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (ioctl(dev, DIOCGETSTATESNV, &nv)) {
|
||||||
|
free(nv.data);
|
||||||
|
return (errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
nvl = nvlist_unpack(nv.data, nv.len, 0);
|
||||||
|
if (nvl == NULL) {
|
||||||
|
free(nv.data);
|
||||||
|
return (EIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
states->count = nvlist_get_number(nvl, "count");
|
||||||
|
|
||||||
|
/* Are there any states? */
|
||||||
|
if (states->count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (nvlist_exists_nvlist_array(nvl, "states"))
|
||||||
|
slist = nvlist_get_nvlist_array(nvl, "states", &found_count);
|
||||||
|
else
|
||||||
|
found_count = 0;
|
||||||
|
|
||||||
|
if (found_count < states->count) {
|
||||||
|
size_t new_size = nv.size +
|
||||||
|
(nv.size * states->count / (found_count + 1) * 2);
|
||||||
|
|
||||||
|
/* Our buffer is too small. Estimate what we need based
|
||||||
|
* on how many states fit in the previous allocation
|
||||||
|
* and how many states there are. Doubled for margin.
|
||||||
|
* */
|
||||||
|
nv.data = realloc(nv.data, new_size);
|
||||||
|
nv.size = new_size;
|
||||||
|
|
||||||
|
if (nv.data == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < found_count; i++) {
|
||||||
|
struct pfctl_state *s = malloc(sizeof(*s));
|
||||||
|
if (s == NULL) {
|
||||||
|
pfctl_free_states(states);
|
||||||
|
nvlist_destroy(nvl);
|
||||||
|
free(nv.data);
|
||||||
|
return (ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_nvstate_to_state(slist[i], s);
|
||||||
|
TAILQ_INSERT_TAIL(&states->states, s, entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pfctl_free_states(struct pfctl_states *states)
|
||||||
|
{
|
||||||
|
struct pfctl_state *s, *tmp;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(s, &states->states, entry, tmp) {
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(states, sizeof(*states));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
_pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
||||||
unsigned int *killed, uint64_t ioctlval)
|
unsigned int *killed, uint64_t ioctlval)
|
||||||
|
@ -197,6 +197,64 @@ struct pfctl_kill {
|
|||||||
bool kill_match;
|
bool kill_match;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pfctl_state_scrub {
|
||||||
|
bool timestamp;
|
||||||
|
uint8_t ttl;
|
||||||
|
uint32_t ts_mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pfctl_state_peer {
|
||||||
|
struct pfctl_state_scrub *scrub;
|
||||||
|
uint32_t seqlo;
|
||||||
|
uint32_t seqhi;
|
||||||
|
uint32_t seqdiff;
|
||||||
|
uint16_t max_win;
|
||||||
|
uint16_t mss;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t wscale;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pfctl_state_key {
|
||||||
|
struct pf_addr addr[2];
|
||||||
|
uint16_t port[2];
|
||||||
|
sa_family_t af;
|
||||||
|
uint8_t proto;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pfctl_state {
|
||||||
|
TAILQ_ENTRY(pfctl_state) entry;
|
||||||
|
|
||||||
|
uint64_t id;
|
||||||
|
uint32_t creatorid;
|
||||||
|
uint8_t direction;
|
||||||
|
|
||||||
|
struct pfctl_state_peer src;
|
||||||
|
struct pfctl_state_peer dst;
|
||||||
|
|
||||||
|
uint32_t rule;
|
||||||
|
uint32_t anchor;
|
||||||
|
uint32_t nat_rule;
|
||||||
|
struct pf_addr rt_addr;
|
||||||
|
struct pfctl_state_key key[2]; /* addresses stack and wire */
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
uint64_t packets[2];
|
||||||
|
uint64_t bytes[2];
|
||||||
|
uint32_t creation;
|
||||||
|
uint32_t expire;
|
||||||
|
uint32_t pfsync_time;
|
||||||
|
uint16_t tag;
|
||||||
|
uint8_t log;
|
||||||
|
uint8_t state_flags;
|
||||||
|
uint8_t timeout;
|
||||||
|
uint32_t sync_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
TAILQ_HEAD(pfctl_statelist, pfctl_state);
|
||||||
|
struct pfctl_states {
|
||||||
|
struct pfctl_statelist states;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket,
|
int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket,
|
||||||
const char *anchor, u_int32_t ruleset, struct pfctl_rule *rule,
|
const char *anchor, u_int32_t ruleset, struct pfctl_rule *rule,
|
||||||
char *anchor_call);
|
char *anchor_call);
|
||||||
@ -207,6 +265,8 @@ int pfctl_add_rule(int dev, const struct pfctl_rule *r,
|
|||||||
const char *anchor, const char *anchor_call, u_int32_t ticket,
|
const char *anchor, const char *anchor_call, u_int32_t ticket,
|
||||||
u_int32_t pool_ticket);
|
u_int32_t pool_ticket);
|
||||||
int pfctl_set_keepcounters(int dev, bool keep);
|
int pfctl_set_keepcounters(int dev, bool keep);
|
||||||
|
int pfctl_get_states(int dev, struct pfctl_states *states);
|
||||||
|
void pfctl_free_states(struct pfctl_states *states);
|
||||||
int pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
int pfctl_clear_states(int dev, const struct pfctl_kill *kill,
|
||||||
unsigned int *killed);
|
unsigned int *killed);
|
||||||
int pfctl_kill_states(int dev, const struct pfctl_kill *kill,
|
int pfctl_kill_states(int dev, const struct pfctl_kill *kill,
|
||||||
|
@ -196,25 +196,27 @@ print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_seq(struct pfsync_state_peer *p)
|
print_seq(struct pfctl_state_peer *p)
|
||||||
{
|
{
|
||||||
if (p->seqdiff)
|
if (p->seqdiff)
|
||||||
printf("[%u + %u](+%u)", ntohl(p->seqlo),
|
printf("[%u + %u](+%u)", p->seqlo,
|
||||||
ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
|
p->seqhi - p->seqlo, p->seqdiff);
|
||||||
else
|
else
|
||||||
printf("[%u + %u]", ntohl(p->seqlo),
|
printf("[%u + %u]", p->seqlo,
|
||||||
ntohl(p->seqhi) - ntohl(p->seqlo));
|
p->seqhi - p->seqlo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_state(struct pfsync_state *s, int opts)
|
print_state(struct pfctl_state *s, int opts)
|
||||||
{
|
{
|
||||||
struct pfsync_state_peer *src, *dst;
|
struct pfctl_state_peer *src, *dst;
|
||||||
struct pfsync_state_key *key, *sk, *nk;
|
struct pfctl_state_key *key, *sk, *nk;
|
||||||
struct protoent *p;
|
struct protoent *p;
|
||||||
int min, sec;
|
int min, sec;
|
||||||
|
sa_family_t af;
|
||||||
|
uint8_t proto;
|
||||||
#ifndef __NO_STRICT_ALIGNMENT
|
#ifndef __NO_STRICT_ALIGNMENT
|
||||||
struct pfsync_state_key aligned_key[2];
|
struct pfctl_state_key aligned_key[2];
|
||||||
|
|
||||||
bcopy(&s->key, aligned_key, sizeof(aligned_key));
|
bcopy(&s->key, aligned_key, sizeof(aligned_key));
|
||||||
key = aligned_key;
|
key = aligned_key;
|
||||||
@ -222,48 +224,51 @@ print_state(struct pfsync_state *s, int opts)
|
|||||||
key = s->key;
|
key = s->key;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
af = s->key[PF_SK_WIRE].af;
|
||||||
|
proto = s->key[PF_SK_WIRE].proto;
|
||||||
|
|
||||||
if (s->direction == PF_OUT) {
|
if (s->direction == PF_OUT) {
|
||||||
src = &s->src;
|
src = &s->src;
|
||||||
dst = &s->dst;
|
dst = &s->dst;
|
||||||
sk = &key[PF_SK_STACK];
|
sk = &key[PF_SK_STACK];
|
||||||
nk = &key[PF_SK_WIRE];
|
nk = &key[PF_SK_WIRE];
|
||||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)
|
||||||
sk->port[0] = nk->port[0];
|
sk->port[0] = nk->port[0];
|
||||||
} else {
|
} else {
|
||||||
src = &s->dst;
|
src = &s->dst;
|
||||||
dst = &s->src;
|
dst = &s->src;
|
||||||
sk = &key[PF_SK_WIRE];
|
sk = &key[PF_SK_WIRE];
|
||||||
nk = &key[PF_SK_STACK];
|
nk = &key[PF_SK_STACK];
|
||||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)
|
||||||
sk->port[1] = nk->port[1];
|
sk->port[1] = nk->port[1];
|
||||||
}
|
}
|
||||||
printf("%s ", s->ifname);
|
printf("%s ", s->ifname);
|
||||||
if ((p = getprotobynumber(s->proto)) != NULL)
|
if ((p = getprotobynumber(proto)) != NULL)
|
||||||
printf("%s ", p->p_name);
|
printf("%s ", p->p_name);
|
||||||
else
|
else
|
||||||
printf("%u ", s->proto);
|
printf("%u ", proto);
|
||||||
|
|
||||||
print_host(&nk->addr[1], nk->port[1], s->af, opts);
|
print_host(&nk->addr[1], nk->port[1], af, opts);
|
||||||
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
|
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], af) ||
|
||||||
nk->port[1] != sk->port[1]) {
|
nk->port[1] != sk->port[1]) {
|
||||||
printf(" (");
|
printf(" (");
|
||||||
print_host(&sk->addr[1], sk->port[1], s->af, opts);
|
print_host(&sk->addr[1], sk->port[1], af, opts);
|
||||||
printf(")");
|
printf(")");
|
||||||
}
|
}
|
||||||
if (s->direction == PF_OUT)
|
if (s->direction == PF_OUT)
|
||||||
printf(" -> ");
|
printf(" -> ");
|
||||||
else
|
else
|
||||||
printf(" <- ");
|
printf(" <- ");
|
||||||
print_host(&nk->addr[0], nk->port[0], s->af, opts);
|
print_host(&nk->addr[0], nk->port[0], af, opts);
|
||||||
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
|
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], af) ||
|
||||||
nk->port[0] != sk->port[0]) {
|
nk->port[0] != sk->port[0]) {
|
||||||
printf(" (");
|
printf(" (");
|
||||||
print_host(&sk->addr[0], sk->port[0], s->af, opts);
|
print_host(&sk->addr[0], sk->port[0], af, opts);
|
||||||
printf(")");
|
printf(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" ");
|
printf(" ");
|
||||||
if (s->proto == IPPROTO_TCP) {
|
if (proto == IPPROTO_TCP) {
|
||||||
if (src->state <= TCPS_TIME_WAIT &&
|
if (src->state <= TCPS_TIME_WAIT &&
|
||||||
dst->state <= TCPS_TIME_WAIT)
|
dst->state <= TCPS_TIME_WAIT)
|
||||||
printf(" %s:%s\n", tcpstates[src->state],
|
printf(" %s:%s\n", tcpstates[src->state],
|
||||||
@ -290,16 +295,16 @@ print_state(struct pfsync_state *s, int opts)
|
|||||||
dst->wscale & PF_WSCALE_MASK);
|
dst->wscale & PF_WSCALE_MASK);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
} else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
|
} else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
|
||||||
dst->state < PFUDPS_NSTATES) {
|
dst->state < PFUDPS_NSTATES) {
|
||||||
const char *states[] = PFUDPS_NAMES;
|
const char *states[] = PFUDPS_NAMES;
|
||||||
|
|
||||||
printf(" %s:%s\n", states[src->state], states[dst->state]);
|
printf(" %s:%s\n", states[src->state], states[dst->state]);
|
||||||
#ifndef INET6
|
#ifndef INET6
|
||||||
} else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
|
} else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
|
||||||
dst->state < PFOTHERS_NSTATES) {
|
dst->state < PFOTHERS_NSTATES) {
|
||||||
#else
|
#else
|
||||||
} else if (s->proto != IPPROTO_ICMP && s->proto != IPPROTO_ICMPV6 &&
|
} else if (proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6 &&
|
||||||
src->state < PFOTHERS_NSTATES && dst->state < PFOTHERS_NSTATES) {
|
src->state < PFOTHERS_NSTATES && dst->state < PFOTHERS_NSTATES) {
|
||||||
#endif
|
#endif
|
||||||
/* XXX ICMP doesn't really have state levels */
|
/* XXX ICMP doesn't really have state levels */
|
||||||
@ -311,10 +316,8 @@ print_state(struct pfsync_state *s, int opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts & PF_OPT_VERBOSE) {
|
if (opts & PF_OPT_VERBOSE) {
|
||||||
u_int64_t packets[2];
|
u_int32_t creation = s->creation;
|
||||||
u_int64_t bytes[2];
|
u_int32_t expire = s->expire;
|
||||||
u_int32_t creation = ntohl(s->creation);
|
|
||||||
u_int32_t expire = ntohl(s->expire);
|
|
||||||
|
|
||||||
sec = creation % 60;
|
sec = creation % 60;
|
||||||
creation /= 60;
|
creation /= 60;
|
||||||
@ -327,19 +330,15 @@ print_state(struct pfsync_state *s, int opts)
|
|||||||
expire /= 60;
|
expire /= 60;
|
||||||
printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
|
printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
|
||||||
|
|
||||||
bcopy(s->packets[0], &packets[0], sizeof(u_int64_t));
|
|
||||||
bcopy(s->packets[1], &packets[1], sizeof(u_int64_t));
|
|
||||||
bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t));
|
|
||||||
bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t));
|
|
||||||
printf(", %ju:%ju pkts, %ju:%ju bytes",
|
printf(", %ju:%ju pkts, %ju:%ju bytes",
|
||||||
(uintmax_t )be64toh(packets[0]),
|
s->packets[0],
|
||||||
(uintmax_t )be64toh(packets[1]),
|
s->packets[1],
|
||||||
(uintmax_t )be64toh(bytes[0]),
|
s->bytes[0],
|
||||||
(uintmax_t )be64toh(bytes[1]));
|
s->bytes[1]);
|
||||||
if (ntohl(s->anchor) != -1)
|
if (s->anchor != -1)
|
||||||
printf(", anchor %u", ntohl(s->anchor));
|
printf(", anchor %u", s->anchor);
|
||||||
if (ntohl(s->rule) != -1)
|
if (s->rule != -1)
|
||||||
printf(", rule %u", ntohl(s->rule));
|
printf(", rule %u", s->rule);
|
||||||
if (s->state_flags & PFSTATE_SLOPPY)
|
if (s->state_flags & PFSTATE_SLOPPY)
|
||||||
printf(", sloppy");
|
printf(", sloppy");
|
||||||
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
|
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
|
||||||
@ -352,10 +351,9 @@ print_state(struct pfsync_state *s, int opts)
|
|||||||
u_int64_t id;
|
u_int64_t id;
|
||||||
|
|
||||||
bcopy(&s->id, &id, sizeof(u_int64_t));
|
bcopy(&s->id, &id, sizeof(u_int64_t));
|
||||||
printf(" id: %016jx creatorid: %08x",
|
printf(" id: %016jx creatorid: %08x", id, s->creatorid);
|
||||||
(uintmax_t )be64toh(id), ntohl(s->creatorid));
|
|
||||||
printf(" gateway: ");
|
printf(" gateway: ");
|
||||||
print_host(&s->rt_addr, 0, s->af, opts);
|
print_host(&s->rt_addr, 0, af, opts);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,48 +1237,27 @@ pfctl_show_src_nodes(int dev, int opts)
|
|||||||
int
|
int
|
||||||
pfctl_show_states(int dev, const char *iface, int opts)
|
pfctl_show_states(int dev, const char *iface, int opts)
|
||||||
{
|
{
|
||||||
struct pfioc_states ps;
|
struct pfctl_states states;
|
||||||
struct pfsync_state *p;
|
struct pfctl_state *s;
|
||||||
char *inbuf = NULL, *newinbuf = NULL;
|
int dotitle = (opts & PF_OPT_SHOWALL);
|
||||||
unsigned int len = 0;
|
|
||||||
int i, dotitle = (opts & PF_OPT_SHOWALL);
|
|
||||||
|
|
||||||
memset(&ps, 0, sizeof(ps));
|
memset(&states, 0, sizeof(states));
|
||||||
for (;;) {
|
|
||||||
ps.ps_len = len;
|
if (pfctl_get_states(dev, &states))
|
||||||
if (len) {
|
return (-1);
|
||||||
newinbuf = realloc(inbuf, len);
|
|
||||||
if (newinbuf == NULL)
|
TAILQ_FOREACH(s, &states.states, entry) {
|
||||||
err(1, "realloc");
|
if (iface != NULL && strcmp(s->ifname, iface))
|
||||||
ps.ps_buf = inbuf = newinbuf;
|
|
||||||
}
|
|
||||||
if (ioctl(dev, DIOCGETSTATES, &ps) < 0) {
|
|
||||||
warn("DIOCGETSTATES");
|
|
||||||
free(inbuf);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
if (ps.ps_len + sizeof(struct pfioc_states) < len)
|
|
||||||
break;
|
|
||||||
if (len == 0 && ps.ps_len == 0)
|
|
||||||
goto done;
|
|
||||||
if (len == 0 && ps.ps_len != 0)
|
|
||||||
len = ps.ps_len;
|
|
||||||
if (ps.ps_len == 0)
|
|
||||||
goto done; /* no states */
|
|
||||||
len *= 2;
|
|
||||||
}
|
|
||||||
p = ps.ps_states;
|
|
||||||
for (i = 0; i < ps.ps_len; i += sizeof(*p), p++) {
|
|
||||||
if (iface != NULL && strcmp(p->ifname, iface))
|
|
||||||
continue;
|
continue;
|
||||||
if (dotitle) {
|
if (dotitle) {
|
||||||
pfctl_print_title("STATES:");
|
pfctl_print_title("STATES:");
|
||||||
dotitle = 0;
|
dotitle = 0;
|
||||||
}
|
}
|
||||||
print_state(p, opts);
|
print_state(s, opts);
|
||||||
}
|
}
|
||||||
done:
|
|
||||||
free(inbuf);
|
pfctl_free_states(&states);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ char *rate2str(double);
|
|||||||
|
|
||||||
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
|
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
|
||||||
void print_host(struct pf_addr *, u_int16_t p, sa_family_t, int);
|
void print_host(struct pf_addr *, u_int16_t p, sa_family_t, int);
|
||||||
void print_seq(struct pfsync_state_peer *);
|
void print_seq(struct pfctl_state_peer *);
|
||||||
void print_state(struct pfsync_state *, int);
|
void print_state(struct pfctl_state *, int);
|
||||||
int unmask(struct pf_addr *, sa_family_t);
|
int unmask(struct pf_addr *, sa_family_t);
|
||||||
|
|
||||||
int pfctl_cmdline_symset(char *);
|
int pfctl_cmdline_symset(char *);
|
||||||
|
Loading…
Reference in New Issue
Block a user