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 (-27 / +67 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
4
3
5
apipa_depend()
4
apipa_depend()
6
{
5
{
7
	program /sbin/arping /bin/arping
6
	program /sbin/arping /bin/arping
8
}
7
}
9
8
10
_random()
9
_random_bytes_as_int()
11
{
10
{
12
	local r=${RANDOM} # checkbashisms: false positive, we handle it AFTERWARDS
11
	local hex num_bytes="$1"
13
	if [ -n "${r}" ]; then
12
14
		echo "${r}"
13
	# While POSIX does not require that /dev/urandom exist, it is a
15
	else
14
	# de-facto standard. Therefore, the following approach should be
16
		uuidgen | sed -n -e 's/[^[:digit:]]//g' -e 's/\(^.\{1,7\}\).*/\1/p'
15
	# highly portable in practice. In the case of Linux, and unlike BSD
17
	fi
16
	# this interface does not block in the event that the CSRNG has not
17
	# yet been seeded. Still, this is acceptable because we do not
18
	# require a guarantee that the entropy be cryptographically secure.
19
	# It's also worth noting that Linux >=5.4 is faster at seeding in
20
	# the absence of RDRAND/RDSEED than previous versions were.
21
	test -e /dev/urandom &&
22
	hex=$(
23
		LC_ALL=C tr -dc '[:xdigit:]' < /dev/urandom |
24
		dd bs="$(( num_bytes * 2 ))" count=1 2>/dev/null) &&
25
	test "${#hex}" = "$(( num_bytes * 2 ))" &&
26
	printf '%d\n' "0x${hex}"
27
}
28
29
_random_apipa_octets()
30
{
31
	local seed
32
33
	# Obtain a highly random 16-bit seed for use by awk's RNG. In the
34
	# unlikely event that the seed ends up being empty, awk will seed
35
	# based on the time of day, with a granularity of one second.
36
	seed=$(_random_bytes_as_int 2)
37
38
	# For APIPA (RFC 3927), the 169.254.0.0/16 address block is
39
	# reserved. This provides 65534 addresses, having accounted for the
40
	# network and broadcast address. Note that we must count from 1.
41
	awk "BEGIN {
42
		srand($seed)
43
		for (i=1; i<65535; i++) print rand() \" \" i
44
	}" |
45
	sort -k 1,1 -n |
46
	POSIXLY_CORRECT=1 awk '{
47
		hex = sprintf("%04x",$2)
48
		printf("%d %d\n", "0x" substr(hex,1,2), "0x" substr(hex,3,2))
49
	}'
18
}
50
}
19
51
20
apipa_start()
52
apipa_start()
21
{
53
{
22
	local iface="$1" i1= i2= addr= i=0
54
	local addr rc
23
55
24
	_exists true || return 1
56
	_exists || return
25
57
26
	einfo "Searching for free addresses in 169.254.0.0/16"
58
	einfo "Searching for free addresses in 169.254.0.0/16"
27
	eindent
59
	eindent
28
60
29
	while [ ${i} -lt 64516 ]; do
61
	exec 3>&1
30
		: $(( i1 = (_random % 255) + 1 ))
62
	addr=$(
31
		: $(( i2 = (_random % 255) + 1 ))
63
		_random_apipa_octets |
32
64
		{
33
		addr="169.254.${i1}.${i2}"
65
			while read -r i1 i2; do
34
		vebegin "${addr}/16"
66
				addr="169.254.${i1}.${i2}"
35
		if ! arping_address "${addr}"; then
67
				vebegin "${addr}/16" >&3
36
			eval config_${config_index}="\"${addr}/16 broadcast 169.254.255.255\""
68
				if ! arping_address "${addr}" >&3; then
37
			: $(( config_index -= 1 ))
69
					printf '%s\n' "${addr}"
38
			veend 0
70
					exit 0
39
			eoutdent
71
				fi
40
			return 0
72
			done
41
		fi
73
			exit 1
74
		}
75
	)
76
	rc=$?
77
	exec 3>&-
42
78
43
		: $(( i += 1 ))
79
	if [ "$rc" = 0 ]; then
44
	done
80
		eval "config_${config_index}=\"\${addr}/16 broadcast 169.254.255.255\""
81
		: $(( config_index -= 1 ))
82
		veend 0
83
	else
84
		eerror "No free address found!"
85
	fi
45
86
46
	eerror "No free address found!"
47
	eoutdent
87
	eoutdent
48
	return 1
88
	return "$rc"
49
}
89
}

Return to bug 766890