#!/usr/bin/env bash :<<'_COMMENTS_' =============================================================================== FILE: get-inet-addrs USAGE: Make file executable or: bash /path/to/get-inet-addrs DESCRIPTION: For network interfaces on a GNU/Linux host with ipv4 addresses assigned get network address info by querying the /proc pseudo-filesystem. OPTIONS: --- REQUIREMENTS: --- BUGS: --- NOTES: Credit: Felix Hauri (www.f-hauri.ch) see http://stackoverflow.com/questions/5281341 Version 1.1 cleans up script layout; no code changes. AUTHOR: G. D. LaBossiere, Xview Solutions Inc. EMAIL: code@XviewSolutions.com VERSION: 1.1 CREATED: 2014-07-06 (Version 1.0) REVISION: 2022-10-19 LICENSE: GNU GPL v3 =============================================================================== _COMMENTS_ #------------------------------------------------------------------------------ # functions #------------------------------------------------------------------------------ # accepts 2 params; invert the order (endianness) of 2nd param's 4 hex values #+ (8 characters), convert to decimal string, assign value to 1st param hex_to_decimal() { printf -v ${1} "%d\n" "0x${2:6:2}${2:4:2}${2:2:2}${2:0:2}" } #------------------------------------------------------------------------------ # accepts 4 params; convert 2nd, 3rd and 4th params from decimal strings to #+ ipv4 addresses (4 octets) and assign values to 1st param decimal_to_network() { local decVal netVal netVal=${1} shift for decVal; do printf -v ${netVal} "%s %s.%s.%s.%s" "${!netVal}" "$(($decVal>>24))" \ "$(($decVal>>16&255))" "$(($decVal>>8&255))" "$(($decVal&255))" done } #------------------------------------------------------------------------------ # accepts 2 params; convert 2nd param decimal string to netmask bit value and #+ assign value to 1st param decimal_to_bits() { local int for ((int=0; int<32 && (1&${2}>>(31-int)); int++)); do :; done printf -v ${1} "%d" "${int}" } #------------------------------------------------------------------------------ # main #------------------------------------------------------------------------------ addressDecVal="" eachConnection="" netmaskDecVal="" networkDecVal="" printFormat="" thisConnection=() thisAddress="" thisMask="" thisRoute=() while read -a thisRoute; do # lines in /proc/net/route where Gateway is 00000000 and Mask is not 00000000 if [[ ${thisRoute[2]} == "00000000" ]] && \ [[ ${thisRoute[7]} != "00000000" ]]; then # convert hex values to decimal strings hex_to_decimal networkDecVal ${thisRoute[1]} hex_to_decimal netmaskDecVal ${thisRoute[7]} # no double-brackets '[[ ]]' else the test will fail if [ $((networkDecVal&netmaskDecVal)) == ${networkDecVal} ]; then # loop thru /proc/net/{tcp,udp} for eachConnection in /proc/net/{tcp,udp}; do # chop each line into fields delimited by colons, spaces, tabs or newlines while IFS=': \t\n' read -a thisConnection; do # if 'local_address' field starts with valid hex character... if [[ ${thisConnection[1]} =~ ^[0-9a-fA-F]*$ ]]; then # ...convert hex value to decimal string and... hex_to_decimal addressDecVal ${thisConnection[1]} # ...pop up 3 levels; no double-brackets '[[ ]]' else the test will fail [ $((addressDecVal&netmaskDecVal)) == ${networkDecVal} ] && break 3 fi done < ${eachConnection} done fi fi done < /proc/net/route # get netmask bit value decimal_to_bits thisMask ${netmaskDecVal} # convert decimal strings to network octets decimal_to_network thisAddress ${addressDecVal} ${networkDecVal} \ ${netmaskDecVal} printf -v printFormat '%-12s: %%s\\n' Interface Address Network Netmask \ Mask\ Length # ${thisRoute[0]} holds the interface name, e.g. eth0 printf "${printFormat}" ${thisRoute[0]} ${thisAddress} ${thisMask}\ bits exit 0