Index: lib/libpfctl/libpfctl.h =================================================================== --- lib/libpfctl/libpfctl.h +++ lib/libpfctl/libpfctl.h @@ -73,6 +73,7 @@ struct pfctl_eth_addr { uint8_t addr[ETHER_ADDR_LEN]; bool neg; + bool isset; }; struct pfctl_eth_rule { Index: lib/libpfctl/libpfctl.c =================================================================== --- lib/libpfctl/libpfctl.c +++ lib/libpfctl/libpfctl.c @@ -533,6 +533,7 @@ static void pfctl_nveth_addr_to_eth_addr(const nvlist_t *nvl, struct pfctl_eth_addr *addr) { + static const u_int8_t EMPTY_MAC[ETHER_ADDR_LEN] = { 0 }; size_t len; const void *data; @@ -541,6 +542,9 @@ memcpy(addr->addr, data, sizeof(addr->addr)); addr->neg = nvlist_get_bool(nvl, "neg"); + + /* To make checks for 'is this address set?' easier. */ + addr->isset = memcmp(addr->addr, EMPTY_MAC, ETHER_ADDR_LEN) != 0; } static nvlist_t * Index: sbin/pfctl/pfctl_parser.c =================================================================== --- sbin/pfctl/pfctl_parser.c +++ sbin/pfctl/pfctl_parser.c @@ -693,6 +693,16 @@ static void print_eth_addr(const struct pfctl_eth_addr *a) { + int i; + for (i = 0; i < ETHER_ADDR_LEN; i++) { + if (a->addr[i] != 0) + break; + } + + /* Unset, so don't print anything. */ + if (i == ETHER_ADDR_LEN) + return; + printf("%s%02x:%02x:%02x:%02x:%02x:%02x", a->neg ? "! " : "", a->addr[0], a->addr[1], a->addr[2], a->addr[3], a->addr[4], a->addr[5]); @@ -723,10 +733,14 @@ if (r->proto) printf(" proto 0x%04x", r->proto); - printf(" from "); - print_eth_addr(&r->src); - printf(" to "); - print_eth_addr(&r->dst); + if (r->src.isset) { + printf(" from "); + print_eth_addr(&r->src); + } + if (r->dst.isset) { + printf(" to "); + print_eth_addr(&r->dst); + } if (r->qname[0]) printf(" queue %s", r->qname);