From b382bfa3aa3f8ef3b35d06c286b09bf9b19a5793 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sat, 15 Mar 2014 07:05:40 +0000 Subject: [PATCH] add system information gathering, in cfengine speek this will create our hard classes --- system_information.sh | 315 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100755 system_information.sh diff --git a/system_information.sh b/system_information.sh new file mode 100755 index 0000000..3d255d9 --- /dev/null +++ b/system_information.sh @@ -0,0 +1,315 @@ +#!/bin/dash + +## +# This is a first test what static informations I can gather from a +# system. The minimal requirement are the IP addresses because +# on these I build up my classes. +# The system type is also important...we might need to be running +# on variuous UNIX flavours. (But for now we focus on various linux +# flavours and maybe FreeBSD. +# + + +# Function calculates number of bit in a netmask +# +mask2cidr() { + local NBITS=0 + local OLDIFS="${IFS}" + IFS=. + + for DEC in $1 + do + case ${DEC} in + 255) NBITS=$((NBITS+8));; + 254) NBITS=$((NBITS+7));; + 252) NBITS=$((NBITS+6));; + 248) NBITS=$((NBITS+5));; + 240) NBITS=$((NBITS+4));; + 224) NBITS=$((NBITS+3));; + 192) NBITS=$((NBITS+2));; + 128) NBITS=$((NBITS+1));; + 0);; + *) NBITS=0; IFS="${OLDIFS}"; return 1 + esac + done + IFS="${OLDIFS}" + ${ECHO} "${NBITS}" +} + +cidr2mask() { + local MASK="" + local FULL_OCTETS=$((${1}/8)) + local PARTIAL_OCTET=$((${1}%8)) + + for I in 0 1 2 3 + do + if [ ${I} -lt ${FULL_OCTETS} ] + then + MASK="${MASK}255" + elif [ ${I} -eq ${FULL_OCTETS} ] + then + MASK="${MASK}$((256-(1<<(8-${PARTIAL_OCTET}))))" + else + MASK="${MASK}0" + fi + ${TEST} ${I} -lt 3 && MASK="${MASK}." + done + + ${ECHO} ${MASK} +} + +## +# 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. +# +get_if_data() { + if [ ${IP} ] + then + eval $(${IP} -o link | ${AWK} '{ + sub(/:/,"",$1); + no=$1; + sub(/:/,"",$2); + name=$2; + for (i=3; i /etc/SuSE-release +# 00 02 - Red Hat ---> /etc/redhat-release, /etc/redhat_version +# 00 04 - Fedora ---> /etc/fedora-release +# 00 08 - Slackware ---> /etc/slackware-release, /etc/slackware-version +# 00 10 - Debian ---> /etc/debian_release, /etc/debian_version +# 00 20 - Mandrake ---> /etc/mandrake-release +# 00 40 - Yellow dog ---> /etc/yellowdog-release +# 00 80 - Sun JDS ---> /etc/sun-release +# 01 00 - Solaris/Sparc ---> /etc/release +# 02 00 - Gentoo ---> /etc/gentoo-release +# +# Here I follow a pessimistic way because I prefere to have no +# identification at all over a wrong one...so I check for all these files. +# If I can't find any or find multiple of them I assume this system +# as unidentified. Anyway when I found one I still check the content... +# Here I need some help as I don't know the valid content of these files. +# For now I assume that at least the name of the distribution is in +# the file. +# +get_dist_info() { + if [ -z "${KERNEL}" ] + then + get_host_info + fi + + if [ "Linux" = "${KERNEL}" ] + then + local SUSE=1 + local REDHAT=2 + local FEDORA=4 + local SLACKWARE=8 + local DEBIAN=16 + local MANDRAKE=32 + local YELLOWDOG=64 + local SUNJDS=128 + local GENTOO=256 + local SOLARIS=512 + + local LAST=${SOLARIS} + + local CHK=$((SUSE|REDHAT|FEDORA|SLACKWARE|DEBIAN|MANDRAKE|\ + YELLOWDOG|SUNJDS|GENTOO|SOLARIS)) + + eval local FILES_${SUSE}=\'/etc/SuSE-release\' + eval local FILES_${REDHAT}=\'/etc/redhat-release /etc/redhat_version\' + eval local FILES_${FEDORA}=\'/etc/fedora-release\' + eval local FILES_${SLACKWARE}=\'/etc/slackware-release /etc/slackware-version\' + eval local FILES_${DEBIAN}=\'/etc/debian_release /etc/debian_version\' + eval local FILES_${MANDRAKE}=\'/etc/mandrake-release\' + eval local FILES_${YELLOWDOG}=\'/etc/yellowdog-release\' + eval local FILES_${SUNJDS}=\'/etc/sun-release\' + eval local FILES_${GENTOO}=\'/etc/gentoo-release\' + eval local FILES_${SOLARIS}=\'/etc/release\' + + local CUR=1 + while [ ${CUR} -le ${LAST} ] + do + local DIR + + eval local FILES=\"\${FILES_${CUR}}\" + + for DIR in ${FILES} + do + ${TEST} -f ${DIR} || CHK=$((CHK&~CUR)) + done + + CUR=$((CUR*2)) + done + + DIST="Unknown" + + ${TEST} ${CHK} -eq ${SUSE} && DIST="Suse" + ${TEST} ${CHK} -eq ${REDHAT} && DIST="Redhat" + ${TEST} ${CHK} -eq ${FEDORA} && DIST="Fedora" + ${TEST} ${CHK} -eq ${SLACKWARE} && DIST="Slakware" + ${TEST} ${CHK} -eq ${DEBIAN} && DIST="Debian" + ${TEST} ${CHK} -eq ${MANDRAKE} && DIST="Mandrake" + ${TEST} ${CHK} -eq ${YELLOWDOG} && DIST="Yellowdog" + ${TEST} ${CHK} -eq ${SUNJDS} && DIST="Sun" + ${TEST} ${CHK} -eq ${GENTOO} && DIST="Gentoo" + ${TEST} ${CHK} -eq ${SOLARIS} && DIST="Solaris" + + if [ 'Unknown' != "${DIST}" ] + then + eval ${GREP} -iq ${DIST} \${FILES_${CHK}} || DIST="Unknown" + fi + + CLASSES="${CLASSES}${DIST} " + else + DIST="${OS}" + fi +} + +## +# Here now starts the usage of the functions defined above. +# + +## +# first specify some programs +# +WHICH="/usr/bin/which" +UNAME="$(${WHICH} uname)" +TEST="$(${WHICH} test)" +GREP="$(${WHICH} grep)" +AWK="$(${WHICH} awk)" +ECHO="$(${WHICH} echo)" +SORT="$(${WHICH} sort)" +TR="$(${WHICH} tr)" +PRINTF="$(${WHICH} printf)" +LOGGER="$(${WHICH} logger)" +IP="$(${WHICH} ip)" +IFCONFIG="$(${WHICH} ifconfig)" + +get_dist_info +get_if_data + +## +# report everysthing +# + +${PRINTF} "%15s : %s\n" "OS" "${OS}" +${PRINTF} "%15s : %s\n" "KERNEL" "${KERNEL}" +${PRINTF} "%15s : %s\n" "VERSION" "${VERSION}" +${PRINTF} "%15s : %s\n" "PLATFORM" "${PLATFORM}" +${PRINTF} "%15s : %s\n" "DIST" "${DIST}" +${PRINTF} "%15s : %s\n" "HOSTNAME" "${HOSTNAME}" +${PRINTF} "%15s : %s\n" "# INTERFACES" "${NINTERFACES}" + +NO=1 +while [ ${NO} -le ${NINTERFACES:=0} ] +do + eval printf \"%15s : %s\\\n\" \"IF${NO}_NAME\" \"\${IF${NO}_NAME}\" + eval printf \"%15s : %s\\\n\" \"IF${NO}_MAC\" \"\${IF${NO}_MAC}\" + eval printf \"%15s : %s\\\n\" \"IF${NO}_STATE\" \"\${IF${NO}_STATE}\" + eval printf \"%15s : %s\\\n\" \"IF${NO}_IPV4\" \"\${IF${NO}_IPV4}\" + eval printf \"%15s : %s\\\n\" \"IF${NO}_IPV6\" \"\${IF${NO}_IPV6}\" + NO=$((NO+1)) +done + +${PRINTF} "%15s : %s\n" "CLASSES" "${CLASSES}" + +echo +echo $(mask2cidr 255.255.128.0) +echo $(cidr2mask 17) +eval echo \$\(cidr2mask $(mask2cidr 255.255.128.0)\) + +# vim: set ts=4 sw=4: