summaryrefslogtreecommitdiff
blob: 5f04978ab811f4c7e09d3bc16128a4c5dace05bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/bin/bash
# Copyright (c) 2004-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# Contributed by Roy Marples (uberlord@gentoo.org)

# char* arping_provides(void)
#
# Returns a string to change module definition for starting up
arping_provides() {
	echo "arping"
}

# void arping_depend(void)
#
# Sets up the dependancies for the module
arping_depend() {
	after system dhcp vlan
}

# bool arping_check_installed(void)
#
# Returns 0 if arping or arping2 is installed, otherwise 1
arping_check_installed() {
	[[ -x /sbin/arping || -x /usr/sbin/arping2 ]] && return 0
	if ${1:-false}; then
		eerror "For arping support emerge net-misc/iputils or net-analyzer/arping"
	fi
	return 1
}

# bool arping_check_depends(void)
#
# Checks to see if we have the needed functions
arping_check_depends() {
	local f

	for f in interface_exists interface_up ; do
		[[ $( type -t "${f}" ) == "function" ]] && continue
		eerror "arping: missing required function ${f}\n"
		return 1
	done

	return 0
}

# bool address_exists(char *interface, char *address)
#
# Returns 0 if the address on the interface responds to an arping
# 1 if not - packets defaults to 1
# If neither arping (net-misc/iputils) or arping2 (net-analyzer/arping)
# is installed then we return 1
address_exists() {
	local iface="$1" address="${2%%/*}" i

	# We only handle IPv4 addresses
	[[ ${address} != *.*.*.* ]] && return 1

	# 0.0.0.0 isn't a valid address - and some lusers have configured this
	[[ ${address} == "0.0.0.0" || ${address} == "0" ]] && return 1

	# We need to bring the interface up to test
	interface_up "${iface}"

	if [[ -x /sbin/arping ]]; then
		/sbin/arping -q -c 2 -w 3 -D -f -I "${iface}" "${address}" \
		&>/dev/null || return 0
	elif [[ -x /usr/sbin/arping2 ]]; then
		for (( i=0; i<3; i++ )); do
			/usr/sbin/arping2 -0 -c 1 -i "${iface}" "${address}" \
			&>/dev/null && return 0
		done
	fi
	return 1
}

# bool arping_gateways(void)
#
# arpings a list of gateways
# If one is foung then apply it's configuration
arping_gateways() {
	local gateways x conf i
	
	eval gateways=\"\$\{arping_${ifvar}\}\"
	[[ -z ${gateways} ]] && return 1

	einfo "Pinging gateways on ${iface} for configuration"
	eindent

	for x in ${gateways}; do
		vebegin "${x}"
		if address_exists "${iface}" "${x}" ; then
			for i in ${x//./ } ; do
				if [[ ${#i} == "2" ]]; then
					conf="${conf}0${i}"
				elif [[ ${#i} == "1" ]]; then
					conf="${conf}00${i}"
				else
					conf="${conf}${i}"
				fi
			done
			veend 0
			eoutdent
			veinfo "Configuring ${iface} for ${x}"
			configure_variables "${iface}" "${conf}"
			return 0
		fi
		veend 1
	done

	eoutdent
	return 1
}

# bool arping_apipa(char *iface)
#
# Tries to locate an address in the 169.254.0.0 netmask 169.254.255.255 range
arping_apipa() {
	local iface="$1" i1 i2 addr i=0

	einfo "Searching for free addresses in 169.254.0.0/16"
	eindent

	while [[ ${i} -lt 64516 ]]; do
		(( i1=${RANDOM}%255 ))
		(( i2=${RANDOM}%255 ))

		addr="169.254.${i1}.${i2}"
		vebegin "${addr}/16"
		if ! address_exists "${iface}" "${addr}" ; then
			config[config_counter]="${addr}/16 broadcast 169.254.255.255"
			(( config_counter-- ))
			veend 0
			eoutdent
			return 0
		fi

		(( i++ ))
	done

	eerror "No free address found!"
	eoutdent
	return 1
}

# bool arping_start(char *iface)
#
# Tries to detect a config based on arpinging things
arping_start() {
	local iface="$1"

	interface_exists "${iface}" true || return 1
	interface_up "${iface}"
	
	arping_gateways "${iface}" && return 0
	arping_apipa "${iface}" && return 0

	return 1
}

# vim:ts=4