Commit 2ea9103924048637d28baf0f7b1dd410f6704c32

Authored by Wolfgang Denk
Committed by Tom Rini
1 parent 04e2a13336

SPDX License cleanup for LiMon imported files

A number of network related files were imported from the LiMon
project; these contain a somewhat unclear license statement:

	Copyright 1994 - 2000 Neil Russell.
	(See License)

I analyzed the source code of LiMon v1.4.2 which was used for this
import.  It does not contain any "License" file, but the top level
directory contains a file "COPYING", which turns out to be GPL v2
of June 1991.  So it is legitimate to conclude that the LiMon derived
files are also to be released under GPLv2.  Mark them as such.

Signed-off-by: Wolfgang Denk <wd@denx.de>

Showing 8 changed files with 8 additions and 1 deletions Inline Diff

1 /* 1 /*
2 * LiMon Monitor (LiMon) - Network. 2 * LiMon Monitor (LiMon) - Network.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * 6 * SPDX-License-Identifier: GPL-2.0
7 * 7 *
8 * History 8 * History
9 * 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added 9 * 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
10 */ 10 */
11 11
12 #ifndef __NET_H__ 12 #ifndef __NET_H__
13 #define __NET_H__ 13 #define __NET_H__
14 14
15 #if defined(CONFIG_8xx) 15 #if defined(CONFIG_8xx)
16 #include <commproc.h> 16 #include <commproc.h>
17 #endif /* CONFIG_8xx */ 17 #endif /* CONFIG_8xx */
18 18
19 #include <asm/cache.h> 19 #include <asm/cache.h>
20 #include <asm/byteorder.h> /* for nton* / ntoh* stuff */ 20 #include <asm/byteorder.h> /* for nton* / ntoh* stuff */
21 21
22 #define DEBUG_LL_STATE 0 /* Link local state machine changes */ 22 #define DEBUG_LL_STATE 0 /* Link local state machine changes */
23 #define DEBUG_DEV_PKT 0 /* Packets or info directed to the device */ 23 #define DEBUG_DEV_PKT 0 /* Packets or info directed to the device */
24 #define DEBUG_NET_PKT 0 /* Packets on info on the network at large */ 24 #define DEBUG_NET_PKT 0 /* Packets on info on the network at large */
25 #define DEBUG_INT_STATE 0 /* Internal network state changes */ 25 #define DEBUG_INT_STATE 0 /* Internal network state changes */
26 26
27 /* 27 /*
28 * The number of receive packet buffers, and the required packet buffer 28 * The number of receive packet buffers, and the required packet buffer
29 * alignment in memory. 29 * alignment in memory.
30 * 30 *
31 */ 31 */
32 32
33 #ifdef CONFIG_SYS_RX_ETH_BUFFER 33 #ifdef CONFIG_SYS_RX_ETH_BUFFER
34 # define PKTBUFSRX CONFIG_SYS_RX_ETH_BUFFER 34 # define PKTBUFSRX CONFIG_SYS_RX_ETH_BUFFER
35 #else 35 #else
36 # define PKTBUFSRX 4 36 # define PKTBUFSRX 4
37 #endif 37 #endif
38 38
39 #define PKTALIGN ARCH_DMA_MINALIGN 39 #define PKTALIGN ARCH_DMA_MINALIGN
40 40
41 /* IPv4 addresses are always 32 bits in size */ 41 /* IPv4 addresses are always 32 bits in size */
42 typedef __be32 IPaddr_t; 42 typedef __be32 IPaddr_t;
43 43
44 44
45 /** 45 /**
46 * An incoming packet handler. 46 * An incoming packet handler.
47 * @param pkt pointer to the application packet 47 * @param pkt pointer to the application packet
48 * @param dport destination UDP port 48 * @param dport destination UDP port
49 * @param sip source IP address 49 * @param sip source IP address
50 * @param sport source UDP port 50 * @param sport source UDP port
51 * @param len packet length 51 * @param len packet length
52 */ 52 */
53 typedef void rxhand_f(uchar *pkt, unsigned dport, 53 typedef void rxhand_f(uchar *pkt, unsigned dport,
54 IPaddr_t sip, unsigned sport, 54 IPaddr_t sip, unsigned sport,
55 unsigned len); 55 unsigned len);
56 56
57 /** 57 /**
58 * An incoming ICMP packet handler. 58 * An incoming ICMP packet handler.
59 * @param type ICMP type 59 * @param type ICMP type
60 * @param code ICMP code 60 * @param code ICMP code
61 * @param dport destination UDP port 61 * @param dport destination UDP port
62 * @param sip source IP address 62 * @param sip source IP address
63 * @param sport source UDP port 63 * @param sport source UDP port
64 * @param pkt pointer to the ICMP packet data 64 * @param pkt pointer to the ICMP packet data
65 * @param len packet length 65 * @param len packet length
66 */ 66 */
67 typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport, 67 typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
68 IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len); 68 IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len);
69 69
70 /* 70 /*
71 * A timeout handler. Called after time interval has expired. 71 * A timeout handler. Called after time interval has expired.
72 */ 72 */
73 typedef void thand_f(void); 73 typedef void thand_f(void);
74 74
75 enum eth_state_t { 75 enum eth_state_t {
76 ETH_STATE_INIT, 76 ETH_STATE_INIT,
77 ETH_STATE_PASSIVE, 77 ETH_STATE_PASSIVE,
78 ETH_STATE_ACTIVE 78 ETH_STATE_ACTIVE
79 }; 79 };
80 80
81 struct eth_device { 81 struct eth_device {
82 char name[16]; 82 char name[16];
83 unsigned char enetaddr[6]; 83 unsigned char enetaddr[6];
84 int iobase; 84 int iobase;
85 int state; 85 int state;
86 86
87 int (*init) (struct eth_device *, bd_t *); 87 int (*init) (struct eth_device *, bd_t *);
88 int (*send) (struct eth_device *, void *packet, int length); 88 int (*send) (struct eth_device *, void *packet, int length);
89 int (*recv) (struct eth_device *); 89 int (*recv) (struct eth_device *);
90 void (*halt) (struct eth_device *); 90 void (*halt) (struct eth_device *);
91 #ifdef CONFIG_MCAST_TFTP 91 #ifdef CONFIG_MCAST_TFTP
92 int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set); 92 int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set);
93 #endif 93 #endif
94 int (*write_hwaddr) (struct eth_device *); 94 int (*write_hwaddr) (struct eth_device *);
95 struct eth_device *next; 95 struct eth_device *next;
96 int index; 96 int index;
97 void *priv; 97 void *priv;
98 }; 98 };
99 99
100 extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */ 100 extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */
101 extern int eth_register(struct eth_device* dev);/* Register network device */ 101 extern int eth_register(struct eth_device* dev);/* Register network device */
102 extern int eth_unregister(struct eth_device *dev);/* Remove network device */ 102 extern int eth_unregister(struct eth_device *dev);/* Remove network device */
103 extern void eth_try_another(int first_restart); /* Change the device */ 103 extern void eth_try_another(int first_restart); /* Change the device */
104 extern void eth_set_current(void); /* set nterface to ethcur var */ 104 extern void eth_set_current(void); /* set nterface to ethcur var */
105 105
106 /* get the current device MAC */ 106 /* get the current device MAC */
107 extern struct eth_device *eth_current; 107 extern struct eth_device *eth_current;
108 108
109 static inline __attribute__((always_inline)) 109 static inline __attribute__((always_inline))
110 struct eth_device *eth_get_dev(void) 110 struct eth_device *eth_get_dev(void)
111 { 111 {
112 return eth_current; 112 return eth_current;
113 } 113 }
114 extern struct eth_device *eth_get_dev_by_name(const char *devname); 114 extern struct eth_device *eth_get_dev_by_name(const char *devname);
115 extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */ 115 extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
116 extern int eth_get_dev_index(void); /* get the device index */ 116 extern int eth_get_dev_index(void); /* get the device index */
117 extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr); 117 extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
118 extern int eth_getenv_enetaddr(char *name, uchar *enetaddr); 118 extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);
119 extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr); 119 extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
120 120
121 /* 121 /*
122 * Get the hardware address for an ethernet interface . 122 * Get the hardware address for an ethernet interface .
123 * Args: 123 * Args:
124 * base_name - base name for device (normally "eth") 124 * base_name - base name for device (normally "eth")
125 * index - device index number (0 for first) 125 * index - device index number (0 for first)
126 * enetaddr - returns 6 byte hardware address 126 * enetaddr - returns 6 byte hardware address
127 * Returns: 127 * Returns:
128 * Return true if the address is valid. 128 * Return true if the address is valid.
129 */ 129 */
130 extern int eth_getenv_enetaddr_by_index(const char *base_name, int index, 130 extern int eth_getenv_enetaddr_by_index(const char *base_name, int index,
131 uchar *enetaddr); 131 uchar *enetaddr);
132 132
133 extern int usb_eth_initialize(bd_t *bi); 133 extern int usb_eth_initialize(bd_t *bi);
134 extern int eth_init(bd_t *bis); /* Initialize the device */ 134 extern int eth_init(bd_t *bis); /* Initialize the device */
135 extern int eth_send(void *packet, int length); /* Send a packet */ 135 extern int eth_send(void *packet, int length); /* Send a packet */
136 136
137 #ifdef CONFIG_API 137 #ifdef CONFIG_API
138 extern int eth_receive(void *packet, int length); /* Receive a packet*/ 138 extern int eth_receive(void *packet, int length); /* Receive a packet*/
139 extern void (*push_packet)(void *packet, int length); 139 extern void (*push_packet)(void *packet, int length);
140 #endif 140 #endif
141 extern int eth_rx(void); /* Check for received packets */ 141 extern int eth_rx(void); /* Check for received packets */
142 extern void eth_halt(void); /* stop SCC */ 142 extern void eth_halt(void); /* stop SCC */
143 extern char *eth_get_name(void); /* get name of current device */ 143 extern char *eth_get_name(void); /* get name of current device */
144 144
145 /* Set active state */ 145 /* Set active state */
146 static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis) 146 static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis)
147 { 147 {
148 eth_get_dev()->state = ETH_STATE_ACTIVE; 148 eth_get_dev()->state = ETH_STATE_ACTIVE;
149 149
150 return 0; 150 return 0;
151 } 151 }
152 /* Set passive state */ 152 /* Set passive state */
153 static inline __attribute__((always_inline)) void eth_halt_state_only(void) 153 static inline __attribute__((always_inline)) void eth_halt_state_only(void)
154 { 154 {
155 eth_get_dev()->state = ETH_STATE_PASSIVE; 155 eth_get_dev()->state = ETH_STATE_PASSIVE;
156 } 156 }
157 157
158 /* 158 /*
159 * Set the hardware address for an ethernet interface based on 'eth%daddr' 159 * Set the hardware address for an ethernet interface based on 'eth%daddr'
160 * environment variable (or just 'ethaddr' if eth_number is 0). 160 * environment variable (or just 'ethaddr' if eth_number is 0).
161 * Args: 161 * Args:
162 * base_name - base name for device (normally "eth") 162 * base_name - base name for device (normally "eth")
163 * eth_number - value of %d (0 for first device of this type) 163 * eth_number - value of %d (0 for first device of this type)
164 * Returns: 164 * Returns:
165 * 0 is success, non-zero is error status from driver. 165 * 0 is success, non-zero is error status from driver.
166 */ 166 */
167 int eth_write_hwaddr(struct eth_device *dev, const char *base_name, 167 int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
168 int eth_number); 168 int eth_number);
169 169
170 #ifdef CONFIG_MCAST_TFTP 170 #ifdef CONFIG_MCAST_TFTP
171 int eth_mcast_join(IPaddr_t mcast_addr, u8 join); 171 int eth_mcast_join(IPaddr_t mcast_addr, u8 join);
172 u32 ether_crc(size_t len, unsigned char const *p); 172 u32 ether_crc(size_t len, unsigned char const *p);
173 #endif 173 #endif
174 174
175 175
176 /**********************************************************************/ 176 /**********************************************************************/
177 /* 177 /*
178 * Protocol headers. 178 * Protocol headers.
179 */ 179 */
180 180
181 /* 181 /*
182 * Ethernet header 182 * Ethernet header
183 */ 183 */
184 184
185 struct ethernet_hdr { 185 struct ethernet_hdr {
186 uchar et_dest[6]; /* Destination node */ 186 uchar et_dest[6]; /* Destination node */
187 uchar et_src[6]; /* Source node */ 187 uchar et_src[6]; /* Source node */
188 ushort et_protlen; /* Protocol or length */ 188 ushort et_protlen; /* Protocol or length */
189 }; 189 };
190 190
191 /* Ethernet header size */ 191 /* Ethernet header size */
192 #define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr)) 192 #define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr))
193 193
194 struct e802_hdr { 194 struct e802_hdr {
195 uchar et_dest[6]; /* Destination node */ 195 uchar et_dest[6]; /* Destination node */
196 uchar et_src[6]; /* Source node */ 196 uchar et_src[6]; /* Source node */
197 ushort et_protlen; /* Protocol or length */ 197 ushort et_protlen; /* Protocol or length */
198 uchar et_dsap; /* 802 DSAP */ 198 uchar et_dsap; /* 802 DSAP */
199 uchar et_ssap; /* 802 SSAP */ 199 uchar et_ssap; /* 802 SSAP */
200 uchar et_ctl; /* 802 control */ 200 uchar et_ctl; /* 802 control */
201 uchar et_snap1; /* SNAP */ 201 uchar et_snap1; /* SNAP */
202 uchar et_snap2; 202 uchar et_snap2;
203 uchar et_snap3; 203 uchar et_snap3;
204 ushort et_prot; /* 802 protocol */ 204 ushort et_prot; /* 802 protocol */
205 }; 205 };
206 206
207 /* 802 + SNAP + ethernet header size */ 207 /* 802 + SNAP + ethernet header size */
208 #define E802_HDR_SIZE (sizeof(struct e802_hdr)) 208 #define E802_HDR_SIZE (sizeof(struct e802_hdr))
209 209
210 /* 210 /*
211 * Virtual LAN Ethernet header 211 * Virtual LAN Ethernet header
212 */ 212 */
213 struct vlan_ethernet_hdr { 213 struct vlan_ethernet_hdr {
214 uchar vet_dest[6]; /* Destination node */ 214 uchar vet_dest[6]; /* Destination node */
215 uchar vet_src[6]; /* Source node */ 215 uchar vet_src[6]; /* Source node */
216 ushort vet_vlan_type; /* PROT_VLAN */ 216 ushort vet_vlan_type; /* PROT_VLAN */
217 ushort vet_tag; /* TAG of VLAN */ 217 ushort vet_tag; /* TAG of VLAN */
218 ushort vet_type; /* protocol type */ 218 ushort vet_type; /* protocol type */
219 }; 219 };
220 220
221 /* VLAN Ethernet header size */ 221 /* VLAN Ethernet header size */
222 #define VLAN_ETHER_HDR_SIZE (sizeof(struct vlan_ethernet_hdr)) 222 #define VLAN_ETHER_HDR_SIZE (sizeof(struct vlan_ethernet_hdr))
223 223
224 #define PROT_IP 0x0800 /* IP protocol */ 224 #define PROT_IP 0x0800 /* IP protocol */
225 #define PROT_ARP 0x0806 /* IP ARP protocol */ 225 #define PROT_ARP 0x0806 /* IP ARP protocol */
226 #define PROT_RARP 0x8035 /* IP ARP protocol */ 226 #define PROT_RARP 0x8035 /* IP ARP protocol */
227 #define PROT_VLAN 0x8100 /* IEEE 802.1q protocol */ 227 #define PROT_VLAN 0x8100 /* IEEE 802.1q protocol */
228 228
229 #define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ 229 #define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
230 #define IPPROTO_UDP 17 /* User Datagram Protocol */ 230 #define IPPROTO_UDP 17 /* User Datagram Protocol */
231 231
232 /* 232 /*
233 * Internet Protocol (IP) header. 233 * Internet Protocol (IP) header.
234 */ 234 */
235 struct ip_hdr { 235 struct ip_hdr {
236 uchar ip_hl_v; /* header length and version */ 236 uchar ip_hl_v; /* header length and version */
237 uchar ip_tos; /* type of service */ 237 uchar ip_tos; /* type of service */
238 ushort ip_len; /* total length */ 238 ushort ip_len; /* total length */
239 ushort ip_id; /* identification */ 239 ushort ip_id; /* identification */
240 ushort ip_off; /* fragment offset field */ 240 ushort ip_off; /* fragment offset field */
241 uchar ip_ttl; /* time to live */ 241 uchar ip_ttl; /* time to live */
242 uchar ip_p; /* protocol */ 242 uchar ip_p; /* protocol */
243 ushort ip_sum; /* checksum */ 243 ushort ip_sum; /* checksum */
244 IPaddr_t ip_src; /* Source IP address */ 244 IPaddr_t ip_src; /* Source IP address */
245 IPaddr_t ip_dst; /* Destination IP address */ 245 IPaddr_t ip_dst; /* Destination IP address */
246 }; 246 };
247 247
248 #define IP_OFFS 0x1fff /* ip offset *= 8 */ 248 #define IP_OFFS 0x1fff /* ip offset *= 8 */
249 #define IP_FLAGS 0xe000 /* first 3 bits */ 249 #define IP_FLAGS 0xe000 /* first 3 bits */
250 #define IP_FLAGS_RES 0x8000 /* reserved */ 250 #define IP_FLAGS_RES 0x8000 /* reserved */
251 #define IP_FLAGS_DFRAG 0x4000 /* don't fragments */ 251 #define IP_FLAGS_DFRAG 0x4000 /* don't fragments */
252 #define IP_FLAGS_MFRAG 0x2000 /* more fragments */ 252 #define IP_FLAGS_MFRAG 0x2000 /* more fragments */
253 253
254 #define IP_HDR_SIZE (sizeof(struct ip_hdr)) 254 #define IP_HDR_SIZE (sizeof(struct ip_hdr))
255 255
256 /* 256 /*
257 * Internet Protocol (IP) + UDP header. 257 * Internet Protocol (IP) + UDP header.
258 */ 258 */
259 struct ip_udp_hdr { 259 struct ip_udp_hdr {
260 uchar ip_hl_v; /* header length and version */ 260 uchar ip_hl_v; /* header length and version */
261 uchar ip_tos; /* type of service */ 261 uchar ip_tos; /* type of service */
262 ushort ip_len; /* total length */ 262 ushort ip_len; /* total length */
263 ushort ip_id; /* identification */ 263 ushort ip_id; /* identification */
264 ushort ip_off; /* fragment offset field */ 264 ushort ip_off; /* fragment offset field */
265 uchar ip_ttl; /* time to live */ 265 uchar ip_ttl; /* time to live */
266 uchar ip_p; /* protocol */ 266 uchar ip_p; /* protocol */
267 ushort ip_sum; /* checksum */ 267 ushort ip_sum; /* checksum */
268 IPaddr_t ip_src; /* Source IP address */ 268 IPaddr_t ip_src; /* Source IP address */
269 IPaddr_t ip_dst; /* Destination IP address */ 269 IPaddr_t ip_dst; /* Destination IP address */
270 ushort udp_src; /* UDP source port */ 270 ushort udp_src; /* UDP source port */
271 ushort udp_dst; /* UDP destination port */ 271 ushort udp_dst; /* UDP destination port */
272 ushort udp_len; /* Length of UDP packet */ 272 ushort udp_len; /* Length of UDP packet */
273 ushort udp_xsum; /* Checksum */ 273 ushort udp_xsum; /* Checksum */
274 }; 274 };
275 275
276 #define IP_UDP_HDR_SIZE (sizeof(struct ip_udp_hdr)) 276 #define IP_UDP_HDR_SIZE (sizeof(struct ip_udp_hdr))
277 #define UDP_HDR_SIZE (IP_UDP_HDR_SIZE - IP_HDR_SIZE) 277 #define UDP_HDR_SIZE (IP_UDP_HDR_SIZE - IP_HDR_SIZE)
278 278
279 /* 279 /*
280 * Address Resolution Protocol (ARP) header. 280 * Address Resolution Protocol (ARP) header.
281 */ 281 */
282 struct arp_hdr { 282 struct arp_hdr {
283 ushort ar_hrd; /* Format of hardware address */ 283 ushort ar_hrd; /* Format of hardware address */
284 # define ARP_ETHER 1 /* Ethernet hardware address */ 284 # define ARP_ETHER 1 /* Ethernet hardware address */
285 ushort ar_pro; /* Format of protocol address */ 285 ushort ar_pro; /* Format of protocol address */
286 uchar ar_hln; /* Length of hardware address */ 286 uchar ar_hln; /* Length of hardware address */
287 # define ARP_HLEN 6 287 # define ARP_HLEN 6
288 uchar ar_pln; /* Length of protocol address */ 288 uchar ar_pln; /* Length of protocol address */
289 # define ARP_PLEN 4 289 # define ARP_PLEN 4
290 ushort ar_op; /* Operation */ 290 ushort ar_op; /* Operation */
291 # define ARPOP_REQUEST 1 /* Request to resolve address */ 291 # define ARPOP_REQUEST 1 /* Request to resolve address */
292 # define ARPOP_REPLY 2 /* Response to previous request */ 292 # define ARPOP_REPLY 2 /* Response to previous request */
293 293
294 # define RARPOP_REQUEST 3 /* Request to resolve address */ 294 # define RARPOP_REQUEST 3 /* Request to resolve address */
295 # define RARPOP_REPLY 4 /* Response to previous request */ 295 # define RARPOP_REPLY 4 /* Response to previous request */
296 296
297 /* 297 /*
298 * The remaining fields are variable in size, according to 298 * The remaining fields are variable in size, according to
299 * the sizes above, and are defined as appropriate for 299 * the sizes above, and are defined as appropriate for
300 * specific hardware/protocol combinations. 300 * specific hardware/protocol combinations.
301 */ 301 */
302 uchar ar_data[0]; 302 uchar ar_data[0];
303 #define ar_sha ar_data[0] 303 #define ar_sha ar_data[0]
304 #define ar_spa ar_data[ARP_HLEN] 304 #define ar_spa ar_data[ARP_HLEN]
305 #define ar_tha ar_data[ARP_HLEN + ARP_PLEN] 305 #define ar_tha ar_data[ARP_HLEN + ARP_PLEN]
306 #define ar_tpa ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN] 306 #define ar_tpa ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN]
307 #if 0 307 #if 0
308 uchar ar_sha[]; /* Sender hardware address */ 308 uchar ar_sha[]; /* Sender hardware address */
309 uchar ar_spa[]; /* Sender protocol address */ 309 uchar ar_spa[]; /* Sender protocol address */
310 uchar ar_tha[]; /* Target hardware address */ 310 uchar ar_tha[]; /* Target hardware address */
311 uchar ar_tpa[]; /* Target protocol address */ 311 uchar ar_tpa[]; /* Target protocol address */
312 #endif /* 0 */ 312 #endif /* 0 */
313 }; 313 };
314 314
315 #define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */ 315 #define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */
316 316
317 /* 317 /*
318 * ICMP stuff (just enough to handle (host) redirect messages) 318 * ICMP stuff (just enough to handle (host) redirect messages)
319 */ 319 */
320 #define ICMP_ECHO_REPLY 0 /* Echo reply */ 320 #define ICMP_ECHO_REPLY 0 /* Echo reply */
321 #define ICMP_NOT_REACH 3 /* Detination unreachable */ 321 #define ICMP_NOT_REACH 3 /* Detination unreachable */
322 #define ICMP_REDIRECT 5 /* Redirect (change route) */ 322 #define ICMP_REDIRECT 5 /* Redirect (change route) */
323 #define ICMP_ECHO_REQUEST 8 /* Echo request */ 323 #define ICMP_ECHO_REQUEST 8 /* Echo request */
324 324
325 /* Codes for REDIRECT. */ 325 /* Codes for REDIRECT. */
326 #define ICMP_REDIR_NET 0 /* Redirect Net */ 326 #define ICMP_REDIR_NET 0 /* Redirect Net */
327 #define ICMP_REDIR_HOST 1 /* Redirect Host */ 327 #define ICMP_REDIR_HOST 1 /* Redirect Host */
328 328
329 /* Codes for NOT_REACH */ 329 /* Codes for NOT_REACH */
330 #define ICMP_NOT_REACH_PORT 3 /* Port unreachable */ 330 #define ICMP_NOT_REACH_PORT 3 /* Port unreachable */
331 331
332 struct icmp_hdr { 332 struct icmp_hdr {
333 uchar type; 333 uchar type;
334 uchar code; 334 uchar code;
335 ushort checksum; 335 ushort checksum;
336 union { 336 union {
337 struct { 337 struct {
338 ushort id; 338 ushort id;
339 ushort sequence; 339 ushort sequence;
340 } echo; 340 } echo;
341 ulong gateway; 341 ulong gateway;
342 struct { 342 struct {
343 ushort unused; 343 ushort unused;
344 ushort mtu; 344 ushort mtu;
345 } frag; 345 } frag;
346 uchar data[0]; 346 uchar data[0];
347 } un; 347 } un;
348 }; 348 };
349 349
350 #define ICMP_HDR_SIZE (sizeof(struct icmp_hdr)) 350 #define ICMP_HDR_SIZE (sizeof(struct icmp_hdr))
351 #define IP_ICMP_HDR_SIZE (IP_HDR_SIZE + ICMP_HDR_SIZE) 351 #define IP_ICMP_HDR_SIZE (IP_HDR_SIZE + ICMP_HDR_SIZE)
352 352
353 /* 353 /*
354 * Maximum packet size; used to allocate packet storage. 354 * Maximum packet size; used to allocate packet storage.
355 * TFTP packets can be 524 bytes + IP header + ethernet header. 355 * TFTP packets can be 524 bytes + IP header + ethernet header.
356 * Lets be conservative, and go for 38 * 16. (Must also be 356 * Lets be conservative, and go for 38 * 16. (Must also be
357 * a multiple of 32 bytes). 357 * a multiple of 32 bytes).
358 */ 358 */
359 /* 359 /*
360 * AS.HARNOIS : Better to set PKTSIZE to maximum size because 360 * AS.HARNOIS : Better to set PKTSIZE to maximum size because
361 * traffic type is not always controlled 361 * traffic type is not always controlled
362 * maximum packet size = 1518 362 * maximum packet size = 1518
363 * maximum packet size and multiple of 32 bytes = 1536 363 * maximum packet size and multiple of 32 bytes = 1536
364 */ 364 */
365 #define PKTSIZE 1518 365 #define PKTSIZE 1518
366 #define PKTSIZE_ALIGN 1536 366 #define PKTSIZE_ALIGN 1536
367 /*#define PKTSIZE 608*/ 367 /*#define PKTSIZE 608*/
368 368
369 /* 369 /*
370 * Maximum receive ring size; that is, the number of packets 370 * Maximum receive ring size; that is, the number of packets
371 * we can buffer before overflow happens. Basically, this just 371 * we can buffer before overflow happens. Basically, this just
372 * needs to be enough to prevent a packet being discarded while 372 * needs to be enough to prevent a packet being discarded while
373 * we are processing the previous one. 373 * we are processing the previous one.
374 */ 374 */
375 #define RINGSZ 4 375 #define RINGSZ 4
376 #define RINGSZ_LOG2 2 376 #define RINGSZ_LOG2 2
377 377
378 /**********************************************************************/ 378 /**********************************************************************/
379 /* 379 /*
380 * Globals. 380 * Globals.
381 * 381 *
382 * Note: 382 * Note:
383 * 383 *
384 * All variables of type IPaddr_t are stored in NETWORK byte order 384 * All variables of type IPaddr_t are stored in NETWORK byte order
385 * (big endian). 385 * (big endian).
386 */ 386 */
387 387
388 /* net.c */ 388 /* net.c */
389 /** BOOTP EXTENTIONS **/ 389 /** BOOTP EXTENTIONS **/
390 extern IPaddr_t NetOurGatewayIP; /* Our gateway IP address */ 390 extern IPaddr_t NetOurGatewayIP; /* Our gateway IP address */
391 extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown) */ 391 extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown) */
392 extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown) */ 392 extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown) */
393 #if defined(CONFIG_BOOTP_DNS2) 393 #if defined(CONFIG_BOOTP_DNS2)
394 extern IPaddr_t NetOurDNS2IP; /* Our 2nd Domain Name Server (0 = unknown) */ 394 extern IPaddr_t NetOurDNS2IP; /* Our 2nd Domain Name Server (0 = unknown) */
395 #endif 395 #endif
396 extern char NetOurNISDomain[32]; /* Our NIS domain */ 396 extern char NetOurNISDomain[32]; /* Our NIS domain */
397 extern char NetOurHostName[32]; /* Our hostname */ 397 extern char NetOurHostName[32]; /* Our hostname */
398 extern char NetOurRootPath[64]; /* Our root path */ 398 extern char NetOurRootPath[64]; /* Our root path */
399 extern ushort NetBootFileSize; /* Our boot file size in blocks */ 399 extern ushort NetBootFileSize; /* Our boot file size in blocks */
400 /** END OF BOOTP EXTENTIONS **/ 400 /** END OF BOOTP EXTENTIONS **/
401 extern ulong NetBootFileXferSize; /* size of bootfile in bytes */ 401 extern ulong NetBootFileXferSize; /* size of bootfile in bytes */
402 extern uchar NetOurEther[6]; /* Our ethernet address */ 402 extern uchar NetOurEther[6]; /* Our ethernet address */
403 extern uchar NetServerEther[6]; /* Boot server enet address */ 403 extern uchar NetServerEther[6]; /* Boot server enet address */
404 extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ 404 extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */
405 extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ 405 extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */
406 extern uchar *NetTxPacket; /* THE transmit packet */ 406 extern uchar *NetTxPacket; /* THE transmit packet */
407 extern uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ 407 extern uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */
408 extern uchar *NetRxPacket; /* Current receive packet */ 408 extern uchar *NetRxPacket; /* Current receive packet */
409 extern int NetRxPacketLen; /* Current rx packet length */ 409 extern int NetRxPacketLen; /* Current rx packet length */
410 extern unsigned NetIPID; /* IP ID (counting) */ 410 extern unsigned NetIPID; /* IP ID (counting) */
411 extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */ 411 extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */
412 extern uchar NetEtherNullAddr[6]; 412 extern uchar NetEtherNullAddr[6];
413 413
414 #define VLAN_NONE 4095 /* untagged */ 414 #define VLAN_NONE 4095 /* untagged */
415 #define VLAN_IDMASK 0x0fff /* mask of valid vlan id */ 415 #define VLAN_IDMASK 0x0fff /* mask of valid vlan id */
416 extern ushort NetOurVLAN; /* Our VLAN */ 416 extern ushort NetOurVLAN; /* Our VLAN */
417 extern ushort NetOurNativeVLAN; /* Our Native VLAN */ 417 extern ushort NetOurNativeVLAN; /* Our Native VLAN */
418 418
419 extern int NetRestartWrap; /* Tried all network devices */ 419 extern int NetRestartWrap; /* Tried all network devices */
420 420
421 enum proto_t { 421 enum proto_t {
422 BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, 422 BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
423 TFTPSRV, TFTPPUT, LINKLOCAL 423 TFTPSRV, TFTPPUT, LINKLOCAL
424 }; 424 };
425 425
426 /* from net/net.c */ 426 /* from net/net.c */
427 extern char BootFile[128]; /* Boot File name */ 427 extern char BootFile[128]; /* Boot File name */
428 428
429 #if defined(CONFIG_CMD_DNS) 429 #if defined(CONFIG_CMD_DNS)
430 extern char *NetDNSResolve; /* The host to resolve */ 430 extern char *NetDNSResolve; /* The host to resolve */
431 extern char *NetDNSenvvar; /* the env var to put the ip into */ 431 extern char *NetDNSenvvar; /* the env var to put the ip into */
432 #endif 432 #endif
433 433
434 #if defined(CONFIG_CMD_PING) 434 #if defined(CONFIG_CMD_PING)
435 extern IPaddr_t NetPingIP; /* the ip address to ping */ 435 extern IPaddr_t NetPingIP; /* the ip address to ping */
436 #endif 436 #endif
437 437
438 #if defined(CONFIG_CMD_CDP) 438 #if defined(CONFIG_CMD_CDP)
439 /* when CDP completes these hold the return values */ 439 /* when CDP completes these hold the return values */
440 extern ushort CDPNativeVLAN; /* CDP returned native VLAN */ 440 extern ushort CDPNativeVLAN; /* CDP returned native VLAN */
441 extern ushort CDPApplianceVLAN; /* CDP returned appliance VLAN */ 441 extern ushort CDPApplianceVLAN; /* CDP returned appliance VLAN */
442 442
443 /* 443 /*
444 * Check for a CDP packet by examining the received MAC address field 444 * Check for a CDP packet by examining the received MAC address field
445 */ 445 */
446 static inline int is_cdp_packet(const uchar *et_addr) 446 static inline int is_cdp_packet(const uchar *et_addr)
447 { 447 {
448 extern const uchar NetCDPAddr[6]; 448 extern const uchar NetCDPAddr[6];
449 449
450 return memcmp(et_addr, NetCDPAddr, 6) == 0; 450 return memcmp(et_addr, NetCDPAddr, 6) == 0;
451 } 451 }
452 #endif 452 #endif
453 453
454 #if defined(CONFIG_CMD_SNTP) 454 #if defined(CONFIG_CMD_SNTP)
455 extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */ 455 extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */
456 extern int NetTimeOffset; /* offset time from UTC */ 456 extern int NetTimeOffset; /* offset time from UTC */
457 #endif 457 #endif
458 458
459 #if defined(CONFIG_MCAST_TFTP) 459 #if defined(CONFIG_MCAST_TFTP)
460 extern IPaddr_t Mcast_addr; 460 extern IPaddr_t Mcast_addr;
461 #endif 461 #endif
462 462
463 /* Initialize the network adapter */ 463 /* Initialize the network adapter */
464 extern void net_init(void); 464 extern void net_init(void);
465 extern int NetLoop(enum proto_t); 465 extern int NetLoop(enum proto_t);
466 466
467 /* Shutdown adapters and cleanup */ 467 /* Shutdown adapters and cleanup */
468 extern void NetStop(void); 468 extern void NetStop(void);
469 469
470 /* Load failed. Start again. */ 470 /* Load failed. Start again. */
471 extern void NetStartAgain(void); 471 extern void NetStartAgain(void);
472 472
473 /* Get size of the ethernet header when we send */ 473 /* Get size of the ethernet header when we send */
474 extern int NetEthHdrSize(void); 474 extern int NetEthHdrSize(void);
475 475
476 /* Set ethernet header; returns the size of the header */ 476 /* Set ethernet header; returns the size of the header */
477 extern int NetSetEther(uchar *, uchar *, uint); 477 extern int NetSetEther(uchar *, uchar *, uint);
478 extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot); 478 extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
479 479
480 /* Set IP header */ 480 /* Set IP header */
481 extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source); 481 extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source);
482 extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, 482 extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
483 int sport, int len); 483 int sport, int len);
484 484
485 /* Checksum */ 485 /* Checksum */
486 extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ 486 extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */
487 extern uint NetCksum(uchar *, int); /* Calculate the checksum */ 487 extern uint NetCksum(uchar *, int); /* Calculate the checksum */
488 488
489 /* Callbacks */ 489 /* Callbacks */
490 extern rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */ 490 extern rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */
491 extern void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */ 491 extern void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */
492 extern rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */ 492 extern rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */
493 extern void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */ 493 extern void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */
494 extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */ 494 extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
495 extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */ 495 extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
496 496
497 /* Network loop state */ 497 /* Network loop state */
498 enum net_loop_state { 498 enum net_loop_state {
499 NETLOOP_CONTINUE, 499 NETLOOP_CONTINUE,
500 NETLOOP_RESTART, 500 NETLOOP_RESTART,
501 NETLOOP_SUCCESS, 501 NETLOOP_SUCCESS,
502 NETLOOP_FAIL 502 NETLOOP_FAIL
503 }; 503 };
504 extern enum net_loop_state net_state; 504 extern enum net_loop_state net_state;
505 505
506 static inline void net_set_state(enum net_loop_state state) 506 static inline void net_set_state(enum net_loop_state state)
507 { 507 {
508 debug_cond(DEBUG_INT_STATE, "--- NetState set to %d\n", state); 508 debug_cond(DEBUG_INT_STATE, "--- NetState set to %d\n", state);
509 net_state = state; 509 net_state = state;
510 } 510 }
511 511
512 /* Transmit a packet */ 512 /* Transmit a packet */
513 static inline void NetSendPacket(uchar *pkt, int len) 513 static inline void NetSendPacket(uchar *pkt, int len)
514 { 514 {
515 (void) eth_send(pkt, len); 515 (void) eth_send(pkt, len);
516 } 516 }
517 517
518 /* 518 /*
519 * Transmit "NetTxPacket" as UDP packet, performing ARP request if needed 519 * Transmit "NetTxPacket" as UDP packet, performing ARP request if needed
520 * (ether will be populated) 520 * (ether will be populated)
521 * 521 *
522 * @param ether Raw packet buffer 522 * @param ether Raw packet buffer
523 * @param dest IP address to send the datagram to 523 * @param dest IP address to send the datagram to
524 * @param dport Destination UDP port 524 * @param dport Destination UDP port
525 * @param sport Source UDP port 525 * @param sport Source UDP port
526 * @param payload_len Length of data after the UDP header 526 * @param payload_len Length of data after the UDP header
527 */ 527 */
528 extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, 528 extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport,
529 int sport, int payload_len); 529 int sport, int payload_len);
530 530
531 /* Processes a received packet */ 531 /* Processes a received packet */
532 extern void NetReceive(uchar *, int); 532 extern void NetReceive(uchar *, int);
533 533
534 #ifdef CONFIG_NETCONSOLE 534 #ifdef CONFIG_NETCONSOLE
535 void NcStart(void); 535 void NcStart(void);
536 int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, 536 int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
537 unsigned src_port, unsigned len); 537 unsigned src_port, unsigned len);
538 #endif 538 #endif
539 539
540 static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) 540 static inline __attribute__((always_inline)) int eth_is_on_demand_init(void)
541 { 541 {
542 #ifdef CONFIG_NETCONSOLE 542 #ifdef CONFIG_NETCONSOLE
543 extern enum proto_t net_loop_last_protocol; 543 extern enum proto_t net_loop_last_protocol;
544 544
545 return net_loop_last_protocol != NETCONS; 545 return net_loop_last_protocol != NETCONS;
546 #else 546 #else
547 return 1; 547 return 1;
548 #endif 548 #endif
549 } 549 }
550 550
551 static inline void eth_set_last_protocol(int protocol) 551 static inline void eth_set_last_protocol(int protocol)
552 { 552 {
553 #ifdef CONFIG_NETCONSOLE 553 #ifdef CONFIG_NETCONSOLE
554 extern enum proto_t net_loop_last_protocol; 554 extern enum proto_t net_loop_last_protocol;
555 555
556 net_loop_last_protocol = protocol; 556 net_loop_last_protocol = protocol;
557 #endif 557 #endif
558 } 558 }
559 559
560 /* 560 /*
561 * Check if autoload is enabled. If so, use either NFS or TFTP to download 561 * Check if autoload is enabled. If so, use either NFS or TFTP to download
562 * the boot file. 562 * the boot file.
563 */ 563 */
564 void net_auto_load(void); 564 void net_auto_load(void);
565 565
566 /* 566 /*
567 * The following functions are a bit ugly, but necessary to deal with 567 * The following functions are a bit ugly, but necessary to deal with
568 * alignment restrictions on ARM. 568 * alignment restrictions on ARM.
569 * 569 *
570 * We're using inline functions, which had the smallest memory 570 * We're using inline functions, which had the smallest memory
571 * footprint in our tests. 571 * footprint in our tests.
572 */ 572 */
573 /* return IP *in network byteorder* */ 573 /* return IP *in network byteorder* */
574 static inline IPaddr_t NetReadIP(void *from) 574 static inline IPaddr_t NetReadIP(void *from)
575 { 575 {
576 IPaddr_t ip; 576 IPaddr_t ip;
577 577
578 memcpy((void *)&ip, (void *)from, sizeof(ip)); 578 memcpy((void *)&ip, (void *)from, sizeof(ip));
579 return ip; 579 return ip;
580 } 580 }
581 581
582 /* return ulong *in network byteorder* */ 582 /* return ulong *in network byteorder* */
583 static inline ulong NetReadLong(ulong *from) 583 static inline ulong NetReadLong(ulong *from)
584 { 584 {
585 ulong l; 585 ulong l;
586 586
587 memcpy((void *)&l, (void *)from, sizeof(l)); 587 memcpy((void *)&l, (void *)from, sizeof(l));
588 return l; 588 return l;
589 } 589 }
590 590
591 /* write IP *in network byteorder* */ 591 /* write IP *in network byteorder* */
592 static inline void NetWriteIP(void *to, IPaddr_t ip) 592 static inline void NetWriteIP(void *to, IPaddr_t ip)
593 { 593 {
594 memcpy(to, (void *)&ip, sizeof(ip)); 594 memcpy(to, (void *)&ip, sizeof(ip));
595 } 595 }
596 596
597 /* copy IP */ 597 /* copy IP */
598 static inline void NetCopyIP(void *to, void *from) 598 static inline void NetCopyIP(void *to, void *from)
599 { 599 {
600 memcpy((void *)to, from, sizeof(IPaddr_t)); 600 memcpy((void *)to, from, sizeof(IPaddr_t));
601 } 601 }
602 602
603 /* copy ulong */ 603 /* copy ulong */
604 static inline void NetCopyLong(ulong *to, ulong *from) 604 static inline void NetCopyLong(ulong *to, ulong *from)
605 { 605 {
606 memcpy((void *)to, (void *)from, sizeof(ulong)); 606 memcpy((void *)to, (void *)from, sizeof(ulong));
607 } 607 }
608 608
609 /** 609 /**
610 * is_zero_ether_addr - Determine if give Ethernet address is all zeros. 610 * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
611 * @addr: Pointer to a six-byte array containing the Ethernet address 611 * @addr: Pointer to a six-byte array containing the Ethernet address
612 * 612 *
613 * Return true if the address is all zeroes. 613 * Return true if the address is all zeroes.
614 */ 614 */
615 static inline int is_zero_ether_addr(const u8 *addr) 615 static inline int is_zero_ether_addr(const u8 *addr)
616 { 616 {
617 return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); 617 return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
618 } 618 }
619 619
620 /** 620 /**
621 * is_multicast_ether_addr - Determine if the Ethernet address is a multicast. 621 * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
622 * @addr: Pointer to a six-byte array containing the Ethernet address 622 * @addr: Pointer to a six-byte array containing the Ethernet address
623 * 623 *
624 * Return true if the address is a multicast address. 624 * Return true if the address is a multicast address.
625 * By definition the broadcast address is also a multicast address. 625 * By definition the broadcast address is also a multicast address.
626 */ 626 */
627 static inline int is_multicast_ether_addr(const u8 *addr) 627 static inline int is_multicast_ether_addr(const u8 *addr)
628 { 628 {
629 return 0x01 & addr[0]; 629 return 0x01 & addr[0];
630 } 630 }
631 631
632 /* 632 /*
633 * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast 633 * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
634 * @addr: Pointer to a six-byte array containing the Ethernet address 634 * @addr: Pointer to a six-byte array containing the Ethernet address
635 * 635 *
636 * Return true if the address is the broadcast address. 636 * Return true if the address is the broadcast address.
637 */ 637 */
638 static inline int is_broadcast_ether_addr(const u8 *addr) 638 static inline int is_broadcast_ether_addr(const u8 *addr)
639 { 639 {
640 return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 640 return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
641 0xff; 641 0xff;
642 } 642 }
643 643
644 /* 644 /*
645 * is_valid_ether_addr - Determine if the given Ethernet address is valid 645 * is_valid_ether_addr - Determine if the given Ethernet address is valid
646 * @addr: Pointer to a six-byte array containing the Ethernet address 646 * @addr: Pointer to a six-byte array containing the Ethernet address
647 * 647 *
648 * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not 648 * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
649 * a multicast address, and is not FF:FF:FF:FF:FF:FF. 649 * a multicast address, and is not FF:FF:FF:FF:FF:FF.
650 * 650 *
651 * Return true if the address is valid. 651 * Return true if the address is valid.
652 */ 652 */
653 static inline int is_valid_ether_addr(const u8 *addr) 653 static inline int is_valid_ether_addr(const u8 *addr)
654 { 654 {
655 /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to 655 /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
656 * explicitly check for it here. */ 656 * explicitly check for it here. */
657 return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); 657 return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
658 } 658 }
659 659
660 /** 660 /**
661 * eth_random_addr - Generate software assigned random Ethernet address 661 * eth_random_addr - Generate software assigned random Ethernet address
662 * @addr: Pointer to a six-byte array containing the Ethernet address 662 * @addr: Pointer to a six-byte array containing the Ethernet address
663 * 663 *
664 * Generate a random Ethernet address (MAC) that is not multicast 664 * Generate a random Ethernet address (MAC) that is not multicast
665 * and has the local assigned bit set. 665 * and has the local assigned bit set.
666 */ 666 */
667 static inline void eth_random_addr(uchar *addr) 667 static inline void eth_random_addr(uchar *addr)
668 { 668 {
669 int i; 669 int i;
670 unsigned int seed = get_timer(0); 670 unsigned int seed = get_timer(0);
671 671
672 for (i = 0; i < 6; i++) 672 for (i = 0; i < 6; i++)
673 addr[i] = rand_r(&seed); 673 addr[i] = rand_r(&seed);
674 674
675 addr[0] &= 0xfe; /* clear multicast bit */ 675 addr[0] &= 0xfe; /* clear multicast bit */
676 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ 676 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
677 } 677 }
678 678
679 /* Convert an IP address to a string */ 679 /* Convert an IP address to a string */
680 extern void ip_to_string(IPaddr_t x, char *s); 680 extern void ip_to_string(IPaddr_t x, char *s);
681 681
682 /* Convert a string to ip address */ 682 /* Convert a string to ip address */
683 extern IPaddr_t string_to_ip(const char *s); 683 extern IPaddr_t string_to_ip(const char *s);
684 684
685 /* Convert a VLAN id to a string */ 685 /* Convert a VLAN id to a string */
686 extern void VLAN_to_string(ushort x, char *s); 686 extern void VLAN_to_string(ushort x, char *s);
687 687
688 /* Convert a string to a vlan id */ 688 /* Convert a string to a vlan id */
689 extern ushort string_to_VLAN(const char *s); 689 extern ushort string_to_VLAN(const char *s);
690 690
691 /* read a VLAN id from an environment variable */ 691 /* read a VLAN id from an environment variable */
692 extern ushort getenv_VLAN(char *); 692 extern ushort getenv_VLAN(char *);
693 693
694 /* copy a filename (allow for "..." notation, limit length) */ 694 /* copy a filename (allow for "..." notation, limit length) */
695 extern void copy_filename(char *dst, const char *src, int size); 695 extern void copy_filename(char *dst, const char *src, int size);
696 696
697 /* get a random source port */ 697 /* get a random source port */
698 extern unsigned int random_port(void); 698 extern unsigned int random_port(void);
699 699
700 /* Update U-Boot over TFTP */ 700 /* Update U-Boot over TFTP */
701 extern int update_tftp(ulong addr); 701 extern int update_tftp(ulong addr);
702 702
703 /**********************************************************************/ 703 /**********************************************************************/
704 704
705 #endif /* __NET_H__ */ 705 #endif /* __NET_H__ */
706 706
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #include <common.h> 12 #include <common.h>
12 13
13 #include "arp.h" 14 #include "arp.h"
14 15
15 #ifndef CONFIG_ARP_TIMEOUT 16 #ifndef CONFIG_ARP_TIMEOUT
16 /* Milliseconds before trying ARP again */ 17 /* Milliseconds before trying ARP again */
17 # define ARP_TIMEOUT 5000UL 18 # define ARP_TIMEOUT 5000UL
18 #else 19 #else
19 # define ARP_TIMEOUT CONFIG_ARP_TIMEOUT 20 # define ARP_TIMEOUT CONFIG_ARP_TIMEOUT
20 #endif 21 #endif
21 22
22 23
23 #ifndef CONFIG_NET_RETRY_COUNT 24 #ifndef CONFIG_NET_RETRY_COUNT
24 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ 25 # define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */
25 #else 26 #else
26 # define ARP_TIMEOUT_COUNT CONFIG_NET_RETRY_COUNT 27 # define ARP_TIMEOUT_COUNT CONFIG_NET_RETRY_COUNT
27 #endif 28 #endif
28 29
29 IPaddr_t NetArpWaitPacketIP; 30 IPaddr_t NetArpWaitPacketIP;
30 static IPaddr_t NetArpWaitReplyIP; 31 static IPaddr_t NetArpWaitReplyIP;
31 /* MAC address of waiting packet's destination */ 32 /* MAC address of waiting packet's destination */
32 uchar *NetArpWaitPacketMAC; 33 uchar *NetArpWaitPacketMAC;
33 int NetArpWaitTxPacketSize; 34 int NetArpWaitTxPacketSize;
34 ulong NetArpWaitTimerStart; 35 ulong NetArpWaitTimerStart;
35 int NetArpWaitTry; 36 int NetArpWaitTry;
36 37
37 static uchar *NetArpTxPacket; /* THE ARP transmit packet */ 38 static uchar *NetArpTxPacket; /* THE ARP transmit packet */
38 static uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; 39 static uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
39 40
40 void ArpInit(void) 41 void ArpInit(void)
41 { 42 {
42 /* XXX problem with bss workaround */ 43 /* XXX problem with bss workaround */
43 NetArpWaitPacketMAC = NULL; 44 NetArpWaitPacketMAC = NULL;
44 NetArpWaitPacketIP = 0; 45 NetArpWaitPacketIP = 0;
45 NetArpWaitReplyIP = 0; 46 NetArpWaitReplyIP = 0;
46 NetArpWaitTxPacketSize = 0; 47 NetArpWaitTxPacketSize = 0;
47 NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1); 48 NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1);
48 NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN; 49 NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN;
49 } 50 }
50 51
51 void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther, 52 void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
52 IPaddr_t targetIP) 53 IPaddr_t targetIP)
53 { 54 {
54 uchar *pkt; 55 uchar *pkt;
55 struct arp_hdr *arp; 56 struct arp_hdr *arp;
56 int eth_hdr_size; 57 int eth_hdr_size;
57 58
58 debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry); 59 debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry);
59 60
60 pkt = NetArpTxPacket; 61 pkt = NetArpTxPacket;
61 62
62 eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP); 63 eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP);
63 pkt += eth_hdr_size; 64 pkt += eth_hdr_size;
64 65
65 arp = (struct arp_hdr *) pkt; 66 arp = (struct arp_hdr *) pkt;
66 67
67 arp->ar_hrd = htons(ARP_ETHER); 68 arp->ar_hrd = htons(ARP_ETHER);
68 arp->ar_pro = htons(PROT_IP); 69 arp->ar_pro = htons(PROT_IP);
69 arp->ar_hln = ARP_HLEN; 70 arp->ar_hln = ARP_HLEN;
70 arp->ar_pln = ARP_PLEN; 71 arp->ar_pln = ARP_PLEN;
71 arp->ar_op = htons(ARPOP_REQUEST); 72 arp->ar_op = htons(ARPOP_REQUEST);
72 73
73 memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); /* source ET addr */ 74 memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); /* source ET addr */
74 NetWriteIP(&arp->ar_spa, sourceIP); /* source IP addr */ 75 NetWriteIP(&arp->ar_spa, sourceIP); /* source IP addr */
75 memcpy(&arp->ar_tha, targetEther, ARP_HLEN); /* target ET addr */ 76 memcpy(&arp->ar_tha, targetEther, ARP_HLEN); /* target ET addr */
76 NetWriteIP(&arp->ar_tpa, targetIP); /* target IP addr */ 77 NetWriteIP(&arp->ar_tpa, targetIP); /* target IP addr */
77 78
78 NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE); 79 NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE);
79 } 80 }
80 81
81 void ArpRequest(void) 82 void ArpRequest(void)
82 { 83 {
83 if ((NetArpWaitPacketIP & NetOurSubnetMask) != 84 if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
84 (NetOurIP & NetOurSubnetMask)) { 85 (NetOurIP & NetOurSubnetMask)) {
85 if (NetOurGatewayIP == 0) { 86 if (NetOurGatewayIP == 0) {
86 puts("## Warning: gatewayip needed but not set\n"); 87 puts("## Warning: gatewayip needed but not set\n");
87 NetArpWaitReplyIP = NetArpWaitPacketIP; 88 NetArpWaitReplyIP = NetArpWaitPacketIP;
88 } else { 89 } else {
89 NetArpWaitReplyIP = NetOurGatewayIP; 90 NetArpWaitReplyIP = NetOurGatewayIP;
90 } 91 }
91 } else { 92 } else {
92 NetArpWaitReplyIP = NetArpWaitPacketIP; 93 NetArpWaitReplyIP = NetArpWaitPacketIP;
93 } 94 }
94 95
95 arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP); 96 arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP);
96 } 97 }
97 98
98 void ArpTimeoutCheck(void) 99 void ArpTimeoutCheck(void)
99 { 100 {
100 ulong t; 101 ulong t;
101 102
102 if (!NetArpWaitPacketIP) 103 if (!NetArpWaitPacketIP)
103 return; 104 return;
104 105
105 t = get_timer(0); 106 t = get_timer(0);
106 107
107 /* check for arp timeout */ 108 /* check for arp timeout */
108 if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) { 109 if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
109 NetArpWaitTry++; 110 NetArpWaitTry++;
110 111
111 if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { 112 if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
112 puts("\nARP Retry count exceeded; starting again\n"); 113 puts("\nARP Retry count exceeded; starting again\n");
113 NetArpWaitTry = 0; 114 NetArpWaitTry = 0;
114 NetStartAgain(); 115 NetStartAgain();
115 } else { 116 } else {
116 NetArpWaitTimerStart = t; 117 NetArpWaitTimerStart = t;
117 ArpRequest(); 118 ArpRequest();
118 } 119 }
119 } 120 }
120 } 121 }
121 122
122 void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) 123 void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
123 { 124 {
124 struct arp_hdr *arp; 125 struct arp_hdr *arp;
125 IPaddr_t reply_ip_addr; 126 IPaddr_t reply_ip_addr;
126 uchar *pkt; 127 uchar *pkt;
127 int eth_hdr_size; 128 int eth_hdr_size;
128 129
129 /* 130 /*
130 * We have to deal with two types of ARP packets: 131 * We have to deal with two types of ARP packets:
131 * - REQUEST packets will be answered by sending our 132 * - REQUEST packets will be answered by sending our
132 * IP address - if we know it. 133 * IP address - if we know it.
133 * - REPLY packates are expected only after we asked 134 * - REPLY packates are expected only after we asked
134 * for the TFTP server's or the gateway's ethernet 135 * for the TFTP server's or the gateway's ethernet
135 * address; so if we receive such a packet, we set 136 * address; so if we receive such a packet, we set
136 * the server ethernet address 137 * the server ethernet address
137 */ 138 */
138 debug_cond(DEBUG_NET_PKT, "Got ARP\n"); 139 debug_cond(DEBUG_NET_PKT, "Got ARP\n");
139 140
140 arp = (struct arp_hdr *)ip; 141 arp = (struct arp_hdr *)ip;
141 if (len < ARP_HDR_SIZE) { 142 if (len < ARP_HDR_SIZE) {
142 printf("bad length %d < %d\n", len, ARP_HDR_SIZE); 143 printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
143 return; 144 return;
144 } 145 }
145 if (ntohs(arp->ar_hrd) != ARP_ETHER) 146 if (ntohs(arp->ar_hrd) != ARP_ETHER)
146 return; 147 return;
147 if (ntohs(arp->ar_pro) != PROT_IP) 148 if (ntohs(arp->ar_pro) != PROT_IP)
148 return; 149 return;
149 if (arp->ar_hln != ARP_HLEN) 150 if (arp->ar_hln != ARP_HLEN)
150 return; 151 return;
151 if (arp->ar_pln != ARP_PLEN) 152 if (arp->ar_pln != ARP_PLEN)
152 return; 153 return;
153 154
154 if (NetOurIP == 0) 155 if (NetOurIP == 0)
155 return; 156 return;
156 157
157 if (NetReadIP(&arp->ar_tpa) != NetOurIP) 158 if (NetReadIP(&arp->ar_tpa) != NetOurIP)
158 return; 159 return;
159 160
160 switch (ntohs(arp->ar_op)) { 161 switch (ntohs(arp->ar_op)) {
161 case ARPOP_REQUEST: 162 case ARPOP_REQUEST:
162 /* reply with our IP address */ 163 /* reply with our IP address */
163 debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP\n"); 164 debug_cond(DEBUG_DEV_PKT, "Got ARP REQUEST, return our IP\n");
164 pkt = (uchar *)et; 165 pkt = (uchar *)et;
165 eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP); 166 eth_hdr_size = net_update_ether(et, et->et_src, PROT_ARP);
166 pkt += eth_hdr_size; 167 pkt += eth_hdr_size;
167 arp->ar_op = htons(ARPOP_REPLY); 168 arp->ar_op = htons(ARPOP_REPLY);
168 memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN); 169 memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN);
169 NetCopyIP(&arp->ar_tpa, &arp->ar_spa); 170 NetCopyIP(&arp->ar_tpa, &arp->ar_spa);
170 memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); 171 memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);
171 NetCopyIP(&arp->ar_spa, &NetOurIP); 172 NetCopyIP(&arp->ar_spa, &NetOurIP);
172 173
173 #ifdef CONFIG_CMD_LINK_LOCAL 174 #ifdef CONFIG_CMD_LINK_LOCAL
174 /* 175 /*
175 * Work-around for brain-damaged Cisco equipment with 176 * Work-around for brain-damaged Cisco equipment with
176 * arp-proxy enabled. 177 * arp-proxy enabled.
177 * 178 *
178 * If the requesting IP is not on our subnet, wait 5ms to 179 * If the requesting IP is not on our subnet, wait 5ms to
179 * reply to ARP request so that our reply will overwrite 180 * reply to ARP request so that our reply will overwrite
180 * the arp-proxy's instead of the other way around. 181 * the arp-proxy's instead of the other way around.
181 */ 182 */
182 if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) != 183 if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) !=
183 (NetReadIP(&arp->ar_spa) & NetOurSubnetMask)) 184 (NetReadIP(&arp->ar_spa) & NetOurSubnetMask))
184 udelay(5000); 185 udelay(5000);
185 #endif 186 #endif
186 NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE); 187 NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
187 return; 188 return;
188 189
189 case ARPOP_REPLY: /* arp reply */ 190 case ARPOP_REPLY: /* arp reply */
190 /* are we waiting for a reply */ 191 /* are we waiting for a reply */
191 if (!NetArpWaitPacketIP) 192 if (!NetArpWaitPacketIP)
192 break; 193 break;
193 194
194 #ifdef CONFIG_KEEP_SERVERADDR 195 #ifdef CONFIG_KEEP_SERVERADDR
195 if (NetServerIP == NetArpWaitPacketIP) { 196 if (NetServerIP == NetArpWaitPacketIP) {
196 char buf[20]; 197 char buf[20];
197 sprintf(buf, "%pM", &arp->ar_sha); 198 sprintf(buf, "%pM", &arp->ar_sha);
198 setenv("serveraddr", buf); 199 setenv("serveraddr", buf);
199 } 200 }
200 #endif 201 #endif
201 202
202 reply_ip_addr = NetReadIP(&arp->ar_spa); 203 reply_ip_addr = NetReadIP(&arp->ar_spa);
203 204
204 /* matched waiting packet's address */ 205 /* matched waiting packet's address */
205 if (reply_ip_addr == NetArpWaitReplyIP) { 206 if (reply_ip_addr == NetArpWaitReplyIP) {
206 debug_cond(DEBUG_DEV_PKT, 207 debug_cond(DEBUG_DEV_PKT,
207 "Got ARP REPLY, set eth addr (%pM)\n", 208 "Got ARP REPLY, set eth addr (%pM)\n",
208 arp->ar_data); 209 arp->ar_data);
209 210
210 /* save address for later use */ 211 /* save address for later use */
211 if (NetArpWaitPacketMAC != NULL) 212 if (NetArpWaitPacketMAC != NULL)
212 memcpy(NetArpWaitPacketMAC, 213 memcpy(NetArpWaitPacketMAC,
213 &arp->ar_sha, ARP_HLEN); 214 &arp->ar_sha, ARP_HLEN);
214 215
215 net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr, 216 net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr,
216 0, len); 217 0, len);
217 218
218 /* set the mac address in the waiting packet's header 219 /* set the mac address in the waiting packet's header
219 and transmit it */ 220 and transmit it */
220 memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest, 221 memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest,
221 &arp->ar_sha, ARP_HLEN); 222 &arp->ar_sha, ARP_HLEN);
222 NetSendPacket(NetTxPacket, NetArpWaitTxPacketSize); 223 NetSendPacket(NetTxPacket, NetArpWaitTxPacketSize);
223 224
224 /* no arp request pending now */ 225 /* no arp request pending now */
225 NetArpWaitPacketIP = 0; 226 NetArpWaitPacketIP = 0;
226 NetArpWaitTxPacketSize = 0; 227 NetArpWaitTxPacketSize = 0;
227 NetArpWaitPacketMAC = NULL; 228 NetArpWaitPacketMAC = NULL;
228 229
229 } 230 }
230 return; 231 return;
231 default: 232 default:
232 debug("Unexpected ARP opcode 0x%x\n", 233 debug("Unexpected ARP opcode 0x%x\n",
233 ntohs(arp->ar_op)); 234 ntohs(arp->ar_op));
234 return; 235 return;
235 } 236 }
236 } 237 }
237 238
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #ifndef __ARP_H__ 12 #ifndef __ARP_H__
12 #define __ARP_H__ 13 #define __ARP_H__
13 14
14 #include <common.h> 15 #include <common.h>
15 16
16 extern IPaddr_t NetArpWaitPacketIP; 17 extern IPaddr_t NetArpWaitPacketIP;
17 /* MAC address of waiting packet's destination */ 18 /* MAC address of waiting packet's destination */
18 extern uchar *NetArpWaitPacketMAC; 19 extern uchar *NetArpWaitPacketMAC;
19 extern int NetArpWaitTxPacketSize; 20 extern int NetArpWaitTxPacketSize;
20 extern ulong NetArpWaitTimerStart; 21 extern ulong NetArpWaitTimerStart;
21 extern int NetArpWaitTry; 22 extern int NetArpWaitTry;
22 23
23 void ArpInit(void); 24 void ArpInit(void);
24 void ArpRequest(void); 25 void ArpRequest(void);
25 void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther, 26 void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
26 IPaddr_t targetIP); 27 IPaddr_t targetIP);
27 void ArpTimeoutCheck(void); 28 void ArpTimeoutCheck(void);
28 void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); 29 void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
29 30
30 #endif /* __ARP_H__ */ 31 #endif /* __ARP_H__ */
31 32
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #include <common.h> 12 #include <common.h>
12 #include <net.h> 13 #include <net.h>
13 #if defined(CONFIG_CDP_VERSION) 14 #if defined(CONFIG_CDP_VERSION)
14 #include <timestamp.h> 15 #include <timestamp.h>
15 #endif 16 #endif
16 17
17 #include "cdp.h" 18 #include "cdp.h"
18 19
19 /* Ethernet bcast address */ 20 /* Ethernet bcast address */
20 const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; 21 const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
21 22
22 #define CDP_DEVICE_ID_TLV 0x0001 23 #define CDP_DEVICE_ID_TLV 0x0001
23 #define CDP_ADDRESS_TLV 0x0002 24 #define CDP_ADDRESS_TLV 0x0002
24 #define CDP_PORT_ID_TLV 0x0003 25 #define CDP_PORT_ID_TLV 0x0003
25 #define CDP_CAPABILITIES_TLV 0x0004 26 #define CDP_CAPABILITIES_TLV 0x0004
26 #define CDP_VERSION_TLV 0x0005 27 #define CDP_VERSION_TLV 0x0005
27 #define CDP_PLATFORM_TLV 0x0006 28 #define CDP_PLATFORM_TLV 0x0006
28 #define CDP_NATIVE_VLAN_TLV 0x000a 29 #define CDP_NATIVE_VLAN_TLV 0x000a
29 #define CDP_APPLIANCE_VLAN_TLV 0x000e 30 #define CDP_APPLIANCE_VLAN_TLV 0x000e
30 #define CDP_TRIGGER_TLV 0x000f 31 #define CDP_TRIGGER_TLV 0x000f
31 #define CDP_POWER_CONSUMPTION_TLV 0x0010 32 #define CDP_POWER_CONSUMPTION_TLV 0x0010
32 #define CDP_SYSNAME_TLV 0x0014 33 #define CDP_SYSNAME_TLV 0x0014
33 #define CDP_SYSOBJECT_TLV 0x0015 34 #define CDP_SYSOBJECT_TLV 0x0015
34 #define CDP_MANAGEMENT_ADDRESS_TLV 0x0016 35 #define CDP_MANAGEMENT_ADDRESS_TLV 0x0016
35 36
36 #define CDP_TIMEOUT 250UL /* one packet every 250ms */ 37 #define CDP_TIMEOUT 250UL /* one packet every 250ms */
37 38
38 static int CDPSeq; 39 static int CDPSeq;
39 static int CDPOK; 40 static int CDPOK;
40 41
41 ushort CDPNativeVLAN; 42 ushort CDPNativeVLAN;
42 ushort CDPApplianceVLAN; 43 ushort CDPApplianceVLAN;
43 44
44 static const uchar CDP_SNAP_hdr[8] = { 45 static const uchar CDP_SNAP_hdr[8] = {
45 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 }; 46 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 };
46 47
47 static ushort 48 static ushort
48 CDP_compute_csum(const uchar *buff, ushort len) 49 CDP_compute_csum(const uchar *buff, ushort len)
49 { 50 {
50 ushort csum; 51 ushort csum;
51 int odd; 52 int odd;
52 ulong result = 0; 53 ulong result = 0;
53 ushort leftover; 54 ushort leftover;
54 ushort *p; 55 ushort *p;
55 56
56 if (len > 0) { 57 if (len > 0) {
57 odd = 1 & (ulong)buff; 58 odd = 1 & (ulong)buff;
58 if (odd) { 59 if (odd) {
59 result = *buff << 8; 60 result = *buff << 8;
60 len--; 61 len--;
61 buff++; 62 buff++;
62 } 63 }
63 while (len > 1) { 64 while (len > 1) {
64 p = (ushort *)buff; 65 p = (ushort *)buff;
65 result += *p++; 66 result += *p++;
66 buff = (uchar *)p; 67 buff = (uchar *)p;
67 if (result & 0x80000000) 68 if (result & 0x80000000)
68 result = (result & 0xFFFF) + (result >> 16); 69 result = (result & 0xFFFF) + (result >> 16);
69 len -= 2; 70 len -= 2;
70 } 71 }
71 if (len) { 72 if (len) {
72 leftover = (signed short)(*(const signed char *)buff); 73 leftover = (signed short)(*(const signed char *)buff);
73 /* 74 /*
74 * CISCO SUCKS big time! (and blows too): 75 * CISCO SUCKS big time! (and blows too):
75 * CDP uses the IP checksum algorithm with a twist; 76 * CDP uses the IP checksum algorithm with a twist;
76 * for the last byte it *sign* extends and sums. 77 * for the last byte it *sign* extends and sums.
77 */ 78 */
78 result = (result & 0xffff0000) | 79 result = (result & 0xffff0000) |
79 ((result + leftover) & 0x0000ffff); 80 ((result + leftover) & 0x0000ffff);
80 } 81 }
81 while (result >> 16) 82 while (result >> 16)
82 result = (result & 0xFFFF) + (result >> 16); 83 result = (result & 0xFFFF) + (result >> 16);
83 84
84 if (odd) 85 if (odd)
85 result = ((result >> 8) & 0xff) | 86 result = ((result >> 8) & 0xff) |
86 ((result & 0xff) << 8); 87 ((result & 0xff) << 8);
87 } 88 }
88 89
89 /* add up 16-bit and 17-bit words for 17+c bits */ 90 /* add up 16-bit and 17-bit words for 17+c bits */
90 result = (result & 0xffff) + (result >> 16); 91 result = (result & 0xffff) + (result >> 16);
91 /* add up 16-bit and 2-bit for 16+c bit */ 92 /* add up 16-bit and 2-bit for 16+c bit */
92 result = (result & 0xffff) + (result >> 16); 93 result = (result & 0xffff) + (result >> 16);
93 /* add up carry.. */ 94 /* add up carry.. */
94 result = (result & 0xffff) + (result >> 16); 95 result = (result & 0xffff) + (result >> 16);
95 96
96 /* negate */ 97 /* negate */
97 csum = ~(ushort)result; 98 csum = ~(ushort)result;
98 99
99 /* run time endian detection */ 100 /* run time endian detection */
100 if (csum != htons(csum)) /* little endian */ 101 if (csum != htons(csum)) /* little endian */
101 csum = htons(csum); 102 csum = htons(csum);
102 103
103 return csum; 104 return csum;
104 } 105 }
105 106
106 static int 107 static int
107 CDPSendTrigger(void) 108 CDPSendTrigger(void)
108 { 109 {
109 uchar *pkt; 110 uchar *pkt;
110 ushort *s; 111 ushort *s;
111 ushort *cp; 112 ushort *cp;
112 struct ethernet_hdr *et; 113 struct ethernet_hdr *et;
113 int len; 114 int len;
114 ushort chksum; 115 ushort chksum;
115 #if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \ 116 #if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \
116 defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM) 117 defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM)
117 char buf[32]; 118 char buf[32];
118 #endif 119 #endif
119 120
120 pkt = NetTxPacket; 121 pkt = NetTxPacket;
121 et = (struct ethernet_hdr *)pkt; 122 et = (struct ethernet_hdr *)pkt;
122 123
123 /* NOTE: trigger sent not on any VLAN */ 124 /* NOTE: trigger sent not on any VLAN */
124 125
125 /* form ethernet header */ 126 /* form ethernet header */
126 memcpy(et->et_dest, NetCDPAddr, 6); 127 memcpy(et->et_dest, NetCDPAddr, 6);
127 memcpy(et->et_src, NetOurEther, 6); 128 memcpy(et->et_src, NetOurEther, 6);
128 129
129 pkt += ETHER_HDR_SIZE; 130 pkt += ETHER_HDR_SIZE;
130 131
131 /* SNAP header */ 132 /* SNAP header */
132 memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)); 133 memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr));
133 pkt += sizeof(CDP_SNAP_hdr); 134 pkt += sizeof(CDP_SNAP_hdr);
134 135
135 /* CDP header */ 136 /* CDP header */
136 *pkt++ = 0x02; /* CDP version 2 */ 137 *pkt++ = 0x02; /* CDP version 2 */
137 *pkt++ = 180; /* TTL */ 138 *pkt++ = 180; /* TTL */
138 s = (ushort *)pkt; 139 s = (ushort *)pkt;
139 cp = s; 140 cp = s;
140 /* checksum (0 for later calculation) */ 141 /* checksum (0 for later calculation) */
141 *s++ = htons(0); 142 *s++ = htons(0);
142 143
143 /* CDP fields */ 144 /* CDP fields */
144 #ifdef CONFIG_CDP_DEVICE_ID 145 #ifdef CONFIG_CDP_DEVICE_ID
145 *s++ = htons(CDP_DEVICE_ID_TLV); 146 *s++ = htons(CDP_DEVICE_ID_TLV);
146 *s++ = htons(CONFIG_CDP_DEVICE_ID); 147 *s++ = htons(CONFIG_CDP_DEVICE_ID);
147 sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther); 148 sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther);
148 memcpy((uchar *)s, buf, 16); 149 memcpy((uchar *)s, buf, 16);
149 s += 16 / 2; 150 s += 16 / 2;
150 #endif 151 #endif
151 152
152 #ifdef CONFIG_CDP_PORT_ID 153 #ifdef CONFIG_CDP_PORT_ID
153 *s++ = htons(CDP_PORT_ID_TLV); 154 *s++ = htons(CDP_PORT_ID_TLV);
154 memset(buf, 0, sizeof(buf)); 155 memset(buf, 0, sizeof(buf));
155 sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index()); 156 sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index());
156 len = strlen(buf); 157 len = strlen(buf);
157 if (len & 1) /* make it even */ 158 if (len & 1) /* make it even */
158 len++; 159 len++;
159 *s++ = htons(len + 4); 160 *s++ = htons(len + 4);
160 memcpy((uchar *)s, buf, len); 161 memcpy((uchar *)s, buf, len);
161 s += len / 2; 162 s += len / 2;
162 #endif 163 #endif
163 164
164 #ifdef CONFIG_CDP_CAPABILITIES 165 #ifdef CONFIG_CDP_CAPABILITIES
165 *s++ = htons(CDP_CAPABILITIES_TLV); 166 *s++ = htons(CDP_CAPABILITIES_TLV);
166 *s++ = htons(8); 167 *s++ = htons(8);
167 *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES); 168 *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES);
168 s += 2; 169 s += 2;
169 #endif 170 #endif
170 171
171 #ifdef CONFIG_CDP_VERSION 172 #ifdef CONFIG_CDP_VERSION
172 *s++ = htons(CDP_VERSION_TLV); 173 *s++ = htons(CDP_VERSION_TLV);
173 memset(buf, 0, sizeof(buf)); 174 memset(buf, 0, sizeof(buf));
174 strcpy(buf, CONFIG_CDP_VERSION); 175 strcpy(buf, CONFIG_CDP_VERSION);
175 len = strlen(buf); 176 len = strlen(buf);
176 if (len & 1) /* make it even */ 177 if (len & 1) /* make it even */
177 len++; 178 len++;
178 *s++ = htons(len + 4); 179 *s++ = htons(len + 4);
179 memcpy((uchar *)s, buf, len); 180 memcpy((uchar *)s, buf, len);
180 s += len / 2; 181 s += len / 2;
181 #endif 182 #endif
182 183
183 #ifdef CONFIG_CDP_PLATFORM 184 #ifdef CONFIG_CDP_PLATFORM
184 *s++ = htons(CDP_PLATFORM_TLV); 185 *s++ = htons(CDP_PLATFORM_TLV);
185 memset(buf, 0, sizeof(buf)); 186 memset(buf, 0, sizeof(buf));
186 strcpy(buf, CONFIG_CDP_PLATFORM); 187 strcpy(buf, CONFIG_CDP_PLATFORM);
187 len = strlen(buf); 188 len = strlen(buf);
188 if (len & 1) /* make it even */ 189 if (len & 1) /* make it even */
189 len++; 190 len++;
190 *s++ = htons(len + 4); 191 *s++ = htons(len + 4);
191 memcpy((uchar *)s, buf, len); 192 memcpy((uchar *)s, buf, len);
192 s += len / 2; 193 s += len / 2;
193 #endif 194 #endif
194 195
195 #ifdef CONFIG_CDP_TRIGGER 196 #ifdef CONFIG_CDP_TRIGGER
196 *s++ = htons(CDP_TRIGGER_TLV); 197 *s++ = htons(CDP_TRIGGER_TLV);
197 *s++ = htons(8); 198 *s++ = htons(8);
198 *(ulong *)s = htonl(CONFIG_CDP_TRIGGER); 199 *(ulong *)s = htonl(CONFIG_CDP_TRIGGER);
199 s += 2; 200 s += 2;
200 #endif 201 #endif
201 202
202 #ifdef CONFIG_CDP_POWER_CONSUMPTION 203 #ifdef CONFIG_CDP_POWER_CONSUMPTION
203 *s++ = htons(CDP_POWER_CONSUMPTION_TLV); 204 *s++ = htons(CDP_POWER_CONSUMPTION_TLV);
204 *s++ = htons(6); 205 *s++ = htons(6);
205 *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION); 206 *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION);
206 #endif 207 #endif
207 208
208 /* length of ethernet packet */ 209 /* length of ethernet packet */
209 len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE); 210 len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE);
210 et->et_protlen = htons(len); 211 et->et_protlen = htons(len);
211 212
212 len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr); 213 len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr);
213 chksum = CDP_compute_csum((uchar *)NetTxPacket + len, 214 chksum = CDP_compute_csum((uchar *)NetTxPacket + len,
214 (uchar *)s - (NetTxPacket + len)); 215 (uchar *)s - (NetTxPacket + len));
215 if (chksum == 0) 216 if (chksum == 0)
216 chksum = 0xFFFF; 217 chksum = 0xFFFF;
217 *cp = htons(chksum); 218 *cp = htons(chksum);
218 219
219 NetSendPacket(NetTxPacket, (uchar *)s - NetTxPacket); 220 NetSendPacket(NetTxPacket, (uchar *)s - NetTxPacket);
220 return 0; 221 return 0;
221 } 222 }
222 223
223 static void 224 static void
224 CDPTimeout(void) 225 CDPTimeout(void)
225 { 226 {
226 CDPSeq++; 227 CDPSeq++;
227 228
228 if (CDPSeq < 3) { 229 if (CDPSeq < 3) {
229 NetSetTimeout(CDP_TIMEOUT, CDPTimeout); 230 NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
230 CDPSendTrigger(); 231 CDPSendTrigger();
231 return; 232 return;
232 } 233 }
233 234
234 /* if not OK try again */ 235 /* if not OK try again */
235 if (!CDPOK) 236 if (!CDPOK)
236 NetStartAgain(); 237 NetStartAgain();
237 else 238 else
238 net_set_state(NETLOOP_SUCCESS); 239 net_set_state(NETLOOP_SUCCESS);
239 } 240 }
240 241
241 void cdp_receive(const uchar *pkt, unsigned len) 242 void cdp_receive(const uchar *pkt, unsigned len)
242 { 243 {
243 const uchar *t; 244 const uchar *t;
244 const ushort *ss; 245 const ushort *ss;
245 ushort type, tlen; 246 ushort type, tlen;
246 ushort vlan, nvlan; 247 ushort vlan, nvlan;
247 248
248 /* minimum size? */ 249 /* minimum size? */
249 if (len < sizeof(CDP_SNAP_hdr) + 4) 250 if (len < sizeof(CDP_SNAP_hdr) + 4)
250 goto pkt_short; 251 goto pkt_short;
251 252
252 /* check for valid CDP SNAP header */ 253 /* check for valid CDP SNAP header */
253 if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0) 254 if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0)
254 return; 255 return;
255 256
256 pkt += sizeof(CDP_SNAP_hdr); 257 pkt += sizeof(CDP_SNAP_hdr);
257 len -= sizeof(CDP_SNAP_hdr); 258 len -= sizeof(CDP_SNAP_hdr);
258 259
259 /* Version of CDP protocol must be >= 2 and TTL != 0 */ 260 /* Version of CDP protocol must be >= 2 and TTL != 0 */
260 if (pkt[0] < 0x02 || pkt[1] == 0) 261 if (pkt[0] < 0x02 || pkt[1] == 0)
261 return; 262 return;
262 263
263 /* 264 /*
264 * if version is greater than 0x02 maybe we'll have a problem; 265 * if version is greater than 0x02 maybe we'll have a problem;
265 * output a warning 266 * output a warning
266 */ 267 */
267 if (pkt[0] != 0x02) 268 if (pkt[0] != 0x02)
268 printf("**WARNING: CDP packet received with a protocol version " 269 printf("**WARNING: CDP packet received with a protocol version "
269 "%d > 2\n", pkt[0] & 0xff); 270 "%d > 2\n", pkt[0] & 0xff);
270 271
271 if (CDP_compute_csum(pkt, len) != 0) 272 if (CDP_compute_csum(pkt, len) != 0)
272 return; 273 return;
273 274
274 pkt += 4; 275 pkt += 4;
275 len -= 4; 276 len -= 4;
276 277
277 vlan = htons(-1); 278 vlan = htons(-1);
278 nvlan = htons(-1); 279 nvlan = htons(-1);
279 while (len > 0) { 280 while (len > 0) {
280 if (len < 4) 281 if (len < 4)
281 goto pkt_short; 282 goto pkt_short;
282 283
283 ss = (const ushort *)pkt; 284 ss = (const ushort *)pkt;
284 type = ntohs(ss[0]); 285 type = ntohs(ss[0]);
285 tlen = ntohs(ss[1]); 286 tlen = ntohs(ss[1]);
286 if (tlen > len) 287 if (tlen > len)
287 goto pkt_short; 288 goto pkt_short;
288 289
289 pkt += tlen; 290 pkt += tlen;
290 len -= tlen; 291 len -= tlen;
291 292
292 ss += 2; /* point ss to the data of the TLV */ 293 ss += 2; /* point ss to the data of the TLV */
293 tlen -= 4; 294 tlen -= 4;
294 295
295 switch (type) { 296 switch (type) {
296 case CDP_DEVICE_ID_TLV: 297 case CDP_DEVICE_ID_TLV:
297 break; 298 break;
298 case CDP_ADDRESS_TLV: 299 case CDP_ADDRESS_TLV:
299 break; 300 break;
300 case CDP_PORT_ID_TLV: 301 case CDP_PORT_ID_TLV:
301 break; 302 break;
302 case CDP_CAPABILITIES_TLV: 303 case CDP_CAPABILITIES_TLV:
303 break; 304 break;
304 case CDP_VERSION_TLV: 305 case CDP_VERSION_TLV:
305 break; 306 break;
306 case CDP_PLATFORM_TLV: 307 case CDP_PLATFORM_TLV:
307 break; 308 break;
308 case CDP_NATIVE_VLAN_TLV: 309 case CDP_NATIVE_VLAN_TLV:
309 nvlan = *ss; 310 nvlan = *ss;
310 break; 311 break;
311 case CDP_APPLIANCE_VLAN_TLV: 312 case CDP_APPLIANCE_VLAN_TLV:
312 t = (const uchar *)ss; 313 t = (const uchar *)ss;
313 while (tlen > 0) { 314 while (tlen > 0) {
314 if (tlen < 3) 315 if (tlen < 3)
315 goto pkt_short; 316 goto pkt_short;
316 317
317 ss = (const ushort *)(t + 1); 318 ss = (const ushort *)(t + 1);
318 319
319 #ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE 320 #ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE
320 if (t[0] == CONFIG_CDP_APPLIANCE_VLAN_TYPE) 321 if (t[0] == CONFIG_CDP_APPLIANCE_VLAN_TYPE)
321 vlan = *ss; 322 vlan = *ss;
322 #else 323 #else
323 /* XXX will this work; dunno */ 324 /* XXX will this work; dunno */
324 vlan = ntohs(*ss); 325 vlan = ntohs(*ss);
325 #endif 326 #endif
326 t += 3; tlen -= 3; 327 t += 3; tlen -= 3;
327 } 328 }
328 break; 329 break;
329 case CDP_TRIGGER_TLV: 330 case CDP_TRIGGER_TLV:
330 break; 331 break;
331 case CDP_POWER_CONSUMPTION_TLV: 332 case CDP_POWER_CONSUMPTION_TLV:
332 break; 333 break;
333 case CDP_SYSNAME_TLV: 334 case CDP_SYSNAME_TLV:
334 break; 335 break;
335 case CDP_SYSOBJECT_TLV: 336 case CDP_SYSOBJECT_TLV:
336 break; 337 break;
337 case CDP_MANAGEMENT_ADDRESS_TLV: 338 case CDP_MANAGEMENT_ADDRESS_TLV:
338 break; 339 break;
339 } 340 }
340 } 341 }
341 342
342 CDPApplianceVLAN = vlan; 343 CDPApplianceVLAN = vlan;
343 CDPNativeVLAN = nvlan; 344 CDPNativeVLAN = nvlan;
344 345
345 CDPOK = 1; 346 CDPOK = 1;
346 return; 347 return;
347 348
348 pkt_short: 349 pkt_short:
349 printf("** CDP packet is too short\n"); 350 printf("** CDP packet is too short\n");
350 return; 351 return;
351 } 352 }
352 353
353 void 354 void
354 CDPStart(void) 355 CDPStart(void)
355 { 356 {
356 printf("Using %s device\n", eth_get_name()); 357 printf("Using %s device\n", eth_get_name());
357 CDPSeq = 0; 358 CDPSeq = 0;
358 CDPOK = 0; 359 CDPOK = 0;
359 360
360 CDPNativeVLAN = htons(-1); 361 CDPNativeVLAN = htons(-1);
361 CDPApplianceVLAN = htons(-1); 362 CDPApplianceVLAN = htons(-1);
362 363
363 NetSetTimeout(CDP_TIMEOUT, CDPTimeout); 364 NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
364 365
365 CDPSendTrigger(); 366 CDPSendTrigger();
366 } 367 }
367 368
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #if defined(CONFIG_CMD_CDP) 12 #if defined(CONFIG_CMD_CDP)
12 13
13 #ifndef __CDP_H__ 14 #ifndef __CDP_H__
14 #define __CDP_H__ 15 #define __CDP_H__
15 16
16 void CDPStart(void); 17 void CDPStart(void);
17 /* Process a received CDP packet */ 18 /* Process a received CDP packet */
18 void cdp_receive(const uchar *pkt, unsigned len); 19 void cdp_receive(const uchar *pkt, unsigned len);
19 20
20 #endif /* __CDP_H__ */ 21 #endif /* __CDP_H__ */
21 #endif 22 #endif
22 23
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 /* 12 /*
12 * General Desription: 13 * General Desription:
13 * 14 *
14 * The user interface supports commands for BOOTP, RARP, and TFTP. 15 * The user interface supports commands for BOOTP, RARP, and TFTP.
15 * Also, we support ARP internally. Depending on available data, 16 * Also, we support ARP internally. Depending on available data,
16 * these interact as follows: 17 * these interact as follows:
17 * 18 *
18 * BOOTP: 19 * BOOTP:
19 * 20 *
20 * Prerequisites: - own ethernet address 21 * Prerequisites: - own ethernet address
21 * We want: - own IP address 22 * We want: - own IP address
22 * - TFTP server IP address 23 * - TFTP server IP address
23 * - name of bootfile 24 * - name of bootfile
24 * Next step: ARP 25 * Next step: ARP
25 * 26 *
26 * LINK_LOCAL: 27 * LINK_LOCAL:
27 * 28 *
28 * Prerequisites: - own ethernet address 29 * Prerequisites: - own ethernet address
29 * We want: - own IP address 30 * We want: - own IP address
30 * Next step: ARP 31 * Next step: ARP
31 * 32 *
32 * RARP: 33 * RARP:
33 * 34 *
34 * Prerequisites: - own ethernet address 35 * Prerequisites: - own ethernet address
35 * We want: - own IP address 36 * We want: - own IP address
36 * - TFTP server IP address 37 * - TFTP server IP address
37 * Next step: ARP 38 * Next step: ARP
38 * 39 *
39 * ARP: 40 * ARP:
40 * 41 *
41 * Prerequisites: - own ethernet address 42 * Prerequisites: - own ethernet address
42 * - own IP address 43 * - own IP address
43 * - TFTP server IP address 44 * - TFTP server IP address
44 * We want: - TFTP server ethernet address 45 * We want: - TFTP server ethernet address
45 * Next step: TFTP 46 * Next step: TFTP
46 * 47 *
47 * DHCP: 48 * DHCP:
48 * 49 *
49 * Prerequisites: - own ethernet address 50 * Prerequisites: - own ethernet address
50 * We want: - IP, Netmask, ServerIP, Gateway IP 51 * We want: - IP, Netmask, ServerIP, Gateway IP
51 * - bootfilename, lease time 52 * - bootfilename, lease time
52 * Next step: - TFTP 53 * Next step: - TFTP
53 * 54 *
54 * TFTP: 55 * TFTP:
55 * 56 *
56 * Prerequisites: - own ethernet address 57 * Prerequisites: - own ethernet address
57 * - own IP address 58 * - own IP address
58 * - TFTP server IP address 59 * - TFTP server IP address
59 * - TFTP server ethernet address 60 * - TFTP server ethernet address
60 * - name of bootfile (if unknown, we use a default name 61 * - name of bootfile (if unknown, we use a default name
61 * derived from our own IP address) 62 * derived from our own IP address)
62 * We want: - load the boot file 63 * We want: - load the boot file
63 * Next step: none 64 * Next step: none
64 * 65 *
65 * NFS: 66 * NFS:
66 * 67 *
67 * Prerequisites: - own ethernet address 68 * Prerequisites: - own ethernet address
68 * - own IP address 69 * - own IP address
69 * - name of bootfile (if unknown, we use a default name 70 * - name of bootfile (if unknown, we use a default name
70 * derived from our own IP address) 71 * derived from our own IP address)
71 * We want: - load the boot file 72 * We want: - load the boot file
72 * Next step: none 73 * Next step: none
73 * 74 *
74 * SNTP: 75 * SNTP:
75 * 76 *
76 * Prerequisites: - own ethernet address 77 * Prerequisites: - own ethernet address
77 * - own IP address 78 * - own IP address
78 * We want: - network time 79 * We want: - network time
79 * Next step: none 80 * Next step: none
80 */ 81 */
81 82
82 83
83 #include <common.h> 84 #include <common.h>
84 #include <command.h> 85 #include <command.h>
85 #include <environment.h> 86 #include <environment.h>
86 #include <net.h> 87 #include <net.h>
87 #if defined(CONFIG_STATUS_LED) 88 #if defined(CONFIG_STATUS_LED)
88 #include <miiphy.h> 89 #include <miiphy.h>
89 #include <status_led.h> 90 #include <status_led.h>
90 #endif 91 #endif
91 #include <watchdog.h> 92 #include <watchdog.h>
92 #include <linux/compiler.h> 93 #include <linux/compiler.h>
93 #include "arp.h" 94 #include "arp.h"
94 #include "bootp.h" 95 #include "bootp.h"
95 #include "cdp.h" 96 #include "cdp.h"
96 #if defined(CONFIG_CMD_DNS) 97 #if defined(CONFIG_CMD_DNS)
97 #include "dns.h" 98 #include "dns.h"
98 #endif 99 #endif
99 #include "link_local.h" 100 #include "link_local.h"
100 #include "nfs.h" 101 #include "nfs.h"
101 #include "ping.h" 102 #include "ping.h"
102 #include "rarp.h" 103 #include "rarp.h"
103 #if defined(CONFIG_CMD_SNTP) 104 #if defined(CONFIG_CMD_SNTP)
104 #include "sntp.h" 105 #include "sntp.h"
105 #endif 106 #endif
106 #include "tftp.h" 107 #include "tftp.h"
107 108
108 DECLARE_GLOBAL_DATA_PTR; 109 DECLARE_GLOBAL_DATA_PTR;
109 110
110 /** BOOTP EXTENTIONS **/ 111 /** BOOTP EXTENTIONS **/
111 112
112 /* Our subnet mask (0=unknown) */ 113 /* Our subnet mask (0=unknown) */
113 IPaddr_t NetOurSubnetMask; 114 IPaddr_t NetOurSubnetMask;
114 /* Our gateways IP address */ 115 /* Our gateways IP address */
115 IPaddr_t NetOurGatewayIP; 116 IPaddr_t NetOurGatewayIP;
116 /* Our DNS IP address */ 117 /* Our DNS IP address */
117 IPaddr_t NetOurDNSIP; 118 IPaddr_t NetOurDNSIP;
118 #if defined(CONFIG_BOOTP_DNS2) 119 #if defined(CONFIG_BOOTP_DNS2)
119 /* Our 2nd DNS IP address */ 120 /* Our 2nd DNS IP address */
120 IPaddr_t NetOurDNS2IP; 121 IPaddr_t NetOurDNS2IP;
121 #endif 122 #endif
122 /* Our NIS domain */ 123 /* Our NIS domain */
123 char NetOurNISDomain[32] = {0,}; 124 char NetOurNISDomain[32] = {0,};
124 /* Our hostname */ 125 /* Our hostname */
125 char NetOurHostName[32] = {0,}; 126 char NetOurHostName[32] = {0,};
126 /* Our bootpath */ 127 /* Our bootpath */
127 char NetOurRootPath[64] = {0,}; 128 char NetOurRootPath[64] = {0,};
128 /* Our bootfile size in blocks */ 129 /* Our bootfile size in blocks */
129 ushort NetBootFileSize; 130 ushort NetBootFileSize;
130 131
131 #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */ 132 #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */
132 IPaddr_t Mcast_addr; 133 IPaddr_t Mcast_addr;
133 #endif 134 #endif
134 135
135 /** END OF BOOTP EXTENTIONS **/ 136 /** END OF BOOTP EXTENTIONS **/
136 137
137 /* The actual transferred size of the bootfile (in bytes) */ 138 /* The actual transferred size of the bootfile (in bytes) */
138 ulong NetBootFileXferSize; 139 ulong NetBootFileXferSize;
139 /* Our ethernet address */ 140 /* Our ethernet address */
140 uchar NetOurEther[6]; 141 uchar NetOurEther[6];
141 /* Boot server enet address */ 142 /* Boot server enet address */
142 uchar NetServerEther[6]; 143 uchar NetServerEther[6];
143 /* Our IP addr (0 = unknown) */ 144 /* Our IP addr (0 = unknown) */
144 IPaddr_t NetOurIP; 145 IPaddr_t NetOurIP;
145 /* Server IP addr (0 = unknown) */ 146 /* Server IP addr (0 = unknown) */
146 IPaddr_t NetServerIP; 147 IPaddr_t NetServerIP;
147 /* Current receive packet */ 148 /* Current receive packet */
148 uchar *NetRxPacket; 149 uchar *NetRxPacket;
149 /* Current rx packet length */ 150 /* Current rx packet length */
150 int NetRxPacketLen; 151 int NetRxPacketLen;
151 /* IP packet ID */ 152 /* IP packet ID */
152 unsigned NetIPID; 153 unsigned NetIPID;
153 /* Ethernet bcast address */ 154 /* Ethernet bcast address */
154 uchar NetBcastAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 155 uchar NetBcastAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
155 uchar NetEtherNullAddr[6]; 156 uchar NetEtherNullAddr[6];
156 #ifdef CONFIG_API 157 #ifdef CONFIG_API
157 void (*push_packet)(void *, int len) = 0; 158 void (*push_packet)(void *, int len) = 0;
158 #endif 159 #endif
159 /* Network loop state */ 160 /* Network loop state */
160 enum net_loop_state net_state; 161 enum net_loop_state net_state;
161 /* Tried all network devices */ 162 /* Tried all network devices */
162 int NetRestartWrap; 163 int NetRestartWrap;
163 /* Network loop restarted */ 164 /* Network loop restarted */
164 static int NetRestarted; 165 static int NetRestarted;
165 /* At least one device configured */ 166 /* At least one device configured */
166 static int NetDevExists; 167 static int NetDevExists;
167 168
168 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */ 169 /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
169 /* default is without VLAN */ 170 /* default is without VLAN */
170 ushort NetOurVLAN = 0xFFFF; 171 ushort NetOurVLAN = 0xFFFF;
171 /* ditto */ 172 /* ditto */
172 ushort NetOurNativeVLAN = 0xFFFF; 173 ushort NetOurNativeVLAN = 0xFFFF;
173 174
174 /* Boot File name */ 175 /* Boot File name */
175 char BootFile[128]; 176 char BootFile[128];
176 177
177 #if defined(CONFIG_CMD_SNTP) 178 #if defined(CONFIG_CMD_SNTP)
178 /* NTP server IP address */ 179 /* NTP server IP address */
179 IPaddr_t NetNtpServerIP; 180 IPaddr_t NetNtpServerIP;
180 /* offset time from UTC */ 181 /* offset time from UTC */
181 int NetTimeOffset; 182 int NetTimeOffset;
182 #endif 183 #endif
183 184
184 static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; 185 static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
185 186
186 /* Receive packet */ 187 /* Receive packet */
187 uchar *NetRxPackets[PKTBUFSRX]; 188 uchar *NetRxPackets[PKTBUFSRX];
188 189
189 /* Current UDP RX packet handler */ 190 /* Current UDP RX packet handler */
190 static rxhand_f *udp_packet_handler; 191 static rxhand_f *udp_packet_handler;
191 /* Current ARP RX packet handler */ 192 /* Current ARP RX packet handler */
192 static rxhand_f *arp_packet_handler; 193 static rxhand_f *arp_packet_handler;
193 #ifdef CONFIG_CMD_TFTPPUT 194 #ifdef CONFIG_CMD_TFTPPUT
194 /* Current ICMP rx handler */ 195 /* Current ICMP rx handler */
195 static rxhand_icmp_f *packet_icmp_handler; 196 static rxhand_icmp_f *packet_icmp_handler;
196 #endif 197 #endif
197 /* Current timeout handler */ 198 /* Current timeout handler */
198 static thand_f *timeHandler; 199 static thand_f *timeHandler;
199 /* Time base value */ 200 /* Time base value */
200 static ulong timeStart; 201 static ulong timeStart;
201 /* Current timeout value */ 202 /* Current timeout value */
202 static ulong timeDelta; 203 static ulong timeDelta;
203 /* THE transmit packet */ 204 /* THE transmit packet */
204 uchar *NetTxPacket; 205 uchar *NetTxPacket;
205 206
206 static int net_check_prereq(enum proto_t protocol); 207 static int net_check_prereq(enum proto_t protocol);
207 208
208 static int NetTryCount; 209 static int NetTryCount;
209 210
210 int __maybe_unused net_busy_flag; 211 int __maybe_unused net_busy_flag;
211 212
212 /**********************************************************************/ 213 /**********************************************************************/
213 214
214 static int on_bootfile(const char *name, const char *value, enum env_op op, 215 static int on_bootfile(const char *name, const char *value, enum env_op op,
215 int flags) 216 int flags)
216 { 217 {
217 switch (op) { 218 switch (op) {
218 case env_op_create: 219 case env_op_create:
219 case env_op_overwrite: 220 case env_op_overwrite:
220 copy_filename(BootFile, value, sizeof(BootFile)); 221 copy_filename(BootFile, value, sizeof(BootFile));
221 break; 222 break;
222 default: 223 default:
223 break; 224 break;
224 } 225 }
225 226
226 return 0; 227 return 0;
227 } 228 }
228 U_BOOT_ENV_CALLBACK(bootfile, on_bootfile); 229 U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
229 230
230 /* 231 /*
231 * Check if autoload is enabled. If so, use either NFS or TFTP to download 232 * Check if autoload is enabled. If so, use either NFS or TFTP to download
232 * the boot file. 233 * the boot file.
233 */ 234 */
234 void net_auto_load(void) 235 void net_auto_load(void)
235 { 236 {
236 #if defined(CONFIG_CMD_NFS) 237 #if defined(CONFIG_CMD_NFS)
237 const char *s = getenv("autoload"); 238 const char *s = getenv("autoload");
238 239
239 if (s != NULL && strcmp(s, "NFS") == 0) { 240 if (s != NULL && strcmp(s, "NFS") == 0) {
240 /* 241 /*
241 * Use NFS to load the bootfile. 242 * Use NFS to load the bootfile.
242 */ 243 */
243 NfsStart(); 244 NfsStart();
244 return; 245 return;
245 } 246 }
246 #endif 247 #endif
247 if (getenv_yesno("autoload") == 0) { 248 if (getenv_yesno("autoload") == 0) {
248 /* 249 /*
249 * Just use BOOTP/RARP to configure system; 250 * Just use BOOTP/RARP to configure system;
250 * Do not use TFTP to load the bootfile. 251 * Do not use TFTP to load the bootfile.
251 */ 252 */
252 net_set_state(NETLOOP_SUCCESS); 253 net_set_state(NETLOOP_SUCCESS);
253 return; 254 return;
254 } 255 }
255 TftpStart(TFTPGET); 256 TftpStart(TFTPGET);
256 } 257 }
257 258
258 static void NetInitLoop(void) 259 static void NetInitLoop(void)
259 { 260 {
260 static int env_changed_id; 261 static int env_changed_id;
261 int env_id = get_env_id(); 262 int env_id = get_env_id();
262 263
263 /* update only when the environment has changed */ 264 /* update only when the environment has changed */
264 if (env_changed_id != env_id) { 265 if (env_changed_id != env_id) {
265 NetOurIP = getenv_IPaddr("ipaddr"); 266 NetOurIP = getenv_IPaddr("ipaddr");
266 NetOurGatewayIP = getenv_IPaddr("gatewayip"); 267 NetOurGatewayIP = getenv_IPaddr("gatewayip");
267 NetOurSubnetMask = getenv_IPaddr("netmask"); 268 NetOurSubnetMask = getenv_IPaddr("netmask");
268 NetServerIP = getenv_IPaddr("serverip"); 269 NetServerIP = getenv_IPaddr("serverip");
269 NetOurNativeVLAN = getenv_VLAN("nvlan"); 270 NetOurNativeVLAN = getenv_VLAN("nvlan");
270 NetOurVLAN = getenv_VLAN("vlan"); 271 NetOurVLAN = getenv_VLAN("vlan");
271 #if defined(CONFIG_CMD_DNS) 272 #if defined(CONFIG_CMD_DNS)
272 NetOurDNSIP = getenv_IPaddr("dnsip"); 273 NetOurDNSIP = getenv_IPaddr("dnsip");
273 #endif 274 #endif
274 env_changed_id = env_id; 275 env_changed_id = env_id;
275 } 276 }
276 if (eth_get_dev()) 277 if (eth_get_dev())
277 memcpy(NetOurEther, eth_get_dev()->enetaddr, 6); 278 memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
278 279
279 return; 280 return;
280 } 281 }
281 282
282 static void net_clear_handlers(void) 283 static void net_clear_handlers(void)
283 { 284 {
284 net_set_udp_handler(NULL); 285 net_set_udp_handler(NULL);
285 net_set_arp_handler(NULL); 286 net_set_arp_handler(NULL);
286 NetSetTimeout(0, NULL); 287 NetSetTimeout(0, NULL);
287 } 288 }
288 289
289 static void net_cleanup_loop(void) 290 static void net_cleanup_loop(void)
290 { 291 {
291 net_clear_handlers(); 292 net_clear_handlers();
292 } 293 }
293 294
294 void net_init(void) 295 void net_init(void)
295 { 296 {
296 static int first_call = 1; 297 static int first_call = 1;
297 298
298 if (first_call) { 299 if (first_call) {
299 /* 300 /*
300 * Setup packet buffers, aligned correctly. 301 * Setup packet buffers, aligned correctly.
301 */ 302 */
302 int i; 303 int i;
303 304
304 NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); 305 NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
305 NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; 306 NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
306 for (i = 0; i < PKTBUFSRX; i++) 307 for (i = 0; i < PKTBUFSRX; i++)
307 NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN; 308 NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;
308 309
309 ArpInit(); 310 ArpInit();
310 net_clear_handlers(); 311 net_clear_handlers();
311 312
312 /* Only need to setup buffer pointers once. */ 313 /* Only need to setup buffer pointers once. */
313 first_call = 0; 314 first_call = 0;
314 } 315 }
315 316
316 NetInitLoop(); 317 NetInitLoop();
317 } 318 }
318 319
319 /**********************************************************************/ 320 /**********************************************************************/
320 /* 321 /*
321 * Main network processing loop. 322 * Main network processing loop.
322 */ 323 */
323 324
324 int NetLoop(enum proto_t protocol) 325 int NetLoop(enum proto_t protocol)
325 { 326 {
326 bd_t *bd = gd->bd; 327 bd_t *bd = gd->bd;
327 int ret = -1; 328 int ret = -1;
328 329
329 NetRestarted = 0; 330 NetRestarted = 0;
330 NetDevExists = 0; 331 NetDevExists = 0;
331 NetTryCount = 1; 332 NetTryCount = 1;
332 debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); 333 debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n");
333 334
334 bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); 335 bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
335 net_init(); 336 net_init();
336 if (eth_is_on_demand_init() || protocol != NETCONS) { 337 if (eth_is_on_demand_init() || protocol != NETCONS) {
337 eth_halt(); 338 eth_halt();
338 eth_set_current(); 339 eth_set_current();
339 if (eth_init(bd) < 0) { 340 if (eth_init(bd) < 0) {
340 eth_halt(); 341 eth_halt();
341 return -1; 342 return -1;
342 } 343 }
343 } else 344 } else
344 eth_init_state_only(bd); 345 eth_init_state_only(bd);
345 346
346 restart: 347 restart:
347 #ifdef CONFIG_USB_KEYBOARD 348 #ifdef CONFIG_USB_KEYBOARD
348 net_busy_flag = 0; 349 net_busy_flag = 0;
349 #endif 350 #endif
350 net_set_state(NETLOOP_CONTINUE); 351 net_set_state(NETLOOP_CONTINUE);
351 352
352 /* 353 /*
353 * Start the ball rolling with the given start function. From 354 * Start the ball rolling with the given start function. From
354 * here on, this code is a state machine driven by received 355 * here on, this code is a state machine driven by received
355 * packets and timer events. 356 * packets and timer events.
356 */ 357 */
357 debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); 358 debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n");
358 NetInitLoop(); 359 NetInitLoop();
359 360
360 switch (net_check_prereq(protocol)) { 361 switch (net_check_prereq(protocol)) {
361 case 1: 362 case 1:
362 /* network not configured */ 363 /* network not configured */
363 eth_halt(); 364 eth_halt();
364 return -1; 365 return -1;
365 366
366 case 2: 367 case 2:
367 /* network device not configured */ 368 /* network device not configured */
368 break; 369 break;
369 370
370 case 0: 371 case 0:
371 NetDevExists = 1; 372 NetDevExists = 1;
372 NetBootFileXferSize = 0; 373 NetBootFileXferSize = 0;
373 switch (protocol) { 374 switch (protocol) {
374 case TFTPGET: 375 case TFTPGET:
375 #ifdef CONFIG_CMD_TFTPPUT 376 #ifdef CONFIG_CMD_TFTPPUT
376 case TFTPPUT: 377 case TFTPPUT:
377 #endif 378 #endif
378 /* always use ARP to get server ethernet address */ 379 /* always use ARP to get server ethernet address */
379 TftpStart(protocol); 380 TftpStart(protocol);
380 break; 381 break;
381 #ifdef CONFIG_CMD_TFTPSRV 382 #ifdef CONFIG_CMD_TFTPSRV
382 case TFTPSRV: 383 case TFTPSRV:
383 TftpStartServer(); 384 TftpStartServer();
384 break; 385 break;
385 #endif 386 #endif
386 #if defined(CONFIG_CMD_DHCP) 387 #if defined(CONFIG_CMD_DHCP)
387 case DHCP: 388 case DHCP:
388 BootpReset(); 389 BootpReset();
389 NetOurIP = 0; 390 NetOurIP = 0;
390 DhcpRequest(); /* Basically same as BOOTP */ 391 DhcpRequest(); /* Basically same as BOOTP */
391 break; 392 break;
392 #endif 393 #endif
393 394
394 case BOOTP: 395 case BOOTP:
395 BootpReset(); 396 BootpReset();
396 NetOurIP = 0; 397 NetOurIP = 0;
397 BootpRequest(); 398 BootpRequest();
398 break; 399 break;
399 400
400 #if defined(CONFIG_CMD_RARP) 401 #if defined(CONFIG_CMD_RARP)
401 case RARP: 402 case RARP:
402 RarpTry = 0; 403 RarpTry = 0;
403 NetOurIP = 0; 404 NetOurIP = 0;
404 RarpRequest(); 405 RarpRequest();
405 break; 406 break;
406 #endif 407 #endif
407 #if defined(CONFIG_CMD_PING) 408 #if defined(CONFIG_CMD_PING)
408 case PING: 409 case PING:
409 ping_start(); 410 ping_start();
410 break; 411 break;
411 #endif 412 #endif
412 #if defined(CONFIG_CMD_NFS) 413 #if defined(CONFIG_CMD_NFS)
413 case NFS: 414 case NFS:
414 NfsStart(); 415 NfsStart();
415 break; 416 break;
416 #endif 417 #endif
417 #if defined(CONFIG_CMD_CDP) 418 #if defined(CONFIG_CMD_CDP)
418 case CDP: 419 case CDP:
419 CDPStart(); 420 CDPStart();
420 break; 421 break;
421 #endif 422 #endif
422 #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) 423 #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
423 case NETCONS: 424 case NETCONS:
424 NcStart(); 425 NcStart();
425 break; 426 break;
426 #endif 427 #endif
427 #if defined(CONFIG_CMD_SNTP) 428 #if defined(CONFIG_CMD_SNTP)
428 case SNTP: 429 case SNTP:
429 SntpStart(); 430 SntpStart();
430 break; 431 break;
431 #endif 432 #endif
432 #if defined(CONFIG_CMD_DNS) 433 #if defined(CONFIG_CMD_DNS)
433 case DNS: 434 case DNS:
434 DnsStart(); 435 DnsStart();
435 break; 436 break;
436 #endif 437 #endif
437 #if defined(CONFIG_CMD_LINK_LOCAL) 438 #if defined(CONFIG_CMD_LINK_LOCAL)
438 case LINKLOCAL: 439 case LINKLOCAL:
439 link_local_start(); 440 link_local_start();
440 break; 441 break;
441 #endif 442 #endif
442 default: 443 default:
443 break; 444 break;
444 } 445 }
445 446
446 break; 447 break;
447 } 448 }
448 449
449 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 450 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
450 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ 451 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \
451 defined(CONFIG_STATUS_LED) && \ 452 defined(CONFIG_STATUS_LED) && \
452 defined(STATUS_LED_RED) 453 defined(STATUS_LED_RED)
453 /* 454 /*
454 * Echo the inverted link state to the fault LED. 455 * Echo the inverted link state to the fault LED.
455 */ 456 */
456 if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) 457 if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR))
457 status_led_set(STATUS_LED_RED, STATUS_LED_OFF); 458 status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
458 else 459 else
459 status_led_set(STATUS_LED_RED, STATUS_LED_ON); 460 status_led_set(STATUS_LED_RED, STATUS_LED_ON);
460 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ 461 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
461 #endif /* CONFIG_MII, ... */ 462 #endif /* CONFIG_MII, ... */
462 #ifdef CONFIG_USB_KEYBOARD 463 #ifdef CONFIG_USB_KEYBOARD
463 net_busy_flag = 1; 464 net_busy_flag = 1;
464 #endif 465 #endif
465 466
466 /* 467 /*
467 * Main packet reception loop. Loop receiving packets until 468 * Main packet reception loop. Loop receiving packets until
468 * someone sets `net_state' to a state that terminates. 469 * someone sets `net_state' to a state that terminates.
469 */ 470 */
470 for (;;) { 471 for (;;) {
471 WATCHDOG_RESET(); 472 WATCHDOG_RESET();
472 #ifdef CONFIG_SHOW_ACTIVITY 473 #ifdef CONFIG_SHOW_ACTIVITY
473 show_activity(1); 474 show_activity(1);
474 #endif 475 #endif
475 /* 476 /*
476 * Check the ethernet for a new packet. The ethernet 477 * Check the ethernet for a new packet. The ethernet
477 * receive routine will process it. 478 * receive routine will process it.
478 */ 479 */
479 eth_rx(); 480 eth_rx();
480 481
481 /* 482 /*
482 * Abort if ctrl-c was pressed. 483 * Abort if ctrl-c was pressed.
483 */ 484 */
484 if (ctrlc()) { 485 if (ctrlc()) {
485 /* cancel any ARP that may not have completed */ 486 /* cancel any ARP that may not have completed */
486 NetArpWaitPacketIP = 0; 487 NetArpWaitPacketIP = 0;
487 488
488 net_cleanup_loop(); 489 net_cleanup_loop();
489 eth_halt(); 490 eth_halt();
490 /* Invalidate the last protocol */ 491 /* Invalidate the last protocol */
491 eth_set_last_protocol(BOOTP); 492 eth_set_last_protocol(BOOTP);
492 493
493 puts("\nAbort\n"); 494 puts("\nAbort\n");
494 /* include a debug print as well incase the debug 495 /* include a debug print as well incase the debug
495 messages are directed to stderr */ 496 messages are directed to stderr */
496 debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); 497 debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n");
497 goto done; 498 goto done;
498 } 499 }
499 500
500 ArpTimeoutCheck(); 501 ArpTimeoutCheck();
501 502
502 /* 503 /*
503 * Check for a timeout, and run the timeout handler 504 * Check for a timeout, and run the timeout handler
504 * if we have one. 505 * if we have one.
505 */ 506 */
506 if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { 507 if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
507 thand_f *x; 508 thand_f *x;
508 509
509 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 510 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
510 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ 511 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \
511 defined(CONFIG_STATUS_LED) && \ 512 defined(CONFIG_STATUS_LED) && \
512 defined(STATUS_LED_RED) 513 defined(STATUS_LED_RED)
513 /* 514 /*
514 * Echo the inverted link state to the fault LED. 515 * Echo the inverted link state to the fault LED.
515 */ 516 */
516 if (miiphy_link(eth_get_dev()->name, 517 if (miiphy_link(eth_get_dev()->name,
517 CONFIG_SYS_FAULT_MII_ADDR)) { 518 CONFIG_SYS_FAULT_MII_ADDR)) {
518 status_led_set(STATUS_LED_RED, STATUS_LED_OFF); 519 status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
519 } else { 520 } else {
520 status_led_set(STATUS_LED_RED, STATUS_LED_ON); 521 status_led_set(STATUS_LED_RED, STATUS_LED_ON);
521 } 522 }
522 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ 523 #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
523 #endif /* CONFIG_MII, ... */ 524 #endif /* CONFIG_MII, ... */
524 debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); 525 debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n");
525 x = timeHandler; 526 x = timeHandler;
526 timeHandler = (thand_f *)0; 527 timeHandler = (thand_f *)0;
527 (*x)(); 528 (*x)();
528 } 529 }
529 530
530 531
531 switch (net_state) { 532 switch (net_state) {
532 533
533 case NETLOOP_RESTART: 534 case NETLOOP_RESTART:
534 NetRestarted = 1; 535 NetRestarted = 1;
535 goto restart; 536 goto restart;
536 537
537 case NETLOOP_SUCCESS: 538 case NETLOOP_SUCCESS:
538 net_cleanup_loop(); 539 net_cleanup_loop();
539 if (NetBootFileXferSize > 0) { 540 if (NetBootFileXferSize > 0) {
540 printf("Bytes transferred = %ld (%lx hex)\n", 541 printf("Bytes transferred = %ld (%lx hex)\n",
541 NetBootFileXferSize, 542 NetBootFileXferSize,
542 NetBootFileXferSize); 543 NetBootFileXferSize);
543 setenv_hex("filesize", NetBootFileXferSize); 544 setenv_hex("filesize", NetBootFileXferSize);
544 setenv_hex("fileaddr", load_addr); 545 setenv_hex("fileaddr", load_addr);
545 } 546 }
546 if (protocol != NETCONS) 547 if (protocol != NETCONS)
547 eth_halt(); 548 eth_halt();
548 else 549 else
549 eth_halt_state_only(); 550 eth_halt_state_only();
550 551
551 eth_set_last_protocol(protocol); 552 eth_set_last_protocol(protocol);
552 553
553 ret = NetBootFileXferSize; 554 ret = NetBootFileXferSize;
554 debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); 555 debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
555 goto done; 556 goto done;
556 557
557 case NETLOOP_FAIL: 558 case NETLOOP_FAIL:
558 net_cleanup_loop(); 559 net_cleanup_loop();
559 /* Invalidate the last protocol */ 560 /* Invalidate the last protocol */
560 eth_set_last_protocol(BOOTP); 561 eth_set_last_protocol(BOOTP);
561 debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); 562 debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
562 goto done; 563 goto done;
563 564
564 case NETLOOP_CONTINUE: 565 case NETLOOP_CONTINUE:
565 continue; 566 continue;
566 } 567 }
567 } 568 }
568 569
569 done: 570 done:
570 #ifdef CONFIG_USB_KEYBOARD 571 #ifdef CONFIG_USB_KEYBOARD
571 net_busy_flag = 0; 572 net_busy_flag = 0;
572 #endif 573 #endif
573 #ifdef CONFIG_CMD_TFTPPUT 574 #ifdef CONFIG_CMD_TFTPPUT
574 /* Clear out the handlers */ 575 /* Clear out the handlers */
575 net_set_udp_handler(NULL); 576 net_set_udp_handler(NULL);
576 net_set_icmp_handler(NULL); 577 net_set_icmp_handler(NULL);
577 #endif 578 #endif
578 return ret; 579 return ret;
579 } 580 }
580 581
581 /**********************************************************************/ 582 /**********************************************************************/
582 583
583 static void 584 static void
584 startAgainTimeout(void) 585 startAgainTimeout(void)
585 { 586 {
586 net_set_state(NETLOOP_RESTART); 587 net_set_state(NETLOOP_RESTART);
587 } 588 }
588 589
589 void NetStartAgain(void) 590 void NetStartAgain(void)
590 { 591 {
591 char *nretry; 592 char *nretry;
592 int retry_forever = 0; 593 int retry_forever = 0;
593 unsigned long retrycnt = 0; 594 unsigned long retrycnt = 0;
594 595
595 nretry = getenv("netretry"); 596 nretry = getenv("netretry");
596 if (nretry) { 597 if (nretry) {
597 if (!strcmp(nretry, "yes")) 598 if (!strcmp(nretry, "yes"))
598 retry_forever = 1; 599 retry_forever = 1;
599 else if (!strcmp(nretry, "no")) 600 else if (!strcmp(nretry, "no"))
600 retrycnt = 0; 601 retrycnt = 0;
601 else if (!strcmp(nretry, "once")) 602 else if (!strcmp(nretry, "once"))
602 retrycnt = 1; 603 retrycnt = 1;
603 else 604 else
604 retrycnt = simple_strtoul(nretry, NULL, 0); 605 retrycnt = simple_strtoul(nretry, NULL, 0);
605 } else 606 } else
606 retry_forever = 1; 607 retry_forever = 1;
607 608
608 if ((!retry_forever) && (NetTryCount >= retrycnt)) { 609 if ((!retry_forever) && (NetTryCount >= retrycnt)) {
609 eth_halt(); 610 eth_halt();
610 net_set_state(NETLOOP_FAIL); 611 net_set_state(NETLOOP_FAIL);
611 return; 612 return;
612 } 613 }
613 614
614 NetTryCount++; 615 NetTryCount++;
615 616
616 eth_halt(); 617 eth_halt();
617 #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER) 618 #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
618 eth_try_another(!NetRestarted); 619 eth_try_another(!NetRestarted);
619 #endif 620 #endif
620 eth_init(gd->bd); 621 eth_init(gd->bd);
621 if (NetRestartWrap) { 622 if (NetRestartWrap) {
622 NetRestartWrap = 0; 623 NetRestartWrap = 0;
623 if (NetDevExists) { 624 if (NetDevExists) {
624 NetSetTimeout(10000UL, startAgainTimeout); 625 NetSetTimeout(10000UL, startAgainTimeout);
625 net_set_udp_handler(NULL); 626 net_set_udp_handler(NULL);
626 } else { 627 } else {
627 net_set_state(NETLOOP_FAIL); 628 net_set_state(NETLOOP_FAIL);
628 } 629 }
629 } else { 630 } else {
630 net_set_state(NETLOOP_RESTART); 631 net_set_state(NETLOOP_RESTART);
631 } 632 }
632 } 633 }
633 634
634 /**********************************************************************/ 635 /**********************************************************************/
635 /* 636 /*
636 * Miscelaneous bits. 637 * Miscelaneous bits.
637 */ 638 */
638 639
639 static void dummy_handler(uchar *pkt, unsigned dport, 640 static void dummy_handler(uchar *pkt, unsigned dport,
640 IPaddr_t sip, unsigned sport, 641 IPaddr_t sip, unsigned sport,
641 unsigned len) 642 unsigned len)
642 { 643 {
643 } 644 }
644 645
645 rxhand_f *net_get_udp_handler(void) 646 rxhand_f *net_get_udp_handler(void)
646 { 647 {
647 return udp_packet_handler; 648 return udp_packet_handler;
648 } 649 }
649 650
650 void net_set_udp_handler(rxhand_f *f) 651 void net_set_udp_handler(rxhand_f *f)
651 { 652 {
652 debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f); 653 debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f);
653 if (f == NULL) 654 if (f == NULL)
654 udp_packet_handler = dummy_handler; 655 udp_packet_handler = dummy_handler;
655 else 656 else
656 udp_packet_handler = f; 657 udp_packet_handler = f;
657 } 658 }
658 659
659 rxhand_f *net_get_arp_handler(void) 660 rxhand_f *net_get_arp_handler(void)
660 { 661 {
661 return arp_packet_handler; 662 return arp_packet_handler;
662 } 663 }
663 664
664 void net_set_arp_handler(rxhand_f *f) 665 void net_set_arp_handler(rxhand_f *f)
665 { 666 {
666 debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f); 667 debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f);
667 if (f == NULL) 668 if (f == NULL)
668 arp_packet_handler = dummy_handler; 669 arp_packet_handler = dummy_handler;
669 else 670 else
670 arp_packet_handler = f; 671 arp_packet_handler = f;
671 } 672 }
672 673
673 #ifdef CONFIG_CMD_TFTPPUT 674 #ifdef CONFIG_CMD_TFTPPUT
674 void net_set_icmp_handler(rxhand_icmp_f *f) 675 void net_set_icmp_handler(rxhand_icmp_f *f)
675 { 676 {
676 packet_icmp_handler = f; 677 packet_icmp_handler = f;
677 } 678 }
678 #endif 679 #endif
679 680
680 void 681 void
681 NetSetTimeout(ulong iv, thand_f *f) 682 NetSetTimeout(ulong iv, thand_f *f)
682 { 683 {
683 if (iv == 0) { 684 if (iv == 0) {
684 debug_cond(DEBUG_INT_STATE, 685 debug_cond(DEBUG_INT_STATE,
685 "--- NetLoop timeout handler cancelled\n"); 686 "--- NetLoop timeout handler cancelled\n");
686 timeHandler = (thand_f *)0; 687 timeHandler = (thand_f *)0;
687 } else { 688 } else {
688 debug_cond(DEBUG_INT_STATE, 689 debug_cond(DEBUG_INT_STATE,
689 "--- NetLoop timeout handler set (%p)\n", f); 690 "--- NetLoop timeout handler set (%p)\n", f);
690 timeHandler = f; 691 timeHandler = f;
691 timeStart = get_timer(0); 692 timeStart = get_timer(0);
692 timeDelta = iv * CONFIG_SYS_HZ / 1000; 693 timeDelta = iv * CONFIG_SYS_HZ / 1000;
693 } 694 }
694 } 695 }
695 696
696 int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, 697 int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport,
697 int payload_len) 698 int payload_len)
698 { 699 {
699 uchar *pkt; 700 uchar *pkt;
700 int eth_hdr_size; 701 int eth_hdr_size;
701 int pkt_hdr_size; 702 int pkt_hdr_size;
702 703
703 /* make sure the NetTxPacket is initialized (NetInit() was called) */ 704 /* make sure the NetTxPacket is initialized (NetInit() was called) */
704 assert(NetTxPacket != NULL); 705 assert(NetTxPacket != NULL);
705 if (NetTxPacket == NULL) 706 if (NetTxPacket == NULL)
706 return -1; 707 return -1;
707 708
708 /* convert to new style broadcast */ 709 /* convert to new style broadcast */
709 if (dest == 0) 710 if (dest == 0)
710 dest = 0xFFFFFFFF; 711 dest = 0xFFFFFFFF;
711 712
712 /* if broadcast, make the ether address a broadcast and don't do ARP */ 713 /* if broadcast, make the ether address a broadcast and don't do ARP */
713 if (dest == 0xFFFFFFFF) 714 if (dest == 0xFFFFFFFF)
714 ether = NetBcastAddr; 715 ether = NetBcastAddr;
715 716
716 pkt = (uchar *)NetTxPacket; 717 pkt = (uchar *)NetTxPacket;
717 718
718 eth_hdr_size = NetSetEther(pkt, ether, PROT_IP); 719 eth_hdr_size = NetSetEther(pkt, ether, PROT_IP);
719 pkt += eth_hdr_size; 720 pkt += eth_hdr_size;
720 net_set_udp_header(pkt, dest, dport, sport, payload_len); 721 net_set_udp_header(pkt, dest, dport, sport, payload_len);
721 pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE; 722 pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
722 723
723 /* if MAC address was not discovered yet, do an ARP request */ 724 /* if MAC address was not discovered yet, do an ARP request */
724 if (memcmp(ether, NetEtherNullAddr, 6) == 0) { 725 if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
725 debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest); 726 debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);
726 727
727 /* save the ip and eth addr for the packet to send after arp */ 728 /* save the ip and eth addr for the packet to send after arp */
728 NetArpWaitPacketIP = dest; 729 NetArpWaitPacketIP = dest;
729 NetArpWaitPacketMAC = ether; 730 NetArpWaitPacketMAC = ether;
730 731
731 /* size of the waiting packet */ 732 /* size of the waiting packet */
732 NetArpWaitTxPacketSize = pkt_hdr_size + payload_len; 733 NetArpWaitTxPacketSize = pkt_hdr_size + payload_len;
733 734
734 /* and do the ARP request */ 735 /* and do the ARP request */
735 NetArpWaitTry = 1; 736 NetArpWaitTry = 1;
736 NetArpWaitTimerStart = get_timer(0); 737 NetArpWaitTimerStart = get_timer(0);
737 ArpRequest(); 738 ArpRequest();
738 return 1; /* waiting */ 739 return 1; /* waiting */
739 } else { 740 } else {
740 debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n", 741 debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
741 &dest, ether); 742 &dest, ether);
742 NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len); 743 NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len);
743 return 0; /* transmitted */ 744 return 0; /* transmitted */
744 } 745 }
745 } 746 }
746 747
747 #ifdef CONFIG_IP_DEFRAG 748 #ifdef CONFIG_IP_DEFRAG
748 /* 749 /*
749 * This function collects fragments in a single packet, according 750 * This function collects fragments in a single packet, according
750 * to the algorithm in RFC815. It returns NULL or the pointer to 751 * to the algorithm in RFC815. It returns NULL or the pointer to
751 * a complete packet, in static storage 752 * a complete packet, in static storage
752 */ 753 */
753 #ifndef CONFIG_NET_MAXDEFRAG 754 #ifndef CONFIG_NET_MAXDEFRAG
754 #define CONFIG_NET_MAXDEFRAG 16384 755 #define CONFIG_NET_MAXDEFRAG 16384
755 #endif 756 #endif
756 /* 757 /*
757 * MAXDEFRAG, above, is chosen in the config file and is real data 758 * MAXDEFRAG, above, is chosen in the config file and is real data
758 * so we need to add the NFS overhead, which is more than TFTP. 759 * so we need to add the NFS overhead, which is more than TFTP.
759 * To use sizeof in the internal unnamed structures, we need a real 760 * To use sizeof in the internal unnamed structures, we need a real
760 * instance (can't do "sizeof(struct rpc_t.u.reply))", unfortunately). 761 * instance (can't do "sizeof(struct rpc_t.u.reply))", unfortunately).
761 * The compiler doesn't complain nor allocates the actual structure 762 * The compiler doesn't complain nor allocates the actual structure
762 */ 763 */
763 static struct rpc_t rpc_specimen; 764 static struct rpc_t rpc_specimen;
764 #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG + sizeof(rpc_specimen.u.reply)) 765 #define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG + sizeof(rpc_specimen.u.reply))
765 766
766 #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE) 767 #define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE)
767 768
768 /* 769 /*
769 * this is the packet being assembled, either data or frag control. 770 * this is the packet being assembled, either data or frag control.
770 * Fragments go by 8 bytes, so this union must be 8 bytes long 771 * Fragments go by 8 bytes, so this union must be 8 bytes long
771 */ 772 */
772 struct hole { 773 struct hole {
773 /* first_byte is address of this structure */ 774 /* first_byte is address of this structure */
774 u16 last_byte; /* last byte in this hole + 1 (begin of next hole) */ 775 u16 last_byte; /* last byte in this hole + 1 (begin of next hole) */
775 u16 next_hole; /* index of next (in 8-b blocks), 0 == none */ 776 u16 next_hole; /* index of next (in 8-b blocks), 0 == none */
776 u16 prev_hole; /* index of prev, 0 == none */ 777 u16 prev_hole; /* index of prev, 0 == none */
777 u16 unused; 778 u16 unused;
778 }; 779 };
779 780
780 static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp) 781 static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp)
781 { 782 {
782 static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); 783 static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
783 static u16 first_hole, total_len; 784 static u16 first_hole, total_len;
784 struct hole *payload, *thisfrag, *h, *newh; 785 struct hole *payload, *thisfrag, *h, *newh;
785 struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff; 786 struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff;
786 uchar *indata = (uchar *)ip; 787 uchar *indata = (uchar *)ip;
787 int offset8, start, len, done = 0; 788 int offset8, start, len, done = 0;
788 u16 ip_off = ntohs(ip->ip_off); 789 u16 ip_off = ntohs(ip->ip_off);
789 790
790 /* payload starts after IP header, this fragment is in there */ 791 /* payload starts after IP header, this fragment is in there */
791 payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); 792 payload = (struct hole *)(pkt_buff + IP_HDR_SIZE);
792 offset8 = (ip_off & IP_OFFS); 793 offset8 = (ip_off & IP_OFFS);
793 thisfrag = payload + offset8; 794 thisfrag = payload + offset8;
794 start = offset8 * 8; 795 start = offset8 * 8;
795 len = ntohs(ip->ip_len) - IP_HDR_SIZE; 796 len = ntohs(ip->ip_len) - IP_HDR_SIZE;
796 797
797 if (start + len > IP_MAXUDP) /* fragment extends too far */ 798 if (start + len > IP_MAXUDP) /* fragment extends too far */
798 return NULL; 799 return NULL;
799 800
800 if (!total_len || localip->ip_id != ip->ip_id) { 801 if (!total_len || localip->ip_id != ip->ip_id) {
801 /* new (or different) packet, reset structs */ 802 /* new (or different) packet, reset structs */
802 total_len = 0xffff; 803 total_len = 0xffff;
803 payload[0].last_byte = ~0; 804 payload[0].last_byte = ~0;
804 payload[0].next_hole = 0; 805 payload[0].next_hole = 0;
805 payload[0].prev_hole = 0; 806 payload[0].prev_hole = 0;
806 first_hole = 0; 807 first_hole = 0;
807 /* any IP header will work, copy the first we received */ 808 /* any IP header will work, copy the first we received */
808 memcpy(localip, ip, IP_HDR_SIZE); 809 memcpy(localip, ip, IP_HDR_SIZE);
809 } 810 }
810 811
811 /* 812 /*
812 * What follows is the reassembly algorithm. We use the payload 813 * What follows is the reassembly algorithm. We use the payload
813 * array as a linked list of hole descriptors, as each hole starts 814 * array as a linked list of hole descriptors, as each hole starts
814 * at a multiple of 8 bytes. However, last byte can be whatever value, 815 * at a multiple of 8 bytes. However, last byte can be whatever value,
815 * so it is represented as byte count, not as 8-byte blocks. 816 * so it is represented as byte count, not as 8-byte blocks.
816 */ 817 */
817 818
818 h = payload + first_hole; 819 h = payload + first_hole;
819 while (h->last_byte < start) { 820 while (h->last_byte < start) {
820 if (!h->next_hole) { 821 if (!h->next_hole) {
821 /* no hole that far away */ 822 /* no hole that far away */
822 return NULL; 823 return NULL;
823 } 824 }
824 h = payload + h->next_hole; 825 h = payload + h->next_hole;
825 } 826 }
826 827
827 /* last fragment may be 1..7 bytes, the "+7" forces acceptance */ 828 /* last fragment may be 1..7 bytes, the "+7" forces acceptance */
828 if (offset8 + ((len + 7) / 8) <= h - payload) { 829 if (offset8 + ((len + 7) / 8) <= h - payload) {
829 /* no overlap with holes (dup fragment?) */ 830 /* no overlap with holes (dup fragment?) */
830 return NULL; 831 return NULL;
831 } 832 }
832 833
833 if (!(ip_off & IP_FLAGS_MFRAG)) { 834 if (!(ip_off & IP_FLAGS_MFRAG)) {
834 /* no more fragmentss: truncate this (last) hole */ 835 /* no more fragmentss: truncate this (last) hole */
835 total_len = start + len; 836 total_len = start + len;
836 h->last_byte = start + len; 837 h->last_byte = start + len;
837 } 838 }
838 839
839 /* 840 /*
840 * There is some overlap: fix the hole list. This code doesn't 841 * There is some overlap: fix the hole list. This code doesn't
841 * deal with a fragment that overlaps with two different holes 842 * deal with a fragment that overlaps with two different holes
842 * (thus being a superset of a previously-received fragment). 843 * (thus being a superset of a previously-received fragment).
843 */ 844 */
844 845
845 if ((h >= thisfrag) && (h->last_byte <= start + len)) { 846 if ((h >= thisfrag) && (h->last_byte <= start + len)) {
846 /* complete overlap with hole: remove hole */ 847 /* complete overlap with hole: remove hole */
847 if (!h->prev_hole && !h->next_hole) { 848 if (!h->prev_hole && !h->next_hole) {
848 /* last remaining hole */ 849 /* last remaining hole */
849 done = 1; 850 done = 1;
850 } else if (!h->prev_hole) { 851 } else if (!h->prev_hole) {
851 /* first hole */ 852 /* first hole */
852 first_hole = h->next_hole; 853 first_hole = h->next_hole;
853 payload[h->next_hole].prev_hole = 0; 854 payload[h->next_hole].prev_hole = 0;
854 } else if (!h->next_hole) { 855 } else if (!h->next_hole) {
855 /* last hole */ 856 /* last hole */
856 payload[h->prev_hole].next_hole = 0; 857 payload[h->prev_hole].next_hole = 0;
857 } else { 858 } else {
858 /* in the middle of the list */ 859 /* in the middle of the list */
859 payload[h->next_hole].prev_hole = h->prev_hole; 860 payload[h->next_hole].prev_hole = h->prev_hole;
860 payload[h->prev_hole].next_hole = h->next_hole; 861 payload[h->prev_hole].next_hole = h->next_hole;
861 } 862 }
862 863
863 } else if (h->last_byte <= start + len) { 864 } else if (h->last_byte <= start + len) {
864 /* overlaps with final part of the hole: shorten this hole */ 865 /* overlaps with final part of the hole: shorten this hole */
865 h->last_byte = start; 866 h->last_byte = start;
866 867
867 } else if (h >= thisfrag) { 868 } else if (h >= thisfrag) {
868 /* overlaps with initial part of the hole: move this hole */ 869 /* overlaps with initial part of the hole: move this hole */
869 newh = thisfrag + (len / 8); 870 newh = thisfrag + (len / 8);
870 *newh = *h; 871 *newh = *h;
871 h = newh; 872 h = newh;
872 if (h->next_hole) 873 if (h->next_hole)
873 payload[h->next_hole].prev_hole = (h - payload); 874 payload[h->next_hole].prev_hole = (h - payload);
874 if (h->prev_hole) 875 if (h->prev_hole)
875 payload[h->prev_hole].next_hole = (h - payload); 876 payload[h->prev_hole].next_hole = (h - payload);
876 else 877 else
877 first_hole = (h - payload); 878 first_hole = (h - payload);
878 879
879 } else { 880 } else {
880 /* fragment sits in the middle: split the hole */ 881 /* fragment sits in the middle: split the hole */
881 newh = thisfrag + (len / 8); 882 newh = thisfrag + (len / 8);
882 *newh = *h; 883 *newh = *h;
883 h->last_byte = start; 884 h->last_byte = start;
884 h->next_hole = (newh - payload); 885 h->next_hole = (newh - payload);
885 newh->prev_hole = (h - payload); 886 newh->prev_hole = (h - payload);
886 if (newh->next_hole) 887 if (newh->next_hole)
887 payload[newh->next_hole].prev_hole = (newh - payload); 888 payload[newh->next_hole].prev_hole = (newh - payload);
888 } 889 }
889 890
890 /* finally copy this fragment and possibly return whole packet */ 891 /* finally copy this fragment and possibly return whole packet */
891 memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len); 892 memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len);
892 if (!done) 893 if (!done)
893 return NULL; 894 return NULL;
894 895
895 localip->ip_len = htons(total_len); 896 localip->ip_len = htons(total_len);
896 *lenp = total_len + IP_HDR_SIZE; 897 *lenp = total_len + IP_HDR_SIZE;
897 return localip; 898 return localip;
898 } 899 }
899 900
900 static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp) 901 static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
901 { 902 {
902 u16 ip_off = ntohs(ip->ip_off); 903 u16 ip_off = ntohs(ip->ip_off);
903 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG))) 904 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
904 return ip; /* not a fragment */ 905 return ip; /* not a fragment */
905 return __NetDefragment(ip, lenp); 906 return __NetDefragment(ip, lenp);
906 } 907 }
907 908
908 #else /* !CONFIG_IP_DEFRAG */ 909 #else /* !CONFIG_IP_DEFRAG */
909 910
910 static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp) 911 static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
911 { 912 {
912 u16 ip_off = ntohs(ip->ip_off); 913 u16 ip_off = ntohs(ip->ip_off);
913 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG))) 914 if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
914 return ip; /* not a fragment */ 915 return ip; /* not a fragment */
915 return NULL; 916 return NULL;
916 } 917 }
917 #endif 918 #endif
918 919
919 /** 920 /**
920 * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently 921 * Receive an ICMP packet. We deal with REDIRECT and PING here, and silently
921 * drop others. 922 * drop others.
922 * 923 *
923 * @parma ip IP packet containing the ICMP 924 * @parma ip IP packet containing the ICMP
924 */ 925 */
925 static void receive_icmp(struct ip_udp_hdr *ip, int len, 926 static void receive_icmp(struct ip_udp_hdr *ip, int len,
926 IPaddr_t src_ip, struct ethernet_hdr *et) 927 IPaddr_t src_ip, struct ethernet_hdr *et)
927 { 928 {
928 struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src; 929 struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
929 930
930 switch (icmph->type) { 931 switch (icmph->type) {
931 case ICMP_REDIRECT: 932 case ICMP_REDIRECT:
932 if (icmph->code != ICMP_REDIR_HOST) 933 if (icmph->code != ICMP_REDIR_HOST)
933 return; 934 return;
934 printf(" ICMP Host Redirect to %pI4 ", 935 printf(" ICMP Host Redirect to %pI4 ",
935 &icmph->un.gateway); 936 &icmph->un.gateway);
936 break; 937 break;
937 default: 938 default:
938 #if defined(CONFIG_CMD_PING) 939 #if defined(CONFIG_CMD_PING)
939 ping_receive(et, ip, len); 940 ping_receive(et, ip, len);
940 #endif 941 #endif
941 #ifdef CONFIG_CMD_TFTPPUT 942 #ifdef CONFIG_CMD_TFTPPUT
942 if (packet_icmp_handler) 943 if (packet_icmp_handler)
943 packet_icmp_handler(icmph->type, icmph->code, 944 packet_icmp_handler(icmph->type, icmph->code,
944 ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src), 945 ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
945 icmph->un.data, ntohs(ip->udp_len)); 946 icmph->un.data, ntohs(ip->udp_len));
946 #endif 947 #endif
947 break; 948 break;
948 } 949 }
949 } 950 }
950 951
951 void 952 void
952 NetReceive(uchar *inpkt, int len) 953 NetReceive(uchar *inpkt, int len)
953 { 954 {
954 struct ethernet_hdr *et; 955 struct ethernet_hdr *et;
955 struct ip_udp_hdr *ip; 956 struct ip_udp_hdr *ip;
956 IPaddr_t dst_ip; 957 IPaddr_t dst_ip;
957 IPaddr_t src_ip; 958 IPaddr_t src_ip;
958 int eth_proto; 959 int eth_proto;
959 #if defined(CONFIG_CMD_CDP) 960 #if defined(CONFIG_CMD_CDP)
960 int iscdp; 961 int iscdp;
961 #endif 962 #endif
962 ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; 963 ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
963 964
964 debug_cond(DEBUG_NET_PKT, "packet received\n"); 965 debug_cond(DEBUG_NET_PKT, "packet received\n");
965 966
966 NetRxPacket = inpkt; 967 NetRxPacket = inpkt;
967 NetRxPacketLen = len; 968 NetRxPacketLen = len;
968 et = (struct ethernet_hdr *)inpkt; 969 et = (struct ethernet_hdr *)inpkt;
969 970
970 /* too small packet? */ 971 /* too small packet? */
971 if (len < ETHER_HDR_SIZE) 972 if (len < ETHER_HDR_SIZE)
972 return; 973 return;
973 974
974 #ifdef CONFIG_API 975 #ifdef CONFIG_API
975 if (push_packet) { 976 if (push_packet) {
976 (*push_packet)(inpkt, len); 977 (*push_packet)(inpkt, len);
977 return; 978 return;
978 } 979 }
979 #endif 980 #endif
980 981
981 #if defined(CONFIG_CMD_CDP) 982 #if defined(CONFIG_CMD_CDP)
982 /* keep track if packet is CDP */ 983 /* keep track if packet is CDP */
983 iscdp = is_cdp_packet(et->et_dest); 984 iscdp = is_cdp_packet(et->et_dest);
984 #endif 985 #endif
985 986
986 myvlanid = ntohs(NetOurVLAN); 987 myvlanid = ntohs(NetOurVLAN);
987 if (myvlanid == (ushort)-1) 988 if (myvlanid == (ushort)-1)
988 myvlanid = VLAN_NONE; 989 myvlanid = VLAN_NONE;
989 mynvlanid = ntohs(NetOurNativeVLAN); 990 mynvlanid = ntohs(NetOurNativeVLAN);
990 if (mynvlanid == (ushort)-1) 991 if (mynvlanid == (ushort)-1)
991 mynvlanid = VLAN_NONE; 992 mynvlanid = VLAN_NONE;
992 993
993 eth_proto = ntohs(et->et_protlen); 994 eth_proto = ntohs(et->et_protlen);
994 995
995 if (eth_proto < 1514) { 996 if (eth_proto < 1514) {
996 struct e802_hdr *et802 = (struct e802_hdr *)et; 997 struct e802_hdr *et802 = (struct e802_hdr *)et;
997 /* 998 /*
998 * Got a 802.2 packet. Check the other protocol field. 999 * Got a 802.2 packet. Check the other protocol field.
999 * XXX VLAN over 802.2+SNAP not implemented! 1000 * XXX VLAN over 802.2+SNAP not implemented!
1000 */ 1001 */
1001 eth_proto = ntohs(et802->et_prot); 1002 eth_proto = ntohs(et802->et_prot);
1002 1003
1003 ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE); 1004 ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE);
1004 len -= E802_HDR_SIZE; 1005 len -= E802_HDR_SIZE;
1005 1006
1006 } else if (eth_proto != PROT_VLAN) { /* normal packet */ 1007 } else if (eth_proto != PROT_VLAN) { /* normal packet */
1007 ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE); 1008 ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE);
1008 len -= ETHER_HDR_SIZE; 1009 len -= ETHER_HDR_SIZE;
1009 1010
1010 } else { /* VLAN packet */ 1011 } else { /* VLAN packet */
1011 struct vlan_ethernet_hdr *vet = 1012 struct vlan_ethernet_hdr *vet =
1012 (struct vlan_ethernet_hdr *)et; 1013 (struct vlan_ethernet_hdr *)et;
1013 1014
1014 debug_cond(DEBUG_NET_PKT, "VLAN packet received\n"); 1015 debug_cond(DEBUG_NET_PKT, "VLAN packet received\n");
1015 1016
1016 /* too small packet? */ 1017 /* too small packet? */
1017 if (len < VLAN_ETHER_HDR_SIZE) 1018 if (len < VLAN_ETHER_HDR_SIZE)
1018 return; 1019 return;
1019 1020
1020 /* if no VLAN active */ 1021 /* if no VLAN active */
1021 if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE 1022 if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE
1022 #if defined(CONFIG_CMD_CDP) 1023 #if defined(CONFIG_CMD_CDP)
1023 && iscdp == 0 1024 && iscdp == 0
1024 #endif 1025 #endif
1025 ) 1026 )
1026 return; 1027 return;
1027 1028
1028 cti = ntohs(vet->vet_tag); 1029 cti = ntohs(vet->vet_tag);
1029 vlanid = cti & VLAN_IDMASK; 1030 vlanid = cti & VLAN_IDMASK;
1030 eth_proto = ntohs(vet->vet_type); 1031 eth_proto = ntohs(vet->vet_type);
1031 1032
1032 ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE); 1033 ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE);
1033 len -= VLAN_ETHER_HDR_SIZE; 1034 len -= VLAN_ETHER_HDR_SIZE;
1034 } 1035 }
1035 1036
1036 debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x\n", eth_proto); 1037 debug_cond(DEBUG_NET_PKT, "Receive from protocol 0x%x\n", eth_proto);
1037 1038
1038 #if defined(CONFIG_CMD_CDP) 1039 #if defined(CONFIG_CMD_CDP)
1039 if (iscdp) { 1040 if (iscdp) {
1040 cdp_receive((uchar *)ip, len); 1041 cdp_receive((uchar *)ip, len);
1041 return; 1042 return;
1042 } 1043 }
1043 #endif 1044 #endif
1044 1045
1045 if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) { 1046 if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {
1046 if (vlanid == VLAN_NONE) 1047 if (vlanid == VLAN_NONE)
1047 vlanid = (mynvlanid & VLAN_IDMASK); 1048 vlanid = (mynvlanid & VLAN_IDMASK);
1048 /* not matched? */ 1049 /* not matched? */
1049 if (vlanid != (myvlanid & VLAN_IDMASK)) 1050 if (vlanid != (myvlanid & VLAN_IDMASK))
1050 return; 1051 return;
1051 } 1052 }
1052 1053
1053 switch (eth_proto) { 1054 switch (eth_proto) {
1054 1055
1055 case PROT_ARP: 1056 case PROT_ARP:
1056 ArpReceive(et, ip, len); 1057 ArpReceive(et, ip, len);
1057 break; 1058 break;
1058 1059
1059 #ifdef CONFIG_CMD_RARP 1060 #ifdef CONFIG_CMD_RARP
1060 case PROT_RARP: 1061 case PROT_RARP:
1061 rarp_receive(ip, len); 1062 rarp_receive(ip, len);
1062 break; 1063 break;
1063 #endif 1064 #endif
1064 case PROT_IP: 1065 case PROT_IP:
1065 debug_cond(DEBUG_NET_PKT, "Got IP\n"); 1066 debug_cond(DEBUG_NET_PKT, "Got IP\n");
1066 /* Before we start poking the header, make sure it is there */ 1067 /* Before we start poking the header, make sure it is there */
1067 if (len < IP_UDP_HDR_SIZE) { 1068 if (len < IP_UDP_HDR_SIZE) {
1068 debug("len bad %d < %lu\n", len, 1069 debug("len bad %d < %lu\n", len,
1069 (ulong)IP_UDP_HDR_SIZE); 1070 (ulong)IP_UDP_HDR_SIZE);
1070 return; 1071 return;
1071 } 1072 }
1072 /* Check the packet length */ 1073 /* Check the packet length */
1073 if (len < ntohs(ip->ip_len)) { 1074 if (len < ntohs(ip->ip_len)) {
1074 debug("len bad %d < %d\n", len, ntohs(ip->ip_len)); 1075 debug("len bad %d < %d\n", len, ntohs(ip->ip_len));
1075 return; 1076 return;
1076 } 1077 }
1077 len = ntohs(ip->ip_len); 1078 len = ntohs(ip->ip_len);
1078 debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n", 1079 debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n",
1079 len, ip->ip_hl_v & 0xff); 1080 len, ip->ip_hl_v & 0xff);
1080 1081
1081 /* Can't deal with anything except IPv4 */ 1082 /* Can't deal with anything except IPv4 */
1082 if ((ip->ip_hl_v & 0xf0) != 0x40) 1083 if ((ip->ip_hl_v & 0xf0) != 0x40)
1083 return; 1084 return;
1084 /* Can't deal with IP options (headers != 20 bytes) */ 1085 /* Can't deal with IP options (headers != 20 bytes) */
1085 if ((ip->ip_hl_v & 0x0f) > 0x05) 1086 if ((ip->ip_hl_v & 0x0f) > 0x05)
1086 return; 1087 return;
1087 /* Check the Checksum of the header */ 1088 /* Check the Checksum of the header */
1088 if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) { 1089 if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) {
1089 debug("checksum bad\n"); 1090 debug("checksum bad\n");
1090 return; 1091 return;
1091 } 1092 }
1092 /* If it is not for us, ignore it */ 1093 /* If it is not for us, ignore it */
1093 dst_ip = NetReadIP(&ip->ip_dst); 1094 dst_ip = NetReadIP(&ip->ip_dst);
1094 if (NetOurIP && dst_ip != NetOurIP && dst_ip != 0xFFFFFFFF) { 1095 if (NetOurIP && dst_ip != NetOurIP && dst_ip != 0xFFFFFFFF) {
1095 #ifdef CONFIG_MCAST_TFTP 1096 #ifdef CONFIG_MCAST_TFTP
1096 if (Mcast_addr != dst_ip) 1097 if (Mcast_addr != dst_ip)
1097 #endif 1098 #endif
1098 return; 1099 return;
1099 } 1100 }
1100 /* Read source IP address for later use */ 1101 /* Read source IP address for later use */
1101 src_ip = NetReadIP(&ip->ip_src); 1102 src_ip = NetReadIP(&ip->ip_src);
1102 /* 1103 /*
1103 * The function returns the unchanged packet if it's not 1104 * The function returns the unchanged packet if it's not
1104 * a fragment, and either the complete packet or NULL if 1105 * a fragment, and either the complete packet or NULL if
1105 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL) 1106 * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
1106 */ 1107 */
1107 ip = NetDefragment(ip, &len); 1108 ip = NetDefragment(ip, &len);
1108 if (!ip) 1109 if (!ip)
1109 return; 1110 return;
1110 /* 1111 /*
1111 * watch for ICMP host redirects 1112 * watch for ICMP host redirects
1112 * 1113 *
1113 * There is no real handler code (yet). We just watch 1114 * There is no real handler code (yet). We just watch
1114 * for ICMP host redirect messages. In case anybody 1115 * for ICMP host redirect messages. In case anybody
1115 * sees these messages: please contact me 1116 * sees these messages: please contact me
1116 * (wd@denx.de), or - even better - send me the 1117 * (wd@denx.de), or - even better - send me the
1117 * necessary fixes :-) 1118 * necessary fixes :-)
1118 * 1119 *
1119 * Note: in all cases where I have seen this so far 1120 * Note: in all cases where I have seen this so far
1120 * it was a problem with the router configuration, 1121 * it was a problem with the router configuration,
1121 * for instance when a router was configured in the 1122 * for instance when a router was configured in the
1122 * BOOTP reply, but the TFTP server was on the same 1123 * BOOTP reply, but the TFTP server was on the same
1123 * subnet. So this is probably a warning that your 1124 * subnet. So this is probably a warning that your
1124 * configuration might be wrong. But I'm not really 1125 * configuration might be wrong. But I'm not really
1125 * sure if there aren't any other situations. 1126 * sure if there aren't any other situations.
1126 * 1127 *
1127 * Simon Glass <sjg@chromium.org>: We get an ICMP when 1128 * Simon Glass <sjg@chromium.org>: We get an ICMP when
1128 * we send a tftp packet to a dead connection, or when 1129 * we send a tftp packet to a dead connection, or when
1129 * there is no server at the other end. 1130 * there is no server at the other end.
1130 */ 1131 */
1131 if (ip->ip_p == IPPROTO_ICMP) { 1132 if (ip->ip_p == IPPROTO_ICMP) {
1132 receive_icmp(ip, len, src_ip, et); 1133 receive_icmp(ip, len, src_ip, et);
1133 return; 1134 return;
1134 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ 1135 } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */
1135 return; 1136 return;
1136 } 1137 }
1137 1138
1138 debug_cond(DEBUG_DEV_PKT, 1139 debug_cond(DEBUG_DEV_PKT,
1139 "received UDP (to=%pI4, from=%pI4, len=%d)\n", 1140 "received UDP (to=%pI4, from=%pI4, len=%d)\n",
1140 &dst_ip, &src_ip, len); 1141 &dst_ip, &src_ip, len);
1141 1142
1142 #ifdef CONFIG_UDP_CHECKSUM 1143 #ifdef CONFIG_UDP_CHECKSUM
1143 if (ip->udp_xsum != 0) { 1144 if (ip->udp_xsum != 0) {
1144 ulong xsum; 1145 ulong xsum;
1145 ushort *sumptr; 1146 ushort *sumptr;
1146 ushort sumlen; 1147 ushort sumlen;
1147 1148
1148 xsum = ip->ip_p; 1149 xsum = ip->ip_p;
1149 xsum += (ntohs(ip->udp_len)); 1150 xsum += (ntohs(ip->udp_len));
1150 xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; 1151 xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;
1151 xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff; 1152 xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff;
1152 xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff; 1153 xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;
1153 xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff; 1154 xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff;
1154 1155
1155 sumlen = ntohs(ip->udp_len); 1156 sumlen = ntohs(ip->udp_len);
1156 sumptr = (ushort *) &(ip->udp_src); 1157 sumptr = (ushort *) &(ip->udp_src);
1157 1158
1158 while (sumlen > 1) { 1159 while (sumlen > 1) {
1159 ushort sumdata; 1160 ushort sumdata;
1160 1161
1161 sumdata = *sumptr++; 1162 sumdata = *sumptr++;
1162 xsum += ntohs(sumdata); 1163 xsum += ntohs(sumdata);
1163 sumlen -= 2; 1164 sumlen -= 2;
1164 } 1165 }
1165 if (sumlen > 0) { 1166 if (sumlen > 0) {
1166 ushort sumdata; 1167 ushort sumdata;
1167 1168
1168 sumdata = *(unsigned char *) sumptr; 1169 sumdata = *(unsigned char *) sumptr;
1169 sumdata = (sumdata << 8) & 0xff00; 1170 sumdata = (sumdata << 8) & 0xff00;
1170 xsum += sumdata; 1171 xsum += sumdata;
1171 } 1172 }
1172 while ((xsum >> 16) != 0) { 1173 while ((xsum >> 16) != 0) {
1173 xsum = (xsum & 0x0000ffff) + 1174 xsum = (xsum & 0x0000ffff) +
1174 ((xsum >> 16) & 0x0000ffff); 1175 ((xsum >> 16) & 0x0000ffff);
1175 } 1176 }
1176 if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) { 1177 if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
1177 printf(" UDP wrong checksum %08lx %08x\n", 1178 printf(" UDP wrong checksum %08lx %08x\n",
1178 xsum, ntohs(ip->udp_xsum)); 1179 xsum, ntohs(ip->udp_xsum));
1179 return; 1180 return;
1180 } 1181 }
1181 } 1182 }
1182 #endif 1183 #endif
1183 1184
1184 1185
1185 #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) 1186 #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
1186 nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, 1187 nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
1187 src_ip, 1188 src_ip,
1188 ntohs(ip->udp_dst), 1189 ntohs(ip->udp_dst),
1189 ntohs(ip->udp_src), 1190 ntohs(ip->udp_src),
1190 ntohs(ip->udp_len) - UDP_HDR_SIZE); 1191 ntohs(ip->udp_len) - UDP_HDR_SIZE);
1191 #endif 1192 #endif
1192 /* 1193 /*
1193 * IP header OK. Pass the packet to the current handler. 1194 * IP header OK. Pass the packet to the current handler.
1194 */ 1195 */
1195 (*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE, 1196 (*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
1196 ntohs(ip->udp_dst), 1197 ntohs(ip->udp_dst),
1197 src_ip, 1198 src_ip,
1198 ntohs(ip->udp_src), 1199 ntohs(ip->udp_src),
1199 ntohs(ip->udp_len) - UDP_HDR_SIZE); 1200 ntohs(ip->udp_len) - UDP_HDR_SIZE);
1200 break; 1201 break;
1201 } 1202 }
1202 } 1203 }
1203 1204
1204 1205
1205 /**********************************************************************/ 1206 /**********************************************************************/
1206 1207
1207 static int net_check_prereq(enum proto_t protocol) 1208 static int net_check_prereq(enum proto_t protocol)
1208 { 1209 {
1209 switch (protocol) { 1210 switch (protocol) {
1210 /* Fall through */ 1211 /* Fall through */
1211 #if defined(CONFIG_CMD_PING) 1212 #if defined(CONFIG_CMD_PING)
1212 case PING: 1213 case PING:
1213 if (NetPingIP == 0) { 1214 if (NetPingIP == 0) {
1214 puts("*** ERROR: ping address not given\n"); 1215 puts("*** ERROR: ping address not given\n");
1215 return 1; 1216 return 1;
1216 } 1217 }
1217 goto common; 1218 goto common;
1218 #endif 1219 #endif
1219 #if defined(CONFIG_CMD_SNTP) 1220 #if defined(CONFIG_CMD_SNTP)
1220 case SNTP: 1221 case SNTP:
1221 if (NetNtpServerIP == 0) { 1222 if (NetNtpServerIP == 0) {
1222 puts("*** ERROR: NTP server address not given\n"); 1223 puts("*** ERROR: NTP server address not given\n");
1223 return 1; 1224 return 1;
1224 } 1225 }
1225 goto common; 1226 goto common;
1226 #endif 1227 #endif
1227 #if defined(CONFIG_CMD_DNS) 1228 #if defined(CONFIG_CMD_DNS)
1228 case DNS: 1229 case DNS:
1229 if (NetOurDNSIP == 0) { 1230 if (NetOurDNSIP == 0) {
1230 puts("*** ERROR: DNS server address not given\n"); 1231 puts("*** ERROR: DNS server address not given\n");
1231 return 1; 1232 return 1;
1232 } 1233 }
1233 goto common; 1234 goto common;
1234 #endif 1235 #endif
1235 #if defined(CONFIG_CMD_NFS) 1236 #if defined(CONFIG_CMD_NFS)
1236 case NFS: 1237 case NFS:
1237 #endif 1238 #endif
1238 case TFTPGET: 1239 case TFTPGET:
1239 case TFTPPUT: 1240 case TFTPPUT:
1240 if (NetServerIP == 0) { 1241 if (NetServerIP == 0) {
1241 puts("*** ERROR: `serverip' not set\n"); 1242 puts("*** ERROR: `serverip' not set\n");
1242 return 1; 1243 return 1;
1243 } 1244 }
1244 #if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \ 1245 #if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \
1245 defined(CONFIG_CMD_DNS) 1246 defined(CONFIG_CMD_DNS)
1246 common: 1247 common:
1247 #endif 1248 #endif
1248 /* Fall through */ 1249 /* Fall through */
1249 1250
1250 case NETCONS: 1251 case NETCONS:
1251 case TFTPSRV: 1252 case TFTPSRV:
1252 if (NetOurIP == 0) { 1253 if (NetOurIP == 0) {
1253 puts("*** ERROR: `ipaddr' not set\n"); 1254 puts("*** ERROR: `ipaddr' not set\n");
1254 return 1; 1255 return 1;
1255 } 1256 }
1256 /* Fall through */ 1257 /* Fall through */
1257 1258
1258 #ifdef CONFIG_CMD_RARP 1259 #ifdef CONFIG_CMD_RARP
1259 case RARP: 1260 case RARP:
1260 #endif 1261 #endif
1261 case BOOTP: 1262 case BOOTP:
1262 case CDP: 1263 case CDP:
1263 case DHCP: 1264 case DHCP:
1264 case LINKLOCAL: 1265 case LINKLOCAL:
1265 if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { 1266 if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
1266 int num = eth_get_dev_index(); 1267 int num = eth_get_dev_index();
1267 1268
1268 switch (num) { 1269 switch (num) {
1269 case -1: 1270 case -1:
1270 puts("*** ERROR: No ethernet found.\n"); 1271 puts("*** ERROR: No ethernet found.\n");
1271 return 1; 1272 return 1;
1272 case 0: 1273 case 0:
1273 puts("*** ERROR: `ethaddr' not set\n"); 1274 puts("*** ERROR: `ethaddr' not set\n");
1274 break; 1275 break;
1275 default: 1276 default:
1276 printf("*** ERROR: `eth%daddr' not set\n", 1277 printf("*** ERROR: `eth%daddr' not set\n",
1277 num); 1278 num);
1278 break; 1279 break;
1279 } 1280 }
1280 1281
1281 NetStartAgain(); 1282 NetStartAgain();
1282 return 2; 1283 return 2;
1283 } 1284 }
1284 /* Fall through */ 1285 /* Fall through */
1285 default: 1286 default:
1286 return 0; 1287 return 0;
1287 } 1288 }
1288 return 0; /* OK */ 1289 return 0; /* OK */
1289 } 1290 }
1290 /**********************************************************************/ 1291 /**********************************************************************/
1291 1292
1292 int 1293 int
1293 NetCksumOk(uchar *ptr, int len) 1294 NetCksumOk(uchar *ptr, int len)
1294 { 1295 {
1295 return !((NetCksum(ptr, len) + 1) & 0xfffe); 1296 return !((NetCksum(ptr, len) + 1) & 0xfffe);
1296 } 1297 }
1297 1298
1298 1299
1299 unsigned 1300 unsigned
1300 NetCksum(uchar *ptr, int len) 1301 NetCksum(uchar *ptr, int len)
1301 { 1302 {
1302 ulong xsum; 1303 ulong xsum;
1303 ushort *p = (ushort *)ptr; 1304 ushort *p = (ushort *)ptr;
1304 1305
1305 xsum = 0; 1306 xsum = 0;
1306 while (len-- > 0) 1307 while (len-- > 0)
1307 xsum += *p++; 1308 xsum += *p++;
1308 xsum = (xsum & 0xffff) + (xsum >> 16); 1309 xsum = (xsum & 0xffff) + (xsum >> 16);
1309 xsum = (xsum & 0xffff) + (xsum >> 16); 1310 xsum = (xsum & 0xffff) + (xsum >> 16);
1310 return xsum & 0xffff; 1311 return xsum & 0xffff;
1311 } 1312 }
1312 1313
1313 int 1314 int
1314 NetEthHdrSize(void) 1315 NetEthHdrSize(void)
1315 { 1316 {
1316 ushort myvlanid; 1317 ushort myvlanid;
1317 1318
1318 myvlanid = ntohs(NetOurVLAN); 1319 myvlanid = ntohs(NetOurVLAN);
1319 if (myvlanid == (ushort)-1) 1320 if (myvlanid == (ushort)-1)
1320 myvlanid = VLAN_NONE; 1321 myvlanid = VLAN_NONE;
1321 1322
1322 return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE : 1323 return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE :
1323 VLAN_ETHER_HDR_SIZE; 1324 VLAN_ETHER_HDR_SIZE;
1324 } 1325 }
1325 1326
1326 int 1327 int
1327 NetSetEther(uchar *xet, uchar * addr, uint prot) 1328 NetSetEther(uchar *xet, uchar * addr, uint prot)
1328 { 1329 {
1329 struct ethernet_hdr *et = (struct ethernet_hdr *)xet; 1330 struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
1330 ushort myvlanid; 1331 ushort myvlanid;
1331 1332
1332 myvlanid = ntohs(NetOurVLAN); 1333 myvlanid = ntohs(NetOurVLAN);
1333 if (myvlanid == (ushort)-1) 1334 if (myvlanid == (ushort)-1)
1334 myvlanid = VLAN_NONE; 1335 myvlanid = VLAN_NONE;
1335 1336
1336 memcpy(et->et_dest, addr, 6); 1337 memcpy(et->et_dest, addr, 6);
1337 memcpy(et->et_src, NetOurEther, 6); 1338 memcpy(et->et_src, NetOurEther, 6);
1338 if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) { 1339 if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
1339 et->et_protlen = htons(prot); 1340 et->et_protlen = htons(prot);
1340 return ETHER_HDR_SIZE; 1341 return ETHER_HDR_SIZE;
1341 } else { 1342 } else {
1342 struct vlan_ethernet_hdr *vet = 1343 struct vlan_ethernet_hdr *vet =
1343 (struct vlan_ethernet_hdr *)xet; 1344 (struct vlan_ethernet_hdr *)xet;
1344 1345
1345 vet->vet_vlan_type = htons(PROT_VLAN); 1346 vet->vet_vlan_type = htons(PROT_VLAN);
1346 vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK)); 1347 vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
1347 vet->vet_type = htons(prot); 1348 vet->vet_type = htons(prot);
1348 return VLAN_ETHER_HDR_SIZE; 1349 return VLAN_ETHER_HDR_SIZE;
1349 } 1350 }
1350 } 1351 }
1351 1352
1352 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot) 1353 int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
1353 { 1354 {
1354 ushort protlen; 1355 ushort protlen;
1355 1356
1356 memcpy(et->et_dest, addr, 6); 1357 memcpy(et->et_dest, addr, 6);
1357 memcpy(et->et_src, NetOurEther, 6); 1358 memcpy(et->et_src, NetOurEther, 6);
1358 protlen = ntohs(et->et_protlen); 1359 protlen = ntohs(et->et_protlen);
1359 if (protlen == PROT_VLAN) { 1360 if (protlen == PROT_VLAN) {
1360 struct vlan_ethernet_hdr *vet = 1361 struct vlan_ethernet_hdr *vet =
1361 (struct vlan_ethernet_hdr *)et; 1362 (struct vlan_ethernet_hdr *)et;
1362 vet->vet_type = htons(prot); 1363 vet->vet_type = htons(prot);
1363 return VLAN_ETHER_HDR_SIZE; 1364 return VLAN_ETHER_HDR_SIZE;
1364 } else if (protlen > 1514) { 1365 } else if (protlen > 1514) {
1365 et->et_protlen = htons(prot); 1366 et->et_protlen = htons(prot);
1366 return ETHER_HDR_SIZE; 1367 return ETHER_HDR_SIZE;
1367 } else { 1368 } else {
1368 /* 802.2 + SNAP */ 1369 /* 802.2 + SNAP */
1369 struct e802_hdr *et802 = (struct e802_hdr *)et; 1370 struct e802_hdr *et802 = (struct e802_hdr *)et;
1370 et802->et_prot = htons(prot); 1371 et802->et_prot = htons(prot);
1371 return E802_HDR_SIZE; 1372 return E802_HDR_SIZE;
1372 } 1373 }
1373 } 1374 }
1374 1375
1375 void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source) 1376 void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source)
1376 { 1377 {
1377 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; 1378 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
1378 1379
1379 /* 1380 /*
1380 * Construct an IP header. 1381 * Construct an IP header.
1381 */ 1382 */
1382 /* IP_HDR_SIZE / 4 (not including UDP) */ 1383 /* IP_HDR_SIZE / 4 (not including UDP) */
1383 ip->ip_hl_v = 0x45; 1384 ip->ip_hl_v = 0x45;
1384 ip->ip_tos = 0; 1385 ip->ip_tos = 0;
1385 ip->ip_len = htons(IP_HDR_SIZE); 1386 ip->ip_len = htons(IP_HDR_SIZE);
1386 ip->ip_id = htons(NetIPID++); 1387 ip->ip_id = htons(NetIPID++);
1387 ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ 1388 ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
1388 ip->ip_ttl = 255; 1389 ip->ip_ttl = 255;
1389 ip->ip_sum = 0; 1390 ip->ip_sum = 0;
1390 /* already in network byte order */ 1391 /* already in network byte order */
1391 NetCopyIP((void *)&ip->ip_src, &source); 1392 NetCopyIP((void *)&ip->ip_src, &source);
1392 /* already in network byte order */ 1393 /* already in network byte order */
1393 NetCopyIP((void *)&ip->ip_dst, &dest); 1394 NetCopyIP((void *)&ip->ip_dst, &dest);
1394 } 1395 }
1395 1396
1396 void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, 1397 void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport,
1397 int len) 1398 int len)
1398 { 1399 {
1399 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; 1400 struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
1400 1401
1401 /* 1402 /*
1402 * If the data is an odd number of bytes, zero the 1403 * If the data is an odd number of bytes, zero the
1403 * byte after the last byte so that the checksum 1404 * byte after the last byte so that the checksum
1404 * will work. 1405 * will work.
1405 */ 1406 */
1406 if (len & 1) 1407 if (len & 1)
1407 pkt[IP_UDP_HDR_SIZE + len] = 0; 1408 pkt[IP_UDP_HDR_SIZE + len] = 0;
1408 1409
1409 net_set_ip_header(pkt, dest, NetOurIP); 1410 net_set_ip_header(pkt, dest, NetOurIP);
1410 ip->ip_len = htons(IP_UDP_HDR_SIZE + len); 1411 ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
1411 ip->ip_p = IPPROTO_UDP; 1412 ip->ip_p = IPPROTO_UDP;
1412 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); 1413 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
1413 1414
1414 ip->udp_src = htons(sport); 1415 ip->udp_src = htons(sport);
1415 ip->udp_dst = htons(dport); 1416 ip->udp_dst = htons(dport);
1416 ip->udp_len = htons(UDP_HDR_SIZE + len); 1417 ip->udp_len = htons(UDP_HDR_SIZE + len);
1417 ip->udp_xsum = 0; 1418 ip->udp_xsum = 0;
1418 } 1419 }
1419 1420
1420 void copy_filename(char *dst, const char *src, int size) 1421 void copy_filename(char *dst, const char *src, int size)
1421 { 1422 {
1422 if (*src && (*src == '"')) { 1423 if (*src && (*src == '"')) {
1423 ++src; 1424 ++src;
1424 --size; 1425 --size;
1425 } 1426 }
1426 1427
1427 while ((--size > 0) && *src && (*src != '"')) 1428 while ((--size > 0) && *src && (*src != '"'))
1428 *dst++ = *src++; 1429 *dst++ = *src++;
1429 *dst = '\0'; 1430 *dst = '\0';
1430 } 1431 }
1431 1432
1432 #if defined(CONFIG_CMD_NFS) || \ 1433 #if defined(CONFIG_CMD_NFS) || \
1433 defined(CONFIG_CMD_SNTP) || \ 1434 defined(CONFIG_CMD_SNTP) || \
1434 defined(CONFIG_CMD_DNS) 1435 defined(CONFIG_CMD_DNS)
1435 /* 1436 /*
1436 * make port a little random (1024-17407) 1437 * make port a little random (1024-17407)
1437 * This keeps the math somewhat trivial to compute, and seems to work with 1438 * This keeps the math somewhat trivial to compute, and seems to work with
1438 * all supported protocols/clients/servers 1439 * all supported protocols/clients/servers
1439 */ 1440 */
1440 unsigned int random_port(void) 1441 unsigned int random_port(void)
1441 { 1442 {
1442 return 1024 + (get_timer(0) % 0x4000); 1443 return 1024 + (get_timer(0) % 0x4000);
1443 } 1444 }
1444 #endif 1445 #endif
1445 1446
1446 void ip_to_string(IPaddr_t x, char *s) 1447 void ip_to_string(IPaddr_t x, char *s)
1447 { 1448 {
1448 x = ntohl(x); 1449 x = ntohl(x);
1449 sprintf(s, "%d.%d.%d.%d", 1450 sprintf(s, "%d.%d.%d.%d",
1450 (int) ((x >> 24) & 0xff), 1451 (int) ((x >> 24) & 0xff),
1451 (int) ((x >> 16) & 0xff), 1452 (int) ((x >> 16) & 0xff),
1452 (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff) 1453 (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff)
1453 ); 1454 );
1454 } 1455 }
1455 1456
1456 void VLAN_to_string(ushort x, char *s) 1457 void VLAN_to_string(ushort x, char *s)
1457 { 1458 {
1458 x = ntohs(x); 1459 x = ntohs(x);
1459 1460
1460 if (x == (ushort)-1) 1461 if (x == (ushort)-1)
1461 x = VLAN_NONE; 1462 x = VLAN_NONE;
1462 1463
1463 if (x == VLAN_NONE) 1464 if (x == VLAN_NONE)
1464 strcpy(s, "none"); 1465 strcpy(s, "none");
1465 else 1466 else
1466 sprintf(s, "%d", x & VLAN_IDMASK); 1467 sprintf(s, "%d", x & VLAN_IDMASK);
1467 } 1468 }
1468 1469
1469 ushort string_to_VLAN(const char *s) 1470 ushort string_to_VLAN(const char *s)
1470 { 1471 {
1471 ushort id; 1472 ushort id;
1472 1473
1473 if (s == NULL) 1474 if (s == NULL)
1474 return htons(VLAN_NONE); 1475 return htons(VLAN_NONE);
1475 1476
1476 if (*s < '0' || *s > '9') 1477 if (*s < '0' || *s > '9')
1477 id = VLAN_NONE; 1478 id = VLAN_NONE;
1478 else 1479 else
1479 id = (ushort)simple_strtoul(s, NULL, 10); 1480 id = (ushort)simple_strtoul(s, NULL, 10);
1480 1481
1481 return htons(id); 1482 return htons(id);
1482 } 1483 }
1483 1484
1484 ushort getenv_VLAN(char *var) 1485 ushort getenv_VLAN(char *var)
1485 { 1486 {
1486 return string_to_VLAN(getenv(var)); 1487 return string_to_VLAN(getenv(var));
1487 } 1488 }
1488 1489
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #include "ping.h" 12 #include "ping.h"
12 #include "arp.h" 13 #include "arp.h"
13 14
14 static ushort PingSeqNo; 15 static ushort PingSeqNo;
15 16
16 /* The ip address to ping */ 17 /* The ip address to ping */
17 IPaddr_t NetPingIP; 18 IPaddr_t NetPingIP;
18 19
19 static void set_icmp_header(uchar *pkt, IPaddr_t dest) 20 static void set_icmp_header(uchar *pkt, IPaddr_t dest)
20 { 21 {
21 /* 22 /*
22 * Construct an IP and ICMP header. 23 * Construct an IP and ICMP header.
23 */ 24 */
24 struct ip_hdr *ip = (struct ip_hdr *)pkt; 25 struct ip_hdr *ip = (struct ip_hdr *)pkt;
25 struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE); 26 struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
26 27
27 net_set_ip_header(pkt, dest, NetOurIP); 28 net_set_ip_header(pkt, dest, NetOurIP);
28 29
29 ip->ip_len = htons(IP_ICMP_HDR_SIZE); 30 ip->ip_len = htons(IP_ICMP_HDR_SIZE);
30 ip->ip_p = IPPROTO_ICMP; 31 ip->ip_p = IPPROTO_ICMP;
31 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); 32 ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
32 33
33 icmp->type = ICMP_ECHO_REQUEST; 34 icmp->type = ICMP_ECHO_REQUEST;
34 icmp->code = 0; 35 icmp->code = 0;
35 icmp->checksum = 0; 36 icmp->checksum = 0;
36 icmp->un.echo.id = 0; 37 icmp->un.echo.id = 0;
37 icmp->un.echo.sequence = htons(PingSeqNo++); 38 icmp->un.echo.sequence = htons(PingSeqNo++);
38 icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1); 39 icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1);
39 } 40 }
40 41
41 static int ping_send(void) 42 static int ping_send(void)
42 { 43 {
43 uchar *pkt; 44 uchar *pkt;
44 int eth_hdr_size; 45 int eth_hdr_size;
45 46
46 /* XXX always send arp request */ 47 /* XXX always send arp request */
47 48
48 debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP); 49 debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP);
49 50
50 NetArpWaitPacketIP = NetPingIP; 51 NetArpWaitPacketIP = NetPingIP;
51 52
52 eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP); 53 eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP);
53 pkt = (uchar *)NetTxPacket + eth_hdr_size; 54 pkt = (uchar *)NetTxPacket + eth_hdr_size;
54 55
55 set_icmp_header(pkt, NetPingIP); 56 set_icmp_header(pkt, NetPingIP);
56 57
57 /* size of the waiting packet */ 58 /* size of the waiting packet */
58 NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE; 59 NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE;
59 60
60 /* and do the ARP request */ 61 /* and do the ARP request */
61 NetArpWaitTry = 1; 62 NetArpWaitTry = 1;
62 NetArpWaitTimerStart = get_timer(0); 63 NetArpWaitTimerStart = get_timer(0);
63 ArpRequest(); 64 ArpRequest();
64 return 1; /* waiting */ 65 return 1; /* waiting */
65 } 66 }
66 67
67 static void ping_timeout(void) 68 static void ping_timeout(void)
68 { 69 {
69 eth_halt(); 70 eth_halt();
70 net_set_state(NETLOOP_FAIL); /* we did not get the reply */ 71 net_set_state(NETLOOP_FAIL); /* we did not get the reply */
71 } 72 }
72 73
73 void ping_start(void) 74 void ping_start(void)
74 { 75 {
75 printf("Using %s device\n", eth_get_name()); 76 printf("Using %s device\n", eth_get_name());
76 NetSetTimeout(10000UL, ping_timeout); 77 NetSetTimeout(10000UL, ping_timeout);
77 78
78 ping_send(); 79 ping_send();
79 } 80 }
80 81
81 void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) 82 void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
82 { 83 {
83 struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src; 84 struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
84 IPaddr_t src_ip; 85 IPaddr_t src_ip;
85 int eth_hdr_size; 86 int eth_hdr_size;
86 87
87 switch (icmph->type) { 88 switch (icmph->type) {
88 case ICMP_ECHO_REPLY: 89 case ICMP_ECHO_REPLY:
89 src_ip = NetReadIP((void *)&ip->ip_src); 90 src_ip = NetReadIP((void *)&ip->ip_src);
90 if (src_ip == NetPingIP) 91 if (src_ip == NetPingIP)
91 net_set_state(NETLOOP_SUCCESS); 92 net_set_state(NETLOOP_SUCCESS);
92 return; 93 return;
93 case ICMP_ECHO_REQUEST: 94 case ICMP_ECHO_REQUEST:
94 eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP); 95 eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP);
95 96
96 debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return " 97 debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return "
97 "%d bytes\n", eth_hdr_size + len); 98 "%d bytes\n", eth_hdr_size + len);
98 99
99 ip->ip_sum = 0; 100 ip->ip_sum = 0;
100 ip->ip_off = 0; 101 ip->ip_off = 0;
101 NetCopyIP((void *)&ip->ip_dst, &ip->ip_src); 102 NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
102 NetCopyIP((void *)&ip->ip_src, &NetOurIP); 103 NetCopyIP((void *)&ip->ip_src, &NetOurIP);
103 ip->ip_sum = ~NetCksum((uchar *)ip, 104 ip->ip_sum = ~NetCksum((uchar *)ip,
104 IP_HDR_SIZE >> 1); 105 IP_HDR_SIZE >> 1);
105 106
106 icmph->type = ICMP_ECHO_REPLY; 107 icmph->type = ICMP_ECHO_REPLY;
107 icmph->checksum = 0; 108 icmph->checksum = 0;
108 icmph->checksum = ~NetCksum((uchar *)icmph, 109 icmph->checksum = ~NetCksum((uchar *)icmph,
109 (len - IP_HDR_SIZE) >> 1); 110 (len - IP_HDR_SIZE) >> 1);
110 NetSendPacket((uchar *)et, eth_hdr_size + len); 111 NetSendPacket((uchar *)et, eth_hdr_size + len);
111 return; 112 return;
112 /* default: 113 /* default:
113 return;*/ 114 return;*/
114 } 115 }
115 } 116 }
116 117
1 /* 1 /*
2 * Copied from Linux Monitor (LiMon) - Networking. 2 * Copied from Linux Monitor (LiMon) - Networking.
3 * 3 *
4 * Copyright 1994 - 2000 Neil Russell. 4 * Copyright 1994 - 2000 Neil Russell.
5 * (See License) 5 * (See License)
6 * Copyright 2000 Roland Borde 6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi 7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de 8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
9 * SPDX-License-Identifier: GPL-2.0
9 */ 10 */
10 11
11 #ifndef __PING_H__ 12 #ifndef __PING_H__
12 #define __PING_H__ 13 #define __PING_H__
13 14
14 #include <common.h> 15 #include <common.h>
15 #include <net.h> 16 #include <net.h>
16 17
17 /* 18 /*
18 * Initialize ping (beginning of netloop) 19 * Initialize ping (beginning of netloop)
19 */ 20 */
20 void ping_start(void); 21 void ping_start(void);
21 22
22 /* 23 /*
23 * Deal with the receipt of a ping packet 24 * Deal with the receipt of a ping packet
24 * 25 *
25 * @param et Ethernet header in packet 26 * @param et Ethernet header in packet
26 * @param ip IP header in the same packet 27 * @param ip IP header in the same packet
27 * @param len Packet length 28 * @param len Packet length
28 */ 29 */
29 void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); 30 void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
30 31
31 #endif /* __PING_H__ */ 32 #endif /* __PING_H__ */
32 33