| … | |
… | |
| 18 | eerror "For arping support emerge net-misc/iputils or net-analyzer/arping" |
18 | eerror "For arping support emerge net-misc/iputils or net-analyzer/arping" |
| 19 | fi |
19 | fi |
| 20 | return 1 |
20 | return 1 |
| 21 | } |
21 | } |
| 22 | |
22 | |
|
|
23 | # void arping_sleep(char *interface) |
|
|
24 | # |
|
|
25 | # Allows the interface to settle on the LAN - normally takes around 3 seconds |
|
|
26 | # This requires the use of a global variable, ARPING_SLEPT |
|
|
27 | arping_sleep() { |
|
|
28 | local iface="$1" |
|
|
29 | [[ ${ARPING_SLEPT} == "1" ]] && return |
|
|
30 | |
|
|
31 | local ifvar="$(bash_variable "${iface}")" |
|
|
32 | local s="arping_sleep_${ifvar}" |
|
|
33 | s="${!s}" |
|
|
34 | if [[ -z ${s} ]] ; then |
|
|
35 | s="${arping_sleep}" |
|
|
36 | s="${s:-1}" |
|
|
37 | fi |
|
|
38 | sleep "${s}" |
|
|
39 | ARPING_SLEPT="1" |
|
|
40 | } |
|
|
41 | |
| 23 | # bool arping_address_exists(char *interface, char *address) |
42 | # bool arping_address_exists(char *interface, char *address) |
| 24 | # |
43 | # |
| 25 | # Returns 0 if the address on the interface responds to an arping |
44 | # Returns 0 if the address on the interface responds to an arping |
| 26 | # 1 if not - packets defaults to 1 |
45 | # 1 if not - packets defaults to 1 |
| 27 | # If neither arping (net-misc/iputils) or arping2 (net-analyzer/arping) |
46 | # If neither arping (net-misc/iputils) or arping2 (net-analyzer/arping) |
| 28 | # is installed then we return 1 |
47 | # is installed then we return 1 |
| 29 | arping_address_exists() { |
48 | arping_address_exists() { |
| 30 | local iface="$1" address="${2%%/*}" i |
49 | local iface="$1" ip="${2%%/*}" mac="$3" foundmac= i= w= |
| 31 | |
50 | |
| 32 | # We only handle IPv4 addresses |
51 | # We only handle IPv4 addresses |
| 33 | [[ ${address} != *.*.*.* ]] && return 1 |
52 | [[ ${ip} != *.*.*.* ]] && return 1 |
| 34 | |
53 | |
| 35 | # 0.0.0.0 isn't a valid address - and some lusers have configured this |
54 | # 0.0.0.0 isn't a valid address - and some lusers have configured this |
| 36 | [[ ${address} == "0.0.0.0" || ${address} == "0" ]] && return 1 |
55 | [[ ${ip} == "0.0.0.0" || ${ip} == "0" ]] && return 1 |
| 37 | |
56 | |
| 38 | # We need to bring the interface up to test |
57 | # We need to bring the interface up to test |
| 39 | interface_exists "${iface}" || return 1 |
58 | interface_exists "${iface}" || return 1 |
| 40 | interface_up "${iface}" |
59 | interface_up "${iface}" |
| 41 | |
60 | |
|
|
61 | arping_sleep |
|
|
62 | |
|
|
63 | local ifvar="$(bash_variable "${iface}")" |
|
|
64 | w="arping_wait_${ifvar}" |
|
|
65 | w="${!w}" |
|
|
66 | [[ -z ${w} ]] && w="${arping_wait:-3}" |
|
|
67 | |
| 42 | if [[ -x /sbin/arping ]] ; then |
68 | if [[ -x /sbin/arping ]] ; then |
| 43 | /sbin/arping -q -c 2 -w 3 -D -f -I "${iface}" "${address}" \ |
69 | foundmac="$(arping -c 2 -w "${w}" -D -f -I "${iface}" \ |
| 44 | &>/dev/null || return 0 |
70 | "${ip}" 2>/dev/null \ |
|
|
71 | | sed -n 's/.*\[\([^]]*\)\].*/\U\1/p')" |
| 45 | elif [[ -x /usr/sbin/arping2 ]] ; then |
72 | elif [[ -x /usr/sbin/arping2 ]] ; then |
| 46 | for (( i=0; i<3; i++ )) ; do |
73 | for (( i=0; i<w; i++ )) ; do |
| 47 | /usr/sbin/arping2 -0 -c 1 -i "${iface}" "${address}" \ |
74 | foundmac="$(arping2 -r -0 -c 1 -i "${iface}" \ |
| 48 | &>/dev/null && return 0 |
75 | "${ip}" 2>/dev/null)" |
|
|
76 | if [[ $? == "0" ]] ; then |
|
|
77 | foundmac="$(echo "${foundmac}" \ |
|
|
78 | | tr '[:lower:]' '[:upper:]')" |
|
|
79 | break |
|
|
80 | fi |
|
|
81 | foundmac= |
| 49 | done |
82 | done |
| 50 | fi |
83 | fi |
|
|
84 | |
|
|
85 | [[ -z ${foundmac} ]] && return 1 |
|
|
86 | |
|
|
87 | if [[ -n ${mac} ]] ; then |
|
|
88 | if [[ ${mac} != "${foundmac}" ]] ; then |
|
|
89 | vewarn "Found ${ip} but MAC ${foundmac} does not match" |
| 51 | return 1 |
90 | return 1 |
|
|
91 | fi |
|
|
92 | fi |
|
|
93 | |
|
|
94 | return 0 |
| 52 | } |
95 | } |
| 53 | |
96 | |
| 54 | # bool arping_start(char *iface) |
97 | # bool arping_start(char *iface) |
| 55 | # |
98 | # |
| 56 | # arpings a list of gateways |
99 | # arpings a list of gateways |
| 57 | # If one is foung then apply it's configuration |
100 | # If one is foung then apply it's configuration |
| 58 | arping_start() { |
101 | arping_start() { |
| 59 | local iface="$1" gateways x conf i |
102 | local iface="$1" gateways x conf i |
| 60 | |
103 | local ifvar="$(bash_variable "${iface}")" |
| 61 | interface_exists "${iface}" true || return 1 |
|
|
| 62 | |
104 | |
| 63 | einfo "Pinging gateways on ${iface} for configuration" |
105 | einfo "Pinging gateways on ${iface} for configuration" |
| 64 | |
106 | |
| 65 | gateways="gateways_${ifvar}[@]" |
107 | gateways="gateways_${ifvar}[@]" |
| 66 | if [[ -z "${!gateways}" ]] ; then |
108 | if [[ -z "${!gateways}" ]] ; then |
| 67 | eerror "No gateways have been defined (gateways_${ifvar}=\"...\")" |
109 | eerror "No gateways have been defined (gateways_${ifvar}=( \"...\"))" |
| 68 | return 1 |
110 | return 1 |
| 69 | fi |
111 | fi |
| 70 | |
112 | |
| 71 | eindent |
113 | eindent |
| 72 | |
114 | |
| 73 | for x in ${!gateways}; do |
115 | for x in ${!gateways}; do |
|
|
116 | local -a a=( ${x//,/ } ) |
|
|
117 | local ip="${a[0]}" mac="${a[1]}" extra= |
|
|
118 | if [[ -n ${mac} ]] ; then |
|
|
119 | mac="$(echo "${mac}" | tr '[:lower:]' '[:upper:]')" |
|
|
120 | extra="(MAC ${mac})" |
|
|
121 | fi |
|
|
122 | |
| 74 | vebegin "${x}" |
123 | vebegin "${ip} ${extra}" |
| 75 | if arping_address_exists "${iface}" "${x}" ; then |
124 | if arping_address_exists "${iface}" "${ip}" "${mac}" ; then |
| 76 | for i in ${x//./ } ; do |
125 | for i in ${ip//./ } ; do |
| 77 | if [[ ${#i} == "2" ]] ; then |
126 | if [[ ${#i} == "2" ]] ; then |
| 78 | conf="${conf}0${i}" |
127 | conf="${conf}0${i}" |
| 79 | elif [[ ${#i} == "1" ]] ; then |
128 | elif [[ ${#i} == "1" ]] ; then |
| 80 | conf="${conf}00${i}" |
129 | conf="${conf}00${i}" |
| 81 | else |
130 | else |
| 82 | conf="${conf}${i}" |
131 | conf="${conf}${i}" |
| 83 | fi |
132 | fi |
| 84 | done |
133 | done |
|
|
134 | [[ -n ${mac} ]] && conf="${conf}_${mac//:/}" |
|
|
135 | |
| 85 | veend 0 |
136 | veend 0 |
| 86 | eoutdent |
137 | eoutdent |
| 87 | veinfo "Configuring ${iface} for ${x}" |
138 | veinfo "Configuring ${iface} for ${ip} ${extra}" |
| 88 | configure_variables "${iface}" "${conf}" |
139 | configure_variables "${iface}" "${conf}" |
| 89 | |
140 | |
| 90 | # Call the system module as we've aleady passed it by .... |
141 | # Call the system module as we've aleady passed it by .... |
| 91 | # And it *has* to be pre_start for other things to work correctly |
142 | # And it *has* to be pre_start for other things to work correctly |
| 92 | system_pre_start "${iface}" |
143 | system_pre_start "${iface}" |
| 93 | |
144 | |
| 94 | t="config_${ifvar}[@]" |
145 | t="config_${ifvar}[@]" |
|
|
146 | |
|
|
147 | # Only return if we HAVE a config that doesn't include |
|
|
148 | # arping to avoid infinite recursion. |
|
|
149 | if [[ " ${!t} " != *" arping "* ]] ; then |
| 95 | config=( "${!t}" ) |
150 | config=( "${!t}" ) |
| 96 | t="fallback_config_${ifvar}[@]" |
151 | t="fallback_config_${ifvar}[@]" |
| 97 | fallback_config=( "${!t}" ) |
152 | fallback_config=( "${!t}" ) |
| 98 | t="fallback_route_${ifvar}[@]" |
153 | t="fallback_route_${ifvar}[@]" |
| 99 | fallback_route=( "${!t}" ) |
154 | fallback_route=( "${!t}" ) |
| 100 | config_counter=-1 |
155 | config_counter=-1 |
| 101 | return 0 |
156 | return 0 |
|
|
157 | fi |
| 102 | fi |
158 | fi |
| 103 | veend 1 |
159 | veend 1 |
| 104 | done |
160 | done |
| 105 | |
161 | |
| 106 | eoutdent |
162 | eoutdent |