Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 766890 | Differences between
and this patch

Collapse All | Expand All

(-)a/net/apipa.sh (-17 / +70 lines)
Lines 1-49 Link Here
1
# Copyright (c) 2007-2008 Roy Marples <roy@marples.name>
1
# Copyright (c) 2007-2008 Roy Marples <roy@marples.name>
2
# Released under the 2-clause BSD license.
2
# Released under the 2-clause BSD license.
3
# shellcheck shell=sh disable=SC1008
3
# shellcheck shell=sh disable=SC2094
4
4
5
apipa_depend()
5
apipa_depend()
6
{
6
{
7
	program /sbin/arping /bin/arping
7
	program /sbin/arping /bin/arping
8
}
8
}
9
9
10
_random()
10
_random_bytes_as_int()
11
{
11
{
12
	local r=${RANDOM} # checkbashisms: false positive, we handle it AFTERWARDS
12
	local hex num_bytes="$1"
13
	if [ -n "${r}" ]; then
13
14
		echo "${r}"
14
	# While POSIX does not require that /dev/urandom exist, it is a
15
	# de-facto standard. Therefore, the following approach should be
16
	# highly portable in practice. In the case of Linux, and unlike BSD
17
	# this interface does not block in the event that the CSRNG has not
18
	# yet been seeded. Still, this is acceptable because we do not
19
	# require a guarantee that the entropy be cryptographically secure.
20
	# It's also worth noting that Linux >=5.4 is faster at seeding in
21
	# the absence of RDRAND/RDSEED than previous versions were.
22
	test -e /dev/urandom &&
23
	hex=$(
24
		LC_ALL=C tr -dc '[:xdigit:]' < /dev/urandom |
25
		dd bs="$(( num_bytes * 2 ))" count=1 2>/dev/null) &&
26
	test "${#hex}" = "$(( num_bytes * 2 ))" &&
27
	printf '%d\n' "0x${hex}"
28
}
29
30
_random_apipa_octets()
31
{
32
	local seed
33
34
	# Obtain a high-entropy 16-bit seed for use by awk's RNG. In the
35
	# unlikely event that the seed ends up being empty, awk will seed
36
	# based on the time of day, with a granularity of one second.
37
	seed=$(_random_bytes_as_int 2)
38
39
	# For APIPA (RFC 3927), the 169.254.0.0/16 address block is
40
	# reserved. This provides 65534 addresses, having accounted for the
41
	# network and broadcast address. Note that we must count from 1.
42
	awk "BEGIN {
43
		srand($seed)
44
		for (i=1; i<65535; i++) print rand() \" \" i
45
	}" |
46
	sort -k 1,1 -n |
47
	POSIXLY_CORRECT=1 awk '{
48
		hex = sprintf("%04x",$2)
49
		printf("%d %d\n", "0x" substr(hex,1,2), "0x" substr(hex,3,2))
50
	}'
51
}
52
53
_mktemp() {
54
	local tmpfile randchars
55
56
	# Try to use the non-standard mktemp(1) utility first.
57
	if command -v mktemp >/dev/null; then
58
		tmpfile=$(mktemp)
15
	else
59
	else
16
		uuidgen | sed -n -e 's/[^[:digit:]]//g' -e 's/\(^.\{1,7\}\).*/\1/p'
60
		# See the definition of _random_bytes_as_int() for a
17
	fi
61
		# justification of this method. It would have been nice to use
62
		# the mkstemp function of m4(1) but, despite being defined by
63
		# POSIX-1.2008, support is not yet sufficiently widespread.
64
		randchars=$(
65
			LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom |
66
			dd bs=10 count=1 2>/dev/null) &&
67
		test "${#randchars}" = 10 &&
68
		tmpfile="${TMPDIR:-/tmp}/tmp.${randchars}" &&
69
		: >"${tmpfile}"
70
	fi &&
71
	printf '%s\n' "${tmpfile}"
18
}
72
}
19
73
20
apipa_start()
74
apipa_start()
21
{
75
{
22
	local iface="$1" i1= i2= addr= i=0
76
	local tmpfile i1 i2 addr
23
77
24
	_exists true || return 1
78
	_exists &&
79
	tmpfile=$(_mktemp) &&
80
	_random_apipa_octets > "${tmpfile}" || return
25
81
26
	einfo "Searching for free addresses in 169.254.0.0/16"
82
	einfo "Searching for free addresses in 169.254.0.0/16"
27
	eindent
83
	eindent
28
84
29
	while [ ${i} -lt 64516 ]; do
85
	while read -r i1 i2; do
30
		: $(( i1 = (_random % 255) + 1 ))
31
		: $(( i2 = (_random % 255) + 1 ))
32
33
		addr="169.254.${i1}.${i2}"
86
		addr="169.254.${i1}.${i2}"
34
		vebegin "${addr}/16"
87
		vebegin "${addr}/16"
35
		if ! arping_address "${addr}"; then
88
		if ! arping_address "${addr}"; then
36
			eval config_${config_index}="\"${addr}/16 broadcast 169.254.255.255\""
89
			eval "config_${config_index}=\"\${addr}/16 broadcast 169.254.255.255\""
37
			: $(( config_index -= 1 ))
90
			: $(( config_index -= 1 ))
38
			veend 0
91
			veend 0
39
			eoutdent
92
			eoutdent
93
			rm -f -- "${tmpfile}"
40
			return 0
94
			return 0
41
		fi
95
		fi
42
96
	done < "${tmpfile}"
43
		: $(( i += 1 ))
44
	done
45
97
46
	eerror "No free address found!"
98
	eerror "No free address found!"
47
	eoutdent
99
	eoutdent
100
	rm -f -- "${tmpfile}"
48
	return 1
101
	return 1
49
}
102
}

Return to bug 766890