* We want: - load the boot file
* Next step: none
*
- * SNTP:
- *
- * Prerequisites: - own ethernet address
- * - own IP address
- * We want: - network time
- * Next step: none
*
* WOL:
*
#include <common.h>
+#include <bootstage.h>
#include <command.h>
#include <console.h>
-#include <environment.h>
+#include <env.h>
+#include <env_internal.h>
#include <errno.h>
+#include <image.h>
+#include <log.h>
#include <net.h>
#include <net/fastboot.h>
#include <net/tftp.h>
+#if defined(CONFIG_CMD_PCAP)
+#include <net/pcap.h>
+#endif
+#include <net/udp.h>
#if defined(CONFIG_LED_STATUS)
#include <miiphy.h>
#include <status_led.h>
#include "nfs.h"
#include "ping.h"
#include "rarp.h"
-#if defined(CONFIG_CMD_SNTP)
-#include "sntp.h"
-#endif
#if defined(CONFIG_CMD_WOL)
#include "wol.h"
#endif
/* Boot file size in blocks as reported by the DHCP server */
u32 net_boot_file_expected_size_in_blocks;
-#if defined(CONFIG_CMD_SNTP)
-/* NTP server IP address */
-struct in_addr net_ntp_server;
-/* offset time from UTC */
-int net_ntp_time_offset;
-#endif
-
static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
/* Receive packets */
uchar *net_rx_packets[PKTBUFSRX];
*/
void net_auto_load(void)
{
-#if defined(CONFIG_CMD_NFS)
+#if defined(CONFIG_CMD_NFS) && !defined(CONFIG_SPL_BUILD)
const char *s = env_get("autoload");
if (s != NULL && strcmp(s, "NFS") == 0) {
if (net_check_prereq(NFS)) {
/* We aren't expecting to get a serverip, so just accept the assigned IP */
-#ifdef CONFIG_BOOTP_SERVERIP
- net_set_state(NETLOOP_SUCCESS);
-#else
- printf("Cannot autoload with NFS\n");
- net_set_state(NETLOOP_FAIL);
-#endif
+ if (IS_ENABLED(CONFIG_BOOTP_SERVERIP)) {
+ net_set_state(NETLOOP_SUCCESS);
+ } else {
+ printf("Cannot autoload with NFS\n");
+ net_set_state(NETLOOP_FAIL);
+ }
return;
}
/*
}
if (net_check_prereq(TFTPGET)) {
/* We aren't expecting to get a serverip, so just accept the assigned IP */
-#ifdef CONFIG_BOOTP_SERVERIP
- net_set_state(NETLOOP_SUCCESS);
-#else
- printf("Cannot autoload with TFTPGET\n");
- net_set_state(NETLOOP_FAIL);
-#endif
+ if (IS_ENABLED(CONFIG_BOOTP_SERVERIP)) {
+ net_set_state(NETLOOP_SUCCESS);
+ } else {
+ printf("Cannot autoload with TFTPGET\n");
+ net_set_state(NETLOOP_FAIL);
+ }
return;
}
tftp_start(TFTPGET);
}
-static void net_init_loop(void)
+static int net_init_loop(void)
{
if (eth_get_dev())
memcpy(net_ethaddr, eth_get_ethaddr(), 6);
+ else
+ /*
+ * Not ideal, but there's no way to get the actual error, and I
+ * don't feel like fixing all the users of eth_get_dev to deal
+ * with errors.
+ */
+ return -ENONET;
- return;
+ return 0;
}
static void net_clear_handlers(void)
net_clear_handlers();
}
-void net_init(void)
+int net_init(void)
{
static int first_call = 1;
first_call = 0;
}
- net_init_loop();
+ return net_init_loop();
}
/**********************************************************************/
int ret = -EINVAL;
enum net_loop_state prev_net_state = net_state;
+#if defined(CONFIG_CMD_PING)
+ if (protocol != PING)
+ net_ping_ip.s_addr = 0;
+#endif
net_restarted = 0;
net_dev_exists = 0;
net_try_count = 1;
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
net_init();
- if (eth_is_on_demand_init() || protocol != NETCONS) {
+ if (eth_is_on_demand_init()) {
eth_halt();
eth_set_current();
ret = eth_init();
net_dev_exists = 1;
net_boot_file_size = 0;
switch (protocol) {
+#ifdef CONFIG_CMD_TFTPBOOT
case TFTPGET:
#ifdef CONFIG_CMD_TFTPPUT
case TFTPPUT:
/* always use ARP to get server ethernet address */
tftp_start(protocol);
break;
+#endif
#ifdef CONFIG_CMD_TFTPSRV
case TFTPSRV:
tftp_start_server();
dhcp_request(); /* Basically same as BOOTP */
break;
#endif
-
+#if defined(CONFIG_CMD_BOOTP)
case BOOTP:
bootp_reset();
net_ip.s_addr = 0;
bootp_request();
break;
-
+#endif
#if defined(CONFIG_CMD_RARP)
case RARP:
rarp_try = 0;
ping_start();
break;
#endif
-#if defined(CONFIG_CMD_NFS)
+#if defined(CONFIG_CMD_NFS) && !defined(CONFIG_SPL_BUILD)
case NFS:
nfs_start();
break;
nc_start();
break;
#endif
-#if defined(CONFIG_CMD_SNTP)
- case SNTP:
- sntp_start();
- break;
-#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
dns_start();
break;
}
+ if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP)
+ udp_start();
+
break;
}
*/
for (;;) {
WATCHDOG_RESET();
-#ifdef CONFIG_SHOW_ACTIVITY
- show_activity(1);
-#endif
if (arp_timeout_check() > 0)
time_start = get_timer(0);
printf("Bytes transferred = %d (%x hex)\n",
net_boot_file_size, net_boot_file_size);
env_set_hex("filesize", net_boot_file_size);
- env_set_hex("fileaddr", load_addr);
+ env_set_hex("fileaddr", image_load_addr);
}
if (protocol != NETCONS)
eth_halt();
net_set_icmp_handler(NULL);
#endif
net_set_state(prev_net_state);
+
+#if defined(CONFIG_CMD_PCAP)
+ if (pcap_active())
+ pcap_print_status();
+#endif
return ret;
}
* to the algorithm in RFC815. It returns NULL or the pointer to
* a complete packet, in static storage
*/
-#ifndef CONFIG_NET_MAXDEFRAG
-#define CONFIG_NET_MAXDEFRAG 16384
-#endif
#define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG)
#define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
int offset8, start, len, done = 0;
u16 ip_off = ntohs(ip->ip_off);
+ if (ip->ip_len < IP_MIN_FRAG_DATAGRAM_SIZE)
+ return NULL;
+
/* payload starts after IP header, this fragment is in there */
payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
offset8 = (ip_off & IP_OFFS);
debug_cond(DEBUG_NET_PKT, "packet received\n");
+#if defined(CONFIG_CMD_PCAP)
+ pcap_post(in_packet, len, false);
+#endif
net_rx_packet = in_packet;
net_rx_packet_len = len;
et = (struct ethernet_hdr *)in_packet;
return;
}
+ if (ntohs(ip->udp_len) < UDP_HDR_SIZE || ntohs(ip->udp_len) > ntohs(ip->ip_len))
+ return;
+
debug_cond(DEBUG_DEV_PKT,
"received UDP (to=%pI4, from=%pI4, len=%d)\n",
&dst_ip, &src_ip, len);
-#ifdef CONFIG_UDP_CHECKSUM
- if (ip->udp_xsum != 0) {
+ if (IS_ENABLED(CONFIG_UDP_CHECKSUM) && ip->udp_xsum != 0) {
ulong xsum;
- ushort *sumptr;
+ u8 *sumptr;
ushort sumlen;
xsum = ip->ip_p;
xsum += (ntohl(ip->ip_dst.s_addr) >> 0) & 0x0000ffff;
sumlen = ntohs(ip->udp_len);
- sumptr = (ushort *)&(ip->udp_src);
+ sumptr = (u8 *)&ip->udp_src;
while (sumlen > 1) {
- ushort sumdata;
-
- sumdata = *sumptr++;
- xsum += ntohs(sumdata);
+ /* inlined ntohs() to avoid alignment errors */
+ xsum += (sumptr[0] << 8) + sumptr[1];
+ sumptr += 2;
sumlen -= 2;
}
- if (sumlen > 0) {
- ushort sumdata;
-
- sumdata = *(unsigned char *)sumptr;
- sumdata = (sumdata << 8) & 0xff00;
- xsum += sumdata;
- }
+ if (sumlen > 0)
+ xsum += (sumptr[0] << 8) + sumptr[0];
while ((xsum >> 16) != 0) {
xsum = (xsum & 0x0000ffff) +
((xsum >> 16) & 0x0000ffff);
return;
}
}
-#endif
#if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_SPL_BUILD)
nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
}
goto common;
#endif
-#if defined(CONFIG_CMD_SNTP)
- case SNTP:
- if (net_ntp_server.s_addr == 0) {
- puts("*** ERROR: NTP server address not given\n");
- return 1;
- }
- goto common;
-#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
if (net_dns_server.s_addr == 0) {
}
goto common;
#endif
+#if defined(CONFIG_PROT_UDP)
+ case UDP:
+ if (udp_prereq())
+ return 1;
+ goto common;
+#endif
+
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
puts("*** ERROR: `serverip' not set\n");
return 1;
}
-#if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
- defined(CONFIG_CMD_DNS)
+#if defined(CONFIG_CMD_PING) || \
+ defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP)
common:
#endif
/* Fall through */
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
{
char *colon;
+ struct in_addr ip;
+ ip.s_addr = 0;
if (net_boot_file_name[0] == '\0')
return 0;
colon = strchr(net_boot_file_name, ':');
if (colon) {
- if (ipaddr)
- *ipaddr = string_to_ip(net_boot_file_name);
+ ip = string_to_ip(net_boot_file_name);
+ if (ipaddr && ip.s_addr)
+ *ipaddr = ip;
+ }
+ if (ip.s_addr) {
strncpy(filename, colon + 1, max_len);
} else {
strncpy(filename, net_boot_file_name, max_len);
return 1;
}
-#if defined(CONFIG_CMD_NFS) || \
- defined(CONFIG_CMD_SNTP) || \
- defined(CONFIG_CMD_DNS)
-/*
- * make port a little random (1024-17407)
- * This keeps the math somewhat trivial to compute, and seems to work with
- * all supported protocols/clients/servers
- */
-unsigned int random_port(void)
-{
- return 1024 + (get_timer(0) % 0x4000);
-}
-#endif
-
void ip_to_string(struct in_addr x, char *s)
{
x.s_addr = ntohl(x.s_addr);
if (*s < '0' || *s > '9')
id = VLAN_NONE;
else
- id = (ushort)simple_strtoul(s, NULL, 10);
+ id = (ushort)dectoul(s, NULL);
return htons(id);
}