1 /** @file
2 * @brief Network shell module
3 *
4 * Provide some networking shell commands that can be useful to applications.
5 */
6
7 /*
8 * Copyright (c) 2016 Intel Corporation
9 * Copyright (c) 2023 Nordic Semiconductor ASA
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 */
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG);
16
17 #include <zephyr/kernel.h>
18 #include <zephyr/random/random.h>
19 #include <stdlib.h>
20
21 #include <zephyr/net/ethernet.h>
22
23 #include "net_shell_private.h"
24 #include "net_shell.h"
25
get_iface_idx(const struct shell * sh,char * index_str)26 int get_iface_idx(const struct shell *sh, char *index_str)
27 {
28 char *endptr;
29 int idx;
30
31 if (!index_str) {
32 PR_WARNING("Interface index is missing.\n");
33 return -EINVAL;
34 }
35
36 idx = strtol(index_str, &endptr, 10);
37 if (*endptr != '\0') {
38 PR_WARNING("Invalid index %s\n", index_str);
39 return -ENOENT;
40 }
41
42 if (idx < 0 || idx > 255) {
43 PR_WARNING("Invalid index %d\n", idx);
44 return -ERANGE;
45 }
46
47 return idx;
48 }
49
addrtype2str(enum net_addr_type addr_type)50 const char *addrtype2str(enum net_addr_type addr_type)
51 {
52 switch (addr_type) {
53 case NET_ADDR_ANY:
54 return "<unknown type>";
55 case NET_ADDR_AUTOCONF:
56 return "autoconf";
57 case NET_ADDR_DHCP:
58 return "DHCP";
59 case NET_ADDR_MANUAL:
60 return "manual";
61 case NET_ADDR_OVERRIDABLE:
62 return "overridable";
63 }
64
65 return "<invalid type>";
66 }
67
addrstate2str(enum net_addr_state addr_state)68 const char *addrstate2str(enum net_addr_state addr_state)
69 {
70 switch (addr_state) {
71 case NET_ADDR_ANY_STATE:
72 return "<unknown state>";
73 case NET_ADDR_TENTATIVE:
74 return "tentative";
75 case NET_ADDR_PREFERRED:
76 return "preferred";
77 case NET_ADDR_DEPRECATED:
78 return "deprecated";
79 }
80
81 return "<invalid state>";
82 }
83
84 #if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_NATIVE)
get_addresses(struct net_context * context,char addr_local[],int local_len,char addr_remote[],int remote_len)85 void get_addresses(struct net_context *context,
86 char addr_local[], int local_len,
87 char addr_remote[], int remote_len)
88 {
89 if (IS_ENABLED(CONFIG_NET_IPV6) && context->local.family == AF_INET6) {
90 snprintk(addr_local, local_len, "[%s]:%u",
91 net_sprint_ipv6_addr(
92 net_sin6_ptr(&context->local)->sin6_addr),
93 ntohs(net_sin6_ptr(&context->local)->sin6_port));
94 snprintk(addr_remote, remote_len, "[%s]:%u",
95 net_sprint_ipv6_addr(
96 &net_sin6(&context->remote)->sin6_addr),
97 ntohs(net_sin6(&context->remote)->sin6_port));
98
99 } else if (IS_ENABLED(CONFIG_NET_IPV4) && context->local.family == AF_INET) {
100 snprintk(addr_local, local_len, "%s:%d",
101 net_sprint_ipv4_addr(
102 net_sin_ptr(&context->local)->sin_addr),
103 ntohs(net_sin_ptr(&context->local)->sin_port));
104
105 /* Check if we need to print the v4-mapping-to-v6 address */
106 if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) &&
107 net_sin(&context->remote)->sin_family == AF_INET6 &&
108 net_ipv6_addr_is_v4_mapped(&net_sin6(&context->remote)->sin6_addr)) {
109 snprintk(addr_remote, remote_len, "[%s]:%d",
110 net_sprint_ipv6_addr(
111 &net_sin6(&context->remote)->sin6_addr),
112 ntohs(net_sin6(&context->remote)->sin6_port));
113 } else {
114 snprintk(addr_remote, remote_len, "%s:%d",
115 net_sprint_ipv4_addr(
116 &net_sin(&context->remote)->sin_addr),
117 ntohs(net_sin(&context->remote)->sin_port));
118 }
119
120 } else if (context->local.family == AF_UNSPEC) {
121 snprintk(addr_local, local_len, "AF_UNSPEC");
122 } else if (context->local.family == AF_PACKET) {
123 snprintk(addr_local, local_len, "AF_PACKET");
124 } else if (context->local.family == AF_CAN) {
125 snprintk(addr_local, local_len, "AF_CAN");
126 } else {
127 snprintk(addr_local, local_len, "AF_UNK(%d)",
128 context->local.family);
129 }
130 }
131 #endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_NATIVE */
132
iface2str(struct net_if * iface,const char ** extra)133 const char *iface2str(struct net_if *iface, const char **extra)
134 {
135 #ifdef CONFIG_NET_L2_IEEE802154
136 if (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) {
137 if (extra) {
138 *extra = "=============";
139 }
140
141 return "IEEE 802.15.4";
142 }
143 #endif
144
145 #ifdef CONFIG_NET_L2_ETHERNET
146 if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
147 struct ethernet_context *eth_ctx = net_if_l2_data(iface);
148
149 if (eth_ctx->eth_if_type == L2_ETH_IF_TYPE_WIFI) {
150 if (extra) {
151 *extra = "====";
152 }
153
154 return "WiFi";
155 }
156
157 if (extra) {
158 *extra = "========";
159 }
160
161 return "Ethernet";
162 }
163 #endif
164
165 #ifdef CONFIG_NET_L2_VIRTUAL
166 if (net_if_l2(iface) == &NET_L2_GET_NAME(VIRTUAL)) {
167 if (extra) {
168 *extra = "=======";
169 }
170
171 return "Virtual";
172 }
173 #endif
174
175 #ifdef CONFIG_NET_L2_PPP
176 if (net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) {
177 if (extra) {
178 *extra = "===";
179 }
180
181 return "PPP";
182 }
183 #endif
184
185 #ifdef CONFIG_NET_L2_DUMMY
186 if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
187 if (extra) {
188 *extra = "=====";
189 }
190
191 return "Dummy";
192 }
193 #endif
194
195 #ifdef CONFIG_NET_L2_OPENTHREAD
196 if (net_if_l2(iface) == &NET_L2_GET_NAME(OPENTHREAD)) {
197 if (extra) {
198 *extra = "==========";
199 }
200
201 return "OpenThread";
202 }
203 #endif
204
205 #ifdef CONFIG_NET_L2_BT
206 if (net_if_l2(iface) == &NET_L2_GET_NAME(BLUETOOTH)) {
207 if (extra) {
208 *extra = "=========";
209 }
210
211 return "Bluetooth";
212 }
213 #endif
214
215 #ifdef CONFIG_NET_OFFLOAD
216 if (net_if_is_ip_offloaded(iface)) {
217 if (extra) {
218 *extra = "==========";
219 }
220
221 return "IP Offload";
222 }
223 #endif
224
225 #ifdef CONFIG_NET_L2_CANBUS_RAW
226 if (net_if_l2(iface) == &NET_L2_GET_NAME(CANBUS_RAW)) {
227 if (extra) {
228 *extra = "==========";
229 }
230
231 return "CANBUS_RAW";
232 }
233 #endif
234
235 if (extra) {
236 *extra = "==============";
237 }
238
239 return "<unknown type>";
240 }
241
242 /* Placeholder for net commands that are configured in the rest of the .c files */
243 SHELL_SUBCMD_SET_CREATE(net_cmds, (net));
244
245 SHELL_CMD_REGISTER(net, &net_cmds, "Networking commands", NULL);
246
net_shell_init(void)247 int net_shell_init(void)
248 {
249 if (IS_ENABLED(CONFIG_NET_MGMT_EVENT_MONITOR_AUTO_START)) {
250 events_enable();
251 }
252
253 return 0;
254 }
255