Net_MAC
[ class tree: Net_MAC ] [ index: Net_MAC ] [ all elements ]

Source for file MAC.php

Documentation is available at MAC.php

  1. <?php // -*- mode:php; tab-width:4; c-basic-offset:4; intent-tabs-mode:nil; -*-
  2. /* 
  3.  * This file contains the MAC class
  4.  *
  5.  * Copyright (c) 2006 Andrew Teixeira
  6.  *
  7.  * PHP Version 5
  8.  *
  9.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  10.  * that is available through the world-wide-web at the following URI:
  11.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  12.  * the PHP License and are unable to obtain it through the web, please
  13.  * send a note to license@php.net so we can mail you a copy immediately.
  14.  *
  15.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  16.  * @link      http://pear.php.net/package/Net_MAC
  17.  * @author    Andrew Teixeira <ateixeira@gmail.com>
  18.  *
  19.  * $Id: MAC.php,v 1.6 2007/05/01 18:03:57 atex Exp $
  20.  */
  21.  
  22. /**
  23.  * Require PEAR/Exception.php since we will be using PEAR Exceptions
  24.  * in this class.
  25.  */
  26. require_once 'PEAR/Exception.php';
  27.  
  28. /**
  29.  * Constant to represent the maximum length of a line in the
  30.  * manufacturers file.
  31.  */
  32. define('NET_MAC_LINE_MAXLENGTH'256);
  33.  
  34. /**
  35.  * Error constant: signifies no problem (OK)
  36.  */
  37. define('NET_MAC_ERROR_OK'0);
  38.  
  39. /**
  40.  * Error constant: signifies a bad option being passed to a function
  41.  */
  42. define('NET_MAC_ERROR_BADOPT'1);
  43.  
  44. /**
  45.  * Error constant: signifies bad data being passed to a function
  46.  */
  47. define('NET_MAC_ERROR_BADDATA'2);
  48.  
  49. /**
  50.  * Error constant: signifies a bad database connection
  51.  */
  52. define('NET_MAC_ERROR_BADDB'3);
  53.  
  54. /**
  55.  * Error constant: signifies a bad manufacturers file
  56.  */
  57. define('NET_MAC_ERROR_BADFILE'4);
  58.  
  59.  
  60. /**
  61.  * Extension of the main PEAR_Exception Class for use with the Net_MAC
  62.  * class.
  63.  *
  64.  * @package   Net_MAC
  65.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  66.  * @link      http://pear.php.net/package/Net_MAC
  67.  * @version   1.0
  68.  * @author    Andrew Teixeira <ateixeira@gmail.com>
  69.  *
  70.  * @access    public
  71.  */
  72. class Net_MAC_Exception extends PEAR_Exception {}
  73.  
  74.  
  75. /**
  76.  * Class to validate and cleanly format Media Access Control (MAC)
  77.  * addresses
  78.  *
  79.  * @package   Net_MAC
  80.  * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
  81.  * @link      http://pear.php.net/package/Net_MAC
  82.  * @version   1.0
  83.  * @author    Andrew Teixeira <ateixeira@gmail.com>
  84.  *
  85.  * @access    public
  86.  */
  87. class Net_MAC
  88. {
  89.     /**
  90.      * The MAC address to work on.
  91.      *
  92.      * @access protected
  93.      * @var string 
  94.      */
  95.     protected $_macaddr;
  96.  
  97.     /**
  98.      * A database instance to use in looking up MAC-to-vendor
  99.      * relationships.
  100.      *
  101.      * @access protected
  102.      * @var object 
  103.      */
  104.     protected $_db;
  105.  
  106.     /**
  107.      * The options to use while connecting to the database.
  108.      *
  109.      * @access protected
  110.      * @var array 
  111.      */
  112.     protected $_dbOptions;
  113.  
  114.     /**
  115.      * The default constructor
  116.      *
  117.      * This is the default constructor that will create and populate a
  118.      * valid Net_MAC object.
  119.      *
  120.      * @access public
  121.      *
  122.      * @param object &$db A valid instantiated {@link }
  123.      *  http://pear.php.net/package/MDB2/ MDB2} object to use when
  124.      *  adding/retrieving information from the database for MAC address
  125.      *  vendors
  126.      * @param array $options An array of options to use with the
  127.      *  database in retrieving MAC address vendors.  The associative
  128.      *  array should have key/value pairs as follows:
  129.      *
  130.      *  <ul>
  131.      *   <li><b>tablename</b>: The name of the table where MAC address
  132.      *   vendor information lives</li>
  133.      *   <li><b>macaddrcol</b>: The name of the column containing the
  134.      *   MAC address prefixes</li>
  135.      *   <li><b>vendorcol</b>: The name of the column containing the
  136.      *   vendor name</li>
  137.      *   <li><b>desccol</b>: The name of the column containing any
  138.      *   extra descriptive information derived from the vendor list</li>
  139.      *  </ul>
  140.      *
  141.      * @return void No return value.  A {@link Net_MAC_Exception}
  142.      *  Net_MAC_Exception} Exception object will be thrown if there is
  143.      *  an error during construction so the constructor should be
  144.      *  called from a try/catch block
  145.      */
  146.     function __construct(&$db$options = NULL{
  147.         require_once 'MDB2.php';
  148.  
  149.         $this->_db = NULL;
  150.         $this->_macaddr = NULL;
  151.         $this->_dbOptions = NULL;
  152.     
  153.         if (!$db instanceof MDB2_Driver_Common{
  154.             throw new Net_MAC_Exception('Bad database object'NET_MAC_ERROR_BADDB);
  155.         }
  156.  
  157.         if (!is_array($options)) {
  158.             throw new Net_MAC_Exception('Second parameter must be an array'NET_MAC_ERROR_BADOPT);
  159.         }
  160.  
  161.         if (!isset($options['tablename'])) {
  162.             throw new Net_MAC_Exception('No table name given in options'NET_MAC_ERROR_BADDATA);
  163.         }
  164.  
  165.         if (!isset($options['macaddrcol'])) {
  166.             throw new Net_MAC_Exception('No MAC address column name given in options'NET_MAC_ERROR_BADDATA);
  167.         }
  168.  
  169.         if (!isset($options['vendorcol'])) {
  170.             throw new Net_MAC_Exception('No vendor column name given in options'NET_MAC_ERROR_BADDATA);
  171.         }
  172.  
  173.         if (!isset($options['desccol'])) {
  174.             throw new Net_MAC_Exception('No description column name given in options'NET_MAC_ERROR_BADDATA);
  175.         }
  176.  
  177.         $this->_db = $db;
  178.         $this->_db->loadModule('Extended');
  179.         $this->_dbOptions = $options;
  180.     /* end default constructor */
  181.  
  182.     /**
  183.      * Checks a MAC address
  184.      *
  185.      * This function will check a MAC address to make sure it is
  186.      * valid.
  187.      *
  188.      * @access static
  189.      *
  190.      * @param string $input The string containing the MAC Address
  191.      * @param string $delimiter The string representing the delimiter
  192.      *  to use when verifying the MAC Address
  193.      *
  194.      * @return string <b>true</b> if the MAC address is valid,
  195.      *  <b>false</b> otherwise
  196.      */
  197.     static function check($input$delimiter ':')
  198.     {
  199.         // Check for 6 octets without any punctuation
  200.         $retval preg_match('/^([0-9a-fA-F][0-9a-fA-F]\Q'.$delimiter.'\E){5}([0-9a-fA-F][0-9a-fA-F]){1}$/'$input);
  201.                     
  202.         return $retval;
  203.     /* end method check */
  204.  
  205.     /**
  206.      * Sets the MAC address
  207.      *
  208.      * This method will set the MAC address in the class.
  209.      *
  210.      * @access public
  211.      *
  212.      * @param string $macaddr The string representing the MAC address
  213.      * @param string $delimiter The string representing the delimiter
  214.      *  to use when verifying the MAC Address
  215.      *
  216.      * @return bool Returns <b>true</b> if the MAC address is set
  217.      *  correctly, <b>false</b> otherwise
  218.      */
  219.     function setMAC($macaddr$delimiter ':')
  220.     {
  221.         $validMAC = self::check($macaddr$delimiter);
  222.         if ($validMAC{
  223.             $this->_macaddr = $macaddr;
  224.             return true;
  225.         }
  226.  
  227.         return false;
  228.     /* end method setMac */
  229.  
  230.     /**
  231.      * Formats a MAC address
  232.      *
  233.      * This function will format a MAC address into XX:XX:XX:XX:XX:XX
  234.      * format from whatever format is passed to the function.  The
  235.      * delimiter (: in the example above) will be replaced with
  236.      * whatever string is passed to the $delimiter parameter
  237.      * (default :).
  238.      *
  239.      * @access static
  240.      *
  241.      * @param string $input The string containing the MAC Address
  242.      * @param string $delimiter The string representing the delimiter
  243.      *  to use when formatting the MAC Address
  244.      * @param bool $uppercase If set to true (default), the
  245.      *  hexadecimal values in the MAC Address will be returned in
  246.      *  uppercase.  If false, the hexadecimal values will be returned
  247.      *  in lowercase.
  248.      *
  249.      * @return string The formatted MAC Address or <b>false</b> on
  250.      *  error
  251.      */
  252.     static function format($input$delimiter ':'$uppercase = true)
  253.     {
  254.         /* Replace all characters not in a valid MAC address with
  255.          * nothing.  We are going to be testing for a MAC address as
  256.          * XXXXXXXXXXXX instead of XX:XX:XX:XX:XX:XX
  257.          */
  258.         $macaddr preg_replace('/[g-zG-Z]*\W*_*/'''$input);
  259.         
  260.         /* If $uppercase is true, set all the alpha characters to
  261.          * uppercase, otherwise set all the alpha characters to
  262.          * lowercase 
  263.          */
  264.         $macaddr ($uppercasestrtoupper($macaddrstrtolower($macaddr);
  265.  
  266.         // Check for 6 octets without any punctuation
  267.         if (!preg_match('/^([0-9a-fA-F][0-9a-fA-F]){6}$/'$macaddr)) {
  268.             return false;
  269.         }
  270.             
  271.         // Add back in the $delimiter delimiters
  272.         $macaddr preg_replace('/([0-9a-fA-F][0-9a-fA-F]){1}/''$1' $delimiter$macaddr);
  273.  
  274.         // Remove the trailing $delimiter
  275.         $macaddr preg_replace('/' $delimiter '$/'''$macaddr);
  276.  
  277.         return $macaddr;
  278.     /* end method format */
  279.  
  280.     /**
  281.      * Import a manufacturers' file to the database
  282.      *
  283.      * This method will parse a manufacturers' file, such as the one
  284.      * from {@link }
  285.      * http://anonsvn.wireshark.org/wireshark/trunk/manuf}, containing
  286.      * a list of MAC address prefix-to-vendor relationships.  If the
  287.      * $doReturn parameter is <b>false</b>, then the data will be
  288.      * imported into the database defined by the factory of this
  289.      * class.  However, if $doReturn is <b>true</b>, then the return
  290.      * will be an associative array with the key being the MAC address
  291.      * prefix and the data being an associative array with the keys
  292.      * 'vendor' and 'description'.
  293.      *
  294.      * @access public
  295.      *
  296.      * @param string $file The filename or URL of the manufacturers'
  297.      *  file to parse.
  298.      * @param bool $doReturn If <b>true</b>, an array will be
  299.      *  returned, if <b>false</b>, the data will be imported into the
  300.      *  database. (default: false)
  301.      *
  302.      * @return mixed If $doReturn is true, the method will return an
  303.      *  array.  Otherwise, the method will return <b>true</b> on
  304.      *  success.  A {@link Net_MAC_Exception Net_MAC_Exception}
  305.      *  Exception object will be thrown on failure in either case.
  306.      */
  307.     function importVendors($file$doReturn = false{
  308.         if ($file == NULL{
  309.             throw new Net_MAC_Exception('No file or URL given'NET_MAC_ERROR_BADFILE);
  310.         }
  311.  
  312.         $fp @fopen($file'r');
  313.         if ($fp == false{
  314.             throw new Net_MAC_Exception('Cannot open the file or URL given'NET_MAC_ERROR_BADFILE);
  315.         }
  316.  
  317.         if ($doReturn{
  318.             $retArr = array();
  319.         }
  320.         else {
  321.             // Prepare parameters for MDB2->buildManipSQL()
  322.             $fields = array ($this->_dbOptions['macaddrcol'],
  323.                              $this->_dbOptions['vendorcol'],
  324.                              $this->_dbOptions['desccol']);
  325.  
  326.             $sql $this->_db->buildManipSQL($this->_dbOptions['tablename'],
  327.                                              $fieldsMDB2_AUTOQUERY_INSERT);
  328.  
  329.             $query $this->_db->prepare($sql);
  330.         }
  331.  
  332.         while ($line fgets($fpNET_MAC_LINE_MAXLENGTH)) {
  333.             // Remove comments
  334.             if preg_match('/^\#/'$line) ) {
  335.                 continue;
  336.             }
  337.  
  338.             if preg_match('/^([0-9A-Fa-f][0-9A-Fa-f]:){2}([0-9A-Fa-f][0-9A-Fa-f]){1}/'$line) ) {
  339.                 $pieces preg_split('/\s+/'$line);
  340.  
  341.                 // Since the file is space-delimited, we now need to
  342.                 // reconstruct the description field if it existed
  343.                 $desc = NULL;
  344.                 for ($i = 3; $i count($pieces)$i++{
  345.                     $desc .= $pieces[$i].' ';
  346.                 }
  347.                 $desc rtrim($desc);
  348.  
  349.                 if ( (isset($pieces[0])) && (isset($pieces[1])) ) {
  350.                     if ($doReturn{
  351.                         $retArr[$pieces[0]] = array('vendor' => $pieces[1],
  352.                                                     'description' => $desc);
  353.                     }
  354.                     else {
  355.                         $values = array($pieces[0]$pieces[1]$desc);
  356.                         $result $query->execute($values);
  357.                     }
  358.                 }
  359.             }
  360.         }
  361.  
  362.         return ($doReturn$retArr : true;
  363.     /* end method importVendors */
  364.  
  365.     /**
  366.      * Finds the vendor for a MAC address
  367.      *
  368.      * This method will search through the database to find a vendor
  369.      * that matches the MAC address stored in the class using {@link }
  370.      * setMAC setMAC}.  If the $macList parameter is set, the method
  371.      * will use the array stored in $macList as the data source to
  372.      * find the MAC vendor instead of the database.  The array would
  373.      * have to be an array with the same characteristics as one
  374.      * returned from the {@link importVendors importVendors} method
  375.      * when using the $doReturn parameter.
  376.      *
  377.      * @access public
  378.      *
  379.      * @param bool $getDescription If set to true, the return value
  380.      *  will be an array with keys 'vendor' and 'description'.
  381.      *  Normally the method will simply return the vendor name.
  382.      * @param array $macList An optional list of MAC-to-vendor
  383.      *  relationships to search instead of using the
  384.      *  database. (default: NULL)
  385.      *
  386.      * @return mixed Returns an associative array if $getDescription
  387.      *  is <b>true</b>, returns a string with the vendor name if
  388.      *  $getDescription is <b>false</b>.  If the MAC vendor cannot be
  389.      *  found in the vendor list, <b>false</b> is returned.
  390.      */
  391.     function findVendor($getDescription = false$macList = NULL)
  392.     {
  393.         if ($macList == NULL{
  394.             $macaddrcol $this->_dbOptions['macaddrcol'];
  395.             $vendorcol $this->_dbOptions['vendorcol'];
  396.             $desccol $this->_dbOptions['desccol'];
  397.  
  398.             /* The manufacturers' list only uses the first 3 octets,
  399.              * so we need to get that portion of the stored MAC
  400.              * address. */
  401.             $macaddr substr(self::format($this->_macaddr':')08);
  402.  
  403.             // Prepare parameters for MDB2->buildManipSQL()
  404.             $fields = array ($macaddrcol$vendorcol$desccol);
  405.             $where = "$macaddrcol = '$macaddr'";
  406.  
  407.             $sql $this->_db->buildManipSQL($this->_dbOptions['tablename'],
  408.                                              $fieldsMDB2_AUTOQUERY_SELECT,
  409.                                              $where);
  410.  
  411.             $query $this->_db->prepare($sql);
  412.             $result $query->execute();
  413.  
  414.             if ( (MDB2::isError($result)) || ($result->numRows(== 0) ) {
  415.                 return false;
  416.             }
  417.  
  418.             $macInfo $result->fetchRow(MDB2_FETCHMODE_ASSOC);
  419.  
  420.             if ($getDescription{
  421.                 return array($vendorcol => $macInfo[$vendorcol],
  422.                              $desccol => $macInfo[$desccol]);
  423.             }
  424.             else {
  425.                 return $macInfo[$vendorcol];
  426.             }
  427.         }
  428.         else {
  429.             return false;
  430.         }
  431.     /* end method findVendor */
  432.  
  433. /* end class Net_MAC */
  434.  
  435. /*
  436.  * Local variables:
  437.  * tab-width: 4
  438.  * c-basic-offset: 4
  439.  * indent-tabs-mode: nil
  440.  * End:
  441.  */
  442. ?>

Documentation generated on Wed, 09 Dec 2015 22:35:59 +0000 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.