Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions src/test/ipfilter_logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,38 @@ static void ip_to_str(uint32_t net_ip, char *buf, size_t len)
buf[len - 1] = '\0';
}

static void log_ports(uint8_t proto, const struct wolfIP_filter_metadata *meta)
static const char *proto_to_name(uint16_t proto)
{
switch (proto) {
case WOLFIP_FILTER_PROTO_ETH:
return "ETH";
case WOLFIP_FILTER_PROTO_IP:
return "IP";
case WOLFIP_FILTER_PROTO_TCP:
return "TCP";
case WOLFIP_FILTER_PROTO_UDP:
return "UDP";
case WOLFIP_FILTER_PROTO_ICMP:
return "ICMP";
default:
return "UNKNOWN";
}
}

static void log_ports(uint16_t proto, const struct wolfIP_filter_metadata *meta)
{
if (proto == 0)
return;
if (proto == WI_IPPROTO_TCP) {
if (proto == WOLFIP_FILTER_PROTO_TCP) {
printf(" tcp=%u->%u flags=0x%02x",
ee16(meta->l4.tcp.src_port),
ee16(meta->l4.tcp.dst_port),
ntohs(meta->l4.tcp.src_port),
ntohs(meta->l4.tcp.dst_port),
meta->l4.tcp.flags);
} else if (proto == WI_IPPROTO_UDP) {
} else if (proto == WOLFIP_FILTER_PROTO_UDP) {
printf(" udp=%u->%u",
ee16(meta->l4.udp.src_port),
ee16(meta->l4.udp.dst_port));
} else if (proto == WI_IPPROTO_ICMP) {
ntohs(meta->l4.udp.src_port),
ntohs(meta->l4.udp.dst_port));
} else if (proto == WOLFIP_FILTER_PROTO_ICMP) {
printf(" icmp type=%u code=%u",
meta->l4.icmp.type,
meta->l4.icmp.code);
Expand All @@ -107,16 +125,16 @@ static int filter_logger_cb(void *arg, const struct wolfIP_filter_event *event)
mac_to_str(event->meta.src_mac, src_mac, sizeof(src_mac));
mac_to_str(event->meta.dst_mac, dst_mac, sizeof(dst_mac));

printf("[ipfilter] reason=%s if=%u len=%" PRIu32
" ip=%s->%s mac=%s->%s proto=%u",
printf("[ipfilter] %s reason=%s if=%u len=%" PRIu32
" ip=%s->%s mac=%s->%s",
proto_to_name(event->meta.ip_proto),
filter_reason_str(event->reason),
event->if_idx,
event->length,
src_ip,
dst_ip,
src_mac,
dst_mac,
event->meta.ip_proto);
dst_mac);
log_ports(event->meta.ip_proto, &event->meta);
printf("\n");

Expand Down
68 changes: 66 additions & 2 deletions src/wolfip.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ struct PACKED wolfIP_icmp_ttl_exceeded_packet {
static wolfIP_filter_cb wolfip_filter_cb;
static void *wolfip_filter_arg;
static uint32_t wolfip_filter_mask;
static uint32_t wolfip_filter_mask_eth;
static uint32_t wolfip_filter_mask_ip;
static uint32_t wolfip_filter_mask_tcp;
static uint32_t wolfip_filter_mask_udp;
static uint32_t wolfip_filter_mask_icmp;
static int wolfip_filter_lock;

void wolfIP_filter_set_callback(wolfIP_filter_cb cb, void *arg)
Expand All @@ -456,6 +461,31 @@ void wolfIP_filter_set_mask(uint32_t mask)
wolfip_filter_mask = mask;
}

void wolfIP_filter_set_eth_mask(uint32_t mask)
{
wolfip_filter_mask_eth = mask;
}

void wolfIP_filter_set_ip_mask(uint32_t mask)
{
wolfip_filter_mask_ip = mask;
}

void wolfIP_filter_set_tcp_mask(uint32_t mask)
{
wolfip_filter_mask_tcp = mask;
}

void wolfIP_filter_set_udp_mask(uint32_t mask)
{
wolfip_filter_mask_udp = mask;
}

void wolfIP_filter_set_icmp_mask(uint32_t mask)
{
wolfip_filter_mask_icmp = mask;
}

uint32_t wolfIP_filter_get_mask(void)
{
return wolfip_filter_mask;
Expand All @@ -466,14 +496,37 @@ static void wolfIP_filter_init_metadata(struct wolfIP_filter_metadata *meta)
memset(meta, 0, sizeof(*meta));
}

static uint32_t wolfIP_filter_mask_for_proto(uint16_t proto)
{
switch (proto) {
case WOLFIP_FILTER_PROTO_ETH:
return wolfip_filter_mask_eth ? wolfip_filter_mask_eth : wolfip_filter_mask;
case WOLFIP_FILTER_PROTO_IP:
return wolfip_filter_mask_ip ? wolfip_filter_mask_ip : wolfip_filter_mask;
case WOLFIP_FILTER_PROTO_TCP:
return wolfip_filter_mask_tcp ? wolfip_filter_mask_tcp : wolfip_filter_mask;
case WOLFIP_FILTER_PROTO_UDP:
return wolfip_filter_mask_udp ? wolfip_filter_mask_udp : wolfip_filter_mask;
case WOLFIP_FILTER_PROTO_ICMP:
return wolfip_filter_mask_icmp ? wolfip_filter_mask_icmp : wolfip_filter_mask;
default:
return wolfip_filter_mask;
}
}

static int wolfIP_filter_dispatch(enum wolfIP_filter_reason reason, struct wolfIP *s, unsigned int if_idx, const void *buffer, uint32_t length, const struct wolfIP_filter_metadata *meta)
{
struct wolfIP_filter_event event;
int ret;
uint32_t mask;

if (!wolfip_filter_cb)
return 0;
if ((wolfip_filter_mask & (1U << reason)) == 0)
if (!meta)
mask = wolfip_filter_mask;
else
mask = wolfIP_filter_mask_for_proto(meta->ip_proto);
if ((mask & (1U << reason)) == 0)
return 0;
if (wolfip_filter_lock)
return 0;
Expand Down Expand Up @@ -504,6 +557,7 @@ static int wolfIP_filter_notify_eth(enum wolfIP_filter_reason reason, struct wol
memcpy(meta.src_mac, eth->src, sizeof(meta.src_mac));
memcpy(meta.dst_mac, eth->dst, sizeof(meta.dst_mac));
meta.eth_type = eth->type;
meta.ip_proto = WOLFIP_FILTER_PROTO_ETH;

return wolfIP_filter_dispatch(reason, s, if_idx, eth, len, &meta);
}
Expand All @@ -515,7 +569,10 @@ static void wolfIP_filter_fill_ip_metadata(struct wolfIP_filter_metadata *meta,
{
meta->src_ip = ip->src;
meta->dst_ip = ip->dst;
meta->ip_proto = ip->proto;
meta->ip_proto = (ip->proto == WI_IPPROTO_TCP) ? WOLFIP_FILTER_PROTO_TCP :
(ip->proto == WI_IPPROTO_UDP) ? WOLFIP_FILTER_PROTO_UDP :
(ip->proto == WI_IPPROTO_ICMP) ? WOLFIP_FILTER_PROTO_ICMP :
WOLFIP_FILTER_PROTO_IP;
#ifdef ETHERNET
memcpy(meta->src_mac, ip->eth.src, sizeof(meta->src_mac));
memcpy(meta->dst_mac, ip->eth.dst, sizeof(meta->dst_mac));
Expand All @@ -529,6 +586,10 @@ static int wolfIP_filter_notify_ip(enum wolfIP_filter_reason reason, struct wolf

wolfIP_filter_init_metadata(&meta);
wolfIP_filter_fill_ip_metadata(&meta, ip);
if (meta.ip_proto == WOLFIP_FILTER_PROTO_TCP ||
meta.ip_proto == WOLFIP_FILTER_PROTO_UDP ||
meta.ip_proto == WOLFIP_FILTER_PROTO_ICMP)
meta.ip_proto = WOLFIP_FILTER_PROTO_IP;

return wolfIP_filter_dispatch(reason, s, if_idx, ip, len, &meta);
}
Expand All @@ -539,6 +600,7 @@ static int wolfIP_filter_notify_tcp(enum wolfIP_filter_reason reason, struct wol

wolfIP_filter_init_metadata(&meta);
wolfIP_filter_fill_ip_metadata(&meta, &tcp->ip);
meta.ip_proto = WOLFIP_FILTER_PROTO_TCP;
meta.l4.tcp.src_port = tcp->src_port;
meta.l4.tcp.dst_port = tcp->dst_port;
meta.l4.tcp.flags = tcp->flags;
Expand All @@ -552,6 +614,7 @@ static int wolfIP_filter_notify_udp(enum wolfIP_filter_reason reason, struct wol

wolfIP_filter_init_metadata(&meta);
wolfIP_filter_fill_ip_metadata(&meta, &udp->ip);
meta.ip_proto = WOLFIP_FILTER_PROTO_UDP;
meta.l4.udp.src_port = udp->src_port;
meta.l4.udp.dst_port = udp->dst_port;

Expand All @@ -564,6 +627,7 @@ static int wolfIP_filter_notify_icmp(enum wolfIP_filter_reason reason, struct wo

wolfIP_filter_init_metadata(&meta);
wolfIP_filter_fill_ip_metadata(&meta, &icmp->ip);
meta.ip_proto = WOLFIP_FILTER_PROTO_ICMP;
meta.l4.icmp.type = icmp->type;
meta.l4.icmp.code = icmp->code;

Expand Down
13 changes: 12 additions & 1 deletion wolfip-filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ enum wolfIP_filter_reason {

#define WOLFIP_FILT_MASK(reason) (1U << (reason))

#define WOLFIP_FILTER_PROTO_ETH 0x008f
#define WOLFIP_FILTER_PROTO_IP 0x0800
#define WOLFIP_FILTER_PROTO_TCP 0x0006
#define WOLFIP_FILTER_PROTO_UDP 0x0011
#define WOLFIP_FILTER_PROTO_ICMP 0x0001

struct wolfIP_filter_metadata {
uint8_t src_mac[6];
uint8_t dst_mac[6];
uint16_t eth_type;
uint32_t src_ip;
uint32_t dst_ip;
uint8_t ip_proto;
uint16_t ip_proto;
Comment thread
douzzer marked this conversation as resolved.
union {
struct {
uint16_t src_port;
Expand Down Expand Up @@ -62,6 +68,11 @@ typedef int (*wolfIP_filter_cb)(void *arg, const struct wolfIP_filter_event *eve

void wolfIP_filter_set_callback(wolfIP_filter_cb cb, void *arg);
void wolfIP_filter_set_mask(uint32_t mask);
void wolfIP_filter_set_eth_mask(uint32_t mask);
void wolfIP_filter_set_ip_mask(uint32_t mask);
void wolfIP_filter_set_tcp_mask(uint32_t mask);
void wolfIP_filter_set_udp_mask(uint32_t mask);
void wolfIP_filter_set_icmp_mask(uint32_t mask);
uint32_t wolfIP_filter_get_mask(void);

#endif /* WOLFIP_FILTER_H */