You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.0 KiB
241 lines
6.0 KiB
##
|
|
# \file
|
|
|
|
# To each interface a set of caller functions exist, that take an instance
|
|
# of an object and then in turn call the implementation for the class of
|
|
# this object. If there is none within the class it looks into its
|
|
# parent class and so forth.
|
|
#
|
|
# This is somewhat similar to late binding in real OOP languages, but
|
|
# by far not so elaborated. This is not a real object oriented language
|
|
# and will surely never ever provide all features these have.
|
|
#
|
|
# That said it has proven very usefull for me to orgnize code and prevent
|
|
# code duplication.
|
|
#
|
|
# \author Georg Hopp
|
|
#
|
|
# \copyright
|
|
# Copyright © 2014 Georg Hopp
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
##
|
|
# retrieve interfaces. I prefer using ip if it is
|
|
# available, else I fallback to ifconfig... don't know
|
|
# how to retrieve this information on other systems.
|
|
# This also exports the environment variables.
|
|
#
|
|
gather_interface_info() {
|
|
[ -z "${NINTERFACES}" ] || return
|
|
|
|
local NO=1
|
|
|
|
if [ ${IP} ]
|
|
then
|
|
gather_if_info_ip
|
|
else
|
|
if [ ${IFCONFIG} ]
|
|
then
|
|
gather_if_info_ifconfig
|
|
else
|
|
${LOGGER} -p local0.warn 'Found no way to retrieve interface information.'
|
|
fi
|
|
fi
|
|
|
|
export NINTERFACES
|
|
|
|
while [ ${NO} -le ${NINTERFACES:=0} ]
|
|
do
|
|
export IF${NO}_NAME IF${NO}_MAC IF${NO}_STATE IF${NO}_IPV4 IF${NO}_IPV6
|
|
NO=$((NO+1))
|
|
done
|
|
}
|
|
|
|
##
|
|
# get the interface information from the ip tool
|
|
#
|
|
gather_if_info_ip() {
|
|
eval $(${IP} -o link | ${AWK} '{
|
|
sub(/:/,"",$1);
|
|
ifno=$1;
|
|
sub(/:/,"",$2);
|
|
name=$2;
|
|
classes=classes "net_iface_" name " ";
|
|
for (i=3; i<NF; i++) {
|
|
if ($i == "state") {
|
|
i++; state=$i
|
|
}
|
|
if ($i ~ /link/) {
|
|
i++; mac=$i;
|
|
classes=classes mac " "
|
|
}
|
|
}
|
|
print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";";
|
|
if ("UP" == state) classes=classes mac " ";
|
|
if_numbers=if_numbers " " ifno;
|
|
no+=1
|
|
}
|
|
BEGIN {
|
|
classes="";
|
|
no=1;
|
|
if_numbers=""
|
|
}
|
|
END {
|
|
print "set_class " classes ";";
|
|
print "NINTERFACES=" FNR ";"
|
|
sub(/^ */,"",if_numbers);
|
|
sub(/ *$/,"",if_numbers);
|
|
print "IF_NUMBERS=\"" if_numbers "\";";
|
|
}')
|
|
|
|
eval $(${IP} -o addr | ${AWK} -v if_numbers="${IF_NUMBERS}" '{
|
|
sub(/:/,"",$1);
|
|
if_no=$1;
|
|
no=r_if_numbers[if_no];
|
|
if ($3 == "inet") {
|
|
split($4,addr,/[\/]/);
|
|
ipv4=ipv4 addr[1] " ";
|
|
network(no, addr[1], addr[2]);
|
|
classes=classes addr[1] " "
|
|
}
|
|
if ($3 == "inet6") {
|
|
split($4,addr,/[\/]/);
|
|
ipv6=ipv6 addr[1] " ";
|
|
classes=classes addr[1] " "
|
|
}
|
|
}
|
|
$1 != current_if {
|
|
print "IF" no "_IPV4=\"" ipv4 "\";";
|
|
print "IF" no "_IPV6=\"" ipv6 " \";";
|
|
print "IF" no "_NETWORK=\"" networks "\";";
|
|
print "IF" no "_MASK=\"" netmasks "\";";
|
|
current_if=$1;
|
|
ipv6=ipv4="";
|
|
networks=netmasks="";
|
|
}
|
|
BEGIN {
|
|
classes="";
|
|
sub(/^ */,"",if_numbers);
|
|
sub(/ *$/,"",if_numbers);
|
|
split(if_numbers,tmp_array,/ /);
|
|
for(no in tmp_array) {
|
|
if_no=tmp_array[no];
|
|
r_if_numbers[if_no]=no;
|
|
}
|
|
current_if=$1;
|
|
}
|
|
END {
|
|
print "set_class " classes ";"
|
|
}
|
|
function network(no, addr, cidr) {
|
|
mask="";
|
|
net="";
|
|
full_octets=cidr/8;
|
|
part_octets=cidr%8;
|
|
split(addr,parts,/\./);
|
|
for(i=1; i<5; i++) {
|
|
if(i-1 < full_octets) {
|
|
mask=mask "255";
|
|
net=net parts[i];
|
|
} else {
|
|
if (i-1 == full_octets) {
|
|
mpart=256-lshift(1, 8-part_octets);
|
|
mask=mask mpart;
|
|
net=net and(parts[i],mpart);
|
|
} else {
|
|
mask=mask "0";
|
|
net=net "0";
|
|
}
|
|
}
|
|
if (i < 4) {
|
|
mask=mask ".";
|
|
net=net ".";
|
|
}
|
|
}
|
|
classes=classes net " ";
|
|
networks=networks net " ";
|
|
netmasks=netmasks mask " ";
|
|
}')
|
|
}
|
|
|
|
##
|
|
# get interface data via the ifconfig tool
|
|
# FIXME This is outdated. It does not set classes at all.
|
|
#
|
|
gather_if_info_ifconfig() {
|
|
eval $(${IFCONFIG} -a | ${AWK} --non-decimal-data '
|
|
/^[^ \t]/ {
|
|
if ("UP" == state) classes=classes mac " ";
|
|
if ("" != name) {
|
|
print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";" \
|
|
"IF" no "_IPV4=\"" ipv4 "\";" \
|
|
"IF" no "_IPV6=\"" ipv6 "\";" \
|
|
"IF" no "_NETWORK=\"" networks "\";" \
|
|
"IF" no "_MASK=\"" netmasks "\";";
|
|
no++;
|
|
}
|
|
ipv4=ipv6=mac="";
|
|
networks=netmasks="";
|
|
sub(/:/,"",$1);
|
|
name=$1;
|
|
state="DOWN";
|
|
}
|
|
/ether/ { mac=$2 }
|
|
/inet / {
|
|
ipv4=ipv4 $2 " ";
|
|
if("0x" == substr($4,0,2)) {
|
|
mask=netmask sprintf("%d.%d.%d.%d ",
|
|
"0x" substr($4,2,2),
|
|
"0x" substr($4,4,2),
|
|
"0x" substr($4,6,2),
|
|
"0x" substr($4,8,2));
|
|
} else {
|
|
mask=mask $4 " ";
|
|
}
|
|
split($2,parts,/\./);
|
|
split(mask,mparts,/\./);
|
|
for(i=1; i<5; i++) {
|
|
net=net and(parts[i],mparts[i]);
|
|
if(i < 4) net=net ".";
|
|
}
|
|
classes=classes $2 " ";
|
|
classes=classes net " ";
|
|
networks=networks net " ";
|
|
netmasks=netmasks mask " ";
|
|
}
|
|
/inet6/ {
|
|
sub(/%.*/,"",$2);
|
|
ipv6=ipv6 $2 " ";
|
|
classes=classes $2 " "
|
|
}
|
|
(/status/ && /active/) || /^lo[0-9]/ { state="UP" }
|
|
BEGIN {
|
|
classes="";
|
|
state="DOWN";
|
|
no=1;
|
|
mac="";
|
|
}
|
|
END {
|
|
if ("UP" == state) classes=classes mac " ";
|
|
print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";" \
|
|
"IF" no "_IPV4=\"${IF" no "_IPV4}" ipv4 " \";" \
|
|
"IF" no "_IPV6=\"${IF" no "_IPV6}" ipv6 " \";";
|
|
print "set_class " classes ";";
|
|
print "NINTERFACES=" no
|
|
}')
|
|
}
|
|
|
|
# vim: set ts=4 sw=4:
|