Blame view
cmd/net.c
9.67 KB
3863585bb
|
1 2 3 4 |
/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * |
1a4596601
|
5 |
* SPDX-License-Identifier: GPL-2.0+ |
3863585bb
|
6 7 8 9 10 11 12 |
*/ /* * Boot support */ #include <common.h> #include <command.h> |
3863585bb
|
13 |
#include <net.h> |
e4bf0c5cf
|
14 |
static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []); |
3863585bb
|
15 |
|
088f1b199
|
16 |
static int do_bootp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
3863585bb
|
17 |
{ |
088f1b199
|
18 |
return netboot_common(BOOTP, cmdtp, argc, argv); |
3863585bb
|
19 |
} |
0d4983930
|
20 21 |
U_BOOT_CMD( bootp, 3, 1, do_bootp, |
2fb2604d5
|
22 |
"boot image via network using BOOTP/TFTP protocol", |
a89c33db9
|
23 |
"[loadAddress] [[hostIPaddr:]bootfilename]" |
8bde7f776
|
24 |
); |
088f1b199
|
25 |
int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
3863585bb
|
26 |
{ |
573f14fe4
|
27 28 29 30 31 32 |
int ret; bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start"); ret = netboot_common(TFTPGET, cmdtp, argc, argv); bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done"); return ret; |
3863585bb
|
33 |
} |
0d4983930
|
34 35 |
U_BOOT_CMD( tftpboot, 3, 1, do_tftpb, |
2fb2604d5
|
36 |
"boot image via network using TFTP protocol", |
a89c33db9
|
37 |
"[loadAddress] [[hostIPaddr:]bootfilename]" |
8bde7f776
|
38 |
); |
2d46cf291
|
39 |
#ifdef CONFIG_CMD_TFTPPUT |
0c1b869b2
|
40 |
static int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
2d46cf291
|
41 |
{ |
85848f037
|
42 |
return netboot_common(TFTPPUT, cmdtp, argc, argv); |
2d46cf291
|
43 44 45 46 47 48 49 50 |
} U_BOOT_CMD( tftpput, 4, 1, do_tftpput, "TFTP put command, for uploading files to a server", "Address Size [[hostIPaddr:]filename]" ); #endif |
7a83af07a
|
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
#ifdef CONFIG_CMD_TFTPSRV static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { return netboot_common(TFTPSRV, cmdtp, argc, argv); } U_BOOT_CMD( tftpsrv, 2, 1, do_tftpsrv, "act as a TFTP server and boot the first received file", "[loadAddress] " "Listen for an incoming TFTP transfer, receive a file and boot it. " "The transfer is aborted if a transfer has not been started after " "about 50 seconds or if Ctrl-C is pressed." ); #endif |
bf6cb247a
|
69 |
#ifdef CONFIG_CMD_RARP |
088f1b199
|
70 |
int do_rarpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
3863585bb
|
71 |
{ |
088f1b199
|
72 |
return netboot_common(RARP, cmdtp, argc, argv); |
3863585bb
|
73 |
} |
0d4983930
|
74 75 |
U_BOOT_CMD( rarpboot, 3, 1, do_rarpb, |
2fb2604d5
|
76 |
"boot image via network using RARP/TFTP protocol", |
a89c33db9
|
77 |
"[loadAddress] [[hostIPaddr:]bootfilename]" |
8bde7f776
|
78 |
); |
bf6cb247a
|
79 |
#endif |
8bde7f776
|
80 |
|
c76fe4742
|
81 |
#if defined(CONFIG_CMD_DHCP) |
088f1b199
|
82 |
static int do_dhcp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
3863585bb
|
83 84 85 |
{ return netboot_common(DHCP, cmdtp, argc, argv); } |
8bde7f776
|
86 |
|
0d4983930
|
87 88 |
U_BOOT_CMD( dhcp, 3, 1, do_dhcp, |
2fb2604d5
|
89 |
"boot image via network using DHCP/TFTP protocol", |
a89c33db9
|
90 |
"[loadAddress] [[hostIPaddr:]bootfilename]" |
8bde7f776
|
91 |
); |
902531788
|
92 |
#endif |
3863585bb
|
93 |
|
c76fe4742
|
94 |
#if defined(CONFIG_CMD_NFS) |
088f1b199
|
95 |
static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
cbd8a35c6
|
96 97 98 99 100 101 |
{ return netboot_common(NFS, cmdtp, argc, argv); } U_BOOT_CMD( nfs, 3, 1, do_nfs, |
2fb2604d5
|
102 |
"boot image via network using NFS protocol", |
a89c33db9
|
103 |
"[loadAddress] [[hostIPaddr:]bootfilename]" |
cbd8a35c6
|
104 |
); |
902531788
|
105 |
#endif |
cbd8a35c6
|
106 |
|
088f1b199
|
107 |
static void netboot_update_env(void) |
3863585bb
|
108 |
{ |
6e5923851
|
109 |
char tmp[22]; |
3863585bb
|
110 |
|
049a95a77
|
111 112 |
if (net_gateway.s_addr) { ip_to_string(net_gateway, tmp); |
382bee57f
|
113 |
env_set("gatewayip", tmp); |
6e5923851
|
114 |
} |
3863585bb
|
115 |
|
049a95a77
|
116 117 |
if (net_netmask.s_addr) { ip_to_string(net_netmask, tmp); |
382bee57f
|
118 |
env_set("netmask", tmp); |
6e5923851
|
119 |
} |
3863585bb
|
120 |
|
586cbe51a
|
121 |
if (net_hostname[0]) |
382bee57f
|
122 |
env_set("hostname", net_hostname); |
3863585bb
|
123 |
|
586cbe51a
|
124 |
if (net_root_path[0]) |
382bee57f
|
125 |
env_set("rootpath", net_root_path); |
3863585bb
|
126 |
|
049a95a77
|
127 128 |
if (net_ip.s_addr) { ip_to_string(net_ip, tmp); |
382bee57f
|
129 |
env_set("ipaddr", tmp); |
6e5923851
|
130 |
} |
a3e1a727f
|
131 132 |
#if !defined(CONFIG_BOOTP_SERVERIP) /* |
ff78ad284
|
133 |
* Only attempt to change serverip if net/bootp.c:store_net_params() |
a3e1a727f
|
134 135 |
* could have set it */ |
049a95a77
|
136 137 |
if (net_server_ip.s_addr) { ip_to_string(net_server_ip, tmp); |
382bee57f
|
138 |
env_set("serverip", tmp); |
6e5923851
|
139 |
} |
a3e1a727f
|
140 |
#endif |
049a95a77
|
141 142 |
if (net_dns_server.s_addr) { ip_to_string(net_dns_server, tmp); |
382bee57f
|
143 |
env_set("dnsip", tmp); |
6e5923851
|
144 |
} |
1fe80d79c
|
145 |
#if defined(CONFIG_BOOTP_DNS2) |
049a95a77
|
146 147 |
if (net_dns_server2.s_addr) { ip_to_string(net_dns_server2, tmp); |
382bee57f
|
148 |
env_set("dnsip2", tmp); |
6e5923851
|
149 |
} |
fe389a82c
|
150 |
#endif |
586cbe51a
|
151 |
if (net_nis_domain[0]) |
382bee57f
|
152 |
env_set("domain", net_nis_domain); |
ea287debe
|
153 |
|
4fd5055f5
|
154 |
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET) |
bc0571fc1
|
155 156 |
if (net_ntp_time_offset) { sprintf(tmp, "%d", net_ntp_time_offset); |
382bee57f
|
157 |
env_set("timeoffset", tmp); |
ea287debe
|
158 159 |
} #endif |
4fd5055f5
|
160 |
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) |
049a95a77
|
161 162 |
if (net_ntp_server.s_addr) { ip_to_string(net_ntp_server, tmp); |
382bee57f
|
163 |
env_set("ntpserverip", tmp); |
ea287debe
|
164 165 |
} #endif |
3863585bb
|
166 |
} |
6e5923851
|
167 |
|
e4bf0c5cf
|
168 169 |
static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]) |
3863585bb
|
170 171 |
{ char *s; |
2e4970d81
|
172 |
char *end; |
3863585bb
|
173 174 |
int rcode = 0; int size; |
2e4970d81
|
175 |
ulong addr; |
3863585bb
|
176 177 |
/* pre-set load_addr */ |
00caae6d4
|
178 |
s = env_get("loadaddr"); |
4fd5055f5
|
179 |
if (s != NULL) |
3863585bb
|
180 |
load_addr = simple_strtoul(s, NULL, 16); |
3863585bb
|
181 182 183 184 |
switch (argc) { case 1: break; |
2e4970d81
|
185 186 187 188 189 |
case 2: /* * Only one arg - accept two forms: * Just load address, or just boot file name. The latter * form must be written in a format which can not be * mis-interpreted as a valid number. |
3863585bb
|
190 |
*/ |
2e4970d81
|
191 192 193 194 |
addr = simple_strtoul(argv[1], &end, 16); if (end == (argv[1] + strlen(argv[1]))) load_addr = addr; else |
1411157d8
|
195 196 |
copy_filename(net_boot_file_name, argv[1], sizeof(net_boot_file_name)); |
3863585bb
|
197 |
break; |
4fd5055f5
|
198 199 |
case 3: load_addr = simple_strtoul(argv[1], NULL, 16); |
1411157d8
|
200 201 |
copy_filename(net_boot_file_name, argv[2], sizeof(net_boot_file_name)); |
3863585bb
|
202 203 |
break; |
2d46cf291
|
204 205 |
#ifdef CONFIG_CMD_TFTPPUT case 4: |
38bd80b48
|
206 |
if (strict_strtoul(argv[1], 16, &save_addr) < 0 || |
4fd5055f5
|
207 |
strict_strtoul(argv[2], 16, &save_size) < 0) { |
38bd80b48
|
208 209 |
printf("Invalid address/size "); |
85848f037
|
210 |
return CMD_RET_USAGE; |
38bd80b48
|
211 |
} |
1411157d8
|
212 213 |
copy_filename(net_boot_file_name, argv[3], sizeof(net_boot_file_name)); |
2d46cf291
|
214 215 |
break; #endif |
47e26b1bf
|
216 |
default: |
770605e4f
|
217 |
bootstage_error(BOOTSTAGE_ID_NET_START); |
4c12eeb8b
|
218 |
return CMD_RET_USAGE; |
3863585bb
|
219 |
} |
770605e4f
|
220 |
bootstage_mark(BOOTSTAGE_ID_NET_START); |
3863585bb
|
221 |
|
bc0571fc1
|
222 |
size = net_loop(proto); |
4fd5055f5
|
223 |
if (size < 0) { |
770605e4f
|
224 |
bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK); |
85848f037
|
225 |
return CMD_RET_FAILURE; |
566a494f5
|
226 |
} |
770605e4f
|
227 |
bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK); |
3863585bb
|
228 |
|
bc0571fc1
|
229 |
/* net_loop ok, update environment */ |
3863585bb
|
230 |
netboot_update_env(); |
eb9401e3e
|
231 |
/* done if no file was loaded (no errors though) */ |
566a494f5
|
232 |
if (size == 0) { |
770605e4f
|
233 |
bootstage_error(BOOTSTAGE_ID_NET_LOADED); |
85848f037
|
234 |
return CMD_RET_SUCCESS; |
566a494f5
|
235 |
} |
eb9401e3e
|
236 |
|
770605e4f
|
237 |
bootstage_mark(BOOTSTAGE_ID_NET_LOADED); |
c8e66db78
|
238 |
|
67d668bf9
|
239 |
rcode = bootm_maybe_autostart(cmdtp, argv[0]); |
3863585bb
|
240 |
|
85848f037
|
241 |
if (rcode == CMD_RET_SUCCESS) |
770605e4f
|
242 |
bootstage_mark(BOOTSTAGE_ID_NET_DONE); |
85848f037
|
243 244 |
else bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR); |
3863585bb
|
245 246 |
return rcode; } |
c76fe4742
|
247 |
#if defined(CONFIG_CMD_PING) |
088f1b199
|
248 |
static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
73a8b27c5
|
249 250 |
{ if (argc < 2) |
85848f037
|
251 |
return CMD_RET_USAGE; |
73a8b27c5
|
252 |
|
049a95a77
|
253 254 |
net_ping_ip = string_to_ip(argv[1]); if (net_ping_ip.s_addr == 0) |
4c12eeb8b
|
255 |
return CMD_RET_USAGE; |
73a8b27c5
|
256 |
|
bc0571fc1
|
257 |
if (net_loop(PING) < 0) { |
73a8b27c5
|
258 259 |
printf("ping failed; host %s is not alive ", argv[1]); |
85848f037
|
260 |
return CMD_RET_FAILURE; |
73a8b27c5
|
261 262 263 264 |
} printf("host %s is alive ", argv[1]); |
85848f037
|
265 |
return CMD_RET_SUCCESS; |
73a8b27c5
|
266 |
} |
6dff55297
|
267 268 269 |
U_BOOT_CMD( ping, 2, 1, do_ping, |
2fb2604d5
|
270 |
"send ICMP ECHO_REQUEST to network host", |
a89c33db9
|
271 |
"pingAddress" |
6dff55297
|
272 |
); |
902531788
|
273 |
#endif |
73a8b27c5
|
274 |
|
c76fe4742
|
275 |
#if defined(CONFIG_CMD_CDP) |
a3d991bd0
|
276 277 278 279 |
static void cdp_update_env(void) { char tmp[16]; |
6aede5b75
|
280 281 282 283 |
if (cdp_appliance_vlan != htons(-1)) { printf("CDP offered appliance VLAN %d ", ntohs(cdp_appliance_vlan)); |
4fd5055f5
|
284 |
vlan_to_string(cdp_appliance_vlan, tmp); |
382bee57f
|
285 |
env_set("vlan", tmp); |
4fd5055f5
|
286 |
net_our_vlan = cdp_appliance_vlan; |
a3d991bd0
|
287 |
} |
6aede5b75
|
288 289 290 |
if (cdp_native_vlan != htons(-1)) { printf("CDP offered native VLAN %d ", ntohs(cdp_native_vlan)); |
4fd5055f5
|
291 |
vlan_to_string(cdp_native_vlan, tmp); |
382bee57f
|
292 |
env_set("nvlan", tmp); |
4fd5055f5
|
293 |
net_native_vlan = cdp_native_vlan; |
a3d991bd0
|
294 |
} |
a3d991bd0
|
295 |
} |
088f1b199
|
296 |
int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
a3d991bd0
|
297 298 |
{ int r; |
bc0571fc1
|
299 |
r = net_loop(CDP); |
a3d991bd0
|
300 301 302 |
if (r < 0) { printf("cdp failed; perhaps not a CISCO switch? "); |
85848f037
|
303 |
return CMD_RET_FAILURE; |
a3d991bd0
|
304 305 306 |
} cdp_update_env(); |
85848f037
|
307 |
return CMD_RET_SUCCESS; |
a3d991bd0
|
308 309 310 311 |
} U_BOOT_CMD( cdp, 1, 1, do_cdp, |
ec5c04cdb
|
312 |
"Perform CDP network configuration", |
4b58266e9
|
313 314 |
" " |
a3d991bd0
|
315 |
); |
902531788
|
316 |
#endif |
a3d991bd0
|
317 |
|
c76fe4742
|
318 |
#if defined(CONFIG_CMD_SNTP) |
088f1b199
|
319 |
int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
ea287debe
|
320 321 322 323 |
{ char *toff; if (argc < 2) { |
723806cc5
|
324 |
net_ntp_server = env_get_ip("ntpserverip"); |
049a95a77
|
325 |
if (net_ntp_server.s_addr == 0) { |
088f1b199
|
326 327 |
printf("ntpserverip not set "); |
85848f037
|
328 |
return CMD_RET_FAILURE; |
ea287debe
|
329 330 |
} } else { |
049a95a77
|
331 332 |
net_ntp_server = string_to_ip(argv[1]); if (net_ntp_server.s_addr == 0) { |
088f1b199
|
333 334 |
printf("Bad NTP server IP address "); |
85848f037
|
335 |
return CMD_RET_FAILURE; |
ea287debe
|
336 337 |
} } |
00caae6d4
|
338 |
toff = env_get("timeoffset"); |
088f1b199
|
339 |
if (toff == NULL) |
bc0571fc1
|
340 |
net_ntp_time_offset = 0; |
088f1b199
|
341 |
else |
bc0571fc1
|
342 |
net_ntp_time_offset = simple_strtol(toff, NULL, 10); |
ea287debe
|
343 |
|
bc0571fc1
|
344 |
if (net_loop(SNTP) < 0) { |
d6840e3d7
|
345 346 |
printf("SNTP failed: host %pI4 not responding ", |
4fd5055f5
|
347 |
&net_ntp_server); |
85848f037
|
348 |
return CMD_RET_FAILURE; |
ea287debe
|
349 |
} |
85848f037
|
350 |
return CMD_RET_SUCCESS; |
ea287debe
|
351 352 353 354 |
} U_BOOT_CMD( sntp, 2, 1, do_sntp, |
2fb2604d5
|
355 |
"synchronize RTC via network", |
ea287debe
|
356 357 358 |
"[NTP server IP] " ); |
902531788
|
359 |
#endif |
1a32bf418
|
360 361 |
#if defined(CONFIG_CMD_DNS) |
54841ab50
|
362 |
int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
1a32bf418
|
363 |
{ |
47e26b1bf
|
364 |
if (argc == 1) |
4c12eeb8b
|
365 |
return CMD_RET_USAGE; |
1a32bf418
|
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
/* * We should check for a valid hostname: * - Each label must be between 1 and 63 characters long * - the entire hostname has a maximum of 255 characters * - only the ASCII letters 'a' through 'z' (case-insensitive), * the digits '0' through '9', and the hyphen * - cannot begin or end with a hyphen * - no other symbols, punctuation characters, or blank spaces are * permitted * but hey - this is a minimalist implmentation, so only check length * and let the name server deal with things. */ if (strlen(argv[1]) >= 255) { printf("dns error: hostname too long "); |
85848f037
|
382 |
return CMD_RET_FAILURE; |
1a32bf418
|
383 |
} |
786eac5f9
|
384 |
net_dns_resolve = argv[1]; |
1a32bf418
|
385 386 |
if (argc == 3) |
786eac5f9
|
387 |
net_dns_env_var = argv[2]; |
1a32bf418
|
388 |
else |
786eac5f9
|
389 |
net_dns_env_var = NULL; |
1a32bf418
|
390 |
|
bc0571fc1
|
391 |
if (net_loop(DNS) < 0) { |
1a32bf418
|
392 393 |
printf("dns lookup of %s failed, check setup ", argv[1]); |
85848f037
|
394 |
return CMD_RET_FAILURE; |
1a32bf418
|
395 |
} |
85848f037
|
396 |
return CMD_RET_SUCCESS; |
1a32bf418
|
397 398 399 400 401 402 403 404 405 |
} U_BOOT_CMD( dns, 3, 1, do_dns, "lookup the IP of a hostname", "hostname [envvar]" ); #endif /* CONFIG_CMD_DNS */ |
d22c338e0
|
406 407 408 409 410 411 |
#if defined(CONFIG_CMD_LINK_LOCAL) static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char tmp[22]; |
bc0571fc1
|
412 |
if (net_loop(LINKLOCAL) < 0) |
85848f037
|
413 |
return CMD_RET_FAILURE; |
d22c338e0
|
414 |
|
049a95a77
|
415 416 |
net_gateway.s_addr = 0; ip_to_string(net_gateway, tmp); |
382bee57f
|
417 |
env_set("gatewayip", tmp); |
d22c338e0
|
418 |
|
049a95a77
|
419 |
ip_to_string(net_netmask, tmp); |
382bee57f
|
420 |
env_set("netmask", tmp); |
d22c338e0
|
421 |
|
049a95a77
|
422 |
ip_to_string(net_ip, tmp); |
382bee57f
|
423 424 |
env_set("ipaddr", tmp); env_set("llipaddr", tmp); /* store this for next time */ |
d22c338e0
|
425 |
|
85848f037
|
426 |
return CMD_RET_SUCCESS; |
d22c338e0
|
427 428 429 430 431 432 433 434 435 |
} U_BOOT_CMD( linklocal, 1, 1, do_link_local, "acquire a network IP address using the link-local protocol", "" ); #endif /* CONFIG_CMD_LINK_LOCAL */ |