1 /*
2  * Copyright (c) 2025 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_shell);
9 
10 #include <zephyr/net/net_pkt_filter.h>
11 
12 #include "net_shell_private.h"
13 
14 
15 #if defined(CONFIG_NET_PKT_FILTER)
rule_type2str(enum npf_rule_type type)16 static const char *rule_type2str(enum npf_rule_type type)
17 {
18 	switch (type) {
19 	case NPF_RULE_TYPE_SEND:
20 		return "send";
21 	case NPF_RULE_TYPE_RECV:
22 		return "recv";
23 	case NPF_RULE_TYPE_LOCAL_IN_RECV:
24 		return "local recv";
25 	case NPF_RULE_TYPE_IPV4_RECV:
26 		return "IPv4 recv";
27 	case NPF_RULE_TYPE_IPV6_RECV:
28 		return "IPv6 recv";
29 	case NPF_RULE_TYPE_UNKNOWN:
30 		__fallthrough;
31 	default:
32 		break;
33 	}
34 
35 	return "<UNKNOWN>";
36 }
37 
verdict2str(enum net_verdict verdict)38 static const char *verdict2str(enum net_verdict verdict)
39 {
40 	switch (verdict) {
41 	case NET_OK:
42 		return "OK";
43 	case NET_DROP:
44 		return "DROP";
45 	case NET_CONTINUE:
46 		return "CONTINUE";
47 	default:
48 		break;
49 	}
50 
51 	return "<UNK>";
52 }
53 
rule_cb(struct npf_rule * rule,enum npf_rule_type type,void * user_data)54 static void rule_cb(struct npf_rule *rule, enum npf_rule_type type, void *user_data)
55 {
56 	struct net_shell_user_data *data = user_data;
57 	const struct shell *sh = data->sh;
58 	int *count = data->user_data;
59 
60 	PR("[%2d]  %-10s  %-7s  %-5d",
61 	   (*count) + 1, rule_type2str(type), verdict2str(rule->result), rule->nb_tests);
62 
63 	for (int i = 0; i < rule->nb_tests; i++) {
64 		/* Allocate room for storing two full IPv4/6 addresses */
65 #define MAX_BUF_LEN ((IS_ENABLED(CONFIG_NET_IPV6) ?		\
66 		      INET6_ADDRSTRLEN : INET_ADDRSTRLEN) * 2)
67 		char buf[MAX_BUF_LEN] = { 0 };
68 		struct npf_test *test;
69 		const char *str;
70 
71 		test = rule->tests[i];
72 
73 		str = npf_test_get_str(test, buf, sizeof(buf) - 1);
74 		PR("%s%s%s", str, buf[0] != '\0' ? buf : "",
75 		   i == rule->nb_tests - 1 ? "" : ",");
76 	}
77 
78 	PR("\n");
79 	(*count)++;
80 }
81 #endif /* CONFIG_NET_PKT_FILTER */
82 
cmd_net_filter(const struct shell * sh,size_t argc,char * argv[])83 static int cmd_net_filter(const struct shell *sh, size_t argc, char *argv[])
84 {
85 	ARG_UNUSED(argc);
86 	ARG_UNUSED(argv);
87 
88 #if defined(CONFIG_NET_PKT_FILTER)
89 	struct net_shell_user_data user_data;
90 	int count = 0;
91 
92 	PR("Rule  %-10s  Verdict  Tests\n", "Type");
93 
94 	user_data.sh = sh;
95 	user_data.user_data = &count;
96 
97 	npf_rules_foreach(rule_cb, &user_data);
98 
99 	if (count == 0) {
100 		PR("No network packet filter rules\n");
101 	}
102 #else
103 	PR_INFO("Set %s to enable %s support.\n",
104 		"CONFIG_NET_PKT_FILTER",
105 		"packet filter information");
106 
107 #endif /* CONFIG_NET_PKT_FILTER */
108 
109 	return 0;
110 }
111 
112 
113 SHELL_SUBCMD_ADD((net), filter, NULL, "Print information about network packet filters.",
114 		 cmd_net_filter, 1, 0);
115