-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathInterfaceUtils.sh
More file actions
executable file
·251 lines (212 loc) · 8.65 KB
/
InterfaceUtils.sh
File metadata and controls
executable file
·251 lines (212 loc) · 8.65 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/usr/bin/env bash
#if [ "$InterfaceUtilsVersion" ]; then return 0; fi
#readonly InterfaceUtilsVersion="1.0"
# The methods used in this script are taken from airmon-ng.
# This is all thanks for the airmon-ng authors, thanks guys.
InterfaceUtilsOutputDevice="/dev/stdout"
if [ -d /sys/bus/usb ] # && hash lsusb;
then InterfaceUSBBus=1
fi
if [ -d /sys/bus/pci -o -d /sys/bus/pci_express -o -d /proc/bus/pci ] # && hash lspci;
then InterfacePCIBus=1
fi
# Checks if the interface belongs to a physical device.
function interface_is_real() {
test -d /sys/class/net/$1/device
return $?
}
# Checks if the interface belongs to a wireless device.
function interface_is_wireless() {
grep -qs "DEVTYPE=wlan" /sys/class/net/$1/uevent
return $?
}
# Returns an array of absolutely all interfaces.
# Notice: That includes interfaces such as the loopback interface.
function interface_list_all() {
InterfaceListAll=(/sys/class/net/*)
InterfaceListAll=("${InterfaceListAll[@]//\/sys\/class\/net\//}")
}
# Returns an array of interfaces pertaining to a wireless device.
function interface_list_wireless() {
InterfaceListWireless=()
interface_list_all
local __interface_list_wireless__candidate
for __interface_list_wireless__candidate in "${InterfaceListAll[@]}"; do
if interface_is_wireless $__interface_list_wireless__candidate; then InterfaceListWireless+=("$__interface_list_wireless__candidate")
fi
done
}
function interface_driver() {
InterfaceDriver=$(basename $(readlink /sys/class/net/$1/device/driver))
}
function interface_physical() {
if [ ! "$1" ]; then return 1; fi
unset InterfacePhysical
local -r interface_physical_path="/sys/class/net/$1/phy80211"
if [ -d "$interface_physical_path" ]; then
if [ -r "$interface_physical_path/name" ]; then InterfacePhysical="$(cat "$interface_physical_path/name")"
fi
if [ ! "${InterfacePhysical// /}" ]; then InterfacePhysical="$(ls -l "$interface_physical_path" | sed 's/^.*\/\([a-zA-Z0-9_-]*\)$/\1/')"
fi
fi
if [ ! "$InterfacePhysical" ]; then return 2; fi
}
function interface_hardware() {
if [ ! "$1" ]; then return 1; fi
local __interface_hardware__device="/sys/class/net/$1/device"
local __interface_hardware__hwinfo="$__interface_hardware__device/modalias"
InterfaceHardwareBus="$(cut -d ":" -f 1 "$__interface_hardware__hwinfo" 2>$InterfaceUtilsOutputDevice)"
case "$InterfaceHardwareBus" in
"usb") # Wanted to replace the line below with awk, but i'll probably just add complexity & issues (mawk vs gawk).
InterfaceHardwareID="$(cut -d ":" -f 2 $__interface_hardware__hwinfo | cut -b 1-10 | sed 's/^.//;s/p/:/')"
;;
"pci" | "pcmcia" | "sdio")
InterfaceHardwareID="$(cat "$__interface_hardware__device/vendor" 2>$InterfaceUtilsOutputDevice):$(cat "$__interface_hardware__device/device" 2>$InterfaceUtilsOutputDevice)"
;;
default) # The following will only work for USB devices.
InterfaceHardwareID="$(cat "$__interface_hardware__device/idVendor" 2>$InterfaceUtilsOutputDevice):$(cat "$__interface_hardware__device/idProduct" 2>$InterfaceUtilsOutputDevice)"
InterfaceHardwareBus="usb"
;; # This will be reset below if InterfaceHardwareID is invalid.
esac
# Check for invalid InterfaceHardwareID (starts or ends with :) .. not a happy face, still won't quote it.
if echo "$InterfaceHardwareID" | grep -Eq "^:|:$"; then
unset InterfaceHardwareID
unset InterfaceHardwareBus
return 2
else
# Remove any extraneous hex markers.
InterfaceHardwareID=${InterfaceHardwareID//0x/}
fi
}
function interface_chipset() {
# Clear previous values to avoid stale chipset info when detection fails.
InterfaceChipset=""
InterfaceHardwareBus=""
InterfaceHardwareID=""
if [ ! "$1" ]; then return 1; fi
if ! interface_hardware "$1"; then
InterfaceChipset="Unknown device chipset"
return 2
fi
case "$InterfaceHardwareBus" in
"usb")
if [ ! "$InterfaceUSBBus" ]; then return 3; fi
InterfaceChipset="$(lsusb -d "$InterfaceHardwareID" | head -n1 - | cut -f3- -d ":" | sed 's/^....//;s/ Network Connection//g;s/ Wireless Adapter//g;s/^ //')"
;;
"pci" | "pcmcia")
if [ ! "$InterfacePCIBus" ]; then return 4; fi
InterfaceChipset="$(lspci -d $InterfaceHardwareID | cut -f3- -d ":" | sed 's/Wireless LAN Controller //g;s/ Network Connection//g;s/ Wireless Adapter//;s/^ //')"
;;
"sdio")
if [[ "${InterfaceHardwareID,,}" == "02d0"* ]]; then InterfaceChipset=$(printf "Broadcom %d" 0x${InterfaceHardwareID:5})
else InterfaceChipset="Unknown chipset for SDIO device."
fi
;;
default)
InterfaceChipset="Unknown device chipset & device bus."
;;
esac
# Ensure we never leak a previous value on unexpected paths.
if [ -z "$InterfaceChipset" ]; then InterfaceChipset="Unknown device chipset"; fi
}
function interface_bands() {
if [ ! "$1" ]; then return 1; fi
InterfaceBands=""
interface_physical "$1"
if [ ! "$InterfacePhysical" ]; then return 2; fi
local __interface_bands__iw
__interface_bands__iw=$(command -v iw 2>/dev/null || echo /usr/sbin/iw)
if [ ! -x "$__interface_bands__iw" ]; then return 3; fi
local __interface_bands__info
__interface_bands__info=$("$__interface_bands__iw" phy "$InterfacePhysical" info 2>/dev/null)
if [ ! "$__interface_bands__info" ]; then return 4; fi
local __interface_bands__list=""
if echo "$__interface_bands__info" | grep -qE "24[0-9][0-9][.0-9]* MHz"; then __interface_bands__list="2.4GHz"; fi
if echo "$__interface_bands__info" | grep -qE "5[0-9]{3}[.0-9]* MHz"; then
[ "$__interface_bands__list" ] && __interface_bands__list="$__interface_bands__list/" || true
__interface_bands__list="${__interface_bands__list}5GHz"
fi
if echo "$__interface_bands__info" | grep -qE "6[0-9]{3}[.0-9]* MHz"; then
[ "$__interface_bands__list" ] && __interface_bands__list="$__interface_bands__list/" || true
__interface_bands__list="${__interface_bands__list}6GHz"
fi
InterfaceBands="${__interface_bands__list:-unknown}"
}
# Returns the bus type of a wireless interface (usb, pci, or unknown).
# Result is stored in InterfaceBus.
function interface_bus() {
if [ ! "$1" ]; then return 1; fi
InterfaceBus=""
local __device_path
__device_path=$(readlink -f "/sys/class/net/$1/device" 2>/dev/null)
if [ ! "$__device_path" ] || [ ! -d "$__device_path" ]; then
InterfaceBus="unknown"
return 2
fi
local __uevent="$__device_path/uevent"
if [ -f "$__uevent" ]; then
if grep -q "^MODALIAS=usb:" "$__uevent" 2>/dev/null; then
InterfaceBus="usb"; return 0
elif grep -q "^MODALIAS=pci:" "$__uevent" 2>/dev/null; then
InterfaceBus="pci"; return 0
elif grep -q "^MODALIAS=sdio:" "$__uevent" 2>/dev/null; then
InterfaceBus="sdio"; return 0
fi
fi
# Fallback: check the resolved device path for bus indicators.
if echo "$__device_path" | grep -q "/usb[0-9]*/"; then
InterfaceBus="usb"; return 0
fi
InterfaceBus="unknown"
}
function interface_state() {
if [ ! "$1" ]; then return 1; fi
local __interface_state__stateFile="/sys/class/net/$1/operstate"
if [ ! -f "$__interface_state__stateFile" ]; then return 2; fi
InterfaceState=$(cat "$__interface_state__stateFile")
}
function interface_set_state() {
if [ "${#@}" -ne 2 ]; then return 1; fi
# TODO: Add alternatives to 'ip' in case of failure.
ip link set "$1" "$2"
return $?
}
function interface_set_mode() {
if [ "${#@}" -ne 2 ]; then return 1; fi
if ! interface_set_state "$1" "down"; then return 2; fi
if ! iw dev "$1" set type "$2" &> $InterfaceUtilsOutputDevice; then
if ! iwconfig "$1" mode "$2" &> $InterfaceUtilsOutputDevice
then return 3
fi
fi
if ! interface_set_state "$1" "up"; then return 4; fi
}
function interface_reidentify() {
if [ ${#@} -ne 2 ]; then return 1; fi
local -r __interface_reidentify__oldIdentifier=$1
local -r __interface_reidentify__newIdentifier=$2
if [[ $__interface_reidentify__newIdentifier == *" "* ]]
then return 2
fi
# Check if interface already has the desired name
if [ "$__interface_reidentify__oldIdentifier" = "$__interface_reidentify__newIdentifier" ]; then
return 0
fi
if ! interface_set_state $__interface_reidentify__oldIdentifier down
then return 3
fi
# TODO: Add alternatives to 'ip' in case of failure.
ip link set $__interface_reidentify__oldIdentifier name $__interface_reidentify__newIdentifier 2>/dev/null
local result=$?
# If rename failed because name already exists, check if it's our interface
if [ $result -ne 0 ]; then
if ip link show "$__interface_reidentify__newIdentifier" &>/dev/null; then
# Name exists - if old interface is gone, assume it was already renamed
if ! ip link show "$__interface_reidentify__oldIdentifier" &>/dev/null; then
return 0
fi
fi
fi
return $result
}
# FLUXSCRIPT END