Blame view

lib/net_utils.c 1.95 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
6a45e3849   Dirk Behme   Make getenv_IPadd...
2
3
4
5
6
7
8
9
  /*
   * Generic network code. Moved from net.c
   *
   * Copyright 1994 - 2000 Neil Russell.
   * Copyright 2000 Roland Borde
   * Copyright 2000 Paolo Scaffardi
   * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
   * Copyright 2009 Dirk Behme, dirk.behme@googlemail.com
6a45e3849   Dirk Behme   Make getenv_IPadd...
10
11
12
   */
  
  #include <common.h>
049a95a77   Joe Hershberger   net: cosmetic: Ch...
13
  struct in_addr string_to_ip(const char *s)
6a45e3849   Dirk Behme   Make getenv_IPadd...
14
  {
049a95a77   Joe Hershberger   net: cosmetic: Ch...
15
  	struct in_addr addr;
6a45e3849   Dirk Behme   Make getenv_IPadd...
16
17
  	char *e;
  	int i;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
18
  	addr.s_addr = 0;
6a45e3849   Dirk Behme   Make getenv_IPadd...
19
  	if (s == NULL)
049a95a77   Joe Hershberger   net: cosmetic: Ch...
20
  		return addr;
6a45e3849   Dirk Behme   Make getenv_IPadd...
21

049a95a77   Joe Hershberger   net: cosmetic: Ch...
22
  	for (addr.s_addr = 0, i = 0; i < 4; ++i) {
6a45e3849   Dirk Behme   Make getenv_IPadd...
23
  		ulong val = s ? simple_strtoul(s, &e, 10) : 0;
d921ed9a2   Chris Packham   lib: net_utils: m...
24
25
26
27
  		if (val > 255) {
  			addr.s_addr = 0;
  			return addr;
  		}
f267e40f9   Chris Packham   lib: net_utils: e...
28
29
30
31
  		if (i != 3 && *e != '.') {
  			addr.s_addr = 0;
  			return addr;
  		}
049a95a77   Joe Hershberger   net: cosmetic: Ch...
32
33
  		addr.s_addr <<= 8;
  		addr.s_addr |= (val & 0xFF);
6a45e3849   Dirk Behme   Make getenv_IPadd...
34
35
36
37
  		if (s) {
  			s = (*e) ? e+1 : e;
  		}
  	}
049a95a77   Joe Hershberger   net: cosmetic: Ch...
38
39
  	addr.s_addr = htonl(addr.s_addr);
  	return addr;
6a45e3849   Dirk Behme   Make getenv_IPadd...
40
  }
fb8977c5b   Joe Hershberger   net: Always build...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  
  void string_to_enetaddr(const char *addr, uint8_t *enetaddr)
  {
  	char *end;
  	int i;
  
  	if (!enetaddr)
  		return;
  
  	for (i = 0; i < 6; ++i) {
  		enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
  		if (addr)
  			addr = (*end) ? end + 1 : end;
  	}
  }
d721001fd   Simon Glass   net: Move the che...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  
  uint compute_ip_checksum(const void *vptr, uint nbytes)
  {
  	int sum, oddbyte;
  	const unsigned short *ptr = vptr;
  
  	sum = 0;
  	while (nbytes > 1) {
  		sum += *ptr++;
  		nbytes -= 2;
  	}
  	if (nbytes == 1) {
  		oddbyte = 0;
  		((u8 *)&oddbyte)[0] = *(u8 *)ptr;
  		((u8 *)&oddbyte)[1] = 0;
  		sum += oddbyte;
  	}
  	sum = (sum >> 16) + (sum & 0xffff);
  	sum += (sum >> 16);
  	sum = ~sum & 0xffff;
  
  	return sum;
  }
  
  uint add_ip_checksums(uint offset, uint sum, uint new)
  {
  	ulong checksum;
  
  	sum = ~sum & 0xffff;
  	new = ~new & 0xffff;
  	if (offset & 1) {
  		/*
  		 * byte-swap the sum if it came from an odd offset; since the
  		 * computation is endian-independent this works.
  		 */
  		new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
  	}
  	checksum = sum + new;
  	if (checksum > 0xffff)
  		checksum -= 0xffff;
  
  	return (~checksum) & 0xffff;
  }
  
  int ip_checksum_ok(const void *addr, uint nbytes)
  {
  	return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
  }