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