"Fossies" - the Fresh Open Source Software Archive

Member "netxms-3.8.193/src/libnetxms/macaddr.cpp" (4 Mar 2021, 6219 Bytes) of package /linux/misc/netxms-3.8.193.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "macaddr.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** NetXMS - Network Management System
    3 ** Utility Library
    4 ** Copyright (C) 2003-2020 Raden Solutions
    5 **
    6 ** This program is free software; you can redistribute it and/or modify
    7 ** it under the terms of the GNU Lesser General Public License as published
    8 ** by the Free Software Foundation; either version 3 of the License, or
    9 ** (at your option) any later version.
   10 **
   11 ** This program is distributed in the hope that it will be useful,
   12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 ** GNU General Public License for more details.
   15 **
   16 ** You should have received a copy of the GNU Lesser General Public License
   17 ** along with this program; if not, write to the Free Software
   18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   19 **
   20 ** File: macaddr.cpp
   21 **
   22 **/
   23 
   24 #include "libnetxms.h"
   25 #include <nxcpapi.h>
   26 #include <netxms-regex.h>
   27 
   28 /**
   29  * Predefined invalid MAC address object
   30  */
   31 const MacAddress LIBNETXMS_EXPORTABLE MacAddress::NONE;
   32 
   33 /**
   34  * Predefined MAC address object 00:00:00:00:00:00
   35  */
   36 const MacAddress LIBNETXMS_EXPORTABLE MacAddress::ZERO(MAC_ADDR_LENGTH);
   37 
   38 /**
   39  * Returns true if it is the broadcast address
   40  */
   41 bool MacAddress::isBroadcast() const
   42 {
   43    if (m_length == 0)
   44       return false;
   45    for(size_t i = 0; i < m_length; i++)
   46       if (m_value[i] != 0xFF)
   47          return false;
   48    return true;
   49 }
   50 
   51 /**
   52  * Returns string representation of MAC address
   53  */
   54 TCHAR *MacAddress::toString(TCHAR *buffer, MacAddressNotation notation) const
   55 {
   56    switch(notation)
   57    {
   58       case MacAddressNotation::FLAT_STRING:
   59          BinToStr(m_value, m_length, buffer);
   60          break;
   61       case MacAddressNotation::COLON_SEPARATED:
   62          toStringInternal(buffer, _T(':'));
   63          break;
   64       case MacAddressNotation::BYTEPAIR_COLON_SEPARATED:
   65          toStringInternal(buffer, _T(':'), true);
   66          break;
   67       case MacAddressNotation::HYPHEN_SEPARATED:
   68          toStringInternal(buffer, _T('-'));
   69          break;
   70       case MacAddressNotation::DOT_SEPARATED:
   71          toStringInternal3(buffer, _T('.'));
   72          break;
   73       case MacAddressNotation::BYTEPAIR_DOT_SEPARATED:
   74          toStringInternal(buffer, _T('.'), true);
   75          break;
   76       case MacAddressNotation::DECIMAL_DOT_SEPARATED:
   77          toStringInternalDecimal(buffer, _T('.'));
   78          break;
   79    }
   80    return buffer;
   81 }
   82 
   83 /**
   84  * Returns string representation of MAC address
   85  */
   86 String MacAddress::toString(MacAddressNotation notation) const
   87 {
   88    if (m_length == 0)
   89       return String();
   90 
   91    TCHAR buffer[64]; // max_length(16) * 4
   92    return String(toString(buffer, notation));
   93 }
   94 
   95 /**
   96  * Internal method to string for inserting separator every third char
   97  */
   98 TCHAR *MacAddress::toStringInternal3(TCHAR *buffer, const TCHAR separator) const
   99 {
  100    TCHAR *curr = buffer;
  101 
  102    for(size_t i = 0; i < m_length; i++)
  103    {
  104       *curr++ = bin2hex(m_value[i] >> 4);
  105       if (((curr+1) - buffer) % 4 == 0)
  106          *curr++ = separator;
  107       *curr++ = bin2hex(m_value[i] & 15);
  108       if (((curr+1) - buffer) % 4 == 0)
  109          *curr++ = separator;
  110    }
  111    *(curr - 1) = 0;
  112    return buffer;
  113 }
  114 
  115 /**
  116  * Internal method to string
  117  */
  118 TCHAR *MacAddress::toStringInternal(TCHAR *buffer, const TCHAR separator, bool bytePair) const
  119 {
  120    TCHAR *curr = buffer;
  121 
  122    for(size_t i = 0; i < m_length; i++)
  123    {
  124       *curr++ = bin2hex(m_value[i] >> 4);
  125       *curr++ = bin2hex(m_value[i] & 15);
  126       if (!bytePair || (((i+1) % 2 == 0)))
  127          *curr++ = separator;
  128    }
  129    *(curr - 1) = 0;
  130    return buffer;
  131 }
  132 
  133 /**
  134  * Internal method to string
  135  */
  136 TCHAR *MacAddress::toStringInternalDecimal(TCHAR *buffer, const TCHAR separator) const
  137 {
  138    TCHAR *curr = buffer;
  139 
  140    for(size_t i = 0; i < m_length; i++)
  141    {
  142       if (i > 0)
  143          *curr++ = separator;
  144       _sntprintf(curr, 4, _T("%u"), static_cast<unsigned int>(m_value[i]));
  145       curr += _tcslen(curr);
  146    }
  147    return buffer;
  148 }
  149 
  150 /**
  151  * Parse string as MAC address
  152  */
  153 MacAddress MacAddress::parse(const char *str)
  154 {
  155    if (str == NULL || strlen(str) > 23)
  156       return MacAddress(MacAddress::ZERO);
  157 
  158    char exp1[254] = { "^([0-9a-fA-F]{2})[ :-]?"
  159                       "([0-9a-fA-F]{2})[ .:-]?"
  160                       "([0-9a-fA-F]{2})[ :-]?"
  161                       "([0-9a-fA-F]{2})[ .:-]?"
  162                       "([0-9a-fA-F]{2})?[ :-]?"
  163                       "([0-9a-fA-F]{2})?[ .:-]?"
  164                       "([0-9a-fA-F]{2})?[ :-]?"
  165                       "([0-9a-fA-F]{2})?$" };
  166 
  167    char exp2[128] = { "^([0-9a-fA-F]{3})\\."
  168                        "([0-9a-fA-F]{3})\\."
  169                        "([0-9a-fA-F]{3})\\."
  170                        "([0-9a-fA-F]{3})$" };
  171 
  172    StringBuffer mac;
  173    const char *errptr;
  174    int erroffset;
  175    pcre *compRegex = pcre_compile(exp1, PCRE_COMMON_FLAGS_A, &errptr, &erroffset, NULL);
  176    if (compRegex != NULL)
  177    {
  178       int ovector[30];
  179       int cgcount = pcre_exec(compRegex, NULL, str, static_cast<int>(strlen(str)), 0, 0, ovector, 30);
  180       if (cgcount >= 7) // at least 6 elements
  181       {
  182          for(int i = 1; i < cgcount; i++)
  183             mac.appendMBString(str + ovector[i * 2], (ovector[i * 2 + 1] - ovector[i * 2]), CP_ACP);
  184          pcre_free(compRegex);
  185       }
  186       else
  187       {
  188          pcre_free(compRegex);
  189          pcre *compRegex = pcre_compile(exp2, PCRE_COMMON_FLAGS_A, &errptr, &erroffset, NULL);
  190          if (compRegex != NULL)
  191          {
  192             cgcount = pcre_exec(compRegex, NULL, str, static_cast<int>(strlen(str)), 0, 0, ovector, 30);
  193             if (cgcount == 5)
  194             {
  195                for(int i = 1; i < cgcount; i++)
  196                   mac.appendMBString(str + ovector[i * 2], (ovector[i * 2 + 1] - ovector[i * 2]), CP_ACP);
  197             }
  198             pcre_free(compRegex);
  199          }
  200       }
  201    }
  202 
  203    if (mac.length() > 0)
  204    {
  205       BYTE buffer[16];
  206       size_t size = StrToBin(mac, buffer, mac.length());
  207       return MacAddress(buffer, size);
  208    }
  209 
  210    return MacAddress(MacAddress::ZERO);
  211 }
  212 
  213 /**
  214  * Parse string as MAC address (WCHAR version)
  215  */
  216 MacAddress MacAddress::parse(const WCHAR *str)
  217 {
  218    char mb[256];
  219    WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, str, -1, mb, 256, NULL, NULL);
  220    return parse(mb);
  221 }