Fixed MacAddress toString function for different formats; Introduced even more MacAdd...
authorEriks Jenkevics <eriks@netxms.org>
Tue, 22 Aug 2017 05:45:44 +0000 (08:45 +0300)
committerEriks Jenkevics <eriks@netxms.org>
Tue, 22 Aug 2017 05:45:51 +0000 (08:45 +0300)
include/nms_util.h
src/java/client/netxms-base/src/main/java/org/netxms/base/MacAddress.java
src/libnetxms/macaddr.cpp
tests/test-libnetxms/test-libnetxms.cpp

index 72e1b3c..05a8b7f 100644 (file)
@@ -1566,6 +1566,7 @@ private:
    size_t m_length;
 
    TCHAR *toStringInternal(TCHAR *buffer, const TCHAR separator, bool bytePair = false) const;
+   TCHAR *toStringInternal3(TCHAR *buffer, const TCHAR separator) const;
 
 public:
    MacAddress() { m_length = 0; memset(m_value, 0, 16); }
index afa2d79..fe5e8e3 100644 (file)
@@ -132,7 +132,7 @@ public class MacAddress
         */
        public static MacAddress parseMacAddress(String str) throws MacAddressFormatException
        {          
-               Pattern pattern = Pattern.compile("^([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})?[ :-]?([0-9a-fA-F]{2})?$");
+               Pattern pattern = Pattern.compile("^([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ .:-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ .:-]?([0-9a-fA-F]{2})[ :-]?([0-9a-fA-F]{2})[ .:-]?([0-9a-fA-F]{2})?[ :-]?([0-9a-fA-F]{2})?$");
                Matcher matcher = pattern.matcher(str.trim());
                if (matcher.matches())
                {
index 90d73d1..59e5006 100644 (file)
@@ -73,7 +73,7 @@ TCHAR *MacAddress::toString(TCHAR *buffer, MacAddressNotation notation) const
          toStringInternal(buffer, _T('-'));
          break;
       case MAC_ADDR_DOT_SEPARATED:
-         toStringInternal(buffer, _T('.'));
+         toStringInternal3(buffer, _T('.'));
          break;
       case MAC_ADDR_BYTEPAIR_DOT_SEPARATED:
          toStringInternal(buffer, _T('.'), true);
@@ -83,6 +83,26 @@ TCHAR *MacAddress::toString(TCHAR *buffer, MacAddressNotation notation) const
 }
 
 /**
+ * Internal method to string for inserting separator every third char
+ */
+TCHAR *MacAddress::toStringInternal3(TCHAR *buffer, const TCHAR separator) const
+{
+   TCHAR *curr = buffer;
+
+   for(int i = 0; i < m_length; i++)
+   {
+      *curr++ = bin2hex(m_value[i] >> 4);
+      if (((curr+1) - buffer) % 4 == 0)
+         *curr++ = separator;
+      *curr++ = bin2hex(m_value[i] & 15);
+      if (((curr+1) - buffer) % 4 == 0)
+         *curr++ = separator;
+   }
+   *(curr - 1) = 0;
+   return buffer;
+}
+
+/**
  * Internal method to string
  */
 TCHAR *MacAddress::toStringInternal(TCHAR *buffer, const TCHAR separator, bool bytePair) const
@@ -93,7 +113,7 @@ TCHAR *MacAddress::toStringInternal(TCHAR *buffer, const TCHAR separator, bool b
    {
       *curr++ = bin2hex(m_value[i] >> 4);
       *curr++ = bin2hex(m_value[i] & 15);
-      if(!bytePair || (i % 2 == 0))
+      if (!bytePair || (((i+1) % 2 == 0)))
          *curr++ = separator;
    }
    *(curr - 1) = 0;
@@ -117,13 +137,14 @@ String MacAddress::toString(MacAddressNotation notation) const
       case MAC_ADDR_COLON_SEPARATED:
       case MAC_ADDR_HYPHEN_SEPARATED:
       case MAC_ADDR_DOT_SEPARATED:
-         stringSize = m_length * 2 + m_length/2; //-1 separator +1 for
+         stringSize = m_length * 2 + m_length; //-1 separator +1 for 0 termination
          break;
       case MAC_ADDR_BYTEPAIR_DOT_SEPARATED:
       case MAC_ADDR_BYTEPAIR_COLON_SEPARATED:
-         stringSize = m_length * 2 + m_length/2; //-1 separator +1 for
+         stringSize = m_length * 2 + m_length/2; //-1 separator +1 for 0 termination
          break;
    }
+   _tprintf(_T("\n Stringsize: %d\n"), stringSize);
    TCHAR *buf = (TCHAR *)malloc(stringSize * sizeof(TCHAR));
    String str(toString(buf, notation));
    free(buf);
@@ -139,17 +160,22 @@ MacAddress MacAddress::parse(const char *str)
       return MacAddress();
 
    regex_t compRegex;
-   char exp[254] = { "^([0-9a-fA-F]{2})[ :-]?"
-                      "([0-9a-fA-F]{2})[ :-]?"
-                      "([0-9a-fA-F]{2})[ :-]?"
-                      "([0-9a-fA-F]{2})[ :-]?"
+   char exp1[254] = { "^([0-9a-fA-F]{2})[ :-]?"
+                      "([0-9a-fA-F]{2})[ .:-]?"
                       "([0-9a-fA-F]{2})[ :-]?"
+                      "([0-9a-fA-F]{2})[ .:-]?"
                       "([0-9a-fA-F]{2})[ :-]?"
+                      "([0-9a-fA-F]{2})[ .:-]?"
                       "([0-9a-fA-F]{2})?[ :-]?"
                       "([0-9a-fA-F]{2})?$" };
 
+   char exp2[128] = { "^([0-9a-fA-F]{3})\\."
+                       "([0-9a-fA-F]{3})\\."
+                       "([0-9a-fA-F]{3})\\."
+                       "([0-9a-fA-F]{3})$" };
+
    String mac;
-   if (tre_regcomp(&compRegex, exp, REG_EXTENDED) == 0)
+   if (tre_regcomp(&compRegex, exp1, REG_EXTENDED) == 0)
    {
       regmatch_t match[9];
       if (tre_regexec(&compRegex, str, 9, match, 0) == 0)
@@ -157,6 +183,19 @@ MacAddress MacAddress::parse(const char *str)
          for(int i = 1; i < 9; i++)
             mac.appendMBString(str+match[i].rm_so, (match[i].rm_eo - match[i].rm_so), CP_ACP);
       }
+      else
+      {
+         regfree(&compRegex);
+         if (tre_regcomp(&compRegex, exp2, REG_EXTENDED) == 0)
+         {
+            regmatch_t match[5];
+            if (tre_regexec(&compRegex, str, 5, match, 0) == 0)
+            {
+               for(int i = 1; i < 5; i++)
+                  mac.appendMBString(str+match[i].rm_so, (match[i].rm_eo - match[i].rm_so), CP_ACP);
+            }
+         }
+      }
       regfree(&compRegex);
    }
 
index 246cdaa..5e84b9f 100644 (file)
@@ -319,14 +319,92 @@ static void TestString()
  */
 static void TestMacAddress()
 {
-   MacAddress a, b, c;
+   MacAddress a, b, c, d, e, f;
+
+   StartTest(_T("MacAddress - parse()"));
+   a = MacAddress::parse("0180C2300100");
+   AssertTrue(_tcscmp(_T("0180C2300100"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("01:80:C2:30:01:00"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("01-80-C2-30-01-00"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("018.0C2.300.100"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0180.C230.0100"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0180:C230:0100"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("01:80:C2:00:00:00");
+   AssertTrue(_tcscmp(_T("0180C2000000"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("01:80:C2:00:00:00"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("01-80-C2-00-00-00"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("018.0C2.000.000"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0180.C200.0000"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0180:C200:0000"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("09-80-C2-FF-FF-FF");
+   AssertTrue(_tcscmp(_T("0980C2FFFFFF"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("09:80:C2:FF:FF:FF"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("09-80-C2-FF-FF-FF"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("098.0C2.FFF.FFF"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0980.C2FF.FFFF"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("0980:C2FF:FFFF"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("482.C6A.1E5.93D");
+   AssertTrue(_tcscmp(_T("482C6A1E593D"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("48:2C:6A:1E:59:3D"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48-2C-6A-1E-59-3D"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482.C6A.1E5.93D"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482C.6A1E.593D"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482C:6A1E:593D"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("48AC.6B1A.F6FD");
+   AssertTrue(_tcscmp(_T("48AC6B1AF6FD"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("48:AC:6B:1A:F6:FD"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48-AC-6B-1A-F6-FD"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48A.C6B.1AF.6FD"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48AC.6B1A.F6FD"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48AC:6B1A:F6FD"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("482C:6A1E:593D");
+   AssertTrue(_tcscmp(_T("482C6A1E593D"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("48:2C:6A:1E:59:3D"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("48-2C-6A-1E-59-3D"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482.C6A.1E5.93D"), (const TCHAR*)a.toString(MAC_ADDR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482C.6A1E.593D"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("482C:6A1E:593D"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("70B3D5B020035F11");
+   AssertTrue(_tcscmp(_T("70B3D5B020035F11"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("70:B3:D5:B0:20:03:5F:11"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70-B3-D5-B0-20-03-5F-11"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3.D5B0.2003.5F11"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3:D5B0:2003:5F11"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("70:B3:D5:B0:20:03:5F:16");
+   AssertTrue(_tcscmp(_T("70B3D5B020035F16"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("70:B3:D5:B0:20:03:5F:16"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70-B3-D5-B0-20-03-5F-16"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3.D5B0.2003.5F16"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3:D5B0:2003:5F16"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("70-B3-D5-B0-20-00-00-39");
+   AssertTrue(_tcscmp(_T("70B3D5B020000039"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("70:B3:D5:B0:20:00:00:39"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70-B3-D5-B0-20-00-00-39"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3.D5B0.2000.0039"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3:D5B0:2000:0039"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+
+   a = MacAddress::parse("70B3.D5B0.2003.5D5E");
+   AssertTrue(_tcscmp(_T("70B3D5B020035D5E"), (const TCHAR*)a.toString(MAC_ADDR_FLAT_STRING)) == 0);
+   AssertTrue(_tcscmp(_T("70:B3:D5:B0:20:03:5D:5E"), (const TCHAR*)a.toString(MAC_ADDR_COLON_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70-B3-D5-B0-20-03-5D-5E"), (const TCHAR*)a.toString(MAC_ADDR_HYPHEN_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3.D5B0.2003.5D5E"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_DOT_SEPARATED)) == 0);
+   AssertTrue(_tcscmp(_T("70B3:D5B0:2003:5D5E"), (const TCHAR*)a.toString(MAC_ADDR_BYTEPAIR_COLON_SEPARATED)) == 0);
+   EndTest();
 
    StartTest(_T("MacAddress - isMulticast()"));
    a = MacAddress::parse("01:80:C2:00:00:00");
    AssertTrue(a.isMulticast());
    b = MacAddress::parse("09-80-C2-FF-FF-FF");
    AssertTrue(b.isMulticast());
-   c = MacAddress::parse("48.2C.6A.1E.59.3D");
+   c = MacAddress::parse("482.C6A.1E5.93D");
    AssertFalse(c.isMulticast());
    EndTest();
 
@@ -335,17 +413,23 @@ static void TestMacAddress()
    AssertTrue(a.isBroadcast());
    b = MacAddress::parse("FF-2C-6A-1E-59-3D");
    AssertFalse(b.isBroadcast());
-   c = MacAddress::parse("FF.FF.C2.FF.FF.FF");
+   c = MacAddress::parse("FFF.FC2.FFF.FFF");
    AssertFalse(c.isBroadcast());
    EndTest();
 
    StartTest(_T("MacAddress - equals()"));
    a = MacAddress::parse("09-80-C2-FF-FF-FF");
    b = MacAddress::parse("48:2C:6A:1E:59:3D");
-   c = MacAddress::parse("09.80.C2.FF.FF.FF");
+   c = MacAddress::parse("098.0C2.FFF.FFF");
+   d = MacAddress::parse("70B3D5B020035F11");
+   e = MacAddress::parse("70B3:D5B0:2003:5F11");
+   f = MacAddress::parse("70B3.D5B0.2003.5D5E");
    AssertFalse(a.equals(b));
    AssertFalse(b.equals(c));
+   AssertFalse(e.equals(f));
+   AssertFalse(d.equals(b));
    AssertTrue(c.equals(a));
+   AssertTrue(d.equals(e));
    EndTest();
 }