msgbartop
More than the bits & pieces
msgbarbottom

02 Jul 09 Parsing ifconfig output in PHP

I recently wrote a class to parse the output of ifcofig (on a debian-based system) and turn the list of interfaces and their attributes into a usable data structure.

Enjoy!

 
class NetworkConfig {
    /*
     * Pass the output of ifconfig into the constructor and this class will create a
     * usable data structure to access config info.  To define parsing fields for
     * the various link encapsulation types, modify the $baseFieldMap or
     * $encapFieldMap arrays as needed
     */
    private $interface = array();
 
    private $baseFieldMap  = array(
                            'rx'          => 'RX bytes:',
                            'tx'          => 'TX bytes:'
                            );
 
    private $encapFieldMap = array(
        'Ethernet'       => array(
                            'mac_address' => 'HWaddr ',
                            'ip_address'  => 'inet addr:',
                            'broadcast'   => 'Bcast:',
                            'netmask'     => 'Mask:'),
        'Local Loopback' => array(
                            'ip_address'  => 'inet addr:')
    );
 
    function __construct($config) {
        $interfaces = split("\n\n", $config);
 
        foreach ($interfaces as $if) {
            if (strlen(trim($if)) > 0) {
                $interface = new stdClass;
                $interface->name = substr($if, 0, strpos($if, " "));
 
                //$interface->raw_output = $if; // raw ifconfig output for the interface
                $interface->encapsulation = TextParser::extractBetween($if, "Link encap:", array("\n", "  "));
 
                $extractFields = $this->baseFieldMap;
                if (is_array($this->encapFieldMap[$interface->encapsulation]) && count($this->encapFieldMap[$interface->encapsulation]) > 0) {
                    $extractFields = array_merge($extractFields, $this->encapFieldMap[$interface->encapsulation]);
                }
 
                foreach ($extractFields as $field => $value) {
                    $interface->$field = TextParser::extractBetween($if, $value, array("\n", "  ", '  '));
                }
                $this->__set($interface->name, $interface);
            }
        }
    }
 
    public function __set($name, $value) {
        $this->interface[$name] = $value;
    }
 
    public function __get($name) {
        if (array_key_exists($name, $this->interface)) {
            return $this->interface[$name];
        }
        $trace = debug_backtrace();
        trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE);
        return null;
    }
 
    public function getInterfaceNames() {
        return array_keys($this->interface);
    }
 
    public function getInterfacesByType($type) {
        $return = array();
        $ifs = $this->getInterfaceNames();
        foreach ($ifs as $if) {
            $iface = $this->__get($if);
            if ($iface->encapsulation == $type) {
                $return[] = $iface;
            }
        }
        return $return;
    }
}
 
class TextParser {
    /*
     * $startInclusive - include the startString matched upon in the final output
     * $stopSting - can accept an array, and will match/terminate on the first value found in the string
    */
    public static function extractBetween(&$string, $startString, $stopString, $startInclusive = false) {
        $startAdd = 0;
        if ($startInclusive == false) {
            $startAdd = strlen($startString);
        }
        $startPos = strpos($string, $startString);
        $startPos += $startAdd;
 
        if (is_array($stopString)) {
            $stopCompare = array();
            foreach ($stopString as $ss) {
                $stp = (strpos($string, $ss, $startPos) - $startPos);
                if ($stp > 0) {
                    $stopCompare[] = $stp;
                }
            }
            if (count($stopCompare) == 0) {
                $extractionLength = 0;
            } else {
                $extractionLength = min($stopCompare);
            }
        } else {
            $extractionLength = (strpos($string, $stopString, $startPos) - $startPos);
        }
        //echo '$string: ' . $string . "\n" . '$extractionLength: ' . $extractionLength . "\n";
        //echo '$extractionLength: ' . $extractionLength . "\n";
        if ($extractionLength > 0) {
            $rtn = trim(substr($string, $startPos, $extractionLength));
        } elseif ($extractionLength < 0) {
            $rtn = trim(substr($string, $startPos));
        } else {
            $rtn = '';
        }
        return $rtn;
    }
}
 


Reader's Comments

  1. |

    Dmitri007-944…

    Замечательный сайт по технике на PHP http://digitaltechniks.ru/ на уровне профи…



Leave a Comment

You must be logged in to post a comment.