server mostly converted to use InetAddress class instead of UINT32 for IP address...
authorVictor Kirhenshtein <victor@netxms.org>
Sat, 28 Feb 2015 18:34:08 +0000 (20:34 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Sat, 28 Feb 2015 18:34:08 +0000 (20:34 +0200)
74 files changed:
include/netxms-version.h
include/netxmsdb.h
include/nms_common.h
include/nms_cscp.h
include/nms_util.h
include/nxcldefs.h
include/nxsnmp.h
sql/schema.in
src/java/client/netxms-base/src/main/java/org/netxms/base/InetAddressEx.java
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPMessage.java
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPMessageField.java
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCObjectModificationData.java
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/AbstractObject.java
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/Cluster.java
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/ClusterSyncNetwork.java [deleted file]
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/Interface.java
src/java/client/netxms-client/src/main/java/org/netxms/client/objects/Subnet.java
src/java/client/netxms-client/src/test/java/org/netxms/client/ObjectTest.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/ClusterNetworks.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/helpers/NetworkListComparator.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/helpers/NetworkListLabelProvider.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/elements/GeneralInfo.java
src/java/netxms-eclipse/ObjectView/src/org/netxms/ui/eclipse/objectview/objecttabs/helpers/InterfaceListComparator.java
src/libnetxms/inetaddr.cpp
src/server/core/Makefile.am
src/server/core/accesspoint.cpp
src/server/core/actions.cpp
src/server/core/agent.cpp
src/server/core/cdp.cpp
src/server/core/cluster.cpp
src/server/core/correlate.cpp
src/server/core/dcobject.cpp
src/server/core/dctarget.cpp
src/server/core/events.cpp
src/server/core/fdb.cpp
src/server/core/inaddr_index.cpp [new file with mode: 0644]
src/server/core/interface.cpp
src/server/core/layer2.cpp
src/server/core/lldp.cpp
src/server/core/main.cpp
src/server/core/mobile.cpp
src/server/core/netinfo.cpp
src/server/core/netobj.cpp
src/server/core/netsrv.cpp
src/server/core/node.cpp
src/server/core/np.cpp
src/server/core/nxcore.vcproj
src/server/core/nxsl_classes.cpp
src/server/core/nxslext.cpp
src/server/core/objects.cpp
src/server/core/objtools.cpp
src/server/core/poll.cpp
src/server/core/session.cpp
src/server/core/snmp.cpp
src/server/core/snmptrap.cpp
src/server/core/subnet.cpp
src/server/core/tracert.cpp
src/server/core/vpnconn.cpp
src/server/core/zone.cpp
src/server/include/nms_core.h
src/server/include/nms_objects.h
src/server/include/nms_topo.h
src/server/include/nxmodule.h
src/server/include/nxsrvapi.h
src/server/libnxsrv/agent.cpp
src/server/libnxsrv/snmpproxy.cpp
src/server/tools/driverloader/loader.cpp
src/server/tools/nxdbmgr/upgrade.cpp
src/snmp/libnxsnmp/transport.cpp
src/snmp/nxsnmpget/nxsnmpget.cpp
src/snmp/nxsnmpset/nxsnmpset.cpp
src/snmp/nxsnmpwalk/nxsnmpwalk.cpp

index c7beefd..02370e1 100644 (file)
@@ -42,7 +42,7 @@
 /**
  * Current client-server protocol version
  */
-#define CLIENT_PROTOCOL_VERSION           45
+#define CLIENT_PROTOCOL_VERSION           46
 
 /**
  * Current mobile device protocol version
index 0039dcf..5b7914a 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   345
+#define DB_FORMAT_VERSION   346
 
 #endif
index 2da48f1..de46402 100644 (file)
@@ -1118,11 +1118,6 @@ typedef struct tagICMPHDR
 #endif
 
 /**
- * Check if IP address is a broadcast
- */
-#define IsBroadcastAddress(addr, mask) (((addr) & (~(mask))) == (~(mask)))
-
-/**
  * Check if given string is NULL and always return valid pointer
  */
 #define CHECK_NULL(x)      ((x) == NULL ? _T("(null)") : (x))
index 835683a..357a13b 100644 (file)
@@ -1092,6 +1092,9 @@ typedef struct
 // Base value for cluster resource list
 #define VID_RESOURCE_LIST_BASE      ((UINT32)0x20000000)
 
+// Base value for cluster sync network list
+#define VID_SYNC_SUBNETS_BASE       ((UINT32)0x28000000)
+
 // Base value for agent's enum values
 #define VID_ENUM_VALUE_BASE         ((UINT32)0x10000000)
 
index d0f2a88..f3cc233 100644 (file)
@@ -892,6 +892,7 @@ private:
 public:
    InetAddress();
    InetAddress(UINT32 addr);
+   InetAddress(UINT32 addr, UINT32 mask);
    InetAddress(BYTE *addr);
 
    bool isAnyLocal() const;
@@ -899,7 +900,7 @@ public:
    bool isMulticast() const;
    bool isBroadcast() const;
    bool isValid() const { return m_family != AF_UNSPEC; }
-   bool isValidUnicast() { return isValid() && !isAnyLocal() && !isLoopback() && !isMulticast() && !isBroadcast(); }
+   bool isValidUnicast() const { return isValid() && !isAnyLocal() && !isLoopback() && !isMulticast() && !isBroadcast(); }
 
    int getFamily() const { return m_family; }
    UINT32 getAddressV4() const { return (m_family == AF_INET) ? m_addr.v4 : 0; }
@@ -912,6 +913,7 @@ public:
 
    void setMaskBits(int m) { m_maskBits = m; }
    int getMaskBits() const { return m_maskBits; }
+   int getHostBits() const { return (m_family == AF_INET) ? (32 - m_maskBits) : (128 - m_maskBits); }
 
    InetAddress getSubnetAddress() const;
    bool isSubnetBroadcast(int maskBits) const;
index 2999721..f49ba73 100644 (file)
@@ -1059,7 +1059,7 @@ typedef struct
 {
        UINT32 dwId;
        TCHAR szName[MAX_DB_STRING];
-       UINT32 dwIpAddr;
+       InetAddress ipAddr;
        UINT32 dwCurrOwner;
 } CLUSTER_RESOURCE;
 
index f37f1af..ac31995 100644 (file)
@@ -629,13 +629,12 @@ public:
        {
                return -1;
        }
-   virtual UINT32 getPeerIpAddress()
+   virtual InetAddress getPeerIpAddress()
    {
-      return 0;
+      return InetAddress();
    }
 
-   UINT32 doRequest(SNMP_PDU *request, SNMP_PDU **response,
-                   UINT32 timeout = INFINITE, int numRetries = 1);
+   UINT32 doRequest(SNMP_PDU *request, SNMP_PDU **response, UINT32 timeout = INFINITE, int numRetries = 1);
 
        void setSecurityContext(SNMP_SecurityContext *ctx);
        SNMP_SecurityContext *getSecurityContext() { return m_securityContext; }
@@ -659,7 +658,7 @@ class LIBNXSNMP_EXPORTABLE SNMP_UDPTransport : public SNMP_Transport
 {
 protected:
    SOCKET m_hSocket;
-   struct sockaddr_in m_peerAddr;
+   SockAddrBuffer m_peerAddr;
        bool m_connected;
    size_t m_dwBufferSize;
    size_t m_dwBytesInBuffer;
@@ -679,9 +678,10 @@ public:
                            struct sockaddr *sender = NULL, socklen_t *addrSize = NULL,
                                SNMP_SecurityContext* (*contextFinder)(struct sockaddr *, socklen_t) = NULL);
    virtual int sendMessage(SNMP_PDU *pPDU);
-   virtual UINT32 getPeerIpAddress();
+   virtual InetAddress getPeerIpAddress();
 
-   UINT32 createUDPTransport(const TCHAR *pszHostName, UINT32 dwHostAddr = 0, WORD wPort = SNMP_DEFAULT_PORT);
+   UINT32 createUDPTransport(const TCHAR *hostName, WORD port = SNMP_DEFAULT_PORT);
+   UINT32 createUDPTransport(const InetAddress& hostAddr, WORD port = SNMP_DEFAULT_PORT);
        bool isConnected() { return m_connected; }
 };
 
index b3a2045..2340d02 100644 (file)
@@ -308,8 +308,8 @@ CREATE TABLE cluster_members
 CREATE TABLE cluster_sync_subnets
 (
        cluster_id integer not null,
-       subnet_addr varchar(15) not null,
-       subnet_mask varchar(15) not null,
+       subnet_addr varchar(48) not null,
+       subnet_mask integer not null,
        PRIMARY KEY(cluster_id,subnet_addr)
 ) TABLE_TYPE;
 
@@ -323,7 +323,7 @@ CREATE TABLE cluster_resources
        cluster_id integer not null,
        resource_id integer not null,
        resource_name varchar(255),
-       ip_addr varchar(15) not null,
+       ip_addr varchar(48) not null,
        current_owner integer not null,
        PRIMARY KEY(cluster_id,resource_id)
 ) TABLE_TYPE;
@@ -334,8 +334,8 @@ CREATE TABLE cluster_resources
 CREATE TABLE subnets
 (
        id integer not null,
-       ip_addr varchar(15) not null,
-       ip_netmask varchar(15) not null,
+       ip_addr varchar(48) not null,
+       ip_netmask integer not null,
        zone_guid integer not null,
        synthetic_mask integer not null,
        PRIMARY KEY(id)
@@ -349,8 +349,8 @@ CREATE TABLE interfaces
        id integer not null,
        node_id integer not null,
        flags integer not null,
-       ip_addr varchar(15) not null,
-       ip_netmask varchar(15) not null,
+       ip_addr varchar(48) not null,
+       ip_netmask integer not null,
        if_type integer not null,
        if_index integer not null,
    mtu integer not null,
@@ -381,7 +381,7 @@ CREATE TABLE network_services
        id integer not null,
        node_id integer not null,
        service_type integer not null,
-       ip_bind_addr varchar(15) not null,
+       ip_bind_addr varchar(48) not null,
        ip_proto integer not null,
        ip_port integer not null,
        check_request SQL_TEXT null,
@@ -409,8 +409,8 @@ CREATE TABLE vpn_connector_networks
 (
        vpn_id integer not null,
        network_type integer not null,  // 0 == local, 1 == remote
-       ip_addr varchar(15) not null,
-       ip_netmask varchar(15) not null,
+       ip_addr varchar(48) not null,
+       ip_netmask integer not null,
        PRIMARY KEY(vpn_id,ip_addr)
 ) TABLE_TYPE;
 
@@ -1081,7 +1081,7 @@ CREATE TABLE snmp_trap_log
 (
        trap_id SQL_INT64 not null,
        trap_timestamp integer not null,
-       ip_addr varchar(15) not null,
+       ip_addr varchar(48) not null,
        object_id integer not null,
        trap_oid varchar(255) not null,
        trap_varlist SQL_TEXT null,
@@ -1111,8 +1111,8 @@ CREATE TABLE address_lists
        list_type integer not null, // discovery filter, etc.
        community_id integer not null, // community id for snmp community addr list, otherwise 0
        addr_type integer not null, // 0 - addr/mask, 1 - address range
-       addr1 varchar(15) not null,
-       addr2 varchar(15) not null,
+       addr1 varchar(48) not null,
+       addr2 varchar(48) not null,
        PRIMARY KEY(list_type,community_id,addr_type,addr1,addr2)
 ) TABLE_TYPE;
 
index e909aa0..8cdba85 100644 (file)
@@ -38,6 +38,27 @@ public class InetAddressEx
       this.mask = mask;
    }
 
+   /**
+    * @param address
+    * @param mask
+    */
+   public InetAddressEx(InetAddress address, InetAddress mask)
+   {
+      this.address = address;
+      this.mask = bitsInMask(mask);
+   }
+
+   /**
+    * Copy constructor
+    * 
+    * @param src
+    */
+   public InetAddressEx(InetAddressEx src)
+   {
+      this.address = src.address;
+      this.mask = src.mask;
+   }
+
    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
@@ -46,4 +67,64 @@ public class InetAddressEx
    {
       return address.getHostAddress() + "/" + mask;
    }
+   
+   /**
+    * Calculate number of bits in network mask
+    * 
+    * @param mask
+    * @return
+    */
+   public static int bitsInMask(InetAddress mask)
+   {
+      int bits = 0;
+      byte[] bytes = mask.getAddress();
+      for(byte b : bytes)
+      {
+         if (b == 0xFF)
+         {
+            bits += 8;
+            continue;
+         }
+         for(int m = 0x80; m != 0; m = m >> 1)
+         {
+            if ((b & m) != m)
+               break;
+            bits++;
+         }
+      }
+      return bits;
+   }
+   
+   /**
+    * Convert bit count into mask
+    * 
+    * @param bits
+    * @return
+    */
+   public InetAddress maskFromBits()
+   {
+      try
+      {
+         byte[] bytes = address.getAddress();
+         int bits = mask;
+         int i = 0;
+         while(bits > 8)
+         {
+            bytes[i++] = (byte)0xFF;
+            bits -= 8;
+         }
+         byte b = (byte)0x80;
+         while(bits > 0)
+         {
+            bytes[i] |= b;
+            b = (byte)(b >> 1);
+            bits--;
+         }
+         return InetAddress.getByAddress(bytes);
+      }
+      catch(Exception e)
+      {
+         return null;
+      }
+   }
 }
index 58a0f55..6981cab 100644 (file)
@@ -864,6 +864,7 @@ public class NXCPCodes
        public static final long VID_CUSTOM_ATTRIBUTES_BASE = 0x70000000L;
    public static final long VID_MODULE_DATA_BASE = 0x71000000L;
        public static final long VID_RESOURCE_LIST_BASE = 0x20000000L;
+   public static final long VID_SYNC_SUBNETS_BASE = 0x28000000L;
        public static final long VID_ENUM_VALUE_BASE = 0x10000000L;
        public static final long VID_ACTION_ARG_BASE = 0x10000000L;
        public static final long VID_PARAM_LIST_BASE = 0x10000000L;
index 4f65d88..73eb362 100644 (file)
@@ -159,7 +159,7 @@ public class NXCPMessage
                                byteArrayInputStream.mark(byteArrayInputStream.available());
                                
                                // Read first 8 bytes - any DF (data field) is at least 8 bytes long
-                               byte[] df = new byte[16];
+                               byte[] df = new byte[32];
                                inputStream.readFully(df, 0, 8);
        
                                switch(df[4])
@@ -185,6 +185,9 @@ public class NXCPMessage
                                                        inputStream.skipBytes(8 - rem);
                                                }
                                                break;
+                                       case NXCPMessageField.TYPE_INETADDR:    // address always 32 byte long
+                                          inputStream.readFully(df, 8, 24);
+                                          break;
                                }
        
                                final NXCPMessageField variable = new NXCPMessageField(df);
@@ -327,6 +330,17 @@ public class NXCPMessage
                setField(new NXCPMessageField(fieldId, value));
        }
 
+   /**
+    * Set field of INETADDR type
+    * 
+    * @param fieldId
+    * @param value
+    */
+   public void setField(long fieldId, InetAddressEx value)
+   {
+      setField(new NXCPMessageField(fieldId, value));
+   }
+       
        /**
         * Set field of BINARY type to GUID value (byte array of length 16).
         * 
@@ -453,6 +467,18 @@ public class NXCPMessage
                return (var != null) ? var.getAsInetAddress() : null;
        }
        
+   /**
+    * Get field as InetAddressEx
+    * 
+    * @param fieldId
+    * @return
+    */
+   public InetAddressEx getFieldAsInetAddressEx(final long fieldId)
+   {
+      final NXCPMessageField var = findField(fieldId);
+      return (var != null) ? var.getAsInetAddressEx() : null;
+   }
+   
        /**
         * Get field as UUID (GUID)
         * 
index dce7907..483f109 100644 (file)
@@ -212,6 +212,20 @@ public class NXCPMessageField
       realValue = (double)0;
        }
 
+   /**
+    * @param varId
+    * @param value
+    */
+   public NXCPMessageField(final long varId, final InetAddressEx value)
+   {
+      id = varId;
+      type = TYPE_INETADDR;
+      inetAddressValue = value;
+      stringValue = inetAddressValue.toString();
+      integerValue = (long)0;
+      realValue = (double)0;
+   }
+
        /**
         * @param varId
         * @param value
index 820659b..b350512 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.netxms.base.GeoLocation;
+import org.netxms.base.InetAddressEx;
 import org.netxms.base.PostalAddress;
 import org.netxms.client.constants.ObjectStatus;
 import org.netxms.client.dashboards.DashboardElement;
@@ -36,7 +37,6 @@ import org.netxms.client.maps.MapLayoutAlgorithm;
 import org.netxms.client.maps.NetworkMapLink;
 import org.netxms.client.maps.elements.NetworkMapElement;
 import org.netxms.client.objects.ClusterResource;
-import org.netxms.client.objects.ClusterSyncNetwork;
 
 /**
  * This class is used to hold data for NXCSession.modifyObject()
@@ -158,7 +158,7 @@ public class NXCObjectModificationData
        private int ifXTablePolicy;
        private String reportDefinition;
        private List<ClusterResource> resourceList;
-       private List<ClusterSyncNetwork> networkList;
+       private List<InetAddressEx> networkList;
        private int statusCalculationMethod;
        private int statusPropagationMethod;
        private ObjectStatus fixedPropagatedStatus;
@@ -1111,7 +1111,7 @@ public class NXCObjectModificationData
        /**
         * @return the networkList
         */
-       public List<ClusterSyncNetwork> getNetworkList()
+       public List<InetAddressEx> getNetworkList()
        {
                return networkList;
        }
@@ -1119,7 +1119,7 @@ public class NXCObjectModificationData
        /**
         * @param networkList the networkList to set
         */
-       public void setNetworkList(List<ClusterSyncNetwork> networkList)
+       public void setNetworkList(List<InetAddressEx> networkList)
        {
                this.networkList = networkList;
                flags |= MODIFY_CLUSTER_NETWORKS;
index a4bc1ae..dde0d58 100644 (file)
@@ -80,6 +80,7 @@ import org.netxms.api.client.users.UserManager;
 import org.netxms.base.CompatTools;
 import org.netxms.base.EncryptionContext;
 import org.netxms.base.GeoLocation;
+import org.netxms.base.InetAddressEx;
 import org.netxms.base.Logger;
 import org.netxms.base.NXCPCodes;
 import org.netxms.base.NXCPDataInputStream;
@@ -134,7 +135,6 @@ import org.netxms.client.objects.BusinessService;
 import org.netxms.client.objects.BusinessServiceRoot;
 import org.netxms.client.objects.Cluster;
 import org.netxms.client.objects.ClusterResource;
-import org.netxms.client.objects.ClusterSyncNetwork;
 import org.netxms.client.objects.Condition;
 import org.netxms.client.objects.Container;
 import org.netxms.client.objects.Dashboard;
@@ -185,7 +185,7 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
 {
    // Various public constants
    public static final int DEFAULT_CONN_PORT = 4701;
-   public static final int CLIENT_PROTOCOL_VERSION = 45;
+   public static final int CLIENT_PROTOCOL_VERSION = 46;
 
    // Authentication types
    public static final int AUTH_TYPE_PASSWORD = 0;
@@ -1042,18 +1042,6 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
    }
 
    /**
-    * Convert IP address to 32 bit integer
-    *
-    * @param addr
-    * @return
-    */
-   private static long int32FromInetAddress(InetAddress addr)
-   {
-      byte[] bytes = addr.getAddress();
-      return (((long)bytes[0] & 0xFF) << 24)  | (((long)bytes[1] & 0xFF) << 16) | (((long)bytes[2] & 0xFF) << 8) | ((long)bytes[3] & 0xFF);
-   }
-
-   /**
     * Create custom object from NXCP message. May be overridden by derived classes to create custom
     * NetXMS objects. This method called before standard object creation, so it can be used for
     * overriding standard object classes. If this method returns null, standard object
@@ -4170,14 +4158,11 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
       {
          int count = data.getNetworkList().size();
          msg.setFieldInt32(NXCPCodes.VID_NUM_SYNC_SUBNETS, count);
-         long[] subnets = new long[count * 2];
-         int pos = 0;
-         for(ClusterSyncNetwork n : data.getNetworkList())
+         long varId = NXCPCodes.VID_SYNC_SUBNETS_BASE;
+         for(InetAddressEx n : data.getNetworkList())
          {
-            subnets[pos++] = int32FromInetAddress(n.getSubnetAddress());
-            subnets[pos++] = int32FromInetAddress(n.getSubnetMask());
+            msg.setField(varId++, n);
          }
-         msg.setField(NXCPCodes.VID_SYNC_SUBNETS, subnets);
       }
 
       if ((flags & NXCObjectModificationData.MODIFY_PRIMARY_NAME) != 0)
index 2c56295..0e4edc9 100644 (file)
@@ -30,6 +30,7 @@ import java.util.UUID;
 import org.netxms.api.client.services.ServiceManager;
 import org.netxms.base.CompatTools;
 import org.netxms.base.GeoLocation;
+import org.netxms.base.InetAddressEx;
 import org.netxms.base.NXCPCodes;
 import org.netxms.base.NXCPMessage;
 import org.netxms.base.NXCommon;
@@ -117,7 +118,7 @@ public abstract class AbstractObject
        protected int objectClass;
        protected ObjectStatus status = ObjectStatus.UNKNOWN;
        protected boolean isDeleted = false;
-       protected InetAddress primaryIP;
+       protected InetAddressEx primaryIP;
        protected String comments;
        protected GeoLocation geolocation;
        protected PostalAddress postalAddress;
@@ -156,7 +157,7 @@ public abstract class AbstractObject
                objectClass = OBJECT_GENERIC;
                try
                {
-                       primaryIP = InetAddress.getByName("0.0.0.0");
+                       primaryIP = new InetAddressEx(InetAddress.getByName("0.0.0.0"), 0);
                }
                catch(UnknownHostException e)
                {
@@ -199,7 +200,7 @@ public abstract class AbstractObject
                guid = msg.getFieldAsUUID(NXCPCodes.VID_GUID);
                objectName = msg.getFieldAsString(NXCPCodes.VID_OBJECT_NAME);
                objectClass = msg.getFieldAsInt32(NXCPCodes.VID_OBJECT_CLASS);
-               primaryIP = msg.getFieldAsInetAddress(NXCPCodes.VID_IP_ADDRESS);
+               primaryIP = msg.getFieldAsInetAddressEx(NXCPCodes.VID_IP_ADDRESS);
                isDeleted = msg.getFieldAsBoolean(NXCPCodes.VID_IS_DELETED);
                status = ObjectStatus.getByValue(msg.getFieldAsInt32(NXCPCodes.VID_OBJECT_STATUS));
                comments = msg.getFieldAsString(NXCPCodes.VID_COMMENTS);
@@ -362,7 +363,7 @@ public abstract class AbstractObject
         */
        public InetAddress getPrimaryIP()
        {
-               return primaryIP;
+               return primaryIP.address;
        }
 
        /**
index 33f49cb..3861c4c 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * NetXMS - open source network management system
- * Copyright (C) 2003-2010 Victor Kirhenshtein
+ * Copyright (C) 2003-2015 Victor Kirhenshtein
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  */
 package org.netxms.client.objects;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
-
+import org.netxms.base.InetAddressEx;
 import org.netxms.base.NXCPCodes;
 import org.netxms.base.NXCPMessage;
 import org.netxms.client.NXCSession;
 
 /**
- * @author victor
- *
+ * Cluster object
  */
 public class Cluster extends GenericObject
 {
        private int clusterType;
-       private List<ClusterSyncNetwork> syncNetworks = new ArrayList<ClusterSyncNetwork>(1);
+       private List<InetAddressEx> syncNetworks = new ArrayList<InetAddressEx>(1);
        private List<ClusterResource> resources = new ArrayList<ClusterResource>();
        private long zoneId;
        
@@ -50,50 +47,18 @@ public class Cluster extends GenericObject
                zoneId = msg.getFieldAsInt64(NXCPCodes.VID_ZONE_ID);
                
                int count = msg.getFieldAsInt32(NXCPCodes.VID_NUM_SYNC_SUBNETS);
-               if (count > 0)
+      long fieldId = NXCPCodes.VID_SYNC_SUBNETS_BASE;
+               for(int i = 0; i < count; i++)
                {
-                       long[] sn = msg.getFieldAsUInt32Array(NXCPCodes.VID_SYNC_SUBNETS);
-                       for(int i = 0; i < sn.length;)
-                       {
-                               InetAddress addr = inetAddressFromInt32(sn[i++]);
-                               InetAddress mask = inetAddressFromInt32(sn[i++]);
-                               syncNetworks.add(new ClusterSyncNetwork(addr, mask));
-                       }
+                  syncNetworks.add(msg.getFieldAsInetAddressEx(fieldId++));
                }
                
                count = msg.getFieldAsInt32(NXCPCodes.VID_NUM_RESOURCES);
-               long baseId = NXCPCodes.VID_RESOURCE_LIST_BASE;
-               for(int i = 0; i < count; i++, baseId += 10)
-               {
-                       resources.add(new ClusterResource(msg, baseId));
-               }
-       }
-       
-       /**
-        * Create InetAddress object from 32bit integer
-        * 
-        * @param intVal
-        * @return
-        */
-       private InetAddress inetAddressFromInt32(long intVal)
-       {
-               final byte[] addr = new byte[4];
-               InetAddress inetAddr;
-               
-               addr[0] =  (byte)((intVal & 0xFF000000) >> 24);
-               addr[1] =  (byte)((intVal & 0x00FF0000) >> 16);
-               addr[2] =  (byte)((intVal & 0x0000FF00) >> 8);
-               addr[3] =  (byte)(intVal & 0x000000FF);
-               
-               try
-               {
-                       inetAddr = InetAddress.getByAddress(addr);
-               }
-               catch(UnknownHostException e)
+               fieldId = NXCPCodes.VID_RESOURCE_LIST_BASE;
+               for(int i = 0; i < count; i++, fieldId += 10)
                {
-                       inetAddr = null;
+                       resources.add(new ClusterResource(msg, fieldId));
                }
-               return inetAddr;
        }
 
        /* (non-Javadoc)
@@ -125,7 +90,7 @@ public class Cluster extends GenericObject
        /**
         * @return the syncNetworks
         */
-       public List<ClusterSyncNetwork> getSyncNetworks()
+       public List<InetAddressEx> getSyncNetworks()
        {
                return syncNetworks;
        }
diff --git a/src/java/client/netxms-client/src/main/java/org/netxms/client/objects/ClusterSyncNetwork.java b/src/java/client/netxms-client/src/main/java/org/netxms/client/objects/ClusterSyncNetwork.java
deleted file mode 100644 (file)
index 405846e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * 
- */
-package org.netxms.client.objects;
-
-import java.net.InetAddress;
-
-/**
- * Cluster sync network
- *
- */
-public class ClusterSyncNetwork
-{
-       private InetAddress subnetAddress;
-       private InetAddress subnetMask;
-       
-       /**
-        * Create cluster sync network object
-        * 
-        * @param subnetAddress Subnet address
-        * @param subnetMask Subnet mask
-        */
-       public ClusterSyncNetwork(InetAddress subnetAddress, InetAddress subnetMask)
-       {
-               this.subnetAddress = subnetAddress;
-               this.subnetMask = subnetMask;
-       }
-       
-       /**
-        * Copy constructor
-        * 
-        * @param src source object
-        */
-       public ClusterSyncNetwork(ClusterSyncNetwork src)
-       {
-               this.subnetAddress = src.subnetAddress;
-               this.subnetMask = src.subnetMask;
-       }
-
-       /**
-        * @return the subnetAddress
-        */
-       public InetAddress getSubnetAddress()
-       {
-               return subnetAddress;
-       }
-
-       /**
-        * @return the subnetMask
-        */
-       public InetAddress getSubnetMask()
-       {
-               return subnetMask;
-       }
-
-       /**
-        * @param subnetAddress the subnetAddress to set
-        */
-       public void setSubnetAddress(InetAddress subnetAddress)
-       {
-               this.subnetAddress = subnetAddress;
-       }
-
-       /**
-        * @param subnetMask the subnetMask to set
-        */
-       public void setSubnetMask(InetAddress subnetMask)
-       {
-               this.subnetMask = subnetMask;
-       }
-}
index caf1ad0..4bb95bc 100644 (file)
@@ -18,8 +18,8 @@
  */
 package org.netxms.client.objects;
 
-import java.net.InetAddress;
-import org.netxms.base.*;
+import org.netxms.base.NXCPCodes;
+import org.netxms.base.NXCPMessage;
 import org.netxms.client.MacAddress;
 import org.netxms.client.NXCSession;
 import org.netxms.client.constants.LinkLayerDiscoveryProtocol;
@@ -104,7 +104,6 @@ public class Interface extends GenericObject
                };
        
        private int flags;
-       private InetAddress subnetMask;
        private int ifIndex;
        private int ifType;
        private int mtu;
@@ -131,7 +130,6 @@ public class Interface extends GenericObject
                super(msg, session);
                
                flags = msg.getFieldAsInt32(NXCPCodes.VID_FLAGS);
-               subnetMask = msg.getFieldAsInetAddress(NXCPCodes.VID_IP_NETMASK);
                ifIndex = msg.getFieldAsInt32(NXCPCodes.VID_IF_INDEX);
                ifType = msg.getFieldAsInt32(NXCPCodes.VID_IF_TYPE);
       mtu = msg.getFieldAsInt32(NXCPCodes.VID_MTU);
@@ -177,10 +175,12 @@ public class Interface extends GenericObject
        /**
         * @return Interface subnet mask
         */
+       /*
        public InetAddress getSubnetMask()
        {
                return subnetMask;
        }
+       */
        
        /**
         * Get number of bits in subnet mask
@@ -189,26 +189,7 @@ public class Interface extends GenericObject
         */
        public int getSubnetMaskBits()
        {
-      byte[] addr = subnetMask.getAddress();
-      int bits = 0;
-      for(int i = 0; i < addr.length; i++)
-      {
-         if (addr[i] == (byte)0xFF)
-         {
-            bits += 8;
-         }
-         else
-         {
-            for(int j = 0x80; j > 0; j >>= 1)
-            {
-               if ((addr[i] & j) == 0)
-                  break;
-               bits++;
-            }
-            break;
-         }
-      }
-      return bits;
+          return primaryIP.mask;
        }
 
        /**
index b57ffca..67f3562 100644 (file)
@@ -18,8 +18,8 @@
  */
 package org.netxms.client.objects;
 
-import java.net.InetAddress;
-import org.netxms.base.*;
+import org.netxms.base.NXCPCodes;
+import org.netxms.base.NXCPMessage;
 import org.netxms.client.NXCSession;
 
 /**
@@ -27,7 +27,6 @@ import org.netxms.client.NXCSession;
  */
 public class Subnet extends GenericObject
 {
-       private InetAddress subnetMask;
        private long zoneId;
 
        /**
@@ -37,7 +36,6 @@ public class Subnet extends GenericObject
        {
                super(msg, session);
                
-               subnetMask = msg.getFieldAsInetAddress(NXCPCodes.VID_IP_NETMASK);
                zoneId = msg.getFieldAsInt64(NXCPCodes.VID_ZONE_ID);
        }
        
@@ -48,35 +46,18 @@ public class Subnet extends GenericObject
         */
        public int getMaskBits()
        {
-          byte[] addr = subnetMask.getAddress();
-          int bits = 0;
-          for(int i = 0; i < addr.length; i++)
-          {
-             if (addr[i] == (byte)0xFF)
-             {
-                bits += 8;
-             }
-             else
-             {
-                for(int j = 0x80; j > 0; j >>= 1)
-                {
-                   if ((addr[i] & j) == 0)
-                      break;
-                   bits++;
-                }
-                break;
-             }
-          }
-          return bits;
+          return primaryIP.mask;
        }
        
        /**
         * @return Subnet mask
         */
+       /*
        public InetAddress getSubnetMask()
        {
                return subnetMask;
        }
+       */
 
        /* (non-Javadoc)
         * @see org.netxms.client.NXCObject#getObjectClassName()
index c139b86..4308dac 100644 (file)
@@ -184,7 +184,7 @@ public class ObjectTest extends SessionTest
       Set<AbstractObject> subnets = object.getAllChilds(AbstractObject.OBJECT_SUBNET);
       for(AbstractObject s : subnets)
       {
-         System.out.println(s.getObjectName() + ": " + ((Subnet)s).getSubnetMask().getHostAddress() + "/" + ((Subnet)s).getMaskBits());
+         System.out.println(s.getObjectName() + ": " + ((Subnet)s).getPrimaryIP().getHostAddress() + "/" + ((Subnet)s).getMaskBits());
       }
       
       session.disconnect();
index bb6afcb..8b30487 100644 (file)
@@ -41,10 +41,10 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.ui.dialogs.PropertyPage;
+import org.netxms.base.InetAddressEx;
 import org.netxms.client.NXCObjectModificationData;
 import org.netxms.client.NXCSession;
 import org.netxms.client.objects.Cluster;
-import org.netxms.client.objects.ClusterSyncNetwork;
 import org.netxms.ui.eclipse.jobs.ConsoleJob;
 import org.netxms.ui.eclipse.objectmanager.Activator;
 import org.netxms.ui.eclipse.objectmanager.Messages;
@@ -68,7 +68,7 @@ public class ClusterNetworks extends PropertyPage
        private Button addButton;
        private Button editButton;
        private Button deleteButton;
-       private List<ClusterSyncNetwork> networks = null;
+       private List<InetAddressEx> networks = null;
        private boolean isModified = false;
        
        /* (non-Javadoc)
@@ -97,9 +97,9 @@ public class ClusterNetworks extends PropertyPage
       viewer.setLabelProvider(new NetworkListLabelProvider());
       viewer.setComparator(new NetworkListComparator());
       
-      networks = new ArrayList<ClusterSyncNetwork>(object.getSyncNetworks().size());
-      for(ClusterSyncNetwork n : object.getSyncNetworks())
-       networks.add(new ClusterSyncNetwork(n));
+      networks = new ArrayList<InetAddressEx>(object.getSyncNetworks().size());
+      for(InetAddressEx n : object.getSyncNetworks())
+       networks.add(new InetAddressEx(n));
       viewer.setInput(networks.toArray());
       
       GridData gridData = new GridData();
@@ -207,7 +207,7 @@ public class ClusterNetworks extends PropertyPage
                ClusterNetworkEditDialog dlg = new ClusterNetworkEditDialog(getShell(), null, null);
                if (dlg.open() == Window.OK)
                {
-                       ClusterSyncNetwork n = new ClusterSyncNetwork(dlg.getAddress(), dlg.getMask());
+                  InetAddressEx n = new InetAddressEx(dlg.getAddress(), dlg.getMask());
                        networks.add(n);
                        viewer.setInput(networks.toArray());
                        viewer.setSelection(new StructuredSelection(n));
@@ -224,12 +224,12 @@ public class ClusterNetworks extends PropertyPage
                if (selection.size() != 1)
                        return;
                
-               ClusterSyncNetwork n = (ClusterSyncNetwork)selection.getFirstElement();
-               ClusterNetworkEditDialog dlg = new ClusterNetworkEditDialog(getShell(), n.getSubnetAddress(), n.getSubnetMask());
+               InetAddressEx n = (InetAddressEx)selection.getFirstElement();
+               ClusterNetworkEditDialog dlg = new ClusterNetworkEditDialog(getShell(), n.address, n.maskFromBits());
                if (dlg.open() == Window.OK)
                {
-                       n.setSubnetAddress(dlg.getAddress());
-                       n.setSubnetMask(dlg.getMask());
+                       n.address = dlg.getAddress();
+                       n.mask = InetAddressEx.bitsInMask(dlg.getMask());
                        viewer.update(n, null);
                        isModified = true;
                }
index bde191c..5a78895 100644 (file)
@@ -21,7 +21,7 @@ package org.netxms.ui.eclipse.objectmanager.propertypages.helpers;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.swt.SWT;
-import org.netxms.client.objects.ClusterSyncNetwork;
+import org.netxms.base.InetAddressEx;
 import org.netxms.ui.eclipse.objectmanager.propertypages.ClusterNetworks;
 import org.netxms.ui.eclipse.widgets.SortableTableViewer;
 
@@ -43,8 +43,8 @@ public class NetworkListComparator extends ViewerComparator
                switch(column)
                {
                        case ClusterNetworks.COLUMN_ADDRESS:
-                               byte[] addr1 = ((ClusterSyncNetwork)e1).getSubnetAddress().getAddress();
-                               byte[] addr2 = ((ClusterSyncNetwork)e2).getSubnetAddress().getAddress();
+                               byte[] addr1 = ((InetAddressEx)e1).address.getAddress();
+                               byte[] addr2 = ((InetAddressEx)e2).address.getAddress();
 
                                result = 0;
                                for(int i = 0; (i < addr1.length) && (result == 0); i++)
@@ -53,14 +53,7 @@ public class NetworkListComparator extends ViewerComparator
                                }
                                break;
                        case ClusterNetworks.COLUMN_NETMASK:
-                               byte[] mask1 = ((ClusterSyncNetwork)e1).getSubnetMask().getAddress();
-                               byte[] mask2 = ((ClusterSyncNetwork)e2).getSubnetMask().getAddress();
-
-                               result = 0;
-                               for(int i = 0; (i < mask1.length) && (result == 0); i++)
-                               {
-                                       result = Integer.signum(mask1[i] - mask2[i]);
-                               }
+                          result = ((InetAddressEx)e1).mask - ((InetAddressEx)e2).mask;
                                break;
                        default:
                                result = 0;
index a5e7f6e..e37d726 100644 (file)
@@ -21,7 +21,7 @@ package org.netxms.ui.eclipse.objectmanager.propertypages.helpers;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
-import org.netxms.client.objects.ClusterSyncNetwork;
+import org.netxms.base.InetAddressEx;
 import org.netxms.ui.eclipse.objectmanager.propertypages.ClusterNetworks;
 
 /**
@@ -44,15 +44,15 @@ public class NetworkListLabelProvider extends LabelProvider implements ITableLab
        @Override
        public String getColumnText(Object element, int columnIndex)
        {
-               if (!(element instanceof ClusterSyncNetwork))
+               if (!(element instanceof InetAddressEx))
                        return null;
 
                switch(columnIndex)
                {
                        case ClusterNetworks.COLUMN_ADDRESS:
-                               return ((ClusterSyncNetwork)element).getSubnetAddress().getHostAddress();
+                               return ((InetAddressEx)element).address.getHostAddress();
                        case ClusterNetworks.COLUMN_NETMASK:
-                               return ((ClusterSyncNetwork)element).getSubnetMask().getHostAddress();
+                               return Integer.toString(((InetAddressEx)element).mask);
                }
                return null;
        }
index cd02231..4f539b1 100644 (file)
@@ -89,8 +89,7 @@ public class GeneralInfo extends TableElement
                                {
                                        if (session.isZoningEnabled())
                                                addPair(Messages.get().GeneralInfo_ZoneId, Long.toString(iface.getZoneId()));
-                                       addPair(Messages.get().GeneralInfo_IPAddr, iface.getPrimaryIP().getHostAddress());
-                                       addPair(Messages.get().GeneralInfo_IPNetMask, iface.getSubnetMask().getHostAddress());
+                                       addPair(Messages.get().GeneralInfo_IPAddr, iface.getPrimaryIP().getHostAddress() + "/" + iface.getSubnetMaskBits());
                                }
             addPair(Messages.get().GeneralInfo_AdmState, iface.getAdminStateAsText());
             addPair(Messages.get().GeneralInfo_OperState, iface.getOperStateAsText());
index 6babef9..7eddf44 100644 (file)
@@ -95,7 +95,7 @@ public class InterfaceListComparator extends ViewerComparator
                        case InterfacesTab.COLUMN_IP_ADDRESS:
                                result = ComparatorHelper.compareInetAddresses(iface1.getPrimaryIP(), iface2.getPrimaryIP());
                                if(result == 0)
-                                  result = ComparatorHelper.compareInetAddresses(iface1.getSubnetMask(), iface2.getSubnetMask());
+                                  result = iface1.getSubnetMaskBits() - iface2.getSubnetMaskBits();
                                break;
                        default:
                                result = 0;
index 849d771..403399c 100644 (file)
@@ -34,6 +34,16 @@ InetAddress::InetAddress(UINT32 addr)
 }
 
 /**
+ * Create IPv4 address object
+ */
+InetAddress::InetAddress(UINT32 addr, UINT32 mask)
+{
+   m_family = AF_INET;
+   m_addr.v4 = addr;
+   m_maskBits = BitsInMask(mask);
+}
+
+/**
  * Create IPv6 address object
  */
 InetAddress::InetAddress(BYTE *addr)
@@ -239,13 +249,15 @@ bool InetAddress::sameSubnet(const InetAddress &a) const
 }
 
 /**
- * Check if two inet addresses are equals
+ * Check if two inet addresses are equal
+ * This method ignores mask bits and only compares addresses. 
+ * To compare two address/mask pairs use InetAddress::compareTo.
  */
 bool InetAddress::equals(const InetAddress &a) const
 {
    if (a.m_family != m_family)
       return false;
-   return ((m_family == AF_INET) ? (a.m_addr.v4 == m_addr.v4) : !memcmp(a.m_addr.v6, m_addr.v6, 16)) && (a.m_maskBits == m_maskBits);
+   return ((m_family == AF_INET) ? (a.m_addr.v4 == m_addr.v4) : !memcmp(a.m_addr.v6, m_addr.v6, 16));
 }
 
 /**
index 1f5fc31..6dad00d 100644 (file)
@@ -14,8 +14,9 @@ libnxcore_la_SOURCES =  accesspoint.cpp acl.cpp actions.cpp admin.cpp \
                        download_job.cpp ef.cpp email.cpp entirenet.cpp \
                        epp.cpp events.cpp evproc.cpp fdb.cpp \
                        filemonitoring.cpp graph.cpp hdlink.cpp hk.cpp id.cpp \
-                       import.cpp index.cpp interface.cpp isc.cpp job.cpp \
-                       jobmgr.cpp jobqueue.cpp layer2.cpp ldap.cpp lln.cpp lldp.cpp \
+                       import.cpp inaddr_index.cpp index.cpp interface.cpp \
+                       isc.cpp job.cpp jobmgr.cpp jobqueue.cpp layer2.cpp \
+                       ldap.cpp lln.cpp lldp.cpp \
                        locks.cpp logfilter.cpp loghandle.cpp logs.cpp \
                        macdb.cpp main.cpp mdconn.cpp mdsession.cpp \
                        mobile.cpp modules.cpp mt.cpp ndd.cpp ndp.cpp \
index b3a2fc4..a8222a9 100644 (file)
@@ -402,8 +402,8 @@ void AccessPoint::updateState(AccessPointState state)
 
    static const TCHAR *names[] = { _T("id"), _T("name"), _T("macAddr"), _T("ipAddr"), _T("vendor"), _T("model"), _T("serialNumber") };
    PostEventWithNames((state == AP_ADOPTED) ? EVENT_AP_ADOPTED : ((state == AP_UNADOPTED) ? EVENT_AP_UNADOPTED : EVENT_AP_DOWN), 
-      m_nodeId, "ishasss", names,
-      m_id, m_name, m_macAddr, m_dwIpAddr
+      m_nodeId, "ishAsss", names,
+      m_id, m_name, m_macAddr, &m_ipAddress
       CHECK_NULL_EX(m_vendor), CHECK_NULL_EX(m_model), CHECK_NULL_EX(m_serialNumber));
 }
 
@@ -420,7 +420,7 @@ void AccessPoint::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQu
 
    /* TODO: read status from controller via driver and use ping as last resort only */
 
-   if (m_dwIpAddr != 0)
+   if (m_ipAddress.isValid())
    {
                UINT32 icmpProxy = 0;
 
@@ -446,7 +446,7 @@ void AccessPoint::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQu
                                {
                                        TCHAR parameter[64], buffer[64];
 
-                                       _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(m_dwIpAddr, buffer));
+                                       _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), m_ipAddress.toString(buffer));
                                        if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
                                        {
                                                DbgPrintf(7, _T("AccessPoint::StatusPoll(%d,%s): proxy response: \"%s\""), m_id, m_name, buffer);
@@ -486,9 +486,10 @@ void AccessPoint::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQu
                }
                else    // not using ICMP proxy
                {
+         TCHAR buffer[64];
                        sendPollerMsg(rqId, _T("      Starting ICMP ping\r\n"));
-                       DbgPrintf(7, _T("AccessPoint::StatusPoll(%d,%s): calling IcmpPing(0x%08X,3,%d,NULL,%d)"), m_id, m_name, htonl(m_dwIpAddr), g_icmpPingTimeout, g_icmpPingSize);
-                       UINT32 dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
+                       DbgPrintf(7, _T("AccessPoint::StatusPoll(%d,%s): calling IcmpPing(%s,3,%d,NULL,%d)"), m_id, m_name, m_ipAddress.toString(buffer), g_icmpPingTimeout, g_icmpPingSize);
+                       UINT32 dwPingStatus = IcmpPing(m_ipAddress, 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
          m_pingLastTimeStamp = time(NULL);
                        if (dwPingStatus == ICMP_SUCCESS)
          {
@@ -546,7 +547,7 @@ void AccessPoint::updatePingData()
          {
             TCHAR parameter[64], buffer[64];
 
-            _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(m_dwIpAddr, buffer));
+            _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), m_ipAddress.toString(buffer));
             if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
             {
                DbgPrintf(7, _T("AccessPoint::updatePingData:  proxy response: \"%s\""), buffer);
@@ -578,7 +579,7 @@ void AccessPoint::updatePingData()
    }
    else        // not using ICMP proxy
    {
-      UINT32 dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
+      UINT32 dwPingStatus = IcmpPing(m_ipAddress, 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
       if (dwPingStatus != ICMP_SUCCESS)
       {
          DbgPrintf(7, _T("AccessPoint::updatePingData: error getting ping %d"), dwPingStatus);
index 9b5f0c5..894e0e5 100644 (file)
@@ -297,7 +297,7 @@ static BOOL ForwardEvent(const TCHAR *server, Event *event)
                object = FindObjectById(event->getSourceId());
                if (object != NULL)
                {
-                       msg.setField(VID_IP_ADDRESS, object->IpAddr());
+                       msg.setField(VID_IP_ADDRESS, object->getIpAddress());
                        msg.setField(VID_EVENT_CODE, event->getCode());
                        msg.setField(VID_EVENT_NAME, event->getName());
                        if (event->getUserTag() != NULL)
index 204b62c..9411775 100644 (file)
@@ -26,7 +26,7 @@
  * Externals
  */
 extern Queue g_nodePollerQueue;
-void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq);
+void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq);
 
 /**
  * Destructor for extended agent connection class
@@ -288,7 +288,7 @@ void AgentConnectionEx::onSnmpTrap(NXCPMessage *msg)
 
       if (acceptTrap)
       {
-         UINT32 originSenderIP = msg->getFieldAsUInt32(VID_IP_ADDRESS);
+         InetAddress originSenderIP = msg->getFieldAsInetAddress(VID_IP_ADDRESS);
          UINT32 pduLenght = msg->getFieldAsUInt32(VID_PDU_SIZE);
          BYTE *pduBytes = (BYTE*)malloc(pduLenght);
          msg->getFieldAsBinary(VID_PDU, pduBytes, pduLenght);
@@ -323,11 +323,7 @@ void AgentConnectionEx::onSnmpTrap(NXCPMessage *msg)
                      SNMP_SecurityContext *context = pTransport->getSecurityContext();
                      context->setAuthoritativeEngine(localEngine);
                   }
-                  struct sockaddr_in addr;
-                  addr.sin_family = AF_INET;
-                  addr.sin_addr.s_addr = htonl(originSenderIP);
-                  addr.sin_port = htons(msg->getFieldAsUInt16(VID_PORT));
-                  ProcessTrap(pdu, &addr, pTransport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
+                  ProcessTrap(pdu, originSenderIP, msg->getFieldAsUInt16(VID_PORT), pTransport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
                }
                else if ((pdu->getVersion() == SNMP_VERSION_3) && (pdu->getCommand() == SNMP_GET_REQUEST) && (pdu->getAuthoritativeEngine().getIdLen() == 0))
                {
@@ -367,7 +363,7 @@ void AgentConnectionEx::onSnmpTrap(NXCPMessage *msg)
          }
          else
          {
-            DbgPrintf(3, _T("AgentConnectionEx::onSnmpTrap(): not possible to find origin node with IP %s and not acepted traps from unknown source."), IpToStr(originSenderIP, ipStringBuffer));
+            DbgPrintf(3, _T("AgentConnectionEx::onSnmpTrap(): cannot find origin node with IP %s and not accepting traps from unknown sources"), originSenderIP.toString(ipStringBuffer));
          }
       }
    }
index 84050a4..2c3ff5b 100644 (file)
@@ -63,7 +63,7 @@ static UINT32 CDPTopoHandler(UINT32 snmpVersion, SNMP_Variable *var, SNMP_Transp
                        TCHAR ifName[MAX_CONNECTOR_NAME] = _T("");
                        pRespPDU->getVariable(0)->getValueAsString(ifName, MAX_CONNECTOR_NAME);
                        DbgPrintf(6, _T("CDP(%s [%d]): remote port is \"%s\""), node->getName(), node->getId(), ifName);
-                       Interface *ifRemote = remoteNode->findInterface(ifName);
+                       Interface *ifRemote = remoteNode->findInterfaceByName(ifName);
                        if (ifRemote != NULL)
                        {
                                DbgPrintf(6, _T("CDP(%s [%d]): remote interface object is %s [%d]"), node->getName(), node->getId(), ifRemote->getName(), ifRemote->getId());
index 45bfa53..ce291f3 100644 (file)
@@ -28,8 +28,7 @@
 Cluster::Cluster() : DataCollectionTarget()
 {
        m_dwClusterType = 0;
-       m_dwNumSyncNets = 0;
-       m_pSyncNetList= NULL;
+   m_syncNetworks = new ObjectArray<InetAddress>(8, 8, true);
        m_dwNumResources = 0;
        m_pResourceList = NULL;
        m_tmLastPoll = 0;
@@ -43,8 +42,7 @@ Cluster::Cluster() : DataCollectionTarget()
 Cluster::Cluster(const TCHAR *pszName, UINT32 zoneId) : DataCollectionTarget(pszName)
 {
        m_dwClusterType = 0;
-       m_dwNumSyncNets = 0;
-       m_pSyncNetList= NULL;
+   m_syncNetworks = new ObjectArray<InetAddress>(8, 8, true);
        m_dwNumResources = 0;
        m_pResourceList = NULL;
        m_tmLastPoll = 0;
@@ -57,7 +55,7 @@ Cluster::Cluster(const TCHAR *pszName, UINT32 zoneId) : DataCollectionTarget(psz
  */
 Cluster::~Cluster()
 {
-       safe_free(m_pSyncNetList);
+   delete m_syncNetworks;
        safe_free(m_pResourceList);
 }
 
@@ -140,15 +138,12 @@ BOOL Cluster::loadFromDatabase(UINT32 dwId)
                        hResult = DBSelect(g_hCoreDB, szQuery);
                        if (hResult != NULL)
                        {
-                               m_dwNumSyncNets = DBGetNumRows(hResult);
-                               if (m_dwNumSyncNets > 0)
+                               int count = DBGetNumRows(hResult);
+                               for(i = 0; i < count; i++)
                                {
-                                       m_pSyncNetList = (IP_NETWORK *)malloc(sizeof(IP_NETWORK) * m_dwNumSyncNets);
-                                       for(i = 0; i < (int)m_dwNumSyncNets; i++)
-                                       {
-                                               m_pSyncNetList[i].dwAddr = DBGetFieldIPAddr(hResult, i, 0);
-                                               m_pSyncNetList[i].dwMask = DBGetFieldIPAddr(hResult, i, 1);
-                                       }
+               InetAddress *addr = new InetAddress(DBGetFieldInetAddr(hResult, i, 0));
+               addr->setMaskBits(DBGetFieldLong(hResult, i, 1));
+               m_syncNetworks->add(addr);
                                }
                                DBFreeResult(hResult);
                        }
@@ -173,7 +168,7 @@ BOOL Cluster::loadFromDatabase(UINT32 dwId)
                                        {
                                                m_pResourceList[i].dwId = DBGetFieldULong(hResult, i, 0);
                                                DBGetField(hResult, i, 1, m_pResourceList[i].szName, MAX_DB_STRING);
-                                               m_pResourceList[i].dwIpAddr = DBGetFieldIPAddr(hResult, i, 2);
+                                               m_pResourceList[i].ipAddr = DBGetFieldInetAddr(hResult, i, 2);
                                                m_pResourceList[i].dwCurrOwner = DBGetFieldULong(hResult, i, 3);
                                        }
                                }
@@ -198,7 +193,7 @@ BOOL Cluster::loadFromDatabase(UINT32 dwId)
  */
 BOOL Cluster::saveToDatabase(DB_HANDLE hdb)
 {
-       TCHAR szQuery[4096], szIpAddr[16], szNetMask[16];
+       TCHAR szQuery[4096], szIpAddr[64];
    BOOL bResult;
    UINT32 i;
 
@@ -260,11 +255,11 @@ BOOL Cluster::saveToDatabase(DB_HANDLE hdb)
                        {
                                _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM cluster_sync_subnets WHERE cluster_id=%d"), m_id);
                                DBQuery(hdb, szQuery);
-                               for(i = 0; i < m_dwNumSyncNets; i++)
+                               for(int i = 0; i < m_syncNetworks->size(); i++)
                                {
-                                       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO cluster_sync_subnets (cluster_id,subnet_addr,subnet_mask) VALUES (%d,'%s','%s')"),
-                                                                m_id, IpToStr(m_pSyncNetList[i].dwAddr, szIpAddr),
-                                                                IpToStr(m_pSyncNetList[i].dwMask, szNetMask));
+               InetAddress *net = m_syncNetworks->get(i);
+                                       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO cluster_sync_subnets (cluster_id,subnet_addr,subnet_mask) VALUES (%d,'%s',%d)"),
+                          (int)m_id, net->toString(szIpAddr), net->getMaskBits());
                                        bResult = DBQuery(hdb, szQuery);
                                        if (!bResult)
                                                break;
@@ -291,7 +286,7 @@ BOOL Cluster::saveToDatabase(DB_HANDLE hdb)
                                {
                                        _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO cluster_resources (cluster_id,resource_id,resource_name,ip_addr,current_owner) VALUES (%d,%d,%s,'%s',%d)"),
                                                   m_id, m_pResourceList[i].dwId, (const TCHAR *)DBPrepareString(hdb, m_pResourceList[i].szName),
-                                                                 IpToStr(m_pResourceList[i].dwIpAddr, szIpAddr),
+                                                                 m_pResourceList[i].ipAddr.toString(szIpAddr),
                                                                  m_pResourceList[i].dwCurrOwner);
                                        bResult = DBQuery(hdb, szQuery);
                                        if (!bResult)
@@ -347,15 +342,17 @@ void Cluster::fillMessage(NXCPMessage *pMsg)
    DataCollectionTarget::fillMessage(pMsg);
    pMsg->setField(VID_CLUSTER_TYPE, m_dwClusterType);
        pMsg->setField(VID_ZONE_ID, m_zoneId);
-       pMsg->setField(VID_NUM_SYNC_SUBNETS, m_dwNumSyncNets);
-       if (m_dwNumSyncNets > 0)
-               pMsg->setFieldFromInt32Array(VID_SYNC_SUBNETS, m_dwNumSyncNets * 2, (UINT32 *)m_pSyncNetList);
-       pMsg->setField(VID_NUM_RESOURCES, m_dwNumResources);
+
+   pMsg->setField(VID_NUM_SYNC_SUBNETS, (UINT32)m_syncNetworks->size());
+   for(i = 0, dwId = VID_SYNC_SUBNETS_BASE; i < (UINT32)m_syncNetworks->size(); i++)
+      pMsg->setField(dwId++, *(m_syncNetworks->get(i)));
+
+   pMsg->setField(VID_NUM_RESOURCES, m_dwNumResources);
        for(i = 0, dwId = VID_RESOURCE_LIST_BASE; i < m_dwNumResources; i++, dwId += 6)
        {
                pMsg->setField(dwId++, m_pResourceList[i].dwId);
                pMsg->setField(dwId++, m_pResourceList[i].szName);
-               pMsg->setField(dwId++, m_pResourceList[i].dwIpAddr);
+               pMsg->setField(dwId++, m_pResourceList[i].ipAddr);
                pMsg->setField(dwId++, m_pResourceList[i].dwCurrOwner);
        }
 }
@@ -375,16 +372,13 @@ UINT32 Cluster::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
    // Change sync subnets
    if (pRequest->isFieldExist(VID_NUM_SYNC_SUBNETS))
        {
-      m_dwNumSyncNets = pRequest->getFieldAsUInt32(VID_NUM_SYNC_SUBNETS);
-               if (m_dwNumSyncNets > 0)
-               {
-                       m_pSyncNetList = (IP_NETWORK *)realloc(m_pSyncNetList, sizeof(IP_NETWORK) * m_dwNumSyncNets);
-                       pRequest->getFieldAsInt32Array(VID_SYNC_SUBNETS, m_dwNumSyncNets * 2, (UINT32 *)m_pSyncNetList);
-               }
-               else
-               {
-                       safe_free_and_null(m_pSyncNetList);
-               }
+      m_syncNetworks->clear();
+      int count = pRequest->getFieldAsInt32(VID_NUM_SYNC_SUBNETS);
+      UINT32 fieldId = VID_SYNC_SUBNETS_BASE;
+      for(int i = 0; i < count; i++)
+      {
+         m_syncNetworks->add(new InetAddress(pRequest->getFieldAsInetAddress(fieldId++)));
+      }
        }
 
    // Change resource list
@@ -402,7 +396,7 @@ UINT32 Cluster::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
                        {
                                pList[i].dwId = pRequest->getFieldAsUInt32(dwId++);
                                pRequest->getFieldAsString(dwId++, pList[i].szName, MAX_DB_STRING);
-                               pList[i].dwIpAddr = pRequest->getFieldAsUInt32(dwId++);
+                               pList[i].ipAddr = pRequest->getFieldAsInetAddress(dwId++);
                        }
 
                        // Update current owner information in existing resources
@@ -435,15 +429,14 @@ UINT32 Cluster::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
 /**
  * Check if given address is within sync network
  */
-bool Cluster::isSyncAddr(UINT32 dwAddr)
+bool Cluster::isSyncAddr(const InetAddress& addr)
 {
-       UINT32 i;
        bool bRet = false;
 
        lockProperties();
-       for(i = 0; i < m_dwNumSyncNets; i++)
+       for(int i = 0; i < m_syncNetworks->size(); i++)
        {
-               if ((dwAddr & m_pSyncNetList[i].dwMask) == m_pSyncNetList[i].dwAddr)
+               if (m_syncNetworks->get(i)->contain(addr))
                {
                        bRet = true;
                        break;
@@ -456,7 +449,7 @@ bool Cluster::isSyncAddr(UINT32 dwAddr)
 /**
  * Check if given address is a resource address
  */
-bool Cluster::isVirtualAddr(UINT32 dwAddr)
+bool Cluster::isVirtualAddr(const InetAddress& addr)
 {
        UINT32 i;
        bool bRet = false;
@@ -464,7 +457,7 @@ bool Cluster::isVirtualAddr(UINT32 dwAddr)
        lockProperties();
        for(i = 0; i < m_dwNumResources; i++)
        {
-               if (m_pResourceList[i].dwIpAddr == dwAddr)
+      if (m_pResourceList[i].ipAddr.equals(addr))
                {
                        bRet = true;
                        break;
@@ -541,7 +534,7 @@ void Cluster::statusPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
                                {
                                        for(k = 0; k < m_dwNumResources; k++)
                                        {
-                                               if (m_pResourceList[k].dwIpAddr == pIfList->get(j)->ipAddr)
+                  if (m_pResourceList[k].ipAddr.equals(pIfList->get(j)->ipAddr))
                                                {
                                                        if (m_pResourceList[k].dwCurrOwner != ppPollList[i]->getId())
                                                        {
index df31431..0147af6 100644 (file)
@@ -91,7 +91,7 @@ static void C_SysNodeDown(Node *pNode, Event *pEvent)
        }
 
        // Check directly connected switch
-       Interface *iface = pNode->findInterface(0, pNode->IpAddr());
+       Interface *iface = pNode->findInterfaceByIP(pNode->getIpAddress());
        if ((iface != NULL) && (iface->getPeerNodeId() != 0))
        {
                if (CheckNodeDown(pNode, pEvent, iface->getPeerNodeId(), _T("upstream switch")))
@@ -140,7 +140,7 @@ static void C_SysNodeDown(Node *pNode, Event *pEvent)
       }
       else
       {
-         Interface *pInterface = ((Node *)hop->object)->findInterface(hop->ifIndex, INADDR_ANY);
+         Interface *pInterface = ((Node *)hop->object)->findInterfaceByIndex(hop->ifIndex);
          if ((pInterface != NULL) && ((pInterface->Status() == STATUS_CRITICAL) || (pInterface->Status() == STATUS_DISABLED)))
          {
                                DbgPrintf(5, _T("C_SysNodeDown: upstream interface %s [%d] on node %s [%d] for current node %s [%d] is down"),
@@ -169,7 +169,7 @@ void CorrelateEvent(Event *pEvent)
    {
       case EVENT_INTERFACE_DISABLED:
                        {
-                               Interface *pInterface = node->findInterface(pEvent->getParameterAsULong(4), INADDR_ANY);
+            Interface *pInterface = node->findInterfaceByIndex(pEvent->getParameterAsULong(4));
                                if (pInterface != NULL)
                                {
                                        pInterface->setLastDownEventId(pEvent->getId());
@@ -178,7 +178,7 @@ void CorrelateEvent(Event *pEvent)
                        break;
       case EVENT_INTERFACE_DOWN:
                        {
-                               Interface *pInterface = node->findInterface(pEvent->getParameterAsULong(4), INADDR_ANY);
+                               Interface *pInterface = node->findInterfaceByIndex(pEvent->getParameterAsULong(4));
                                if (pInterface != NULL)
                                {
                                        pInterface->setLastDownEventId(pEvent->getId());
index 6a8fb05..274c03d 100644 (file)
@@ -325,9 +325,8 @@ void DCObject::expandMacros(const TCHAR *src, TCHAR *dst, size_t dstLen)
                {
                        if (m_pNode != NULL)
                        {
-                               TCHAR ipAddr[32];
-
-                               temp += IpToStr(m_pNode->IpAddr(), ipAddr);
+                               TCHAR ipAddr[64];
+                               temp += m_pNode->getIpAddress().toString(ipAddr);
                        }
                        else
                        {
index 9ec12be..6a86569 100644 (file)
@@ -539,7 +539,7 @@ UINT32 DataCollectionTarget::getInternalItem(const TCHAR *param, size_t bufSize,
    }
    else if (!_tcsicmp(_T("PingTime"), param))
    {
-      if (m_dwIpAddr != 0)
+      if (m_ipAddress.isValid())
       {
          Interface *iface = NULL;
 
@@ -547,7 +547,7 @@ UINT32 DataCollectionTarget::getInternalItem(const TCHAR *param, size_t bufSize,
          LockChildList(FALSE);
          for(int i = 0; i < (int)m_dwChildCount; i++)
          {
-            if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) && (m_pChildList[i]->IpAddr() == m_dwIpAddr))
+            if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) && m_pChildList[i]->getIpAddress().equals(m_ipAddress))
             {
                iface = (Interface *)m_pChildList[i];
                break;
index b82c9a7..f9a3480 100644 (file)
@@ -157,11 +157,16 @@ Event::Event(EVENT_TEMPLATE *pTemplate, UINT32 sourceId, const TCHAR *userTag, c
                _sntprintf(buffer, 16, _T("0x%08X"), va_arg(args, UINT32));
                                        m_parameters.add(buffer);
                break;
-            case 'a':
+            case 'a':   // IPv4 address
                buffer = (TCHAR *)malloc(16 * sizeof(TCHAR));
                IpToStr(va_arg(args, UINT32), buffer);
                                        m_parameters.add(buffer);
                break;
+            case 'A':   // InetAddress object
+               buffer = (TCHAR *)malloc(64 * sizeof(TCHAR));
+               va_arg(args, InetAddress *)->toString(buffer);
+                                       m_parameters.add(buffer);
+               break;
             case 'h':
                buffer = (TCHAR *)malloc(32 * sizeof(TCHAR));
                MACToStr(va_arg(args, BYTE *), buffer);
@@ -266,9 +271,9 @@ TCHAR *Event::expandText(Event *event, UINT32 sourceObject, const TCHAR *textTem
                   dwPos += (UINT32)_tcslen(pObject->getName());
                   break;
                case 'a':   // IP address of event source
-                  dwSize += 16;
+                  dwSize += 64;
                   pText = (TCHAR *)realloc(pText, dwSize * sizeof(TCHAR));
-                  IpToStr(pObject->IpAddr(), &pText[dwPos]);
+                  pObject->getIpAddress().toString(&pText[dwPos]);
                   dwPos = (UINT32)_tcslen(pText);
                   break;
                case 'g':   // Source object's GUID
@@ -846,7 +851,8 @@ static EVENT_TEMPLATE *FindEventTemplate(UINT32 eventCode)
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  * @param names names for parameters (NULL if parameters are unnamed)
@@ -899,7 +905,8 @@ static BOOL RealPostEvent(Queue *queue, UINT32 eventCode, UINT32 sourceId,
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  *        t - timestamp (time_t) as raw value (seconds since epoch)
@@ -928,7 +935,8 @@ BOOL NXCORE_EXPORTABLE PostEvent(UINT32 eventCode, UINT32 sourceId, const char *
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  * @param names names for parameters (NULL if parameters are unnamed)
@@ -957,7 +965,8 @@ BOOL NXCORE_EXPORTABLE PostEventWithNames(UINT32 eventCode, UINT32 sourceId, con
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  * @param names names for parameters (NULL if parameters are unnamed)
@@ -1018,7 +1027,8 @@ BOOL NXCORE_EXPORTABLE PostEventWithNames(UINT32 eventCode, UINT32 sourceId, Str
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  * @param names names for parameters (NULL if parameters are unnamed)
@@ -1049,7 +1059,8 @@ BOOL NXCORE_EXPORTABLE PostEventWithTag(UINT32 eventCode, UINT32 sourceId, const
  *        d - Decimal integer
  *        D - 64-bit decimal integer
  *        x - Hex integer
- *        a - IP address
+ *        a - IPv4 address
+ *        A - InetAddress object
  *        h - MAC (hardware) address
  *        i - Object ID
  */
index 5ae0347..d7e1c85 100644 (file)
@@ -163,7 +163,7 @@ void ForwardingDatabase::print(CONSOLE_CTX ctx, Node *owner)
        for(int i = 0; i < m_fdbSize; i++)
    {
       Node *node = (Node *)FindObjectById(m_fdb[i].nodeObject, OBJECT_NODE);
-      Interface *iface = owner->findInterface(m_fdb[i].ifIndex, INADDR_ANY);
+      Interface *iface = owner->findInterfaceByIndex(m_fdb[i].ifIndex);
       ConsolePrintf(ctx, _T("%s | %7d | %-20s | %4d | %5d | %s\n"), MACToStr(m_fdb[i].macAddr, macAddrStr),
          m_fdb[i].ifIndex, (iface != NULL) ? iface->getName() : _T("\x1b[31;1mUNKNOWN\x1b[0m"), 
          m_fdb[i].port, m_fdb[i].nodeObject, (node != NULL) ? node->getName() : _T("\x1b[31;1mUNKNOWN\x1b[0m"));
@@ -187,7 +187,7 @@ void ForwardingDatabase::fillMessage(NXCPMessage *msg)
       msg->setField(fieldId++, m_fdb[i].nodeObject);
       msg->setField(fieldId++, m_fdb[i].vlanId);
       msg->setField(fieldId++, m_fdb[i].type);
-      Interface *iface = (node != NULL) ? node->findInterface(m_fdb[i].ifIndex, INADDR_ANY) : NULL;
+      Interface *iface = (node != NULL) ? node->findInterfaceByIndex(m_fdb[i].ifIndex) : NULL;
       if (iface != NULL)
       {
          msg->setField(fieldId++, iface->getName());
diff --git a/src/server/core/inaddr_index.cpp b/src/server/core/inaddr_index.cpp
new file mode 100644 (file)
index 0000000..f722f10
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+** NetXMS - Network Management System
+** Copyright (C) 2003-2015 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: inaddr_index.cpp
+**
+**/
+
+#include "nxcore.h"
+#include <uthash.h>
+
+/**
+ * Entry
+ */
+struct InetAddressIndexEntry
+{
+   UT_hash_handle hh;
+   BYTE key[18];
+   NetObj *object;
+};
+
+/**
+ * Constructor
+ */
+InetAddressIndex::InetAddressIndex()
+{
+   m_root = NULL;
+   m_lock = RWLockCreate();
+}
+
+/**
+ * Destructor
+ */
+InetAddressIndex::~InetAddressIndex()
+{
+   InetAddressIndexEntry *entry, *tmp;
+   HASH_ITER(hh, m_root, entry, tmp)
+   {
+      HASH_DEL(m_root, entry);
+      free(entry);
+   }
+   RWLockDestroy(m_lock);
+}
+
+/**
+ * Put object into index
+ *
+ * @param key object's key
+ * @param object object
+ * @return true if existing object was replaced
+ */
+bool InetAddressIndex::put(const InetAddress& addr, NetObj *object)
+{
+   if (!addr.isValid())
+      return false;
+
+   bool replace = true;
+
+   BYTE key[18];
+   addr.buildHashKey(key);
+
+   RWLockWriteLock(m_lock, INFINITE);
+
+   InetAddressIndexEntry *entry;
+   HASH_FIND(hh, m_root, key, 18, entry);
+   if (entry == NULL)
+   {
+      entry = (InetAddressIndexEntry *)malloc(sizeof(InetAddressIndexEntry));
+      memcpy(entry->key, key, 18);
+      HASH_ADD_KEYPTR(hh, m_root, entry->key, 18, entry);
+      replace = false;
+   }
+   entry->object = object;
+
+   RWLockUnlock(m_lock);
+   return replace;
+}
+
+/**
+ * Remove object from index
+ */
+void InetAddressIndex::remove(const InetAddress& addr)
+{
+   if (!addr.isValid())
+      return;
+
+   BYTE key[18];
+   addr.buildHashKey(key);
+
+   RWLockWriteLock(m_lock, INFINITE);
+
+   InetAddressIndexEntry *entry;
+   HASH_FIND(hh, m_root, key, 18, entry);
+   if (entry != NULL)
+   {
+      HASH_DEL(m_root, entry);
+      free(entry);
+   }
+   RWLockUnlock(m_lock);
+}
+
+/**
+ * Get object by IP address
+ */
+NetObj *InetAddressIndex::get(const InetAddress& addr)
+{
+   if (!addr.isValid())
+      return NULL;
+
+   NetObj *object = NULL;
+
+   BYTE key[18];
+   addr.buildHashKey(key);
+
+   RWLockReadLock(m_lock, INFINITE);
+
+   InetAddressIndexEntry *entry;
+   HASH_FIND(hh, m_root, key, 18, entry);
+   if (entry != NULL)
+   {
+      object = entry->object;
+   }
+   RWLockUnlock(m_lock);
+   return object;
+}
+
+/**
+ * Find object using comparator
+ */
+NetObj *InetAddressIndex::find(bool (*comparator)(NetObj *, void *), void *data)
+{
+   NetObj *object = NULL;
+
+   RWLockReadLock(m_lock, INFINITE);
+
+   InetAddressIndexEntry *entry, *tmp;
+   HASH_ITER(hh, m_root, entry, tmp)
+   {
+      if (comparator(entry->object, data))
+      {
+         object = entry->object;
+         break;
+      }
+   }
+
+   RWLockUnlock(m_lock);
+   return object;
+}
+
+/**
+ * Get index size
+ */
+int InetAddressIndex::size()
+{
+   RWLockReadLock(m_lock, INFINITE);
+   int s = HASH_COUNT(m_root);
+   RWLockUnlock(m_lock);
+   return s;
+}
+
+/**
+ * Get all objects
+ */
+ObjectArray<NetObj> *InetAddressIndex::getObjects(bool updateRefCount, bool (*filter)(NetObj *, void *), void *userData)
+{
+   ObjectArray<NetObj> *objects = new ObjectArray<NetObj>();
+
+   RWLockReadLock(m_lock, INFINITE);
+   InetAddressIndexEntry *entry, *tmp;
+   HASH_ITER(hh, m_root, entry, tmp)
+   {
+      if ((filter == NULL) || filter(entry->object, userData))
+      {
+         if (updateRefCount)
+            entry->object->incRefCount();
+         objects->add(entry->object);
+      }
+   }
+   RWLockUnlock(m_lock);
+   return objects;
+}
+
+/**
+ * Execute given callback for each object
+ */
+void InetAddressIndex::forEach(void (*callback)(NetObj *, void *), void *data)
+{
+   RWLockReadLock(m_lock, INFINITE);
+   InetAddressIndexEntry *entry, *tmp;
+   HASH_ITER(hh, m_root, entry, tmp)
+   {
+      callback(entry->object, data);
+   }
+   RWLockUnlock(m_lock);
+}
index 487a1be..ba447ce 100644 (file)
@@ -31,7 +31,6 @@ Interface::Interface() : NetObj()
        m_flags = 0;
        nx_strncpy(m_description, m_name, MAX_DB_STRING);
    m_alias[0] = 0;
-   m_ipNetMask = 0;
    m_index = 0;
    m_type = IFTYPE_OTHER;
    m_mtu = 0;
@@ -56,17 +55,16 @@ Interface::Interface() : NetObj()
 /**
  * Constructor for "fake" interface object
  */
-Interface::Interface(UINT32 dwAddr, UINT32 dwNetMask, UINT32 zoneId, bool bSyntheticMask) : NetObj()
+Interface::Interface(const InetAddress& addr, UINT32 zoneId, bool bSyntheticMask) : NetObj()
 {
        m_flags = bSyntheticMask ? IF_SYNTHETIC_MASK : 0;
-       if ((dwAddr & 0xFF000000) == 0x7F000000)
+   if (addr.isLoopback())
                m_flags |= IF_LOOPBACK;
 
        _tcscpy(m_name, _T("unknown"));
    _tcscpy(m_description, _T("unknown"));
    m_alias[0] = 0;
-   m_dwIpAddr = dwAddr;
-   m_ipNetMask = dwNetMask;
+   m_ipAddress = addr;
    m_index = 1;
    m_type = IFTYPE_OTHER;
    m_mtu = 0;
@@ -92,10 +90,10 @@ Interface::Interface(UINT32 dwAddr, UINT32 dwNetMask, UINT32 zoneId, bool bSynth
 /**
  * Constructor for normal interface object
  */
-Interface::Interface(const TCHAR *name, const TCHAR *descr, UINT32 index, UINT32 ipAddr, UINT32 ipNetMask, UINT32 ifType, UINT32 zoneId)
+Interface::Interface(const TCHAR *name, const TCHAR *descr, UINT32 index, const InetAddress& addr, UINT32 ifType, UINT32 zoneId)
           : NetObj()
 {
-       if (((ipAddr & 0xFF000000) == 0x7F000000) || (ifType == IFTYPE_SOFTWARE_LOOPBACK))
+   if (addr.isLoopback() || (ifType == IFTYPE_SOFTWARE_LOOPBACK))
                m_flags = IF_LOOPBACK;
        else
                m_flags = 0;
@@ -106,8 +104,7 @@ Interface::Interface(const TCHAR *name, const TCHAR *descr, UINT32 index, UINT32
    m_index = index;
    m_type = ifType;
    m_mtu = 0;
-   m_dwIpAddr = ipAddr;
-   m_ipNetMask = ipNetMask;
+   m_ipAddress = addr;
        m_bridgePortNumber = 0;
        m_slotNumber = 0;
        m_portNumber = 0;
@@ -178,8 +175,8 @@ BOOL Interface::loadFromDatabase(UINT32 dwId)
 
    if (DBGetNumRows(hResult) != 0)
    {
-      m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 0);
-      m_ipNetMask = DBGetFieldIPAddr(hResult, 0, 1);
+      m_ipAddress = DBGetFieldInetAddr(hResult, 0, 0);
+      m_ipAddress.setMaskBits(DBGetFieldLong(hResult, 0, 1));
       m_type = DBGetFieldULong(hResult, 0, 2);
       m_index = DBGetFieldULong(hResult, 0, 3);
       UINT32 nodeId = DBGetFieldULong(hResult, 0, 4);
@@ -236,7 +233,7 @@ BOOL Interface::loadFromDatabase(UINT32 dwId)
    loadACLFromDB();
 
        // Validate loopback flag
-       if (((m_dwIpAddr & 0xFF000000) == 0x7F000000) || (m_type == IFTYPE_SOFTWARE_LOOPBACK))
+       if (m_ipAddress.isLoopback() || (m_type == IFTYPE_SOFTWARE_LOOPBACK))
                m_flags |= IF_LOOPBACK;
 
    return bResult;
@@ -247,7 +244,7 @@ BOOL Interface::loadFromDatabase(UINT32 dwId)
  */
 BOOL Interface::saveToDatabase(DB_HANDLE hdb)
 {
-   TCHAR szMacStr[16], szIpAddr[16], szNetMask[16];
+   TCHAR szMacStr[16], szIpAddr[64];
    UINT32 dwNodeId;
 
    lockProperties();
@@ -291,8 +288,8 @@ BOOL Interface::saveToDatabase(DB_HANDLE hdb)
                return FALSE;
        }
 
-       DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, IpToStr(m_dwIpAddr, szIpAddr), DB_BIND_STATIC);
-       DBBind(hStmt, 2, DB_SQLTYPE_VARCHAR, IpToStr(m_ipNetMask, szNetMask), DB_BIND_STATIC);
+       DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, m_ipAddress.toString(szIpAddr), DB_BIND_STATIC);
+       DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_ipAddress.getMaskBits());
        DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, dwNodeId);
        DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, m_type);
        DBBind(hStmt, 5, DB_SQLTYPE_INTEGER, m_index);
@@ -399,7 +396,7 @@ void Interface::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQueu
    if (bNeedPoll)
    {
                // Pings cannot be used for cluster sync interfaces
-      if ((pNode->getFlags() & NF_DISABLE_ICMP) || clusterSync || (m_dwIpAddr == 0) || isLoopback())
+      if ((pNode->getFlags() & NF_DISABLE_ICMP) || clusterSync || !m_ipAddress.isValid() || isLoopback())
       {
                        // Interface doesn't have an IP address, so we can't ping it
                        sendPollerMsg(rqId, POLLER_WARNING _T("      Interface status cannot be determined\r\n"));
@@ -430,9 +427,9 @@ void Interface::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQueu
                                        AgentConnection *conn = proxyNode->createAgentConnection();
                                        if (conn != NULL)
                                        {
-                                               TCHAR parameter[64], buffer[64];
+                                               TCHAR parameter[128], buffer[64];
 
-                                               _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(m_dwIpAddr, buffer));
+                                               _sntprintf(parameter, 128, _T("Icmp.Ping(%s)"), m_ipAddress.toString(buffer));
                                                if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
                                                {
                                                        DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): proxy response: \"%s\""), m_id, m_name, buffer);
@@ -472,8 +469,9 @@ void Interface::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQueu
                        else    // not using ICMP proxy
                        {
                                sendPollerMsg(rqId, _T("      Starting ICMP ping\r\n"));
-                               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): calling IcmpPing(0x%08X,3,%d,%d,%d)"), m_id, m_name, htonl(m_dwIpAddr), g_icmpPingTimeout, m_pingTime, g_icmpPingSize);
-                               UINT32 dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
+                               DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): calling IcmpPing(%s,3,%d,%d,%d)"), 
+               m_id, m_name, (const TCHAR *)m_ipAddress.toString(), g_icmpPingTimeout, m_pingTime, g_icmpPingSize);
+                               UINT32 dwPingStatus = IcmpPing(m_ipAddress, 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
             m_pingLastTimeStamp = time(NULL);
                                if (dwPingStatus == ICMP_SUCCESS)
                                {
@@ -594,7 +592,7 @@ void Interface::statusPoll(ClientSession *session, UINT32 rqId, Queue *eventQueu
                   sendPollerMsg(rqId, _T("      Interface status changed to %s\r\n"), GetStatusAsText(m_iStatus, true));
                   PostEventEx(eventQueue,
                               (expectedState == IF_EXPECTED_STATE_DOWN) ? statusToEventInverted[m_iStatus] : statusToEvent[m_iStatus],
-                                                  pNode->getId(), "dsaad", m_id, m_name, m_dwIpAddr, m_ipNetMask, m_index);
+                                                  pNode->getId(), "dsAdd", m_id, m_name, &m_ipAddress, m_ipAddress.getMaskBits(), m_index);
       }
    }
        else if (expectedState == IF_EXPECTED_STATE_IGNORE)
@@ -649,9 +647,9 @@ void Interface::updatePingData()
          AgentConnection *conn = proxyNode->createAgentConnection();
          if (conn != NULL)
          {
-            TCHAR parameter[64], buffer[64];
+            TCHAR parameter[128], buffer[64];
 
-            _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(m_dwIpAddr, buffer));
+            _sntprintf(parameter, 128, _T("Icmp.Ping(%s)"), m_ipAddress.toString(buffer));
             if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
             {
                DbgPrintf(7, _T("Interface::updatePingData:  proxy response: \"%s\""), buffer);
@@ -683,7 +681,7 @@ void Interface::updatePingData()
    }
    else        // not using ICMP proxy
    {
-      UINT32 dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
+      UINT32 dwPingStatus = IcmpPing(m_ipAddress, 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
       if (dwPingStatus != ICMP_SUCCESS)
       {
          DbgPrintf(7, _T("Interface::updatePingData: error getting ping %d"), dwPingStatus);
@@ -796,7 +794,6 @@ void Interface::fillMessage(NXCPMessage *pMsg)
    pMsg->setField(VID_MTU, m_mtu);
    pMsg->setField(VID_IF_SLOT, m_slotNumber);
    pMsg->setField(VID_IF_PORT, m_portNumber);
-   pMsg->setField(VID_IP_NETMASK, m_ipNetMask);
    pMsg->setField(VID_MAC_ADDR, m_macAddr, MAC_ADDR_LENGTH);
        pMsg->setField(VID_FLAGS, m_flags);
        pMsg->setField(VID_REQUIRED_POLLS, (WORD)m_requiredPollCount);
@@ -865,7 +862,7 @@ UINT32 Interface::wakeUp()
 
    if (memcmp(m_macAddr, "\x00\x00\x00\x00\x00\x00", 6))
    {
-      dwAddr = htonl(m_dwIpAddr | ~m_ipNetMask);
+      dwAddr = htonl(m_ipAddress.getAddressV4() | ~(0xFFFFFFFF << m_ipAddress.getMaskBits()));
       if (SendMagicPacket(dwAddr, m_macAddr, 5))
          dwResult = RCC_SUCCESS;
       else
@@ -905,11 +902,11 @@ UINT32 Interface::getParentNodeId()
 /**
  * Change interface's IP address
  */
-void Interface::setIpAddr(UINT32 dwNewAddr)
+void Interface::setIpAddr(const InetAddress& newAddr)
 {
-   UpdateInterfaceIndex(m_dwIpAddr, dwNewAddr, this);
+   UpdateInterfaceIndex(m_ipAddress, newAddr, this);
    lockProperties();
-   m_dwIpAddr = dwNewAddr;
+   m_ipAddress = newAddr;
    setModified();
    unlockProperties();
 }
@@ -917,16 +914,15 @@ void Interface::setIpAddr(UINT32 dwNewAddr)
 /**
  * Change interface's IP subnet mask
  */
-void Interface::setIpNetMask(UINT32 dwNetMask)
+void Interface::setIpNetMask(int maskBits)
 {
-   UINT32 oldNetMask = m_ipNetMask;
+   int oldNetMask = m_ipAddress.getMaskBits();
    lockProperties();
-   m_ipNetMask = dwNetMask;
+   m_ipAddress.setMaskBits(maskBits);
    setModified();
    unlockProperties();
-   PostEvent(EVENT_IF_MASK_CHANGED, m_id, "dsaada", m_id,
-                m_name, m_dwIpAddr,
-                m_ipNetMask, m_index, oldNetMask);
+   PostEvent(EVENT_IF_MASK_CHANGED, m_id, "dsAddd", m_id,
+                m_name, &m_ipAddress, m_ipAddress.getMaskBits(), m_index, oldNetMask);
 }
 
 /**
@@ -1000,9 +996,9 @@ void Interface::setPeer(Node *node, Interface *iface, LinkLayerProtocol protocol
          _T("localIfIP"), _T("localIfMAC"), _T("remoteNodeId"), _T("remoteNodeName"),
          _T("remoteIfId"), _T("remoteIfIndex"), _T("remoteIfName"), _T("remoteIfIP"),
          _T("remoteIfMAC"), _T("protocol") };
-      PostEventWithNames(EVENT_IF_PEER_CHANGED, getParentNodeId(), "ddsahdsddsah", names,
-         m_id, m_index, m_name, m_dwIpAddr, m_macAddr, node->getId(), node->getName(),
-         iface->getId(), iface->getIfIndex(), iface->getName(), iface->IpAddr(), iface->getMacAddr(),
+      PostEventWithNames(EVENT_IF_PEER_CHANGED, getParentNodeId(), "ddsAhdsddsAhd", names,
+         m_id, m_index, m_name, &m_ipAddress, m_macAddr, node->getId(), node->getName(),
+         iface->getId(), iface->getIfIndex(), iface->getName(), &iface->getIpAddress(), iface->getMacAddr(),
          protocol);
    }
 }
index 7d372a1..c84492e 100644 (file)
@@ -45,8 +45,8 @@ void BuildL2Topology(nxmap_ObjList &topology, Node *root, int nDepth, bool inclu
                        if ((node != NULL) && (nDepth > 0) && (node->isBridge() || includeEndNodes))
                        {
                                BuildL2Topology(topology, node, nDepth - 1, includeEndNodes);
-                               Interface *ifLocal = root->findInterface(info->ifLocal, INADDR_ANY);
-                               Interface *ifRemote = node->findInterface(info->ifRemote, INADDR_ANY);
+                               Interface *ifLocal = root->findInterfaceByIndex(info->ifLocal);
+                               Interface *ifRemote = node->findInterfaceByIndex(info->ifRemote);
                                DbgPrintf(5, _T("BuildL2Topology: root=%s [%d], node=%s [%d], ifLocal=%d %p, ifRemote=%d %p"),
                                          root->getName(), root->getId(), node->getName(), node->getId(), info->ifLocal, ifLocal, info->ifRemote, ifRemote);
                                topology.linkObjectsEx(root->getId(), node->getId(),
@@ -91,7 +91,7 @@ NetObj *FindInterfaceConnectionPoint(const BYTE *macAddr, int *type)
                                int count = fdb->getMacCountOnPort(ifIndex);
                                if (count == 1)
                                {
-                                       Interface *iface = node->findInterface(ifIndex, INADDR_ANY);
+                                       Interface *iface = node->findInterfaceByIndex(ifIndex);
                                        if (iface != NULL)
                                        {
                                                DbgPrintf(4, _T("FindInterfaceConnectionPoint(%s): found interface %s [%d] on node %s [%d]"), macAddrText,
@@ -142,7 +142,7 @@ NetObj *FindInterfaceConnectionPoint(const BYTE *macAddr, int *type)
                   }
                   else
                   {
-                     Interface *iface = node->findInterface(ws->rfIndex, INADDR_ANY);
+                     Interface *iface = node->findInterfaceByIndex(ws->rfIndex);
                      if (iface != NULL)
                      {
                                                      DbgPrintf(4, _T("FindInterfaceConnectionPoint(%s): found matching wireless station on node %s [%d] interface %s"),
@@ -175,7 +175,7 @@ NetObj *FindInterfaceConnectionPoint(const BYTE *macAddr, int *type)
 
        if ((cp == NULL) && (bestMatchNode != NULL))
        {
-               cp = bestMatchNode->findInterface(bestMatchIfIndex, INADDR_ANY);
+               cp = bestMatchNode->findInterfaceByIndex(bestMatchIfIndex);
        }
        return cp;
 }
index 943fe52..c208d4f 100644 (file)
@@ -108,7 +108,7 @@ static Interface *FindRemoteInterface(Node *node, UINT32 idType, BYTE *id, size_
                                ifName[len] = 0;
                        }
 #endif
-                       ifc = node->findInterface(ifName);      /* TODO: find by cached ifName value */
+                       ifc = node->findInterfaceByName(ifName);        /* TODO: find by cached ifName value */
                        if ((ifc == NULL) && !_tcsncmp(node->getObjectId(), _T(".1.3.6.1.4.1.1916.2"), 19))
                        {
                                // Hack for Extreme Networks switches
@@ -116,7 +116,7 @@ static Interface *FindRemoteInterface(Node *node, UINT32 idType, BYTE *id, size_
                                memmove(&ifName[2], ifName, (_tcslen(ifName) + 1) * sizeof(TCHAR));
                                ifName[0] = _T('1');
                                ifName[1] = _T(':');
-                               ifc = node->findInterface(ifName);
+                               ifc = node->findInterfaceByName(ifName);
                        }
                        return ifc;
                case 7: // local identifier
@@ -125,9 +125,9 @@ static Interface *FindRemoteInterface(Node *node, UINT32 idType, BYTE *id, size_
             if (node->isBridge())
                ifc = node->findBridgePort(port.portNumber);
             else
-               ifc = node->findInterface(port.portNumber, INADDR_ANY);
+               ifc = node->findInterfaceByIndex(port.portNumber);
             if (ifc == NULL)  // unable to find interface by bridge port number or interface index, try description
-               ifc = node->findInterface(port.ifDescr);        /* TODO: find by cached ifName value */
+               ifc = node->findInterfaceByName(port.ifDescr);  /* TODO: find by cached ifName value */
                        }
                        else
                        {
@@ -186,7 +186,7 @@ static UINT32 LLDPTopoHandler(UINT32 snmpVersion, SNMP_Variable *var, SNMP_Trans
             // Try to find remote interface by description
             TCHAR *ifDescr = pRespPDU->getVariable(3)->getValueAsString((TCHAR *)remoteIfId, 1024 / sizeof(TCHAR));
             if (ifDescr != NULL)
-               ifRemote = remoteNode->findInterface(ifDescr);
+               ifRemote = remoteNode->findInterfaceByName(ifDescr);
          }
 
                        LL_NEIGHBOR_INFO info;
index 689a0b5..dedeb16 100644 (file)
@@ -1083,36 +1083,36 @@ static bool IsCommand(const TCHAR *cmdTemplate, TCHAR *pszString, int iMinChars)
 }
 
 /**
- * Dump index
+ * Dump index callback (by IP address)
  */
-struct __dump_index_data
+static void DumpIndexCallbackByInetAddr(NetObj *object, void *data)
 {
-       CONSOLE_CTX console;
-       bool indexByIP;
-};
+       TCHAR buffer[64];
+       ConsolePrintf((CONSOLE_CTX)data, _T("%-40s %p %s [%d]\n"), object->getIpAddress().toString(buffer), object, object->getName(), (int)object->getId());
+}
 
-static void DumpIndexCallback(NetObj *object, void *data)
+/**
+ * Dump index (by IP address)
+ */
+static void DumpIndex(CONSOLE_CTX pCtx, InetAddressIndex *index)
 {
-       struct __dump_index_data *d = (struct __dump_index_data *)data;
-       if (d->indexByIP)
-       {
-               TCHAR buffer[16];
-               ConsolePrintf(d->console, _T("%08X [%-15s] %p %s\n"), object->IpAddr(),
-                               IpToStr(object->IpAddr(), buffer),
-                               object, object->getName());
-       }
-       else
-       {
-               ConsolePrintf(d->console, _T("%08X %p %s\n"), object->getId(), object, object->getName());
-       }
+       index->forEach(DumpIndexCallbackByInetAddr, pCtx);
 }
 
-static void DumpIndex(CONSOLE_CTX pCtx, ObjectIndex *index, bool indexByIp)
+/**
+ * Dump index callback (by ID)
+ */
+static void DumpIndexCallbackById(NetObj *object, void *data)
+{
+       ConsolePrintf((CONSOLE_CTX)data, _T("%08X %p %s\n"), object->getId(), object, object->getName());
+}
+
+/**
+ * Dump index (by ID)
+ */
+static void DumpIndex(CONSOLE_CTX pCtx, ObjectIndex *index)
 {
-       struct __dump_index_data data;
-       data.console = pCtx;
-       data.indexByIP = indexByIp;
-       index->forEach(DumpIndexCallback, &data);
+       index->forEach(DumpIndexCallbackById, pCtx);
 }
 
 /**
@@ -1462,31 +1462,31 @@ int ProcessConsoleCommand(const TCHAR *pszCmdLine, CONSOLE_CTX pCtx)
 
                        if (IsCommand(_T("CONDITION"), szBuffer, 1))
                        {
-                               DumpIndex(pCtx, &g_idxConditionById, false);
+                               DumpIndex(pCtx, &g_idxConditionById);
                        }
                        else if (IsCommand(_T("ID"), szBuffer, 2))
                        {
-                               DumpIndex(pCtx, &g_idxObjectById, false);
+                               DumpIndex(pCtx, &g_idxObjectById);
                        }
                        else if (IsCommand(_T("INTERFACE"), szBuffer, 2))
                        {
-                               DumpIndex(pCtx, &g_idxInterfaceByAddr, true);
+                               DumpIndex(pCtx, &g_idxInterfaceByAddr);
                        }
                        else if (IsCommand(_T("NODEADDR"), szBuffer, 5))
                        {
-                               DumpIndex(pCtx, &g_idxNodeByAddr, true);
+                               DumpIndex(pCtx, &g_idxNodeByAddr);
                        }
                        else if (IsCommand(_T("NODEID"), szBuffer, 5))
                        {
-                               DumpIndex(pCtx, &g_idxNodeById, false);
+                               DumpIndex(pCtx, &g_idxNodeById);
                        }
                        else if (IsCommand(_T("SUBNET"), szBuffer, 1))
                        {
-                               DumpIndex(pCtx, &g_idxSubnetByAddr, true);
+                               DumpIndex(pCtx, &g_idxSubnetByAddr);
                        }
                        else if (IsCommand(_T("ZONE"), szBuffer, 1))
                        {
-                               DumpIndex(pCtx, &g_idxZoneByGUID, true);
+                               DumpIndex(pCtx, &g_idxZoneByGUID);
                        }
                        else
                        {
@@ -1851,14 +1851,14 @@ int ProcessConsoleCommand(const TCHAR *pszCmdLine, CONSOLE_CTX pCtx)
                                                        ConsolePrintf(pCtx, _T("Trace from %s to %s (%d hops, %s, source IP %s):\n"),
                                                                        pObject1->getName(), pObject2->getName(), pTrace->getHopCount(),
                                                                        pTrace->isComplete() ? _T("complete") : _T("incomplete"),
-                           IpToStr(pTrace->getSourceAddress(), sourceIp));
+                           pTrace->getSourceAddress().toString(sourceIp));
                                                        for(i = 0; i < pTrace->getHopCount(); i++)
                                                        {
                                                                HOP_INFO *hop = pTrace->getHopInfo(i);
                                                                ConsolePrintf(pCtx, _T("[%d] %s %s %s %d\n"),
                                                                                hop->object->getId(),
                                                                                hop->object->getName(),
-                                                                               IpToStr(hop->nextHop, szNextHop),
+                                                                               hop->nextHop.toString(szNextHop),
                                                                                hop->isVpn ? _T("VPN Connector ID:") : _T("Interface Index: "),
                                                                                hop->ifIndex);
                                                        }
index 17f0afe..380302a 100644 (file)
@@ -257,11 +257,11 @@ void MobileDevice::updateStatus(NXCPMessage *msg)
    }
 
        if (msg->isFieldExist(VID_IP_ADDRESS))
-               m_dwIpAddr = msg->getFieldAsUInt32(VID_IP_ADDRESS);
+               m_ipAddress = msg->getFieldAsInetAddress(VID_IP_ADDRESS);
 
-       TCHAR temp[32];
+       TCHAR temp[64];
        DbgPrintf(5, _T("Mobile device %s [%d] updated from agent (battery=%d addr=%s loc=[%s %s])"),
-                 m_name, (int)m_id, m_batteryLevel, IpToStr(m_dwIpAddr, temp),
+                 m_name, (int)m_id, m_batteryLevel, m_ipAddress.toString(temp),
                                 m_geoLocation.getLatitudeAsString(), m_geoLocation.getLongitudeAsString());
 
        setModified();
index aa8a1f1..8d44f5f 100644 (file)
@@ -166,7 +166,7 @@ static ARP_CACHE *SysGetLocalArpCache()
           (sysArpCache->table[i].dwType == 4))  // Only static and dynamic entries
       {
          pArpCache->pEntries[pArpCache->dwNumEntries].dwIndex = sysArpCache->table[i].dwIndex;
-         pArpCache->pEntries[pArpCache->dwNumEntries].dwIpAddr = ntohl(sysArpCache->table[i].dwAddr);
+         pArpCache->pEntries[pArpCache->dwNumEntries].ipAddr = ntohl(sysArpCache->table[i].dwAddr);
          memcpy(pArpCache->pEntries[pArpCache->dwNumEntries].bMacAddr, sysArpCache->table[i].bPhysAddr, 6);
          pArpCache->dwNumEntries++;
       }
index ac8ffac..d5b907f 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2014 Victor Kirhenshtein
+** Copyright (C) 2003-2015 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -42,7 +42,6 @@ NetObj::NetObj()
    m_isDeleted = false;
    m_isHidden = false;
        m_isSystem = false;
-   m_dwIpAddr = 0;
    m_dwChildCount = 0;
    m_pChildList = NULL;
    m_dwParentCount = 0;
@@ -920,7 +919,7 @@ void NetObj::fillMessage(NXCPMessage *pMsg)
        pMsg->setField(VID_GUID, m_guid, UUID_LENGTH);
    pMsg->setField(VID_OBJECT_NAME, m_name);
    pMsg->setField(VID_OBJECT_STATUS, (WORD)m_iStatus);
-   pMsg->setField(VID_IP_ADDRESS, m_dwIpAddr);
+   pMsg->setField(VID_IP_ADDRESS, m_ipAddress);
    pMsg->setField(VID_IS_DELETED, (WORD)(m_isDeleted ? 1 : 0));
    pMsg->setField(VID_IS_SYSTEM, (WORD)(m_isSystem ? 1 : 0));
 
index 5d008ee..2a5655d 100644 (file)
@@ -100,11 +100,11 @@ BOOL NetworkService::saveToDatabase(DB_HANDLE hdb)
    }
        if (hStmt != NULL)
        {
-          TCHAR szIpAddr[32];
+          TCHAR szIpAddr[64];
 
                DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_hostNode->getId());
                DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, (LONG)m_serviceType);
-               DBBind(hStmt, 3, DB_SQLTYPE_VARCHAR, IpToStr(m_dwIpAddr, szIpAddr), DB_BIND_STATIC);
+               DBBind(hStmt, 3, DB_SQLTYPE_VARCHAR, m_ipAddress.toString(szIpAddr), DB_BIND_STATIC);
                DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, (UINT32)m_proto);
                DBBind(hStmt, 5, DB_SQLTYPE_INTEGER, (UINT32)m_port);
                DBBind(hStmt, 6, DB_SQLTYPE_TEXT, m_request, DB_BIND_STATIC);
@@ -154,7 +154,7 @@ BOOL NetworkService::loadFromDatabase(UINT32 dwId)
    {
       dwHostNodeId = DBGetFieldULong(hResult, 0, 0);
       m_serviceType = DBGetFieldLong(hResult, 0, 1);
-      m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 2);
+      m_ipAddress = DBGetFieldInetAddr(hResult, 0, 2);
       m_proto = (WORD)DBGetFieldULong(hResult, 0, 3);
       m_port = (WORD)DBGetFieldULong(hResult, 0, 4);
       m_request = DBGetField(hResult, 0, 5, NULL, 0);
@@ -286,7 +286,7 @@ UINT32 NetworkService::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLoc
 
    // Listen IP address
    if (pRequest->isFieldExist(VID_IP_ADDRESS))
-      m_dwIpAddr = pRequest->getFieldAsUInt32(VID_IP_ADDRESS);
+      m_ipAddress = pRequest->getFieldAsInetAddress(VID_IP_ADDRESS);
 
    // Service type
    if (pRequest->isFieldExist(VID_SERVICE_TYPE))
@@ -354,13 +354,13 @@ void NetworkService::statusPoll(ClientSession *session, UINT32 rqId, Node *polle
 
    if (pNode != NULL)
    {
-      TCHAR szBuffer[16];
+      TCHAR szBuffer[64];
       UINT32 dwStatus;
 
       sendPollerMsg(rqId, _T("      Polling service from node %s [%s]\r\n"),
-                    pNode->getName(), IpToStr(pNode->IpAddr(), szBuffer));
+                    pNode->getName(), pNode->getIpAddress().toString(szBuffer));
       if (pNode->checkNetworkService(&dwStatus, 
-                                     (m_dwIpAddr == 0) ? m_hostNode->IpAddr() : m_dwIpAddr,
+                                     m_ipAddress.isValid() ? m_ipAddress : m_hostNode->getIpAddress(),
                                      m_serviceType, m_port, m_proto, 
                                      m_request, m_response, &m_responseTime) == ERR_SUCCESS)
       {
index 3869efd..f604777 100644 (file)
@@ -112,11 +112,11 @@ Node::Node() : DataCollectionTarget()
 /**
  * Constructor for new node object
  */
-Node::Node(UINT32 dwAddr, UINT32 dwFlags, UINT32 agentProxy, UINT32 snmpProxy, UINT32 dwZone) : DataCollectionTarget()
+Node::Node(const InetAddress& addr, UINT32 dwFlags, UINT32 agentProxy, UINT32 snmpProxy, UINT32 dwZone) : DataCollectionTarget()
 {
-       IpToStr(dwAddr, m_primaryName);
+   addr.toString(m_primaryName);
    m_iStatus = STATUS_UNKNOWN;
-   m_dwIpAddr = dwAddr;
+   m_ipAddress = addr;
    m_dwFlags = dwFlags;
    m_dwDynamicFlags = 0;
    m_zoneId = dwZone;
@@ -129,7 +129,7 @@ Node::Node(UINT32 dwAddr, UINT32 dwFlags, UINT32 agentProxy, UINT32 snmpProxy, U
        char community[MAX_COMMUNITY_LENGTH];
    ConfigReadStrA(_T("DefaultCommunityString"), community, MAX_COMMUNITY_LENGTH, "public");
        m_snmpSecurity = new SNMP_SecurityContext(community);
-   IpToStr(dwAddr, m_name);    // Make default name from IP address
+   addr.toString(m_name);    // Make default name from IP address
    m_szObjectId[0] = 0;
    m_lastDiscoveryPoll = 0;
    m_lastStatusPoll = 0;
@@ -272,7 +272,7 @@ BOOL Node::loadFromDatabase(UINT32 dwId)
    }
 
    DBGetField(hResult, 0, 0, m_primaryName, MAX_DNS_NAME);
-   m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 1);
+   m_ipAddress = DBGetFieldInetAddr(hResult, 0, 1);
    m_dwFlags = DBGetFieldULong(hResult, 0, 2);
    m_snmpVersion = DBGetFieldLong(hResult, 0, 3);
    m_agentAuthMethod = (WORD)DBGetFieldLong(hResult, 0, 4);
@@ -428,9 +428,9 @@ BOOL Node::saveToDatabase(DB_HANDLE hdb)
                return FALSE;
        }
 
-   TCHAR ipAddr[16], baseAddress[16];
+   TCHAR ipAddr[64], baseAddress[16];
 
-       DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, IpToStr(m_dwIpAddr, ipAddr), DB_BIND_STATIC);
+       DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, m_ipAddress.toString(ipAddr), DB_BIND_STATIC);
        DBBind(hStmt, 2, DB_SQLTYPE_VARCHAR, m_primaryName, DB_BIND_STATIC);
        DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, (LONG)m_wSNMPPort);
        DBBind(hStmt, 4, DB_SQLTYPE_INTEGER, m_dwFlags);
@@ -666,7 +666,7 @@ void Node::addVrrpInterfaces(InterfaceList *ifList)
  * @param hostAddr IP address to match or INADDR_ANY to select first matching interface
  * @return pointer to interface object or NULL if appropriate interface couldn't be found
  */
-Interface *Node::findInterface(UINT32 ifIndex, UINT32 hostAddr)
+Interface *Node::findInterfaceByIndex(UINT32 ifIndex)
 {
    UINT32 i;
    Interface *pInterface;
@@ -676,15 +676,10 @@ Interface *Node::findInterface(UINT32 ifIndex, UINT32 hostAddr)
       if (m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE)
       {
          pInterface = (Interface *)m_pChildList[i];
-                       if ((pInterface->getIfIndex() == ifIndex) || (ifIndex == INVALID_INDEX))
+                       if (pInterface->getIfIndex() == ifIndex)
          {
-            if (((pInterface->IpAddr() & pInterface->getIpNetMask()) ==
-                 (hostAddr & pInterface->getIpNetMask())) ||
-                (hostAddr == INADDR_ANY))
-            {
-               UnlockChildList();
-               return pInterface;
-            }
+            UnlockChildList();
+            return pInterface;
          }
       }
    UnlockChildList();
@@ -695,7 +690,7 @@ Interface *Node::findInterface(UINT32 ifIndex, UINT32 hostAddr)
  * Find interface by name or description
  * Returns pointer to interface object or NULL if appropriate interface couldn't be found
  */
-Interface *Node::findInterface(const TCHAR *name)
+Interface *Node::findInterfaceByName(const TCHAR *name)
 {
    UINT32 i;
    Interface *pInterface;
@@ -764,12 +759,12 @@ Interface *Node::findInterfaceByMAC(const BYTE *macAddr)
  * Find interface by IP address
  * Returns pointer to interface object or NULL if appropriate interface couldn't be found
  */
-Interface *Node::findInterfaceByIP(UINT32 ipAddr)
+Interface *Node::findInterfaceByIP(const InetAddress& addr)
 {
    UINT32 i;
    Interface *pInterface;
 
-       if (ipAddr == 0)
+   if (!addr.isValid())
                return NULL;
 
    LockChildList(FALSE);
@@ -777,7 +772,7 @@ Interface *Node::findInterfaceByIP(UINT32 ipAddr)
       if (m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE)
       {
          pInterface = (Interface *)m_pChildList[i];
-                       if (pInterface->IpAddr() == ipAddr)
+                       if (pInterface->getIpAddress().equals(addr))
          {
             UnlockChildList();
             return pInterface;
@@ -897,7 +892,7 @@ AccessPoint *Node::findAccessPointByBSSID(const BYTE *bssid)
 /**
  * Check if given IP address is one of node's interfaces
  */
-BOOL Node::isMyIP(UINT32 ipAddr)
+bool Node::isMyIP(const InetAddress& addr)
 {
    UINT32 i;
 
@@ -905,14 +900,14 @@ BOOL Node::isMyIP(UINT32 ipAddr)
    for(i = 0; i < m_dwChildCount; i++)
       if (m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE)
       {
-         if (((Interface *)m_pChildList[i])->IpAddr() == ipAddr)
+         if (((Interface *)m_pChildList[i])->getIpAddress().equals(addr))
          {
             UnlockChildList();
-            return TRUE;
+            return true;
          }
       }
    UnlockChildList();
-   return FALSE;
+   return false;
 }
 
 /**
@@ -979,7 +974,7 @@ Interface *Node::createNewInterface(NX_INTERFACE_INFO *info, bool manuallyCreate
                                // Ignore mask 255.255.255.254 - it's invalid
                                if ((info->ipAddr < 0xE0000000) && (info->ipNetMask != 0xFFFFFFFF) && (info->ipNetMask != 0xFFFFFFFE))
                                {
-                                       pSubnet = createSubnet(info->ipAddr, info->ipNetMask, bSyntheticMask);
+                                       pSubnet = createSubnet(InetAddress(info->ipAddr, info->ipNetMask), bSyntheticMask);
                                }
                        }
                        else
@@ -987,7 +982,7 @@ Interface *Node::createNewInterface(NX_INTERFACE_INFO *info, bool manuallyCreate
                                // Set correct netmask if we was asked for it
                                if (info->ipNetMask == 0)
                                {
-                                       info->ipNetMask = pSubnet->getIpNetMask();
+                                       info->ipNetMask = 0xFFFFFFFF << (32 - pSubnet->getIpAddress().getMaskBits());
                                        bSyntheticMask = pSubnet->isSyntheticMask();
                                }
                        }
@@ -997,9 +992,9 @@ Interface *Node::createNewInterface(NX_INTERFACE_INFO *info, bool manuallyCreate
    // Create interface object
    if (info->name[0] != 0)
                pInterface = new Interface(info->name, (info->description[0] != 0) ? info->description : info->name,
-                                 info->index, info->ipAddr, info->ipNetMask, info->type, m_zoneId);
+                                 info->index, InetAddress(info->ipAddr, info->ipNetMask), info->type, m_zoneId);
    else
-      pInterface = new Interface(info->ipAddr, info->ipNetMask, m_zoneId, bSyntheticMask);
+      pInterface = new Interface(InetAddress(info->ipAddr, info->ipNetMask), m_zoneId, bSyntheticMask);
    pInterface->setMacAddr(info->macAddr);
        pInterface->setBridgePortNumber(info->bridgePort);
        pInterface->setSlotNumber(info->slot);
@@ -1014,9 +1009,9 @@ Interface *Node::createNewInterface(NX_INTERFACE_INFO *info, bool manuallyCreate
    if (!m_isHidden)
       pInterface->unhide();
    if (!pInterface->isSystem())
-      PostEvent(EVENT_INTERFACE_ADDED, m_id, "dsaad", pInterface->getId(),
-                pInterface->getName(), pInterface->IpAddr(),
-                pInterface->getIpNetMask(), pInterface->getIfIndex());
+      PostEvent(EVENT_INTERFACE_ADDED, m_id, "dsAdd", pInterface->getId(),
+                pInterface->getName(), &pInterface->getIpAddress(),
+                pInterface->getIpAddress().getMaskBits(), pInterface->getIfIndex());
 
    // Bind node to appropriate subnet
    if (pSubnet != NULL)
@@ -1024,11 +1019,11 @@ Interface *Node::createNewInterface(NX_INTERFACE_INFO *info, bool manuallyCreate
       pSubnet->addNode(this);
 
       // Check if subnet mask is correct on interface
-      if ((pSubnet->getIpNetMask() != pInterface->getIpNetMask()) && !pSubnet->isSyntheticMask() && (info->ipNetMask != 0xFFFFFFFF))
+      if ((pSubnet->getIpAddress().getMaskBits() != pInterface->getIpAddress().getMaskBits()) && !pSubnet->isSyntheticMask() && (info->ipNetMask != 0xFFFFFFFF))
                {
-         PostEvent(EVENT_INCORRECT_NETMASK, m_id, "idsaa", pInterface->getId(),
+         PostEvent(EVENT_INCORRECT_NETMASK, m_id, "idsdd", pInterface->getId(),
                    pInterface->getIfIndex(), pInterface->getName(),
-                   pInterface->getIpNetMask(), pSubnet->getIpNetMask());
+                   pInterface->getIpAddress().getMaskBits(), pSubnet->getIpAddress().getMaskBits());
                }
    }
 
@@ -1045,7 +1040,7 @@ void Node::deleteInterface(Interface *pInterface)
        DbgPrintf(5, _T("Node::deleteInterface(node=%s [%d], interface=%s [%d])"), m_name, m_id, pInterface->getName(), pInterface->getId());
 
    // Check if we should unlink node from interface's subnet
-   if ((pInterface->IpAddr() != 0) && !pInterface->isExcludedFromTopology())
+   if (pInterface->getIpAddress().isValidUnicast() && !pInterface->isExcludedFromTopology())
    {
       BOOL bUnlink = TRUE;
 
@@ -1053,8 +1048,7 @@ void Node::deleteInterface(Interface *pInterface)
       for(i = 0; i < m_dwChildCount; i++)
          if (m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE)
             if (m_pChildList[i] != pInterface)
-               if ((((Interface *)m_pChildList[i])->IpAddr() & ((Interface *)m_pChildList[i])->getIpNetMask()) ==
-                   (pInterface->IpAddr() & pInterface->getIpNetMask()))
+               if (((Interface *)m_pChildList[i])->getIpAddress().getSubnetAddress().equals(pInterface->getIpAddress().getSubnetAddress()))
                {
                   bUnlink = FALSE;
                   break;
@@ -1064,7 +1058,7 @@ void Node::deleteInterface(Interface *pInterface)
       if (bUnlink)
       {
          // Last interface in subnet, should unlink node
-         Subnet *pSubnet = FindSubnetByIP(m_zoneId, pInterface->IpAddr() & pInterface->getIpNetMask());
+         Subnet *pSubnet = FindSubnetByIP(m_zoneId, pInterface->getIpAddress().getSubnetAddress());
          if (pSubnet != NULL)
          {
             DeleteParent(pSubnet);
@@ -1131,7 +1125,7 @@ restart_agent_check:
    }
 
    // Check SNMP agent connectivity
-   if ((m_dwFlags & NF_IS_SNMP) && (!(m_dwFlags & NF_DISABLE_SNMP)) && (m_dwIpAddr != 0))
+   if ((m_dwFlags & NF_IS_SNMP) && (!(m_dwFlags & NF_DISABLE_SNMP)) && m_ipAddress.isValidUnicast())
    {
       TCHAR szBuffer[256];
       UINT32 dwResult;
@@ -1196,7 +1190,7 @@ restart_agent_check:
    }
 
    // Check native agent connectivity
-   if ((m_dwFlags & NF_IS_NATIVE_AGENT) && (!(m_dwFlags & NF_DISABLE_NXCP)) && (m_dwIpAddr != 0))
+   if ((m_dwFlags & NF_IS_NATIVE_AGENT) && (!(m_dwFlags & NF_DISABLE_NXCP)) && m_ipAddress.isValidUnicast())
    {
       DbgPrintf(6, _T("StatusPoll(%s): checking agent"), m_name);
       SetPollerInfo(nPoller, _T("check agent"));
@@ -1297,7 +1291,7 @@ restart_agent_check:
          case OBJECT_INTERFACE:
                           DbgPrintf(7, _T("StatusPoll(%s): polling interface %d [%s]"), m_name, ppPollList[i]->getId(), ppPollList[i]->getName());
             ((Interface *)ppPollList[i])->statusPoll(pSession, dwRqId, pQueue,
-                                       (pCluster != NULL) ? pCluster->isSyncAddr(((Interface *)ppPollList[i])->IpAddr()) : FALSE,
+                                       (pCluster != NULL) ? pCluster->isSyncAddr(((Interface *)ppPollList[i])->getIpAddress()) : FALSE,
                                        pTransport, m_icmpProxy);
             break;
          case OBJECT_NETWORKSERVICE:
@@ -1321,7 +1315,7 @@ restart_agent_check:
 
    // Check if entire node is down
        // This check is disabled for nodes without IP address
-       if (m_dwIpAddr != 0)
+       if (m_ipAddress.isValidUnicast())
        {
                LockChildList(FALSE);
                if (m_dwChildCount > 0)
@@ -1585,7 +1579,7 @@ bool Node::checkNetworkPath(UINT32 dwRqId)
 
        // Check directly connected switch
    sendPollerMsg(dwRqId, _T("Checking ethernet connectivity...\r\n"));
-       Interface *iface = findInterface(INVALID_INDEX, m_dwIpAddr);
+       Interface *iface = findInterfaceByIP(m_ipAddress);
        if ((iface != NULL) && (iface->getPeerNodeId() != 0))
        {
                DbgPrintf(6, _T("Node::checkNetworkPath(%s [%d]): found interface object for primary IP: %s [%d]"), m_name, m_id, iface->getName(), iface->getId());
@@ -1727,19 +1721,19 @@ void Node::updatePrimaryIpAddr()
        if (m_primaryName[0] == 0)
                return;
 
-       UINT32 ipAddr = ntohl(ResolveHostName(m_primaryName));
-       if ((ipAddr != m_dwIpAddr) && ((ipAddr != INADDR_ANY) || _tcscmp(m_primaryName, _T("0.0.0.0"))) && (ipAddr != INADDR_NONE))
+   InetAddress ipAddr = InetAddress::resolveHostName(m_primaryName);
+   if (!ipAddr.equals(m_ipAddress) && (ipAddr.isValidUnicast() || !_tcscmp(m_primaryName, _T("0.0.0.0"))))
        {
-               TCHAR buffer1[32], buffer2[32];
+               TCHAR buffer1[64], buffer2[64];
 
                DbgPrintf(4, _T("IP address for node %s [%d] changed from %s to %s"),
-                       m_name, (int)m_id, IpToStr(m_dwIpAddr, buffer1), IpToStr(ipAddr, buffer2));
-               PostEvent(EVENT_IP_ADDRESS_CHANGED, m_id, "aa", ipAddr, m_dwIpAddr);
+         m_name, (int)m_id, m_ipAddress.toString(buffer1), ipAddr.toString(buffer2));
+               PostEvent(EVENT_IP_ADDRESS_CHANGED, m_id, "AA", &ipAddr, &m_ipAddress);
 
       if (m_dwFlags & NF_REMOTE_AGENT)
       {
          lockProperties();
-         m_dwIpAddr = ipAddr;
+         m_ipAddress = ipAddr;
          setModified();
          unlockProperties();
       }
@@ -1817,10 +1811,10 @@ void Node::configurationPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller
       if (ConfigReadInt(_T("EnableCheckPointSNMP"), 0))
       {
          DbgPrintf(5, _T("ConfPoll(%s): checking for CheckPoint SNMP on port 260"), m_name);
-         if (!((m_dwFlags & NF_IS_CPSNMP) && (m_dwDynamicFlags & NDF_CPSNMP_UNREACHABLE)) && (m_dwIpAddr != 0))
+         if (!((m_dwFlags & NF_IS_CPSNMP) && (m_dwDynamicFlags & NDF_CPSNMP_UNREACHABLE)) && m_ipAddress.isValidUnicast())
          {
                           SNMP_Transport *pTransport = new SNMP_UDPTransport;
-                          ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), CHECKPOINT_SNMP_PORT);
+                          ((SNMP_UDPTransport *)pTransport)->createUDPTransport(m_ipAddress, CHECKPOINT_SNMP_PORT);
             if (SnmpGet(SNMP_VERSION_1, pTransport,
                         _T(".1.3.6.1.4.1.2620.1.1.10.0"), NULL, 0, szBuffer, sizeof(szBuffer), 0) == SNMP_ERR_SUCCESS)
             {
@@ -1960,13 +1954,13 @@ bool Node::confPollAgent(UINT32 dwRqId)
 {
    DbgPrintf(5, _T("ConfPoll(%s): checking for NetXMS agent Flags={%08X} DynamicFlags={%08X}"), m_name, m_dwFlags, m_dwDynamicFlags);
        if (((m_dwFlags & NF_IS_NATIVE_AGENT) && (m_dwDynamicFlags & NDF_AGENT_UNREACHABLE)) ||
-           (m_dwIpAddr == 0) || (m_dwFlags & NF_DISABLE_NXCP))
+           !m_ipAddress.isValidUnicast() || (m_dwFlags & NF_DISABLE_NXCP))
                return false;
 
        bool hasChanges = false;
 
        sendPollerMsg(dwRqId, _T("   Checking NetXMS agent...\r\n"));
-   AgentConnection *pAgentConn = new AgentConnectionEx(m_id, m_dwIpAddr, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
+   AgentConnection *pAgentConn = new AgentConnectionEx(m_id, m_ipAddress, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
    setAgentProxy(pAgentConn);
    DbgPrintf(5, _T("ConfPoll(%s): checking for NetXMS agent - connecting"), m_name);
 
@@ -2155,7 +2149,7 @@ static UINT32 CountingSnmpWalkerCallback(UINT32 version, SNMP_Variable *var, SNM
 bool Node::confPollSnmp(UINT32 dwRqId)
 {
        if (((m_dwFlags & NF_IS_SNMP) && (m_dwDynamicFlags & NDF_SNMP_UNREACHABLE)) ||
-           (m_dwIpAddr == 0) || (m_dwFlags & NF_DISABLE_SNMP))
+           !m_ipAddress.isValidUnicast() || (m_dwFlags & NF_DISABLE_SNMP))
                return false;
 
        bool hasChanges = false;
@@ -2611,7 +2605,7 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
                                        for(j = 0; j < pIfList->size(); j++)
                                        {
                                                if ((pIfList->get(j)->index == pInterface->getIfIndex()) &&
-                                                        (pIfList->get(j)->ipAddr == pInterface->IpAddr()))
+                                                        pInterface->getIpAddress().equals(pIfList->get(j)->ipAddr))
                                                        break;
                                        }
 
@@ -2631,8 +2625,8 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
          for(j = 0; j < iDelCount; j++)
          {
             sendPollerMsg(dwRqId, POLLER_WARNING _T("   Interface \"%s\" is no longer exist\r\n"), ppDeleteList[j]->getName());
-            PostEvent(EVENT_INTERFACE_DELETED, m_id, "dsaa", ppDeleteList[j]->getIfIndex(),
-                      ppDeleteList[j]->getName(), ppDeleteList[j]->IpAddr(), ppDeleteList[j]->getIpNetMask());
+            PostEvent(EVENT_INTERFACE_DELETED, m_id, "dsAd", ppDeleteList[j]->getIfIndex(),
+                      ppDeleteList[j]->getName(), &ppDeleteList[j]->getIpAddress(), ppDeleteList[j]->getIpAddress().getMaskBits());
             deleteInterface(ppDeleteList[j]);
          }
          hasChanges = TRUE;
@@ -2653,7 +2647,7 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
                Interface *pInterface = (Interface *)m_pChildList[i];
 
                if ((ifInfo->index == pInterface->getIfIndex()) &&
-                   (ifInfo->ipAddr == pInterface->IpAddr()))
+                   pInterface->getIpAddress().equals(ifInfo->ipAddr))
                {
                   // Existing interface, check configuration
                   if (memcmp(ifInfo->macAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) && memcmp(ifInfo->macAddr, pInterface->getMacAddr(), MAC_ADDR_LENGTH))
@@ -2695,9 +2689,9 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
                                                {
                                                        pInterface->setPhysicalPortFlag(ifInfo->isPhysicalPort);
                                                }
-                                               if ((ifInfo->ipNetMask != 0) && (ifInfo->ipNetMask != pInterface->getIpNetMask()))
+                                               if ((ifInfo->ipNetMask != 0) && (ifInfo->ipNetMask != pInterface->getIpAddress().getMaskBits()))
                                                {
-                                                       pInterface->setIpNetMask(ifInfo->ipNetMask);
+                                                       pInterface->setIpNetMask(BitsInMask(ifInfo->ipNetMask));
                                                }
                   bNewInterface = FALSE;
                   break;
@@ -2738,8 +2732,8 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
          {
             sendPollerMsg(dwRqId, POLLER_WARNING _T("   Interface \"%s\" is no longer exist\r\n"),
                           ppDeleteList[j]->getName());
-            PostEvent(EVENT_INTERFACE_DELETED, m_id, "dsaa", ppDeleteList[j]->getIfIndex(),
-                      ppDeleteList[j]->getName(), ppDeleteList[j]->IpAddr(), ppDeleteList[j]->getIpNetMask());
+            PostEvent(EVENT_INTERFACE_DELETED, m_id, "dsAd", ppDeleteList[j]->getIfIndex(),
+                      ppDeleteList[j]->getName(), &ppDeleteList[j]->getIpAddress(), ppDeleteList[j]->getIpAddress().getMaskBits());
             deleteInterface(ppDeleteList[j]);
          }
          safe_free(ppDeleteList);
@@ -2754,29 +2748,29 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
          if (pInterface->isFake())
          {
             // Check if primary IP is different from interface's IP
-            if (pInterface->IpAddr() != m_dwIpAddr)
+            if (!pInterface->getIpAddress().equals(m_ipAddress))
             {
                deleteInterface(pInterface);
-                                       if (m_dwIpAddr != 0)
+                                       if (m_ipAddress.isValidUnicast())
                                        {
                                                memset(macAddr, 0, MAC_ADDR_LENGTH);
-                                               Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_dwIpAddr);
+                                               Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_ipAddress);
                                                if (pSubnet != NULL)
-                                                       pSubnet->findMacAddress(m_dwIpAddr, macAddr);
+                                                       pSubnet->findMacAddress(m_ipAddress, macAddr);
                                                pMacAddr = !memcmp(macAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) ? NULL : macAddr;
                                                TCHAR szMac[20];
                                                MACToStr(macAddr, szMac);
                                                DbgPrintf(5, _T("Node::updateInterfaceConfiguration(%s [%u]): got MAC for unknown interface: %s"), m_name, m_id, szMac);
-                  createNewInterface(m_dwIpAddr, dwNetMask, pMacAddr);
+                  createNewInterface(m_ipAddress.getAddressV4(), dwNetMask, pMacAddr);
                                        }
             }
                                else
                                {
                                        // check MAC address
                                        memset(macAddr, 0, MAC_ADDR_LENGTH);
-                                       Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_dwIpAddr);
+                                       Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_ipAddress);
                                        if (pSubnet != NULL)
-                                               pSubnet->findMacAddress(m_dwIpAddr, macAddr);
+                                               pSubnet->findMacAddress(m_ipAddress, macAddr);
                                        if (memcmp(macAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) && memcmp(macAddr, pInterface->getMacAddr(), MAC_ADDR_LENGTH))
                                        {
                   TCHAR szOldMac[16], szNewMac[16];
@@ -2796,17 +2790,17 @@ BOOL Node::updateInterfaceConfiguration(UINT32 dwRqId, UINT32 dwNetMask)
       else if (dwCount == 0)
       {
          // No interfaces at all, create pseudo-interface
-                       if (m_dwIpAddr != 0)
+                       if (m_ipAddress.isValidUnicast())
                        {
                                memset(macAddr, 0, MAC_ADDR_LENGTH);
-                               Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_dwIpAddr);
+                               Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_ipAddress);
                                if (pSubnet != NULL)
-                                       pSubnet->findMacAddress(m_dwIpAddr, macAddr);
+                                       pSubnet->findMacAddress(m_ipAddress, macAddr);
                                pMacAddr = !memcmp(macAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) ? NULL : macAddr;
                                TCHAR szMac[20];
                                MACToStr(macAddr, szMac);
                                DbgPrintf(5, _T("Node::updateInterfaceConfiguration(%s [%u]): got MAC for unknown interface: %s"), m_name, m_id, szMac);
-               createNewInterface(m_dwIpAddr, dwNetMask, pMacAddr);
+               createNewInterface(m_ipAddress.getAddressV4(), dwNetMask, pMacAddr);
                        }
       }
                DbgPrintf(6, _T("Node::updateInterfaceConfiguration(%s [%u]): pflist == NULL, dwCount = %u"), m_name, m_id, dwCount);
@@ -2886,6 +2880,7 @@ void Node::updateContainerMembership()
                                pContainer->AddChild(this);
                                AddParent(pContainer);
                                PostEvent(EVENT_CONTAINER_AUTOBIND, g_dwMgmtNode, "isis", m_id, m_name, pContainer->getId(), pContainer->getName());
+            pContainer->calculateCompoundStatus();
                        }
                }
                else
@@ -2897,6 +2892,7 @@ void Node::updateContainerMembership()
                                pContainer->DeleteChild(this);
                                DeleteParent(pContainer);
                                PostEvent(EVENT_CONTAINER_AUTOUNBIND, g_dwMgmtNode, "isis", m_id, m_name, pContainer->getId(), pContainer->getName());
+            pContainer->calculateCompoundStatus();
                        }
                }
       pContainer->decRefCount();
@@ -3152,7 +3148,7 @@ bool Node::connectToSMCLP()
    // Create new connection object if needed
    if (m_smclpConnection == NULL)
        {
-      m_smclpConnection = new SMCLP_Connection(m_dwIpAddr, 23);
+      m_smclpConnection = new SMCLP_Connection(m_ipAddress.getAddressV4(), 23);
                DbgPrintf(7, _T("Node::connectToSMCLP(%s [%d]): new connection created"), m_name, m_id);
        }
        else
@@ -3167,7 +3163,7 @@ bool Node::connectToSMCLP()
                // Close current connection or clean up after broken connection
                m_smclpConnection->disconnect();
       delete m_smclpConnection;
-      m_smclpConnection = new SMCLP_Connection(m_dwIpAddr, 23);
+      m_smclpConnection = new SMCLP_Connection(m_ipAddress.getAddressV4(), 23);
                DbgPrintf(7, _T("Node::connectToSMCLP(%s [%d]): existing connection reset"), m_name, m_id);
        }
 
@@ -3189,7 +3185,7 @@ BOOL Node::connectToAgent(UINT32 *error, UINT32 *socketError)
    // Create new agent connection object if needed
    if (m_pAgentConnection == NULL)
        {
-      m_pAgentConnection = new AgentConnectionEx(m_id, m_dwIpAddr, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
+      m_pAgentConnection = new AgentConnectionEx(m_id, m_ipAddress, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
                DbgPrintf(7, _T("Node::connectToAgent(%s [%d]): new agent connection created"), m_name, m_id);
        }
        else
@@ -3499,7 +3495,7 @@ UINT32 Node::getItemFromCheckPointSNMP(const TCHAR *szParam, UINT32 dwBufSize, T
                SNMP_Transport *pTransport;
 
                pTransport = new SNMP_UDPTransport;
-               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), CHECKPOINT_SNMP_PORT);
+               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(m_ipAddress, CHECKPOINT_SNMP_PORT);
       dwResult = SnmpGet(SNMP_VERSION_1, pTransport, szParam, NULL, 0, szBuffer, dwBufSize * sizeof(TCHAR), SG_STRING_RESULT);
                delete pTransport;
    }
@@ -3760,15 +3756,16 @@ UINT32 Node::getInternalItem(const TCHAR *param, size_t bufSize, TCHAR *buffer)
                {
                        TCHAR arg[256] = _T("");
              AgentGetParameterArg(param, 1, arg, 256);
-                       UINT32 destAddr = ntohl(_t_inet_addr(arg));
-                       if ((destAddr > 0) && (destAddr < 0xE0000000))
+         InetAddress destAddr = InetAddress::parse(arg);
+                       if (destAddr.isValidUnicast())
                        {
                           bool isVpn;
-                       UINT32 nextHop, ifIndex;
+                       UINT32 ifIndex;
+            InetAddress nextHop;
             TCHAR name[MAX_OBJECT_NAME];
-                               if (getNextHop(m_dwIpAddr, destAddr, &nextHop, &ifIndex, &isVpn, name))
+                               if (getNextHop(m_ipAddress, destAddr, &nextHop, &ifIndex, &isVpn, name))
                                {
-                                       IpToStr(nextHop, buffer);
+               nextHop.toString(buffer);
                                }
                                else
                                {
@@ -4010,7 +4007,7 @@ UINT32 Node::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
       bool wasRemoteAgent = ((m_dwFlags & NF_REMOTE_AGENT) != 0);
       m_dwFlags &= NF_SYSTEM_FLAGS;
       m_dwFlags |= pRequest->getFieldAsUInt32(VID_FLAGS) & NF_USER_FLAGS;
-      if (wasRemoteAgent && !(m_dwFlags & NF_REMOTE_AGENT) && (m_dwIpAddr != 0))
+      if (wasRemoteAgent && !(m_dwFlags & NF_REMOTE_AGENT) && m_ipAddress.isValidUnicast())
       {
          if (IsZoningEnabled())
          {
@@ -4026,10 +4023,10 @@ UINT32 Node::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
          }
          else
          {
-                               g_idxNodeByAddr.put(m_dwIpAddr, this);
+                               g_idxNodeByAddr.put(m_ipAddress, this);
          }
       }
-      else if (!wasRemoteAgent && (m_dwFlags & NF_REMOTE_AGENT) && (m_dwIpAddr != 0))
+      else if (!wasRemoteAgent && (m_dwFlags & NF_REMOTE_AGENT) && m_ipAddress.isValidUnicast())
       {
          if (IsZoningEnabled())
          {
@@ -4045,7 +4042,7 @@ UINT32 Node::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
          }
          else
          {
-                               g_idxNodeByAddr.remove(m_dwIpAddr);
+                               g_idxNodeByAddr.remove(m_ipAddress);
          }
       }
    }
@@ -4053,15 +4050,14 @@ UINT32 Node::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
    // Change primary IP address
    if (pRequest->isFieldExist(VID_IP_ADDRESS))
    {
-      UINT32 i, ipAddr;
-
-      ipAddr = pRequest->getFieldAsUInt32(VID_IP_ADDRESS);
+      InetAddress ipAddr = pRequest->getFieldAsInetAddress(VID_IP_ADDRESS);
 
       // Check if received IP address is one of node's interface addresses
       LockChildList(FALSE);
+      UINT32 i;
       for(i = 0; i < m_dwChildCount; i++)
          if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) &&
-             (m_pChildList[i]->IpAddr() == ipAddr))
+             m_pChildList[i]->getIpAddress().equals(ipAddr))
             break;
       UnlockChildList();
       if (i == m_dwChildCount)
@@ -4075,7 +4071,7 @@ UINT32 Node::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
                // Update primary name if it is not set with the same message
                if (!pRequest->isFieldExist(VID_PRIMARY_NAME))
                {
-                       IpToStr(m_dwIpAddr, m_primaryName);
+                       m_ipAddress.toString(m_primaryName);
                }
 
                agentLock();
@@ -4193,7 +4189,7 @@ UINT32 Node::wakeUp()
    for(i = 0; i < m_dwChildCount; i++)
       if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) &&
           (m_pChildList[i]->Status() != STATUS_UNMANAGED) &&
-          (m_pChildList[i]->IpAddr() != 0))
+          m_pChildList[i]->getIpAddress().isValidUnicast())
       {
          if(memcmp(((Interface *)m_pChildList[i])->getMacAddr(), "\x00\x00\x00\x00\x00\x00", 6))
          {
@@ -4208,10 +4204,9 @@ UINT32 Node::wakeUp()
 
    //If no interface found try to find interface in unmanaged state
    for(i = 0; i < m_dwChildCount; i++)
-      if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) &&
-          (m_pChildList[i]->IpAddr() != 0))
+      if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) && m_pChildList[i]->getIpAddress().isValidUnicast())
       {
-         if(memcmp(((Interface *)m_pChildList[i])->getMacAddr(), "\x00\x00\x00\x00\x00\x00", 6))
+         if (memcmp(((Interface *)m_pChildList[i])->getMacAddr(), "\x00\x00\x00\x00\x00\x00", 6))
          {
             dwResult = ((Interface *)m_pChildList[i])->wakeUp();
             break;
@@ -4384,7 +4379,7 @@ void Node::openTableList(ObjectArray<AgentTableDefinition> **tableList)
 /**
  * Check status of network service
  */
-UINT32 Node::checkNetworkService(UINT32 *pdwStatus, UINT32 ipAddr, int iServiceType,
+UINT32 Node::checkNetworkService(UINT32 *pdwStatus, const InetAddress& ipAddr, int iServiceType,
                                 WORD wPort, WORD wProto, TCHAR *pszRequest,
                                 TCHAR *pszResponse, UINT32 *responseTime)
 {
@@ -4461,7 +4456,7 @@ AgentConnectionEx *Node::createAgentConnection()
       return NULL;
 
    DbgPrintf(6, _T("Node::createAgentConnection(%s [%d])"), m_name, (int)m_id);
-   conn = new AgentConnectionEx(m_id, m_dwIpAddr, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
+   conn = new AgentConnectionEx(m_id, m_ipAddress, m_agentPort, m_agentAuthMethod, m_szSharedSecret);
    setAgentProxy(conn);
    if (!conn->connect(g_pServerKey))
    {
@@ -4476,9 +4471,9 @@ AgentConnectionEx *Node::createAgentConnection()
  * Set node's primary IP address.
  * Assumed that all necessary locks already in place
  */
-void Node::setPrimaryIPAddress(UINT32 addr)
+void Node::setPrimaryIPAddress(const InetAddress& addr)
 {
-       if ((addr == m_dwIpAddr) || (m_dwFlags & NF_REMOTE_AGENT))
+   if (addr.equals(m_ipAddress) || (m_dwFlags & NF_REMOTE_AGENT))
                return;
 
        if (IsZoningEnabled())
@@ -4489,19 +4484,19 @@ void Node::setPrimaryIPAddress(UINT32 addr)
                        DbgPrintf(1, _T("Internal error: zone is NULL in Node::setPrimaryIPAddress (zone ID = %d)"), (int)m_zoneId);
                        return;
                }
-               if (m_dwIpAddr != 0)
+               if (m_ipAddress.isValid())
                        zone->removeFromIndex(this);
-               m_dwIpAddr = addr;
-               if (m_dwIpAddr != 0)
+               m_ipAddress = addr;
+               if (m_ipAddress.isValid())
                        zone->addToIndex(this);
        }
        else
        {
-               if (m_dwIpAddr != 0)
-                       g_idxNodeByAddr.remove(m_dwIpAddr);
-               m_dwIpAddr = addr;
-               if (m_dwIpAddr != 0)
-                       g_idxNodeByAddr.put(m_dwIpAddr, this);
+               if (m_ipAddress.isValid())
+                       g_idxNodeByAddr.remove(m_ipAddress);
+               m_ipAddress = addr;
+               if (m_ipAddress.isValid())
+                       g_idxNodeByAddr.put(m_ipAddress, this);
        }
 }
 
@@ -4510,7 +4505,7 @@ void Node::setPrimaryIPAddress(UINT32 addr)
  *
  * @param ipAddr new IP address
  */
-void Node::changeIPAddress(UINT32 ipAddr)
+void Node::changeIPAddress(const InetAddress& ipAddr)
 {
    UINT32 i;
 
@@ -4519,12 +4514,12 @@ void Node::changeIPAddress(UINT32 ipAddr)
    lockProperties();
 
        // check if primary name is an IP address
-       if (ntohl(ResolveHostName(m_primaryName)) == m_dwIpAddr)
+   if (InetAddress::resolveHostName(m_primaryName).equals(m_ipAddress))
        {
-               TCHAR ipAddrText[16];
-               IpToStr(m_dwIpAddr, ipAddrText);
+               TCHAR ipAddrText[64];
+               m_ipAddress.toString(ipAddrText);
                if (!_tcscmp(ipAddrText, m_primaryName))
-                       IpToStr(ipAddr, m_primaryName);
+                       ipAddr.toString(m_primaryName);
 
                setPrimaryIPAddress(ipAddr);
                m_dwDynamicFlags |= NDF_FORCE_CONFIGURATION_POLL | NDF_RECHECK_CAPABILITIES;
@@ -4660,7 +4655,7 @@ ROUTING_TABLE *Node::getRoutingTable()
 /**
  * Get outward interface for routing to given destination address
  */
-bool Node::getOutwardInterface(UINT32 destAddr, UINT32 *srcAddr, UINT32 *srcIfIndex)
+bool Node::getOutwardInterface(const InetAddress& destAddr, InetAddress *srcAddr, UINT32 *srcIfIndex)
 {
    bool found = false;
    routingTableLock();
@@ -4668,11 +4663,11 @@ bool Node::getOutwardInterface(UINT32 destAddr, UINT32 *srcAddr, UINT32 *srcIfIn
    {
       for(int i = 0; i < m_pRoutingTable->iNumEntries; i++)
                {
-         if ((destAddr & m_pRoutingTable->pRoutes[i].dwDestMask) == m_pRoutingTable->pRoutes[i].dwDestAddr)
+         if ((destAddr.getAddressV4() & m_pRoutingTable->pRoutes[i].dwDestMask) == m_pRoutingTable->pRoutes[i].dwDestAddr)
          {
             *srcIfIndex = m_pRoutingTable->pRoutes[i].dwIfIndex;
-            Interface *iface = findInterface(m_pRoutingTable->pRoutes[i].dwIfIndex, INADDR_ANY);
-            *srcAddr = ((iface != NULL) && (iface->IpAddr() != 0)) ? iface->IpAddr() : m_dwIpAddr;  // use primary IP if outward interface does not have Ip address or cannot be found
+            Interface *iface = findInterfaceByIndex(m_pRoutingTable->pRoutes[i].dwIfIndex);
+            *srcAddr = ((iface != NULL) && iface->getIpAddress().isValidUnicast()) ? iface->getIpAddress() : m_ipAddress;  // use primary IP if outward interface does not have Ip address or cannot be found
             found = true;
             break;
          }
@@ -4689,7 +4684,7 @@ bool Node::getOutwardInterface(UINT32 destAddr, UINT32 *srcAddr, UINT32 *srcIfIn
 /**
  * Get next hop for given destination address
  */
-bool Node::getNextHop(UINT32 srcAddr, UINT32 destAddr, UINT32 *nextHop, UINT32 *ifIndex, bool *isVpn, TCHAR *name)
+bool Node::getNextHop(const InetAddress& srcAddr, const InetAddress& destAddr, InetAddress *nextHop, UINT32 *ifIndex, bool *isVpn, TCHAR *name)
 {
    UINT32 i;
    bool nextHopFound = false;
@@ -4713,10 +4708,9 @@ bool Node::getNextHop(UINT32 srcAddr, UINT32 destAddr, UINT32 *nextHop, UINT32 *
                                break;
                        }
                }
-               else if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) && (m_pChildList[i]->IpAddr() != 0))
+               else if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) && m_pChildList[i]->getIpAddress().isValid())
                {
-                       UINT32 mask = ((Interface *)m_pChildList[i])->getIpNetMask();
-                       if ((destAddr & mask) == (m_pChildList[i]->IpAddr() & mask))
+                       if (m_pChildList[i]->getIpAddress().sameSubnet(destAddr))
                        {
                                *nextHop = destAddr;
                                *ifIndex = ((Interface *)m_pChildList[i])->getIfIndex();
@@ -4745,10 +4739,10 @@ bool Node::getNextHop(UINT32 srcAddr, UINT32 destAddr, UINT32 *nextHop, UINT32 *
       for(i = 0; i < (UINT32)m_pRoutingTable->iNumEntries; i++)
                {
          if ((!nextHopFound || (m_pRoutingTable->pRoutes[i].dwDestMask == 0xFFFFFFFF)) &&
-                           ((destAddr & m_pRoutingTable->pRoutes[i].dwDestMask) == m_pRoutingTable->pRoutes[i].dwDestAddr))
+             ((destAddr.getAddressV4() & m_pRoutingTable->pRoutes[i].dwDestMask) == m_pRoutingTable->pRoutes[i].dwDestAddr))
          {
-            Interface *iface = findInterface(m_pRoutingTable->pRoutes[i].dwIfIndex, INADDR_ANY);
-            if ((m_pRoutingTable->pRoutes[i].dwNextHop == 0) && (iface != NULL) && (iface->getIpNetMask() == 0xFFFFFFFF))
+            Interface *iface = findInterfaceByIndex(m_pRoutingTable->pRoutes[i].dwIfIndex);
+            if ((m_pRoutingTable->pRoutes[i].dwNextHop == 0) && (iface != NULL) && (iface->getIpAddress().getHostBits() == 0))
             {
                // On Linux XEN VMs can be pointed by individual host routes to virtual interfaces
                // where each vif has netmask 255.255.255.255 and next hop in routing table set to 0.0.0.0
@@ -4859,7 +4853,7 @@ void Node::setAgentProxy(AgentConnection *pConn)
                Node *node = (Node *)g_idxNodeById.get(proxyNode);
       if (node != NULL)
       {
-         pConn->setProxy(node->m_dwIpAddr, node->m_agentPort, node->m_agentAuthMethod, node->m_szSharedSecret);
+         pConn->setProxy(node->m_ipAddress, node->m_agentPort, node->m_agentAuthMethod, node->m_szSharedSecret);
       }
    }
 }
@@ -5011,7 +5005,7 @@ SNMP_Transport *Node::createSnmpTransport(WORD port, const TCHAR *context)
        if (snmpProxy == 0)
        {
                pTransport = new SNMP_UDPTransport;
-               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(m_dwIpAddr), (port != 0) ? port : m_wSNMPPort);
+               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(m_ipAddress, (port != 0) ? port : m_wSNMPPort);
        }
        else
        {
@@ -5023,7 +5017,7 @@ SNMP_Transport *Node::createSnmpTransport(WORD port, const TCHAR *context)
                        pConn = proxyNode->createAgentConnection();
                        if (pConn != NULL)
                        {
-                               pTransport = new SNMP_ProxyTransport(pConn, m_dwIpAddr, (port != 0) ? port : m_wSNMPPort);
+                               pTransport = new SNMP_ProxyTransport(pConn, m_ipAddress, (port != 0) ? port : m_wSNMPPort);
                        }
                }
        }
@@ -5083,23 +5077,15 @@ BOOL Node::resolveName(BOOL useOnlyDNS)
 {
        BOOL bSuccess = FALSE;
        BOOL bNameTruncated = FALSE;
-       HOSTENT *hs;
-       UINT32 i, dwAddr;
        TCHAR szBuffer[256];
 
        DbgPrintf(4, _T("Resolving name for node %d [%s]..."), m_id, m_name);
 
        // Try to resolve primary IP
-       dwAddr = htonl(m_dwIpAddr);
-       hs = gethostbyaddr((const char *)&dwAddr, 4, AF_INET);
-       if (hs != NULL)
+   TCHAR name[MAX_OBJECT_NAME];
+       if (m_ipAddress.getHostByAddr(name, MAX_OBJECT_NAME) != NULL)
        {
-#ifdef UNICODE
-               MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hs->h_name, -1, m_name, MAX_OBJECT_NAME);
-               m_name[MAX_OBJECT_NAME - 1] = 0;
-#else
-               nx_strncpy(m_name, hs->h_name, MAX_OBJECT_NAME);
-#endif
+               nx_strncpy(m_name, name, MAX_OBJECT_NAME);
                if (!(g_flags & AF_USE_FQDN_FOR_NODE_NAMES))
                {
                        TCHAR *pPoint = _tcschr(m_name, _T('.'));
@@ -5115,26 +5101,16 @@ BOOL Node::resolveName(BOOL useOnlyDNS)
        {
                // Try to resolve each interface's IP address
                LockChildList(FALSE);
-               for(i = 0; i < m_dwChildCount; i++)
+               for(UINT32 i = 0; i < m_dwChildCount; i++)
                {
                        if ((m_pChildList[i]->getObjectClass() == OBJECT_INTERFACE) &&
-                           !((Interface *)m_pChildList[i])->isLoopback())
+                           !((Interface *)m_pChildList[i])->isLoopback() && m_pChildList[i]->getIpAddress().isValidUnicast())
                        {
-                               dwAddr = htonl(m_pChildList[i]->IpAddr());
-                               if (dwAddr != 0)
-                               {
-                                       hs = gethostbyaddr((const char *)&dwAddr, 4, AF_INET);
-                                       if (hs != NULL)
-                                       {
-#ifdef UNICODE
-                                               MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hs->h_name, -1, m_name, MAX_OBJECT_NAME);
-                                               m_name[MAX_OBJECT_NAME - 1] = 0;
-#else
-                                               nx_strncpy(m_name, hs->h_name, MAX_OBJECT_NAME);
-#endif
-                                               bSuccess = TRUE;
-                                               break;
-                                       }
+            if (m_pChildList[i]->getIpAddress().getHostByAddr(name, MAX_OBJECT_NAME) != NULL)
+            {
+                                       nx_strncpy(m_name, name, MAX_OBJECT_NAME);
+                                       bSuccess = TRUE;
+                                       break;
                                }
                        }
                }
@@ -5404,8 +5380,8 @@ void Node::topologyPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
                        {
                                DbgPrintf(5, _T("Node::topologyPoll(%s [%d]): found peer node %s [%d], localIfIndex=%d remoteIfIndex=%d"),
                                          m_name, m_id, object->getName(), object->getId(), ni->ifLocal, ni->ifRemote);
-                               Interface *ifLocal = findInterface(ni->ifLocal, INADDR_ANY);
-                               Interface *ifRemote = ((Node *)object)->findInterface(ni->ifRemote, INADDR_ANY);
+                               Interface *ifLocal = findInterfaceByIndex(ni->ifLocal);
+            Interface *ifRemote = ((Node *)object)->findInterfaceByIndex(ni->ifRemote);
                                DbgPrintf(5, _T("Node::topologyPoll(%s [%d]): localIfObject=%s remoteIfObject=%s"), m_name, m_id,
                                          (ifLocal != NULL) ? ifLocal->getName() : _T("(null)"),
                                          (ifRemote != NULL) ? ifRemote->getName() : _T("(null)"));
@@ -5535,10 +5511,10 @@ void Node::topologyPoll(ClientSession *pSession, UINT32 dwRqId, int nPoller)
                if ((node != NULL) && (ws->ipAddr == 0))
                {
                   Interface *iface = node->findInterfaceByMAC(ws->macAddr);
-                  if ((iface != NULL) && (iface->IpAddr() != 0))
-                     ws->ipAddr = iface->IpAddr();
+                  if ((iface != NULL) && iface->getIpAddress().isValidUnicast())
+                     ws->ipAddr = iface->getIpAddress().getAddressV4();
                   else
-                     ws->ipAddr = node->IpAddr();
+                     ws->ipAddr = node->getIpAddress().getAddressV4();
                }
                                }
                        }
@@ -5665,7 +5641,7 @@ void Node::resolveVlanPorts(VlanList *vlanList)
                        switch(vlan->getPortReferenceMode())
                        {
                                case VLAN_PRM_IFINDEX:  // interface index
-                                       iface = findInterface(portId, INADDR_ANY);
+               iface = findInterfaceByIndex(portId);
                                        break;
                                case VLAN_PRM_BPORT:            // bridge port number
                                        iface = findBridgePort(portId);
@@ -5683,17 +5659,17 @@ void Node::resolveVlanPorts(VlanList *vlanList)
 /**
  * Create new subnet and bins to this node
  */
-Subnet *Node::createSubnet(DWORD ipAddr, DWORD netMask, bool syntheticMask)
+Subnet *Node::createSubnet(const InetAddress& baseAddr, bool syntheticMask)
 {
+   InetAddress addr = baseAddr.getSubnetAddress();
    if (syntheticMask)
    {
-      while(FindSubnetByIP(m_zoneId, ipAddr & netMask) != NULL)
+      while(FindSubnetByIP(m_zoneId, addr) != NULL)
       {
-         netMask = (netMask >> 1) | 0xFFFFFF00;
+         addr.setMaskBits(addr.getMaskBits() + 1);
       }
    }
-   ipAddr = ipAddr & netMask;
-   Subnet *s = new Subnet(ipAddr, netMask, m_zoneId, syntheticMask);
+   Subnet *s = new Subnet(addr, m_zoneId, syntheticMask);
    NetObjInsert(s, TRUE);
    if (g_flags & AF_ENABLE_ZONING)
    {
@@ -5712,7 +5688,7 @@ Subnet *Node::createSubnet(DWORD ipAddr, DWORD netMask, bool syntheticMask)
           g_pEntireNet->AddSubnet(s);
    }
    s->addNode(this);
-   DbgPrintf(4, _T("Node::createSubnet(): Creating new subnet %s [%d] for node %s [%d]"),
+   DbgPrintf(4, _T("Node::createSubnet(): Created new subnet %s [%d] for node %s [%d]"),
              s->getName(), s->getId(), m_name, m_id);
    return s;
 }
@@ -5736,21 +5712,21 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                   NX_INTERFACE_INFO *iface = pIfList->get(i);
                   if (iface->ipAddr != 0)
                   {
-                          Interface *pInterface = findInterface(iface->index, iface->ipAddr);
-                          if (pInterface == NULL)
+                          Interface *pInterface = findInterfaceByIndex(iface->index);
+                          if ((pInterface == NULL) || !pInterface->getIpAddress().equals(iface->ipAddr))
                           {
-                                  nxlog_write(MSG_INTERNAL_ERROR, EVENTLOG_WARNING_TYPE, "s", _T("Cannot find interface object in Node::CheckSubnetBinding()"));
+                                  nxlog_write(MSG_INTERNAL_ERROR, EVENTLOG_WARNING_TYPE, "s", _T("Cannot find interface object in Node::checkSubnetBinding()"));
                                   break;       // Something goes really wrong
                           }
 
-                          if (pInterface->IpAddr() == m_dwIpAddr)
+                          if (pInterface->getIpAddress().equals(m_ipAddress))
                hasIfaceForPrimaryIp = true;
 
                           if (pInterface->isExcludedFromTopology())
                                   continue;
 
                           // Is cluster interconnect interface?
-                          bool isSync = (pCluster != NULL) ? pCluster->isSyncAddr(pInterface->IpAddr()) : false;
+                          bool isSync = (pCluster != NULL) ? pCluster->isSyncAddr(pInterface->getIpAddress()) : false;
 
                           Subnet *pSubnet = FindSubnetForNode(m_zoneId, iface->ipAddr);
                           if (pSubnet != NULL)
@@ -5765,7 +5741,7 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                                           {
                                                   DbgPrintf(4, _T("Setting correct netmask for subnet %s [%d] from node %s [%d]"),
                                                                            pSubnet->getName(), pSubnet->getId(), m_name, m_id);
-                     if (((pInterface->getIpNetMask() == 0xFFFFFFFF) || (pInterface->getIpNetMask() == 0xFFFFFFFE)) && (getParentCount() > 1))
+                     if ((pInterface->getIpAddress().getHostBits() < 2) && (getParentCount() > 1))
                      {
                         /* Delete subnet object if we try to change it's netmask to 255.255.255.255 or 255.255.255.254 and
                          node has more than one parent. hasIfaceForPrimaryIp paramteter should prevent us from going in
@@ -5775,7 +5751,7 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                      }
                      else
                      {
-                        pSubnet->setCorrectMask(pInterface->IpAddr() & pInterface->getIpNetMask(), pInterface->getIpNetMask());
+                        pSubnet->setCorrectMask(pInterface->getIpAddress().getSubnetAddress());
                      }
                                           }
 
@@ -5790,18 +5766,27 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                           }
                           else if (!isSync)
                           {
+               DbgPrintf(6, _T("Missing subnet for interface %s [%d]"), iface->name, iface->index);
+
                                   // Ignore mask 255.255.255.255 - some point-to-point interfaces can have such mask
                                   // Ignore mask 255.255.255.254 - it's invalid
                                   if ((iface->ipNetMask != 0xFFFFFFFF) && (iface->ipNetMask != 0xFFFFFFFE))
-                  pSubnet = createSubnet(iface->ipAddr, iface->ipNetMask, false);
+               {
+                  pSubnet = createSubnet(InetAddress(iface->ipAddr, iface->ipNetMask), false);
+                                          pSubnet->addNode(this);
+               }
+               else
+               {
+                  DbgPrintf(6, _T("Subnet not required for interface %s [%d]"), iface->name, iface->index);
+               }
                           }
 
                           // Check if subnet mask is correct on interface
-                          if ((pSubnet != NULL) && (pSubnet->getIpNetMask() != pInterface->getIpNetMask()) && (iface->ipNetMask != 0xFFFFFFFF))
+                          if ((pSubnet != NULL) && (pSubnet->getIpAddress().getMaskBits() != pInterface->getIpAddress().getMaskBits()) && (iface->ipNetMask != 0xFFFFFFFF))
                           {
-                                  PostEvent(EVENT_INCORRECT_NETMASK, m_id, "idsaa", pInterface->getId(),
+                                  PostEvent(EVENT_INCORRECT_NETMASK, m_id, "idsdd", pInterface->getId(),
                                                            pInterface->getIfIndex(), pInterface->getName(),
-                                                           pInterface->getIpNetMask(), pSubnet->getIpNetMask());
+                                                           pInterface->getIpAddress().getMaskBits(), pSubnet->getIpAddress().getMaskBits());
                           }
                   }
           }
@@ -5810,9 +5795,9 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
    // Some devices may report interface list, but without IP
    // To prevent such nodes from hanging at top of the tree, attempt
    // to find subnet node primary IP
-   if ((m_dwIpAddr != 0) && !(m_dwFlags & NF_REMOTE_AGENT) && !hasIfaceForPrimaryIp)
+   if (m_ipAddress.isValidUnicast() && !(m_dwFlags & NF_REMOTE_AGENT) && !hasIfaceForPrimaryIp)
    {
-          Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_dwIpAddr);
+          Subnet *pSubnet = FindSubnetForNode(m_zoneId, m_ipAddress);
       if (pSubnet != NULL)
       {
                   // Check if node is linked to this subnet
@@ -5825,7 +5810,9 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
       }
       else
       {
-                  pSubnet = createSubnet(m_dwIpAddr, 0xFFFFFF00, true);
+         InetAddress addr(m_ipAddress);
+         addr.setMaskBits((addr.getFamily() == AF_INET) ? 24 : 64);
+                  pSubnet = createSubnet(addr, true);
       }
    }
 
@@ -5838,7 +5825,7 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                if (m_pParentList[i]->getObjectClass() == OBJECT_SUBNET)
                {
                        Subnet *pSubnet = (Subnet *)m_pParentList[i];
-                       if ((pSubnet->IpAddr() == (m_dwIpAddr & pSubnet->getIpNetMask())) && !(m_dwFlags & NF_REMOTE_AGENT))
+                       if (pSubnet->getIpAddress().contain(m_ipAddress) && !(m_dwFlags & NF_REMOTE_AGENT))
             continue;   // primary IP is in given subnet
 
          UINT32 j;
@@ -5849,11 +5836,11 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
                                        if (((Interface *)m_pChildList[j])->isExcludedFromTopology())
                                                continue;
 
-                                       if (pSubnet->IpAddr() == (m_pChildList[j]->IpAddr() & pSubnet->getIpNetMask()))
+                                       if (pSubnet->getIpAddress().contain(m_pChildList[j]->getIpAddress()))
                                        {
                                                if (pCluster != NULL)
                                                {
-                                                       if (pCluster->isSyncAddr(m_pChildList[j]->IpAddr()))
+                                                       if (pCluster->isSyncAddr(m_pChildList[j]->getIpAddress()))
                                                        {
                                                                j = m_dwChildCount;     // Cause to unbind from this subnet
                                                        }
@@ -5879,6 +5866,7 @@ void Node::checkSubnetBinding(InterfaceList *pIfList)
       NetObj *o = unlinkList.get(n);
       o->DeleteChild(this);
                DeleteParent(o);
+      o->calculateCompoundStatus();
        }
 }
 
@@ -6094,9 +6082,9 @@ TCHAR *Node::expandText(const TCHAR *textTemplate)
                   dwPos += (UINT32)_tcslen(m_name);
                   break;
                case 'a':   // IP address of the node
-                  dwSize += 16;
+                  dwSize += 48;
                   pText = (TCHAR *)realloc(pText, dwSize * sizeof(TCHAR));
-                                               IpToStr(m_dwIpAddr, &pText[dwPos]);
+                                               m_ipAddress.toString(&pText[dwPos]);
                   dwPos = (UINT32)_tcslen(pText);
                   break;
                case 'i':   // Node identifier
@@ -6434,9 +6422,9 @@ void Node::updatePingData()
          AgentConnection *conn = proxyNode->createAgentConnection();
          if (conn != NULL)
          {
-            TCHAR parameter[64], buffer[64];
+            TCHAR parameter[128], buffer[64];
 
-            _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(m_dwIpAddr, buffer));
+            _sntprintf(parameter, 128, _T("Icmp.Ping(%s)"), m_ipAddress.toString(buffer));
             if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
             {
                DbgPrintf(7, _T("Node::updatePingData:  proxy response: \"%s\""), buffer);
@@ -6468,7 +6456,7 @@ void Node::updatePingData()
    }
    else        // not using ICMP proxy
    {
-      UINT32 dwPingStatus = IcmpPing(htonl(m_dwIpAddr), 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
+      UINT32 dwPingStatus = IcmpPing(m_ipAddress, 3, g_icmpPingTimeout, &m_pingTime, g_icmpPingSize);
       if (dwPingStatus != ICMP_SUCCESS)
       {
          DbgPrintf(7, _T("Node::updatePingData: error getting ping %d"), dwPingStatus);
index 29776e4..cfddacf 100644 (file)
@@ -55,18 +55,15 @@ NXSL_Value *NXSL_DiscoveryClass::getAttr(NXSL_Object *pObject, const TCHAR *pszA
    pData = (DISCOVERY_FILTER_DATA *)pObject->getData();
    if (!_tcscmp(pszAttr, _T("ipAddr")))
    {
-      IpToStr(pData->dwIpAddr, szBuffer);
-      pValue = new NXSL_Value(szBuffer);
+      pValue = new NXSL_Value(pData->ipAddr.toString(szBuffer));
    }
    else if (!_tcscmp(pszAttr, _T("netMask")))
    {
-      IpToStr(pData->dwNetMask, szBuffer);
-      pValue = new NXSL_Value(szBuffer);
+      pValue = new NXSL_Value(pData->ipAddr.getMaskBits());
    }
    else if (!_tcscmp(pszAttr, _T("subnet")))
    {
-      IpToStr(pData->dwSubnetAddr, szBuffer);
-      pValue = new NXSL_Value(szBuffer);
+      pValue = new NXSL_Value(pData->ipAddr.getSubnetAddress().toString(szBuffer));
    }
    else if (!_tcscmp(pszAttr, _T("isAgent")))
    {
@@ -128,8 +125,7 @@ static NXSL_DiscoveryClass m_nxslDiscoveryClass;
  * Poll new node for configuration
  * Returns pointer to new node object on success or NULL on failure
  *
- * @param dwIpAddr IP address of new node
- * @param dwNetMask IP network mask or 0 if not known
+ * @param ipAddr IP address of new node
  * @param dwCreationFlags
  * @param agentPort port number of NetXMS agent
  * @param snmpPort port number of SNMP agent
@@ -141,20 +137,20 @@ static NXSL_DiscoveryClass m_nxslDiscoveryClass;
  * @param doConfPoll if set to true, Node::configurationPoll will be called before exit
  * @param discoveredNode must be set to true if node being added automatically by discovery thread
  */
-Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dwCreationFlags,
+Node NXCORE_EXPORTABLE *PollNewNode(const InetAddress& ipAddr, UINT32 dwCreationFlags,
                                     WORD agentPort, WORD snmpPort, const TCHAR *pszName, UINT32 dwProxyNode, UINT32 dwSNMPProxy,
                                     Cluster *pCluster, UINT32 zoneId, bool doConfPoll, bool discoveredNode)
 {
    Node *pNode;
-   TCHAR szIpAddr1[32], szIpAddr2[32];
+   TCHAR szIpAddr[64];
    UINT32 dwFlags = 0;
 
-   DbgPrintf(4, _T("PollNode(%s,%s) zone %d"), IpToStr(dwIpAddr, szIpAddr1), IpToStr(dwNetMask, szIpAddr2), (int)zoneId);
+   DbgPrintf(4, _T("PollNode(%s/%d) zone %d"), ipAddr.toString(szIpAddr), ipAddr.getMaskBits(), (int)zoneId);
    // Check for node existence
-   if ((FindNodeByIP(zoneId, dwIpAddr) != NULL) ||
-       (FindSubnetByIP(zoneId, dwIpAddr) != NULL))
+   if ((FindNodeByIP(zoneId, ipAddr) != NULL) ||
+       (FindSubnetByIP(zoneId, ipAddr) != NULL))
    {
-      DbgPrintf(4, _T("PollNode: Node %s already exist in database"), IpToStr(dwIpAddr, szIpAddr1));
+      DbgPrintf(4, _T("PollNode: Node %s already exist in database"), szIpAddr);
       return NULL;
    }
 
@@ -164,7 +160,7 @@ Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dw
       dwFlags |= NF_DISABLE_SNMP;
    if (dwCreationFlags & NXC_NCF_DISABLE_NXCP)
       dwFlags |= NF_DISABLE_NXCP;
-   pNode = new Node(dwIpAddr, dwFlags, dwProxyNode, dwSNMPProxy, zoneId);
+   pNode = new Node(ipAddr, dwFlags, dwProxyNode, dwSNMPProxy, zoneId);
        if (agentPort != 0)
                pNode->setAgentPort(agentPort);
        if (snmpPort != 0)
@@ -176,22 +172,14 @@ Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dw
        // Use DNS name as primary name if required
        if (discoveredNode && ConfigReadInt(_T("UseDNSNameForDiscoveredNodes"), 0))
        {
-               UINT32 ip = htonl(dwIpAddr);
-               struct hostent *hs = gethostbyaddr((char *)&ip, 4, AF_INET);
-               if (hs != NULL)
+               TCHAR dnsName[MAX_DNS_NAME];
+      if (ipAddr.getHostByAddr(dnsName, MAX_DNS_NAME) != NULL)
                {
-                       TCHAR dnsName[MAX_DNS_NAME];
-#ifdef UNICODE
-                       MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hs->h_name, -1, dnsName, MAX_DNS_NAME);
-                       dnsName[MAX_DNS_NAME - 1] = 0;
-#else
-                       nx_strncpy(dnsName, hs->h_name, MAX_DNS_NAME);
-#endif
-                       if (ntohl(ResolveHostName(dnsName)) == dwIpAddr)
+         if (InetAddress::resolveHostName(dnsName).equals(ipAddr))
                        {
                                // We have valid DNS name which resolves back to node's IP address, use it as primary name
                                pNode->setPrimaryName(dnsName);
-                               DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName, IpToStr(dwIpAddr, szIpAddr1));
+                               DbgPrintf(4, _T("PollNode: Using DNS name %s as primary name for node %s"), dnsName, szIpAddr);
                        }
                }
        }
@@ -214,7 +202,7 @@ Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dw
                ConfigReadInt(_T("DefaultDCIRetentionTime"), 30), pNode));
 
        if (doConfPoll)
-               pNode->configurationPoll(NULL, 0, -1, dwNetMask);
+               pNode->configurationPoll(NULL, 0, -1, ipAddr.getMaskBits());
 
    pNode->unhide();
    PostEvent(EVENT_NODE_ADDED, pNode->getId(), "d", (int)(discoveredNode ? 1 : 0));
@@ -225,29 +213,28 @@ Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dw
 /**
  * Find existing node by MAC address to detect IP address change for already known node.
  *
- * @param dwIpAddr new (discovered) IP address
- * @param dwNetMask network mask for new address
+ * @param ipAddr new (discovered) IP address
  * @param dwZoneID zone ID
  * @param bMacAddr MAC address of discovered node, or NULL if not known
  *
  * @return pointer to existing interface object with given MAC address or NULL if no such interface found
  */
-static Interface *GetOldNodeWithNewIP(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dwZoneId, BYTE *bMacAddr)
+static Interface *GetOldNodeWithNewIP(const InetAddress& ipAddr, UINT32 dwZoneId, BYTE *bMacAddr)
 {
        Subnet *subnet;
        BYTE nodeMacAddr[MAC_ADDR_LENGTH];
-       TCHAR szIpAddr[16], szMacAddr[20];
+       TCHAR szIpAddr[64], szMacAddr[20];
 
-       IpToStr(dwIpAddr, szIpAddr);
+   ipAddr.toString(szIpAddr);
        MACToStr(bMacAddr, szMacAddr);
        DbgPrintf(6, _T("GetOldNodeWithNewIP: ip=%s mac=%s"), szIpAddr, szMacAddr);
 
        if (bMacAddr == NULL)
        {
-               subnet = FindSubnetForNode(dwZoneId, dwIpAddr);
+               subnet = FindSubnetForNode(dwZoneId, ipAddr);
                if (subnet != NULL)
                {
-                       BOOL found = subnet->findMacAddress(dwIpAddr, nodeMacAddr);
+                       BOOL found = subnet->findMacAddress(ipAddr, nodeMacAddr);
                        if (!found)
                        {
                                DbgPrintf(6, _T("GetOldNodeWithNewIP: MAC address not found"));
@@ -276,7 +263,7 @@ static Interface *GetOldNodeWithNewIP(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32
 /**
  * Check if host at given IP address is reachable by NetXMS server
  */
-static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_Transport **transport, AgentConnection **agentConn)
+static bool HostIsReachable(const InetAddress& ipAddr, UINT32 zoneId, bool fullCheck, SNMP_Transport **transport, AgentConnection **agentConn)
 {
        bool reachable = false;
 
@@ -309,9 +296,9 @@ static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_T
                        AgentConnection *conn = proxyNode->createAgentConnection();
                        if (conn != NULL)
                        {
-                               TCHAR parameter[64], buffer[64];
+                               TCHAR parameter[128], buffer[64];
 
-                               _sntprintf(parameter, 64, _T("Icmp.Ping(%s)"), IpToStr(ipAddr, buffer));
+                               _sntprintf(parameter, 128, _T("Icmp.Ping(%s)"), ipAddr.toString(buffer));
                                if (conn->getParameter(parameter, 64, buffer) == ERR_SUCCESS)
                                {
                                        TCHAR *eptr;
@@ -331,7 +318,7 @@ static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_T
        }
        else    // not using ICMP proxy
        {
-               if (IcmpPing(htonl(ipAddr), 3, g_icmpPingTimeout, NULL, g_icmpPingSize) == ICMP_SUCCESS)
+               if (IcmpPing(ipAddr, 3, g_icmpPingTimeout, NULL, g_icmpPingSize) == ICMP_SUCCESS)
                        reachable = true;
        }
 
@@ -345,7 +332,7 @@ static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_T
                Node *proxyNode = (Node *)g_idxNodeById.get(agentProxy);
       if (proxyNode != NULL)
       {
-         pAgentConn->setProxy(htonl(proxyNode->IpAddr()), proxyNode->getAgentPort(),
+         pAgentConn->setProxy(proxyNode->getIpAddress(), proxyNode->getAgentPort(),
                               proxyNode->getAgentAuthMethod(), proxyNode->getSharedSecret());
       }
        }
@@ -394,7 +381,7 @@ static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_T
        else
        {
                pTransport = new SNMP_UDPTransport;
-               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(NULL, htonl(ipAddr), 161);
+               ((SNMP_UDPTransport *)pTransport)->createUDPTransport(ipAddr, 161);
        }
    if (pTransport != NULL)
    {
@@ -424,18 +411,18 @@ static bool HostIsReachable(UINT32 ipAddr, UINT32 zoneId, bool fullCheck, SNMP_T
 /**
  * Check if newly discovered node should be added
  */
-static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE *macAddr)
+static BOOL AcceptNewNode(const InetAddress& addr, UINT32 zoneId, BYTE *macAddr)
 {
    DISCOVERY_FILTER_DATA data;
-   TCHAR szFilter[MAX_DB_STRING], szBuffer[256], szIpAddr[16];
+   TCHAR szFilter[MAX_DB_STRING], szBuffer[256], szIpAddr[64];
    UINT32 dwTemp;
    AgentConnection *pAgentConn;
    BOOL bResult = FALSE;
        SNMP_Transport *pTransport;
 
-       IpToStr(dwIpAddr, szIpAddr);
-   if ((FindNodeByIP(zoneId, dwIpAddr) != NULL) ||
-       (FindSubnetByIP(zoneId, dwIpAddr) != NULL))
+       addr.toString(szIpAddr);
+   if ((FindNodeByIP(zoneId, addr) != NULL) ||
+       (FindSubnetByIP(zoneId, addr) != NULL))
        {
                DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database"), szIpAddr);
       return FALSE;  // Node already exist in database
@@ -452,8 +439,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
    {
       bool stop = false;
       hook->setGlobalVariable(_T("$ipAddr"), new NXSL_Value(szIpAddr));
-      IpToStr(dwNetMask, szBuffer);
-      hook->setGlobalVariable(_T("$ipNetMask"), new NXSL_Value(szBuffer));
+      hook->setGlobalVariable(_T("$ipNetMask"), new NXSL_Value(addr.getMaskBits()));
       MACToStr(macAddr, szBuffer);
       hook->setGlobalVariable(_T("$macAddr"), new NXSL_Value(szBuffer));
       hook->setGlobalVariable(_T("$zoneId"), new NXSL_Value(zoneId));
@@ -475,24 +461,23 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
          return FALSE;  // blocked by hook
    }
 
-       Interface *iface = GetOldNodeWithNewIP(dwIpAddr, dwNetMask, zoneId, macAddr);
+       Interface *iface = GetOldNodeWithNewIP(addr, zoneId, macAddr);
        if (iface != NULL)
        {
-               if (!HostIsReachable(dwIpAddr, zoneId, false, NULL, NULL))
+               if (!HostIsReachable(addr, zoneId, false, NULL, NULL))
                {
                        DbgPrintf(4, _T("AcceptNewNode(%s): found existing interface with same MAC address, but new IP is not reachable"), szIpAddr);
                        return FALSE;
                }
 
                Node *oldNode = iface->getParentNode();
-               if (iface->IpAddr() == oldNode->IpAddr())
+               if (iface->getIpAddress().equals(oldNode->getIpAddress()))
                {
                        // we should change node's primary IP only if old IP for this MAC was also node's primary IP
                        TCHAR szOldIpAddr[16];
-                       IpToStr(oldNode->IpAddr(), szOldIpAddr);
-                       DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database with ip %s, will change to new"), 
-                               szIpAddr, szOldIpAddr);
-                       oldNode->changeIPAddress(dwIpAddr);
+                       oldNode->getIpAddress().toString(szOldIpAddr);
+                       DbgPrintf(4, _T("AcceptNewNode(%s): node already exist in database with ip %s, will change to new"), szIpAddr, szOldIpAddr);
+                       oldNode->changeIPAddress(addr);
                }
                return FALSE;
        }
@@ -502,7 +487,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
        {
                if (g_pModuleList[i].pfAcceptNewNode != NULL)
                {
-                       if (!g_pModuleList[i].pfAcceptNewNode(dwIpAddr, dwNetMask, zoneId, macAddr))
+                       if (!g_pModuleList[i].pfAcceptNewNode(addr, zoneId, macAddr))
                                return FALSE;   // filtered out by module
                }
        }
@@ -514,7 +499,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
    // Check for filter script
    if ((szFilter[0] == 0) || (!_tcsicmp(szFilter, _T("none"))))
        {
-               if (!HostIsReachable(dwIpAddr, zoneId, false, NULL, NULL))
+               if (!HostIsReachable(addr, zoneId, false, NULL, NULL))
                {
                        DbgPrintf(4, _T("AcceptNewNode(%s): host is not reachable"), szIpAddr);
                        return FALSE;
@@ -525,9 +510,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
 
    // Initialize new node data
    memset(&data, 0, sizeof(DISCOVERY_FILTER_DATA));
-   data.dwIpAddr = dwIpAddr;
-   data.dwNetMask = dwNetMask;
-   data.dwSubnetAddr = dwIpAddr & dwNetMask;
+   data.ipAddr = addr;
 
    // Check for address range if we use simple filter instead of script
        UINT32 autoFilterFlags;
@@ -549,13 +532,19 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
                if (nType == 0)
                {
                   // Subnet
-                  bResult = (data.dwIpAddr & DBGetFieldIPAddr(hResult, i, 2)) == DBGetFieldIPAddr(hResult, i, 1);
+                  InetAddress subnet = DBGetFieldInetAddr(hResult, i, 1);
+                  subnet.setMaskBits(DBGetFieldLong(hResult, i, 2));
+                  bResult = subnet.contain(data.ipAddr);
                }
                else
                {
                   // Range
-                  bResult = ((data.dwIpAddr >= DBGetFieldIPAddr(hResult, i, 1)) &&
-                             (data.dwIpAddr <= DBGetFieldIPAddr(hResult, i, 2)));
+                  InetAddress addr1 = DBGetFieldInetAddr(hResult, i, 1);
+                  InetAddress addr2 = DBGetFieldInetAddr(hResult, i, 2);
+                  if ((addr1.getFamily() == data.ipAddr.getFamily()) && (addr2.getFamily() == data.ipAddr.getFamily()))
+                     bResult = (addr1.compareTo(data.ipAddr) <= 0) && (addr2.compareTo(data.ipAddr) >= 0);
+                  else
+                     bResult = FALSE;
                }
             }
             DBFreeResult(hResult);
@@ -567,7 +556,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
    }
 
        // Check if host is reachable
-       if (!HostIsReachable(dwIpAddr, zoneId, true, &pTransport, &pAgentConn))
+       if (!HostIsReachable(addr, zoneId, true, &pTransport, &pAgentConn))
        {
                DbgPrintf(4, _T("AcceptNewNode(%s): host is not reachable"), szIpAddr);
       return FALSE;
@@ -705,7 +694,7 @@ static BOOL AcceptNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 zoneId, BYTE
 THREAD_RESULT THREAD_CALL NodePoller(void *arg)
 {
    NEW_NODE *pInfo;
-       TCHAR szIpAddr[16], szNetMask[16];
+       TCHAR szIpAddr[64];
 
    DbgPrintf(1, _T("Node poller started"));
 
@@ -715,12 +704,12 @@ THREAD_RESULT THREAD_CALL NodePoller(void *arg)
       if (pInfo == INVALID_POINTER_VALUE)
          break;   // Shutdown indicator received
 
-               DbgPrintf(4, _T("NodePoller: processing node %s/%s in zone %d"),
-                         IpToStr(pInfo->dwIpAddr, szIpAddr), IpToStr(pInfo->dwNetMask, szNetMask), (int)pInfo->zoneId);
-      if (pInfo->ignoreFilter || AcceptNewNode(pInfo->dwIpAddr, pInfo->dwNetMask, pInfo->zoneId, pInfo->bMacAddr))
+               DbgPrintf(4, _T("NodePoller: processing node %s/%d in zone %d"),
+                         pInfo->ipAddr.toString(szIpAddr), pInfo->ipAddr.getMaskBits(), (int)pInfo->zoneId);
+      if (pInfo->ignoreFilter || AcceptNewNode(pInfo->ipAddr, pInfo->zoneId, pInfo->bMacAddr))
                {
          ObjectTransactionStart();
-         PollNewNode(pInfo->dwIpAddr, pInfo->dwNetMask, 0, 0, 0, NULL, 0, 0, NULL, pInfo->zoneId, true, true);
+         PollNewNode(pInfo->ipAddr, 0, 0, 0, NULL, 0, 0, NULL, pInfo->zoneId, true, true);
          ObjectTransactionEnd();
                }
       free(pInfo);
index 3a2e26f..7a8d73e 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath=".\inaddr_index.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath=".\index.cpp"
                                >
                        </File>
index 6608e0a..983d4d5 100644 (file)
@@ -152,9 +152,9 @@ NXSL_Value *NXSL_NetObjClass::getAttr(NXSL_Object *pObject, const TCHAR *pszAttr
    }
    else if (!_tcscmp(pszAttr, _T("ipAddr")))
    {
-      TCHAR szBuffer[32];
-      IpToStr(object->IpAddr(), szBuffer);
-      pValue = new NXSL_Value(szBuffer);
+      TCHAR buffer[64];
+      object->getIpAddress().toString(buffer);
+      pValue = new NXSL_Value(buffer);
    }
    else if (!_tcscmp(pszAttr, _T("type")))
    {
@@ -365,7 +365,6 @@ NXSL_Value *NXSL_NodeClass::getAttr(NXSL_Object *pObject, const TCHAR *pszAttr)
 {
    Node *pNode;
    NXSL_Value *pValue = NULL;
-   TCHAR szBuffer[256];
 
    pNode = (Node *)pObject->getData();
    if (!_tcscmp(pszAttr, _T("agentVersion")))
@@ -409,8 +408,9 @@ NXSL_Value *NXSL_NodeClass::getAttr(NXSL_Object *pObject, const TCHAR *pszAttr)
    }
    else if (!_tcscmp(pszAttr, _T("ipAddr")))
    {
-      IpToStr(pNode->IpAddr(), szBuffer);
-      pValue = new NXSL_Value(szBuffer);
+      TCHAR buffer[64];
+      pNode->getIpAddress().toString(buffer);
+      pValue = new NXSL_Value(buffer);
    }
    else if (!_tcscmp(pszAttr, _T("isAgent")))
    {
@@ -607,15 +607,13 @@ NXSL_Value *NXSL_InterfaceClass::getAttr(NXSL_Object *pObject, const TCHAR *pszA
    }
    else if (!_tcscmp(pszAttr, _T("ipAddr")))
    {
-               TCHAR buffer[256];
-      IpToStr(iface->IpAddr(), buffer);
+      TCHAR buffer[64];
+      iface->getIpAddress().toString(buffer);
       pValue = new NXSL_Value(buffer);
    }
    else if (!_tcscmp(pszAttr, _T("ipNetMask")))
    {
-               TCHAR buffer[256];
-               IpToStr(iface->getIpNetMask(), buffer);
-      pValue = new NXSL_Value(buffer);
+      pValue = new NXSL_Value(iface->getIpAddress().getMaskBits());
    }
    else if (!_tcscmp(pszAttr, _T("isExcludedFromTopology")))
    {
index 3b49ff1..746919e 100644 (file)
@@ -147,7 +147,7 @@ static int F_GetInterfaceName(int argc, NXSL_Value **argv, NXSL_Value **ppResult
                return NXSL_ERR_BAD_CLASS;
 
        Node *node = (Node *)object->getData();
-       Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
+       Interface *ifc = node->findInterfaceByIndex(argv[1]->getValueAsUInt32());
        if (ifc != NULL)
        {
                *ppResult = new NXSL_Value(ifc->getName());
@@ -177,7 +177,7 @@ static int F_GetInterfaceObject(int argc, NXSL_Value **argv, NXSL_Value **ppResu
                return NXSL_ERR_BAD_CLASS;
 
        Node *node = (Node *)object->getData();
-       Interface *ifc = node->findInterface(argv[1]->getValueAsUInt32(), INADDR_ANY);
+       Interface *ifc = node->findInterfaceByIndex(argv[1]->getValueAsUInt32());
        if (ifc != NULL)
        {
                *ppResult = new NXSL_Value(new NXSL_Object(&g_nxslInterfaceClass, ifc));
@@ -580,7 +580,7 @@ static int F_CreateNode(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXSL
        const TCHAR *pname = argv[2]->getValueAsCString();
        if (*pname == 0)
                pname = argv[1]->getValueAsCString();
-       Node *node = PollNewNode(ntohl(ResolveHostName(pname)), 0, 0, 0, 0, argv[1]->getValueAsCString(), 0, 0, NULL, 0, true, false);
+   Node *node = PollNewNode(InetAddress::resolveHostName(pname), 0, 0, 0, argv[1]->getValueAsCString(), 0, 0, NULL, 0, true, false);
        if (node != NULL)
        {
                node->setPrimaryName(pname);
index 526a94f..1286e8e 100644 (file)
@@ -42,11 +42,11 @@ CONTAINER_CATEGORY *g_pContainerCatList = NULL;
 Queue *g_pTemplateUpdateQueue = NULL;
 
 ObjectIndex g_idxObjectById;
-ObjectIndex g_idxSubnetByAddr;
-ObjectIndex g_idxInterfaceByAddr;
+InetAddressIndex g_idxSubnetByAddr;
+InetAddressIndex g_idxInterfaceByAddr;
 ObjectIndex g_idxZoneByGUID;
 ObjectIndex g_idxNodeById;
-ObjectIndex g_idxNodeByAddr;
+InetAddressIndex g_idxNodeByAddr;
 ObjectIndex g_idxClusterById;
 ObjectIndex g_idxMobileDeviceById;
 ObjectIndex g_idxAccessPointById;
@@ -363,8 +363,8 @@ void NetObjInsert(NetObj *pObject, BOOL bNewObject)
                }
                else
                {
-                  if (pObject->IpAddr() != 0)
-                                             g_idxNodeByAddr.put(pObject->IpAddr(), pObject);
+                  if (pObject->getIpAddress().isValidUnicast())
+                                             g_idxNodeByAddr.put(pObject->getIpAddress(), pObject);
                }
             }
             break;
@@ -379,7 +379,7 @@ void NetObjInsert(NetObj *pObject, BOOL bNewObject)
             MacDbAddAccessPoint((AccessPoint *)pObject);
             break;
          case OBJECT_SUBNET:
-            if (pObject->IpAddr() != 0)
+            if (pObject->getIpAddress().isValidUnicast())
             {
                                        if (IsZoningEnabled())
                                        {
@@ -396,14 +396,14 @@ void NetObjInsert(NetObj *pObject, BOOL bNewObject)
                                        }
                                        else
                                        {
-                                               g_idxSubnetByAddr.put(pObject->IpAddr(), pObject);
+                                               g_idxSubnetByAddr.put(pObject->getIpAddress(), pObject);
                                        }
                if (bNewObject)
-                  PostEvent(EVENT_SUBNET_ADDED, g_dwMgmtNode, "isaa", pObject->getId(), pObject->getName(), pObject->IpAddr(), ((Subnet *)pObject)->getIpNetMask());
+                  PostEvent(EVENT_SUBNET_ADDED, g_dwMgmtNode, "isAd", pObject->getId(), pObject->getName(), &pObject->getIpAddress(), pObject->getIpAddress().getMaskBits());
             }
             break;
          case OBJECT_INTERFACE:
-            if ((pObject->IpAddr() != 0) && !((Interface *)pObject)->isExcludedFromTopology())
+            if (pObject->getIpAddress().isValidUnicast() && !((Interface *)pObject)->isExcludedFromTopology())
             {
                                        if (IsZoningEnabled())
                                        {
@@ -420,9 +420,9 @@ void NetObjInsert(NetObj *pObject, BOOL bNewObject)
                                        }
                                        else
                                        {
-                                               if (g_idxInterfaceByAddr.put(pObject->IpAddr(), pObject))
-                                                       DbgPrintf(1, _T("WARNING: duplicate interface IP address %08X (interface object %s [%d])"),
-                                                                                pObject->IpAddr(), pObject->getName(), (int)pObject->getId());
+                                               if (g_idxInterfaceByAddr.put(pObject->getIpAddress(), pObject))
+                                                       DbgPrintf(1, _T("WARNING: duplicate interface IP address %s (interface object %s [%d])"),
+                                                                                (const TCHAR *)pObject->getIpAddress().toString(), pObject->getName(), (int)pObject->getId());
                                        }
             }
             MacDbAddInterface((Interface *)pObject);
@@ -519,8 +519,8 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
             }
             else
             {
-                             if (pObject->IpAddr() != 0)
-                                     g_idxNodeByAddr.remove(pObject->IpAddr());
+                             if (pObject->getIpAddress().isValidUnicast())
+                                     g_idxNodeByAddr.remove(pObject->getIpAddress());
             }
          }
          break;
@@ -535,7 +535,7 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
          MacDbRemove(((AccessPoint *)pObject)->getMacAddr());
          break;
       case OBJECT_SUBNET:
-         if (pObject->IpAddr() != 0)
+         if (pObject->getIpAddress().isValidUnicast())
          {
                                if (IsZoningEnabled())
                                {
@@ -552,12 +552,12 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
                                }
                                else
                                {
-                                       g_idxSubnetByAddr.remove(pObject->IpAddr());
+                                       g_idxSubnetByAddr.remove(pObject->getIpAddress());
                                }
          }
          break;
       case OBJECT_INTERFACE:
-         if (pObject->IpAddr() != 0)
+         if (pObject->getIpAddress().isValidUnicast())
          {
                                if (IsZoningEnabled())
                                {
@@ -574,10 +574,10 @@ void NetObjDeleteFromIndexes(NetObj *pObject)
                                }
                                else
                                {
-                                       NetObj *o = g_idxInterfaceByAddr.get(pObject->IpAddr());
+                                       NetObj *o = g_idxInterfaceByAddr.get(pObject->getIpAddress());
                                        if ((o != NULL) && (o->getId() == pObject->getId()))
                                        {
-                                               g_idxInterfaceByAddr.remove(pObject->IpAddr());
+                                               g_idxInterfaceByAddr.remove(pObject->getIpAddress());
                                        }
                                }
          }
@@ -648,9 +648,9 @@ MobileDevice NXCORE_EXPORTABLE *FindMobileDeviceByDeviceID(const TCHAR *deviceId
 /**
  * Find node by IP address
  */
-Node NXCORE_EXPORTABLE *FindNodeByIP(UINT32 zoneId, UINT32 ipAddr)
+Node NXCORE_EXPORTABLE *FindNodeByIP(UINT32 zoneId, const InetAddress& ipAddr)
 {
-   if (ipAddr == 0)
+   if (!ipAddr.isValidUnicast())
       return NULL;
 
        Zone *zone = IsZoningEnabled() ? (Zone *)g_idxZoneByGUID.get(zoneId) : NULL;
@@ -688,9 +688,9 @@ Node NXCORE_EXPORTABLE *FindNodeByIP(UINT32 zoneId, UINT32 ipAddr)
 /**
  * Find interface by IP address
  */
-Interface NXCORE_EXPORTABLE *FindInterfaceByIP(UINT32 zoneId, UINT32 ipAddr)
+Interface NXCORE_EXPORTABLE *FindInterfaceByIP(UINT32 zoneId, const InetAddress& ipAddr)
 {
-   if (ipAddr == 0)
+   if (!ipAddr.isValidUnicast())
       return NULL;
 
        Zone *zone = IsZoningEnabled() ? (Zone *)g_idxZoneByGUID.get(zoneId) : NULL;
@@ -784,9 +784,9 @@ Node NXCORE_EXPORTABLE *FindNodeByBridgeId(const BYTE *bridgeId)
 /**
  * Find subnet by IP address
  */
-Subnet NXCORE_EXPORTABLE *FindSubnetByIP(UINT32 zoneId, UINT32 ipAddr)
+Subnet NXCORE_EXPORTABLE *FindSubnetByIP(UINT32 zoneId, const InetAddress& ipAddr)
 {
-   if (ipAddr == 0)
+   if (!ipAddr.isValidUnicast())
       return NULL;
 
        Subnet *subnet = NULL;
@@ -810,9 +810,9 @@ Subnet NXCORE_EXPORTABLE *FindSubnetByIP(UINT32 zoneId, UINT32 ipAddr)
  */
 struct SUBNET_MATCHING_DATA
 {
-   DWORD ipAddr;     // IP address to find subnet for
-   int maskLen;      // Current match mask length
-   Subnet *subnet;   // search result
+   InetAddress ipAddr; // IP address to find subnet for
+   int maskLen;        // Current match mask length
+   Subnet *subnet;     // search result
 };
 
 /**
@@ -821,9 +821,9 @@ struct SUBNET_MATCHING_DATA
 static void SubnetMatchCallback(NetObj *object, void *arg)
 {
    SUBNET_MATCHING_DATA *data = (SUBNET_MATCHING_DATA *)arg;
-   if ((data->ipAddr & ((Subnet *)object)->getIpNetMask()) == ((Subnet *)object)->IpAddr())
+   if (((Subnet *)object)->getIpAddress().contain(data->ipAddr))
    {
-      int maskLen = BitsInMask(((Subnet *)object)->getIpNetMask());
+      int maskLen = ((Subnet *)object)->getIpAddress().getMaskBits();
       if (maskLen > data->maskLen)
       {
          data->maskLen = maskLen;
@@ -835,13 +835,13 @@ static void SubnetMatchCallback(NetObj *object, void *arg)
 /**
  * Find subnet for given IP address
  */
-Subnet NXCORE_EXPORTABLE *FindSubnetForNode(UINT32 zoneId, UINT32 dwNodeAddr)
+Subnet NXCORE_EXPORTABLE *FindSubnetForNode(UINT32 zoneId, const InetAddress& nodeAddr)
 {
-   if (dwNodeAddr == 0)
+   if (!nodeAddr.isValidUnicast())
       return NULL;
 
    SUBNET_MATCHING_DATA matchData;
-   matchData.ipAddr = dwNodeAddr;
+   matchData.ipAddr = nodeAddr;
    matchData.maskLen = -1;
    matchData.subnet = NULL;
        if (IsZoningEnabled())
@@ -945,19 +945,20 @@ Template NXCORE_EXPORTABLE *FindTemplateByName(const TCHAR *pszName)
        return (Template *)g_idxObjectById.find(TemplateNameComparator, (void *)pszName);
 }
 
-
-//
-// Find cluster by resource IP
-//
-
+/**
+ * Callback for FindClusterByResourceIP
+ */
 static bool ClusterResourceIPComparator(NetObj *object, void *ipAddr)
 {
-       return (object->getObjectClass() == OBJECT_CLUSTER) && !object->isDeleted() && ((Cluster *)object)->isVirtualAddr(CAST_FROM_POINTER(ipAddr, UINT32));
+       return (object->getObjectClass() == OBJECT_CLUSTER) && !object->isDeleted() && ((Cluster *)object)->isVirtualAddr(*((const InetAddress *)ipAddr));
 }
 
-Cluster NXCORE_EXPORTABLE *FindClusterByResourceIP(UINT32 ipAddr)
+/**
+ * Find cluster by resource IP
+ */
+Cluster NXCORE_EXPORTABLE *FindClusterByResourceIP(const InetAddress& ipAddr)
 {
-       return (Cluster *)g_idxObjectById.find(ClusterResourceIPComparator, CAST_TO_POINTER(ipAddr, void *));
+       return (Cluster *)g_idxObjectById.find(ClusterResourceIPComparator, (void *)&ipAddr);
 }
 
 /**
@@ -965,7 +966,7 @@ Cluster NXCORE_EXPORTABLE *FindClusterByResourceIP(UINT32 ipAddr)
  */
 struct __cluster_ip_data
 {
-       UINT32 ipAddr;
+       InetAddress ipAddr;
        UINT32 zoneId;
 };
 
@@ -985,7 +986,7 @@ static bool ClusterIPComparator(NetObj *object, void *data)
  * Check if given IP address is used by cluster (it's either
  * resource IP or located on one of sync subnets)
  */
-bool NXCORE_EXPORTABLE IsClusterIP(UINT32 zoneId, UINT32 ipAddr)
+bool NXCORE_EXPORTABLE IsClusterIP(UINT32 zoneId, const InetAddress& ipAddr)
 {
        struct __cluster_ip_data data;
        data.zoneId = zoneId;
@@ -1755,7 +1756,7 @@ static void DumpObjectCallback(NetObj *object, void *data)
        ConsolePrintf(pCtx, _T("Object ID %d \"%s\"\n")
                        _T("   Class: %s  Primary IP: %s  Status: %s  IsModified: %d  IsDeleted: %d\n"),
                                          object->getId(), object->getName(), (object->getObjectClass() < OBJECT_CUSTOM) ? g_szClassName[object->getObjectClass()] : _T("Custom"),
-                 IpToStr(object->IpAddr(), dd->buffer),
+                 object->getIpAddress().toString(dd->buffer),
                  GetStatusAsText(object->Status(), true),
                  object->isModified(), object->isDeleted());
    ConsolePrintf(pCtx, _T("   Parents: <%s>\n   Childs: <%s>\n"), 
@@ -1774,7 +1775,7 @@ static void DumpObjectCallback(NetObj *object, void *data)
                        ((Node *)object)->getObjectId());
          break;
       case OBJECT_SUBNET:
-         ConsolePrintf(pCtx, _T("   Network mask: %s\n"), IpToStr(((Subnet *)object)->getIpNetMask(), dd->buffer));
+         ConsolePrintf(pCtx, _T("   Network mask: %d\n"), object->getIpAddress().getMaskBits());
          break;
       case OBJECT_CONTAINER:
          pCat = FindContainerCategory(((Container *)object)->getCategory());
@@ -1920,14 +1921,14 @@ void NetObjDelete(NetObj *pObject)
 /**
  * Update interface index when IP address changes
  */
-void UpdateInterfaceIndex(UINT32 dwOldIpAddr, UINT32 dwNewIpAddr, Interface *iface)
+void UpdateInterfaceIndex(const InetAddress& oldIpAddr, const InetAddress& newIpAddr, Interface *iface)
 {
        if (IsZoningEnabled())
        {
                Zone *zone = (Zone *)g_idxZoneByGUID.get(iface->getZoneId());
                if (zone != NULL)
                {
-                       zone->updateInterfaceIndex(dwOldIpAddr, dwNewIpAddr, iface);
+                       zone->updateInterfaceIndex(oldIpAddr, newIpAddr, iface);
                }
                else
                {
@@ -1937,8 +1938,8 @@ void UpdateInterfaceIndex(UINT32 dwOldIpAddr, UINT32 dwNewIpAddr, Interface *ifa
        }
        else
        {
-               g_idxInterfaceByAddr.remove(dwOldIpAddr);
-               g_idxInterfaceByAddr.put(dwNewIpAddr, iface);
+               g_idxInterfaceByAddr.remove(oldIpAddr);
+               g_idxInterfaceByAddr.put(newIpAddr, iface);
        }
 }
 
index 5d8af1a..6fff9b5 100644 (file)
@@ -306,7 +306,7 @@ static void AddSNMPResult(Table *table, int column, SNMP_Variable *pVar, LONG nF
             break;
          case CFMT_IFINDEX:   // Column is an interface index, convert to interface name
             dwIndex = pVar->getValueAsUInt();
-            pInterface = pNode->findInterface(dwIndex, INADDR_ANY);
+            pInterface = pNode->findInterfaceByIndex(dwIndex);
             if (pInterface != NULL)
             {
                nx_strncpy(szBuffer, pInterface->getName(), 4096);
index 7e833ed..27ce7fb 100644 (file)
@@ -413,49 +413,48 @@ static THREAD_RESULT THREAD_CALL RoutePoller(void *arg)
  */
 static bool PollerQueueElementComparator(void *key, void *element)
 {
-       return CAST_FROM_POINTER(key, UINT32) == ((NEW_NODE *)element)->dwIpAddr;
+   return ((InetAddress *)key)->equals(((NEW_NODE *)element)->ipAddr);
 }
 
 /**
  * Check potential new node from ARP cache or routing table
  */
-static void CheckPotentialNode(Node *node, UINT32 ipAddr, UINT32 ifIndex, BYTE *macAddr = NULL)
+static void CheckPotentialNode(Node *node, const InetAddress& ipAddr, UINT32 ifIndex, BYTE *macAddr = NULL)
 {
-       TCHAR buffer[32];
+       TCHAR buffer[64];
 
-       DbgPrintf(6, _T("DiscoveryPoller(): checking potential node %s at %d"), IpToStr(ipAddr, buffer), ifIndex);
-       if ((ipAddr != 0) && (ipAddr != 0xFFFFFFFF) && ((ipAddr & 0xFF000000) != 0x7F000000) &&
+       DbgPrintf(6, _T("DiscoveryPoller(): checking potential node %s at %d"), ipAddr.toString(buffer), ifIndex);
+   if (ipAddr.isValid() && !ipAddr.isBroadcast() && !ipAddr.isLoopback() && !ipAddr.isMulticast() &&
            (FindNodeByIP(node->getZoneId(), ipAddr) == NULL) && !IsClusterIP(node->getZoneId(), ipAddr) && 
-                (g_nodePollerQueue.find(CAST_TO_POINTER(ipAddr, void *), PollerQueueElementComparator) == NULL))
+                (g_nodePollerQueue.find((void *)&ipAddr, PollerQueueElementComparator) == NULL))
    {
-      Interface *pInterface = node->findInterface(ifIndex, ipAddr);
-      if (pInterface != NULL)
+      Interface *pInterface = node->findInterfaceByIndex(ifIndex);
+      if ((pInterface != NULL) && pInterface->getIpAddress().sameSubnet(ipAddr))
                {
-                       DbgPrintf(6, _T("DiscoveryPoller(): interface found: %s [%d] addr=%s mask=%s ifIndex=%d"),
-                                 pInterface->getName(), pInterface->getId(), IpToStr(pInterface->IpAddr(), buffer),
-                                 IpToStr(pInterface->getIpNetMask(), &buffer[16]), pInterface->getIfIndex());
-         if ((ipAddr < 0xE0000000) && !IsBroadcastAddress(ipAddr, pInterface->getIpNetMask()))
+                       DbgPrintf(6, _T("DiscoveryPoller(): interface found: %s [%d] addr=%s/%d ifIndex=%d"),
+                                 pInterface->getName(), pInterface->getId(), pInterface->getIpAddress().toString(buffer),
+                                 pInterface->getIpAddress().getMaskBits(), pInterface->getIfIndex());
+         if (!ipAddr.isSubnetBroadcast(pInterface->getIpAddress().getMaskBits()))
          {
             NEW_NODE *pInfo;
-                               TCHAR buf1[16], buf2[16];
+                               TCHAR buffer[64];
 
             pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-            pInfo->dwIpAddr = ipAddr;
-            pInfo->dwNetMask = pInterface->getIpNetMask();
+            pInfo->ipAddr = ipAddr;
+            pInfo->ipAddr.setMaskBits(pInterface->getIpAddress().getMaskBits());
                                pInfo->zoneId = node->getZoneId();
                                pInfo->ignoreFilter = FALSE;
                                if (macAddr == NULL)
                                        memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
                                else
                                        memcpy(pInfo->bMacAddr, macAddr, MAC_ADDR_LENGTH);
-                               DbgPrintf(5, _T("DiscoveryPoller(): new node queued: %s/%s"),
-                                         IpToStr(pInfo->dwIpAddr, buf1), 
-                                         IpToStr(pInfo->dwNetMask, buf2));
+                               DbgPrintf(5, _T("DiscoveryPoller(): new node queued: %s/%d"),
+                                         pInfo->ipAddr.toString(buffer), pInfo->ipAddr.getMaskBits());
             g_nodePollerQueue.Put(pInfo);
          }
                        else
                        {
-                               DbgPrintf(6, _T("DiscoveryPoller(): potential node %s rejected - broadcast/multicast address"), IpToStr(ipAddr, buffer));
+            DbgPrintf(6, _T("DiscoveryPoller(): potential node %s rejected - broadcast/multicast address"), ipAddr.toString(buffer));
                        }
                }
                else
@@ -465,7 +464,7 @@ static void CheckPotentialNode(Node *node, UINT32 ipAddr, UINT32 ifIndex, BYTE *
    }
        else
        {
-               DbgPrintf(6, _T("DiscoveryPoller(): potential node %s rejected"), IpToStr(ipAddr, buffer));
+               DbgPrintf(6, _T("DiscoveryPoller(): potential node %s rejected"), ipAddr.toString(buffer));
        }
 }
 
@@ -479,8 +478,8 @@ static void CheckHostRoute(Node *node, ROUTE *route)
        Interface *iface;
 
        DbgPrintf(6, _T("DiscoveryPoller(): checking host route %s at %d"), IpToStr(route->dwDestAddr, buffer), route->dwIfIndex);
-       iface = node->findInterface(route->dwIfIndex, route->dwDestAddr);
-       if (iface != NULL)
+       iface = node->findInterfaceByIndex(route->dwIfIndex);
+       if ((iface != NULL) && iface->getIpAddress().sameSubnet(route->dwDestAddr))
        {
                CheckPotentialNode(node, route->dwDestAddr, route->dwIfIndex);
        }
@@ -496,7 +495,7 @@ static void CheckHostRoute(Node *node, ROUTE *route)
 static THREAD_RESULT THREAD_CALL DiscoveryPoller(void *arg)
 {
    Node *pNode;
-   TCHAR szBuffer[MAX_OBJECT_NAME + 64], szIpAddr[16];
+   TCHAR szBuffer[MAX_OBJECT_NAME + 64], szIpAddr[64];
    ARP_CACHE *pArpCache;
        ROUTING_TABLE *rt;
        UINT32 i;
@@ -527,7 +526,7 @@ static THREAD_RESULT THREAD_CALL DiscoveryPoller(void *arg)
       SetPollerState((long)arg, szBuffer);
 
       DbgPrintf(4, _T("Starting discovery poll for node %s (%s) in zone %d"),
-                         pNode->getName(), IpToStr(pNode->IpAddr(), szIpAddr), (int)pNode->getZoneId());
+                         pNode->getName(), pNode->getIpAddress().toString(szIpAddr), (int)pNode->getZoneId());
 
       // Retrieve and analize node's ARP cache
       pArpCache = pNode->getArpCache();
@@ -535,13 +534,13 @@ static THREAD_RESULT THREAD_CALL DiscoveryPoller(void *arg)
       {
          for(i = 0; i < pArpCache->dwNumEntries; i++)
                                if (memcmp(pArpCache->pEntries[i].bMacAddr, "\xFF\xFF\xFF\xFF\xFF\xFF", 6))     // Ignore broadcast addresses
-                                       CheckPotentialNode(pNode, pArpCache->pEntries[i].dwIpAddr, pArpCache->pEntries[i].dwIndex, pArpCache->pEntries[i].bMacAddr);
+                                       CheckPotentialNode(pNode, pArpCache->pEntries[i].ipAddr, pArpCache->pEntries[i].dwIndex, pArpCache->pEntries[i].bMacAddr);
          DestroyArpCache(pArpCache);
       }
 
                // Retrieve and analize node's routing table
       DbgPrintf(5, _T("Discovery poll for node %s (%s) - reading routing table"),
-                pNode->getName(), IpToStr(pNode->IpAddr(), szIpAddr));
+                pNode->getName(), pNode->getIpAddress().toString(szIpAddr));
                rt = pNode->getRoutingTable();
                if (rt != NULL)
                {
@@ -555,7 +554,7 @@ static THREAD_RESULT THREAD_CALL DiscoveryPoller(void *arg)
                }
 
       DbgPrintf(4, _T("Finished discovery poll for node %s (%s)"),
-                pNode->getName(), IpToStr(pNode->IpAddr(), szIpAddr));
+                pNode->getName(), pNode->getIpAddress().toString(szIpAddr));
       pNode->setDiscoveryPollTimeStamp();
       pNode->decRefCount();
    }
@@ -690,14 +689,14 @@ static void CheckRange(int nType, UINT32 dwAddr1, UINT32 dwAddr2)
             pSubnet = FindSubnetForNode(0, dwAddr);
             if (pSubnet != NULL)
             {
-               if ((pSubnet->IpAddr() != dwAddr) && 
-                   !IsBroadcastAddress(dwAddr, pSubnet->getIpNetMask()))
+               if (!pSubnet->getIpAddress().equals(dwAddr) && 
+                   !InetAddress(dwAddr).isSubnetBroadcast(pSubnet->getIpAddress().getMaskBits()))
                {
                   NEW_NODE *pInfo;
 
                   pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-                  pInfo->dwIpAddr = dwAddr;
-                  pInfo->dwNetMask = pSubnet->getIpNetMask();
+                  pInfo->ipAddr = dwAddr;
+                  pInfo->ipAddr.setMaskBits(pSubnet->getIpAddress().getMaskBits());
                                                pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
                                                pInfo->ignoreFilter = FALSE;
                                                memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
@@ -709,8 +708,7 @@ static void CheckRange(int nType, UINT32 dwAddr1, UINT32 dwAddr2)
                NEW_NODE *pInfo;
 
                pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-               pInfo->dwIpAddr = dwAddr;
-               pInfo->dwNetMask = 0;
+               pInfo->ipAddr = dwAddr;
                                        pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
                                        pInfo->ignoreFilter = FALSE;
                                        memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
index fe5bc5c..9acb1ec 100644 (file)
@@ -4383,8 +4383,9 @@ void ClientSession::createObject(NXCPMessage *pRequest)
    int iClass, iServiceType;
    TCHAR szObjectName[MAX_OBJECT_NAME], nodePrimaryName[MAX_DNS_NAME], deviceId[MAX_OBJECT_NAME];
    TCHAR *pszRequest, *pszResponse, *pszComments;
-   UINT32 dwIpAddr, zoneId, nodeId;
+   UINT32 zoneId, nodeId;
    WORD wIpProto, wIpPort;
+   InetAddress ipAddr;
    BOOL bParentAlwaysValid = FALSE;
 
    // Prepare response message
@@ -4401,16 +4402,16 @@ void ClientSession::createObject(NXCPMessage *pRequest)
                if (pRequest->isFieldExist(VID_PRIMARY_NAME))
                {
                        pRequest->getFieldAsString(VID_PRIMARY_NAME, nodePrimaryName, MAX_DNS_NAME);
-                       dwIpAddr = ntohl(ResolveHostName(nodePrimaryName));
+         ipAddr = InetAddress::resolveHostName(nodePrimaryName);
                }
                else
                {
-                       dwIpAddr = pRequest->getFieldAsUInt32(VID_IP_ADDRESS);
-                       IpToStr(dwIpAddr, nodePrimaryName);
+         ipAddr = pRequest->getFieldAsInetAddress(VID_IP_ADDRESS);
+         ipAddr.toString(nodePrimaryName);
                }
-      if ((pParent == NULL) && (dwIpAddr != 0))
+      if ((pParent == NULL) && ipAddr.isValidUnicast())
       {
-         pParent = FindSubnetForNode(zoneId, dwIpAddr);
+         pParent = FindSubnetForNode(zoneId, ipAddr);
          bParentAlwaysValid = TRUE;
       }
    }
@@ -4445,7 +4446,7 @@ void ClientSession::createObject(NXCPMessage *pRequest)
                       {
                               if (g_pModuleList[i].pfValidateObjectCreation != NULL)
                               {
-                        moduleRCC = g_pModuleList[i].pfValidateObjectCreation(iClass, szObjectName, dwIpAddr, zoneId, pRequest);
+                        moduleRCC = g_pModuleList[i].pfValidateObjectCreation(iClass, szObjectName, ipAddr, zoneId, pRequest);
                                       if (moduleRCC != RCC_SUCCESS)
                         {
                            DbgPrintf(4, _T("Creation of object \"%s\" of class %d blocked by module %s (RCC=%d)"), szObjectName, iClass, g_pModuleList[i].szName, moduleRCC);
@@ -4462,16 +4463,16 @@ void ClientSession::createObject(NXCPMessage *pRequest)
                                                   switch(iClass)
                                                   {
                                                           case OBJECT_NODE:
-                                                                  object = PollNewNode(dwIpAddr,
-                                                                                                                           pRequest->getFieldAsUInt32(VID_IP_NETMASK),
-                                                                                                                           pRequest->getFieldAsUInt32(VID_CREATION_FLAGS),
-                                                                                                                           pRequest->getFieldAsUInt16(VID_AGENT_PORT),
-                                                                                                                           pRequest->getFieldAsUInt16(VID_SNMP_PORT),
-                                                                                                                           szObjectName,
-                                                                                                                           pRequest->getFieldAsUInt32(VID_AGENT_PROXY),
-                                                                                                                           pRequest->getFieldAsUInt32(VID_SNMP_PROXY),
-                                                                                                                           (pParent != NULL) ? ((pParent->getObjectClass() == OBJECT_CLUSTER) ? (Cluster *)pParent : NULL) : NULL,
-                                                                                                                           zoneId, false, false);
+                           ipAddr.setMaskBits(pRequest->getFieldAsInt32(VID_IP_NETMASK));
+                                                                  object = PollNewNode(ipAddr,
+                                                                                                                          pRequest->getFieldAsUInt32(VID_CREATION_FLAGS),
+                                                                                                                          pRequest->getFieldAsUInt16(VID_AGENT_PORT),
+                                                                                                                          pRequest->getFieldAsUInt16(VID_SNMP_PORT),
+                                                                                                                          szObjectName,
+                                                                                                                          pRequest->getFieldAsUInt32(VID_AGENT_PROXY),
+                                                                                                                          pRequest->getFieldAsUInt32(VID_SNMP_PROXY),
+                                                                                                                          (pParent != NULL) ? ((pParent->getObjectClass() == OBJECT_CLUSTER) ? (Cluster *)pParent : NULL) : NULL,
+                                                                                                                          zoneId, false, false);
                                                                   if (object != NULL)
                                                                   {
                                                                           ((Node *)object)->setPrimaryName(nodePrimaryName);
@@ -6987,8 +6988,8 @@ void ClientSession::changeObjectZone(NXCPMessage *pRequest)
                                if (zone != NULL)
                                {
                                        // Check if target zone already have object with same primary IP
-                                       if ((FindNodeByIP(zoneId, node->IpAddr()) == NULL) &&
-                                                (FindSubnetByIP(zoneId, node->IpAddr()) == NULL))
+                                       if ((FindNodeByIP(zoneId, node->getIpAddress()) == NULL) &&
+                                                (FindSubnetByIP(zoneId, node->getIpAddress()) == NULL))
                                        {
                                                node->changeZone(zoneId);
                                                msg.setField(VID_RCC, RCC_SUCCESS);
@@ -10698,8 +10699,7 @@ void ClientSession::registerAgent(NXCPMessage *pRequest)
                                NEW_NODE *info;
 
                                info = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-                               info->dwIpAddr = ntohl(((struct sockaddr_in *)m_clientAddr)->sin_addr.s_addr);
-                               info->dwNetMask = 0;
+            info->ipAddr = InetAddress::createFromSockaddr(m_clientAddr);
                                info->zoneId = 0;       // Add to default zone
                                info->ignoreFilter = TRUE;              // Ignore discovery filters and add node anyway
                                g_nodePollerQueue.Put(info);
@@ -11588,7 +11588,7 @@ void ClientSession::findMacAddress(NXCPMessage *request)
              msg.setField(VID_LOCAL_NODE_ID, localNodeId);
                   msg.setField(VID_LOCAL_INTERFACE_ID, localIfId);
                   msg.setField(VID_MAC_ADDR, macAddr, MAC_ADDR_LENGTH);
-                  msg.setField(VID_IP_ADDRESS, (localIf != NULL) ? localIf->IpAddr() : (UINT32)0);
+                  msg.setField(VID_IP_ADDRESS, (localIf != NULL) ? localIf->getIpAddress() : InetAddress());
                   msg.setField(VID_CONNECTION_TYPE, (UINT16)type);
          if (cp->getObjectClass() == OBJECT_INTERFACE)
             debugPrintf(5, _T("findMacAddress: nodeId=%d ifId=%d ifName=%s ifIndex=%d"), node->getId(), cp->getId(), cp->getName(), ((Interface *)cp)->getIfIndex());
@@ -13537,7 +13537,7 @@ void ClientSession::getRoutingTable(NXCPMessage *request)
                msg.setField(id++, rt->pRoutes[i].dwNextHop);
                msg.setField(id++, rt->pRoutes[i].dwIfIndex);
                msg.setField(id++, rt->pRoutes[i].dwRouteType);
-               Interface *iface = node->findInterface(rt->pRoutes[i].dwIfIndex, INADDR_ANY);
+               Interface *iface = node->findInterfaceByIndex(rt->pRoutes[i].dwIfIndex);
                if (iface != NULL)
                {
                   msg.setField(id++, iface->getName());
index c1f4a1c..191198a 100644 (file)
@@ -46,7 +46,7 @@ static UINT32 HandlerArp(UINT32 dwVersion, SNMP_Variable *pVar, SNMP_Transport *
       ((ARP_CACHE *)pArg)->dwNumEntries++;
       ((ARP_CACHE *)pArg)->pEntries = (ARP_ENTRY *)realloc(((ARP_CACHE *)pArg)->pEntries,
                sizeof(ARP_ENTRY) * ((ARP_CACHE *)pArg)->dwNumEntries);
-      ((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].dwIpAddr = ntohl(pVar->getValueAsUInt());
+      ((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].ipAddr = ntohl(pVar->getValueAsUInt());
       memcpy(((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].bMacAddr, bMac, 6);
       ((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].dwIndex = dwIndex;
    }
index 6e6eb6a..98ad016 100644 (file)
@@ -244,18 +244,17 @@ static void BroadcastNewTrap(ClientSession *pSession, void *pArg)
 /**
  * Process trap
  */
-void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq)
+void ProcessTrap(SNMP_PDU *pdu, const InetAddress& srcAddr, int srcPort, SNMP_Transport *pTransport, SNMP_Engine *localEngine, bool isInformRq)
 {
-   UINT32 dwOriginAddr, dwBufPos, dwBufSize, dwMatchLen, dwMatchIdx;
+   UINT32 dwBufPos, dwBufSize, dwMatchLen, dwMatchIdx;
    TCHAR *pszTrapArgs, szBuffer[4096];
    SNMP_Variable *pVar;
    Node *pNode;
        BOOL processed = FALSE;
    int iResult;
 
-   dwOriginAddr = ntohl(pOrigin->sin_addr.s_addr);
    DbgPrintf(4, _T("Received SNMP %s %s from %s"), isInformRq ? _T("INFORM-REQUEST") : _T("TRAP"),
-             pdu->getTrapId()->getValueAsText(), IpToStr(dwOriginAddr, szBuffer));
+             pdu->getTrapId()->getValueAsText(), srcAddr.toString(szBuffer));
        if (isInformRq)
        {
                SNMP_PDU *response = new SNMP_PDU(SNMP_RESPONSE, pdu->getRequestId(), pdu->getVersion());
@@ -270,7 +269,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
        }
 
    // Match IP address to object
-   pNode = FindNodeByIP(0, dwOriginAddr);
+   pNode = FindNodeByIP(0, srcAddr);
 
    // Write trap to log if required
    if (m_bLogAllTraps || (pNode != NULL))
@@ -297,7 +296,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
       _sntprintf(szQuery, 8192, _T("INSERT INTO snmp_trap_log (trap_id,trap_timestamp,")
                                 _T("ip_addr,object_id,trap_oid,trap_varlist) VALUES ")
                                 _T("(") INT64_FMT _T(",%d,'%s',%d,'%s',%s)"),
-                 m_qnTrapId, dwTimeStamp, IpToStr(dwOriginAddr, szBuffer),
+                 m_qnTrapId, dwTimeStamp, srcAddr.toString(szBuffer),
                  (pNode != NULL) ? pNode->getId() : (UINT32)0, pdu->getTrapId()->getValueAsText(),
                  (const TCHAR *)DBPrepareString(g_hCoreDB, pszTrapArgs));
       QueueSQLRequest(szQuery);
@@ -308,7 +307,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
       msg.setField(VID_RECORDS_ORDER, (WORD)RECORD_ORDER_NORMAL);
       msg.setField(VID_TRAP_LOG_MSG_BASE, (QWORD)m_qnTrapId);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 1, dwTimeStamp);
-      msg.setField(VID_TRAP_LOG_MSG_BASE + 2, dwOriginAddr);
+      msg.setField(VID_TRAP_LOG_MSG_BASE + 2, srcAddr);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 3, (pNode != NULL) ? pNode->getId() : (UINT32)0);
       msg.setField(VID_TRAP_LOG_MSG_BASE + 4, (TCHAR *)pdu->getTrapId()->getValueAsText());
       msg.setField(VID_TRAP_LOG_MSG_BASE + 5, pszTrapArgs);
@@ -370,7 +369,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
 
          if (dwMatchLen > 0)
          {
-            GenerateTrapEvent(pNode->getId(), dwMatchIdx, pdu, (int)ntohs(pOrigin->sin_port));
+            GenerateTrapEvent(pNode->getId(), dwMatchIdx, pdu, srcPort);
          }
          else     // Process unmatched traps
          {
@@ -394,7 +393,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
                // Generate default event for unmatched traps
                const TCHAR *names[3] = { _T("oid"), NULL, _T("sourcePort") };
                PostEventWithNames(EVENT_SNMP_UNMATCHED_TRAP, pNode->getId(), "ssd", names,
-                  pdu->getTrapId()->getValueAsText(), pszTrapArgs, (int)ntohs(pOrigin->sin_port));
+                  pdu->getTrapId()->getValueAsText(), pszTrapArgs, srcPort);
                free(pszTrapArgs);
             }
          }
@@ -407,17 +406,17 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
    }
    else if (g_flags & AF_SNMP_TRAP_DISCOVERY)  // unknown node, discovery enabled
    {
-      DbgPrintf(4, _T("ProcessTrap: trap not matched to node, adding new IP address %s for discovery"), IpToStr(dwOriginAddr, szBuffer));
-      Subnet *subnet = FindSubnetForNode(0, dwOriginAddr);
+      DbgPrintf(4, _T("ProcessTrap: trap not matched to node, adding new IP address %s for discovery"), srcAddr.toString(szBuffer));
+      Subnet *subnet = FindSubnetForNode(0, srcAddr);
       if (subnet != NULL)
       {
-         if ((subnet->IpAddr() != dwOriginAddr) && !IsBroadcastAddress(dwOriginAddr, subnet->getIpNetMask()))
+         if (!subnet->getIpAddress().equals(srcAddr) && !srcAddr.isSubnetBroadcast(subnet->getIpAddress().getMaskBits()))
          {
             NEW_NODE *pInfo;
 
             pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-            pInfo->dwIpAddr = dwOriginAddr;
-            pInfo->dwNetMask = subnet->getIpNetMask();
+            pInfo->ipAddr = srcAddr;
+            pInfo->ipAddr.setMaskBits(subnet->getIpAddress().getMaskBits());
                                pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
                                pInfo->ignoreFilter = FALSE;
                                memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
@@ -429,8 +428,7 @@ void ProcessTrap(SNMP_PDU *pdu, struct sockaddr_in *pOrigin, SNMP_Transport *pTr
          NEW_NODE *pInfo;
 
          pInfo = (NEW_NODE *)malloc(sizeof(NEW_NODE));
-         pInfo->dwIpAddr = dwOriginAddr;
-         pInfo->dwNetMask = 0;
+         pInfo->ipAddr = srcAddr;
                        pInfo->zoneId = 0;      /* FIXME: add correct zone ID */
                        pInfo->ignoreFilter = FALSE;
                        memset(pInfo->bMacAddr, 0, MAC_ADDR_LENGTH);
@@ -461,17 +459,13 @@ static SNMP_SecurityContext *ContextFinder(struct sockaddr *addr, socklen_t addr
  */
 THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg)
 {
-   SOCKET hSocket;
-   struct sockaddr_in addr;
-   int iBytes;
-   socklen_t nAddrLen;
    SNMP_UDPTransport *pTransport;
    SNMP_PDU *pdu;
 
        static BYTE engineId[] = { 0x80, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00 };
        SNMP_Engine localEngine(engineId, 12);
 
-   hSocket = socket(AF_INET, SOCK_DGRAM, 0);
+   SOCKET hSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (hSocket == INVALID_SOCKET)
    {
       nxlog_write(MSG_SOCKET_FAILED, EVENTLOG_ERROR_TYPE, "s", "SNMPTrapReceiver");
@@ -482,19 +476,20 @@ THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg)
        SetSocketReuseFlag(hSocket);
 
    // Fill in local address structure
-   memset(&addr, 0, sizeof(struct sockaddr_in));
-   addr.sin_family = AF_INET;
-   addr.sin_addr.s_addr = ResolveHostName(g_szListenAddress);
-   addr.sin_port = htons(m_wTrapPort);
+   struct sockaddr_in servAddr;
+   memset(&servAddr, 0, sizeof(struct sockaddr_in));
+   servAddr.sin_family = AF_INET;
+   servAddr.sin_addr.s_addr = ResolveHostName(g_szListenAddress);
+   servAddr.sin_port = htons(m_wTrapPort);
 
    // Bind socket
-   if (bind(hSocket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
+   if (bind(hSocket, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) != 0)
    {
       nxlog_write(MSG_BIND_ERROR, EVENTLOG_ERROR_TYPE, "dse", m_wTrapPort, _T("SNMPTrapReceiver"), WSAGetLastError());
       closesocket(hSocket);
       return THREAD_OK;
    }
-       nxlog_write(MSG_LISTENING_FOR_SNMP, EVENTLOG_INFORMATION_TYPE, "ad", ntohl(addr.sin_addr.s_addr), m_wTrapPort);
+       nxlog_write(MSG_LISTENING_FOR_SNMP, EVENTLOG_INFORMATION_TYPE, "ad", ntohl(servAddr.sin_addr.s_addr), m_wTrapPort);
 
    pTransport = new SNMP_UDPTransport(hSocket);
        pTransport->enableEngineIdAutoupdate(true);
@@ -504,9 +499,10 @@ THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg)
    // Wait for packets
    while(!IsShutdownInProgress())
    {
-      nAddrLen = sizeof(struct sockaddr_in);
-      iBytes = pTransport->readMessage(&pdu, 2000, (struct sockaddr *)&addr, &nAddrLen, ContextFinder);
-      if ((iBytes > 0) && (pdu != NULL))
+      struct sockaddr_in addr;
+      socklen_t addrLen = sizeof(struct sockaddr_in);
+      int bytes = pTransport->readMessage(&pdu, 2000, (struct sockaddr *)&addr, &addrLen, ContextFinder);
+      if ((bytes > 0) && (pdu != NULL))
       {
                        DbgPrintf(6, _T("SNMPTrapReceiver: received PDU of type %d"), pdu->getCommand());
                        if ((pdu->getCommand() == SNMP_TRAP) || (pdu->getCommand() == SNMP_INFORM_REQUEST))
@@ -516,7 +512,7 @@ THREAD_RESULT THREAD_CALL SNMPTrapReceiver(void *pArg)
                                        SNMP_SecurityContext *context = pTransport->getSecurityContext();
                                        context->setAuthoritativeEngine(localEngine);
                                }
-            ProcessTrap(pdu, &addr, pTransport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
+            ProcessTrap(pdu, InetAddress::createFromSockaddr((struct sockaddr *)&addr), ntohs(addr.sin_port), pTransport, &localEngine, pdu->getCommand() == SNMP_INFORM_REQUEST);
                        }
                        else if ((pdu->getVersion() == SNMP_VERSION_3) && (pdu->getCommand() == SNMP_GET_REQUEST) && (pdu->getAuthoritativeEngine().getIdLen() == 0))
                        {
index 0344030..0f75242 100644 (file)
@@ -26,7 +26,6 @@
  */
 Subnet::Subnet() : NetObj()
 {
-   m_dwIpNetMask = 0;
    m_zoneId = 0;
        m_bSyntheticMask = false;
 }
@@ -34,13 +33,11 @@ Subnet::Subnet() : NetObj()
 /**
  * Subnet class constructor
  */
-Subnet::Subnet(UINT32 dwAddr, UINT32 dwNetMask, UINT32 dwZone, bool bSyntheticMask) : NetObj()
+Subnet::Subnet(const InetAddress& addr, UINT32 dwZone, bool bSyntheticMask) : NetObj()
 {
-   TCHAR szBuffer[32];
-
-   m_dwIpAddr = dwAddr;
-   m_dwIpNetMask = dwNetMask;
-   _sntprintf(m_name, MAX_OBJECT_NAME, _T("%s/%d"), IpToStr(dwAddr, szBuffer), BitsInMask(dwNetMask));
+   TCHAR szBuffer[64];
+   _sntprintf(m_name, MAX_OBJECT_NAME, _T("%s/%d"), addr.toString(szBuffer), addr.getMaskBits());
+   m_ipAddress = addr;
    m_zoneId = dwZone;
        m_bSyntheticMask = bSyntheticMask;
 }
@@ -76,8 +73,8 @@ BOOL Subnet::loadFromDatabase(UINT32 dwId)
       return FALSE;
    }
 
-   m_dwIpAddr = DBGetFieldIPAddr(hResult, 0, 0);
-   m_dwIpNetMask = DBGetFieldIPAddr(hResult, 0, 1);
+   m_ipAddress = DBGetFieldInetAddr(hResult, 0, 0);
+   m_ipAddress.setMaskBits(DBGetFieldLong(hResult, 0, 1));
    m_zoneId = DBGetFieldULong(hResult, 0, 2);
        m_bSyntheticMask = DBGetFieldLong(hResult, 0, 3) ? true : false;
 
@@ -94,37 +91,23 @@ BOOL Subnet::loadFromDatabase(UINT32 dwId)
  */
 BOOL Subnet::saveToDatabase(DB_HANDLE hdb)
 {
-   TCHAR szQuery[1024], szIpAddr[16], szNetMask[16];
-   DB_RESULT hResult;
+   TCHAR szQuery[1024], szIpAddr[64];
    UINT32 i;
-   BOOL bNewObject = TRUE;
 
    // Lock object's access
    lockProperties();
 
    saveCommonProperties(hdb);
 
-   // Check for object's existence in database
-   _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM subnets WHERE id=%d"), m_id);
-   hResult = DBSelect(hdb, szQuery);
-   if (hResult != 0)
-   {
-      if (DBGetNumRows(hResult) > 0)
-         bNewObject = FALSE;
-      DBFreeResult(hResult);
-   }
-
    // Form and execute INSERT or UPDATE query
-   if (bNewObject)
+   if (IsDatabaseRecordExist(hdb, _T("subnets"), _T("id"), m_id))
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
-                          _T("INSERT INTO subnets (id,ip_addr,ip_netmask,zone_guid,synthetic_mask) VALUES (%d,'%s','%s',%d,%d)"),
-                 m_id, IpToStr(m_dwIpAddr, szIpAddr),
-                                         IpToStr(m_dwIpNetMask, szNetMask), m_zoneId, m_bSyntheticMask ? 1 : 0);
+                          _T("UPDATE subnets SET ip_addr='%s',ip_netmask=%d,zone_guid=%d,synthetic_mask=%d WHERE id=%d"),
+                 m_ipAddress.toString(szIpAddr), m_ipAddress.getMaskBits(), m_zoneId, m_bSyntheticMask ? 1 : 0, m_id);
    else
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
-                          _T("UPDATE subnets SET ip_addr='%s',ip_netmask='%s',zone_guid=%d,synthetic_mask=%d WHERE id=%d"),
-                 IpToStr(m_dwIpAddr, szIpAddr),
-                                         IpToStr(m_dwIpNetMask, szNetMask), m_zoneId, m_bSyntheticMask ? 1 : 0, m_id);
+                          _T("INSERT INTO subnets (id,ip_addr,ip_netmask,zone_guid,synthetic_mask) VALUES (%d,'%s',%d,%d,%d)"),
+                 m_id, m_ipAddress.toString(szIpAddr), m_ipAddress.getMaskBits(), m_zoneId, m_bSyntheticMask ? 1 : 0);
    DBQuery(hdb, szQuery);
 
    // Update node to subnet mapping
@@ -167,7 +150,6 @@ bool Subnet::deleteFromDatabase(DB_HANDLE hdb)
 void Subnet::fillMessage(NXCPMessage *pMsg)
 {
    NetObj::fillMessage(pMsg);
-   pMsg->setField(VID_IP_NETMASK, m_dwIpNetMask);
    pMsg->setField(VID_ZONE_ID, m_zoneId);
        pMsg->setField(VID_SYNTHETIC_MASK, (WORD)(m_bSyntheticMask ? 1 : 0));
 }
@@ -175,34 +157,32 @@ void Subnet::fillMessage(NXCPMessage *pMsg)
 /**
  * Set correct netmask for subnet
  */
-void Subnet::setCorrectMask(UINT32 dwAddr, UINT32 dwMask)
+void Subnet::setCorrectMask(const InetAddress& addr)
 {
-       TCHAR szName[MAX_OBJECT_NAME], szBuffer[32];
+       TCHAR szName[MAX_OBJECT_NAME], szBuffer[64];
 
        lockProperties();
 
        // Check if name is default
-       _sntprintf(szName, MAX_OBJECT_NAME, _T("%s/%d"), IpToStr(m_dwIpAddr, szBuffer), BitsInMask(m_dwIpNetMask));
+       _sntprintf(szName, MAX_OBJECT_NAME, _T("%s/%d"), m_ipAddress.toString(szBuffer), m_ipAddress.getMaskBits());
        if (!_tcsicmp(szName, m_name))
        {
                // Change name
-               _sntprintf(m_name, MAX_OBJECT_NAME, _T("%s/%d"), IpToStr(dwAddr, szBuffer), BitsInMask(dwMask));
+      _sntprintf(m_name, MAX_OBJECT_NAME, _T("%s/%d"), addr.toString(szBuffer), addr.getMaskBits());
        }
 
-       bool shouldReaddNode = m_dwIpAddr != dwAddr;
-
-   if(shouldReaddNode)
+       bool reAdd = !m_ipAddress.equals(addr);
+   if (reAdd)
    {
-      g_idxSubnetByAddr.remove(m_dwIpAddr);
+      g_idxSubnetByAddr.remove(m_ipAddress);
    }
 
-       m_dwIpAddr = dwAddr;
-       m_dwIpNetMask = dwMask;
+       m_ipAddress = addr;
        m_bSyntheticMask = false;
 
-       if(shouldReaddNode)
+       if (reAdd)
    {
-      g_idxSubnetByAddr.put(m_dwIpAddr, this);
+      g_idxSubnetByAddr.put(m_ipAddress, this);
    }
        setModified();
        unlockProperties();
@@ -216,7 +196,7 @@ void Subnet::setCorrectMask(UINT32 dwAddr, UINT32 dwMask)
  * @param macAddr buffer for found MAC address
  * @return true if MAC address found
  */
-bool Subnet::findMacAddress(UINT32 ipAddr, BYTE *macAddr)
+bool Subnet::findMacAddress(const InetAddress& ipAddr, BYTE *macAddr)
 {
        bool success = false;
 
@@ -235,7 +215,7 @@ bool Subnet::findMacAddress(UINT32 ipAddr, BYTE *macAddr)
 
                for(UINT32 j = 0; j < arpCache->dwNumEntries; j++)
                {
-                       if (arpCache->pEntries[j].dwIpAddr == ipAddr)
+                       if (arpCache->pEntries[j].ipAddr.equals(ipAddr))
                        {
                                memcpy(macAddr, arpCache->pEntries[j].bMacAddr, MAC_ADDR_LENGTH);
                                success = true;
@@ -290,14 +270,14 @@ bool Subnet::showThresholdSummary()
  */
 UINT32 *Subnet::buildAddressMap(int *length)
 {
-   *length = 1 << (32 - BitsInMask(m_dwIpNetMask));
+   *length = 1 << (32 - m_ipAddress.getMaskBits());
    if ((*length < 2) || (*length > 65536))
       return NULL;
    UINT32 *map = (UINT32 *)malloc(*length * sizeof(UINT32));
 
    map[0] = 0xFFFFFFFF; // subnet
    map[*length - 1] = 0xFFFFFFFF;   // broadcast
-   UINT32 addr = m_dwIpAddr + 1;
+   UINT32 addr = m_ipAddress.getAddressV4() + 1;
    for(int i = 1; i < *length - 1; i++, addr++)
    {
       Node *node = FindNodeByIP(m_zoneId, addr);
@@ -312,6 +292,6 @@ UINT32 *Subnet::buildAddressMap(int *length)
  */
 void Subnet::prepareForDeletion()
 {
-   PostEvent(EVENT_SUBNET_DELETED, g_dwMgmtNode, "isaa", m_id, m_name, m_dwIpAddr, m_dwIpNetMask);
+   PostEvent(EVENT_SUBNET_DELETED, g_dwMgmtNode, "isAd", m_id, m_name, &m_ipAddress, m_ipAddress.getMaskBits());
    NetObj::prepareForDeletion();
 }
index 8685377..d3f25df 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * Network path constructor
  */
-NetworkPath::NetworkPath(UINT32 srcAddr)
+NetworkPath::NetworkPath(const InetAddress& srcAddr)
 {
    m_sourceAddress = srcAddr;
        m_hopCount = 0;
@@ -47,7 +47,7 @@ NetworkPath::~NetworkPath()
 /**
  * Add hop to path
  */
-void NetworkPath::addHop(UINT32 nextHop, NetObj *currentObject, UINT32 ifIndex, bool isVpn, const TCHAR *name)
+void NetworkPath::addHop(const InetAddress& nextHop, NetObj *currentObject, UINT32 ifIndex, bool isVpn, const TCHAR *name)
 {
        if (m_hopCount == m_allocated)
        {
@@ -87,9 +87,10 @@ void NetworkPath::fillMessage(NXCPMessage *msg)
  */
 NetworkPath *TraceRoute(Node *pSrc, Node *pDest)
 {
-   UINT32 srcAddr, srcIfIndex;
-   if (!pSrc->getOutwardInterface(pDest->IpAddr(), &srcAddr, &srcIfIndex))
-      srcAddr = pSrc->IpAddr();
+   UINT32 srcIfIndex;
+   InetAddress srcAddr;
+   if (!pSrc->getOutwardInterface(pDest->getIpAddress(), &srcAddr, &srcIfIndex))
+      srcAddr = pSrc->getIpAddress();
 
    NetworkPath *path = new NetworkPath(srcAddr);
 
@@ -97,14 +98,15 @@ NetworkPath *TraceRoute(Node *pSrc, Node *pDest)
    Node *pCurr, *pNext;
    for(pCurr = pSrc; (pCurr != pDest) && (pCurr != NULL) && (hopCount < 30); pCurr = pNext, hopCount++)
    {
-      UINT32 dwNextHop, dwIfIndex;
+      UINT32 dwIfIndex;
+      InetAddress nextHop;
       bool isVpn;
       TCHAR name[MAX_OBJECT_NAME];
-      if (pCurr->getNextHop(srcAddr, pDest->IpAddr(), &dwNextHop, &dwIfIndex, &isVpn, name))
+      if (pCurr->getNextHop(srcAddr, pDest->getIpAddress(), &nextHop, &dwIfIndex, &isVpn, name))
       {
-                       pNext = FindNodeByIP(pSrc->getZoneId(), dwNextHop);
-                       path->addHop(dwNextHop, pCurr, dwIfIndex, isVpn, name);
-         if ((pNext == pCurr) || (dwNextHop == 0))
+                       pNext = FindNodeByIP(pSrc->getZoneId(), nextHop);
+                       path->addHop(nextHop, pCurr, dwIfIndex, isVpn, name);
+         if ((pNext == pCurr) || !nextHop.isValid())
             pNext = NULL;     // Directly connected subnet or too many hops, stop trace
       }
       else
@@ -114,7 +116,7 @@ NetworkPath *TraceRoute(Node *pSrc, Node *pDest)
    }
        if (pCurr == pDest)
        {
-               path->addHop(0, pCurr, 0, false, _T(""));
+      path->addHop(InetAddress(), pCurr, 0, false, _T(""));
                path->setComplete();
        }
 
index ba97fb1..b3ea54e 100644 (file)
 VPNConnector::VPNConnector() : NetObj()
 {
    m_dwPeerGateway = 0;
-   m_dwNumLocalNets = 0;
-   m_dwNumRemoteNets = 0;
-   m_pLocalNetList = NULL;
-   m_pRemoteNetList = NULL;
+   m_localNetworks = new ObjectArray<InetAddress>(8, 8, true);
+   m_remoteNetworks = new ObjectArray<InetAddress>(8, 8, true);
 }
 
 /**
@@ -40,10 +38,8 @@ VPNConnector::VPNConnector() : NetObj()
 VPNConnector::VPNConnector(bool hidden) : NetObj()
 {
    m_dwPeerGateway = 0;
-   m_dwNumLocalNets = 0;
-   m_dwNumRemoteNets = 0;
-   m_pLocalNetList = NULL;
-   m_pRemoteNetList = NULL;
+   m_localNetworks = new ObjectArray<InetAddress>(8, 8, true);
+   m_remoteNetworks = new ObjectArray<InetAddress>(8, 8, true);
    m_isHidden = hidden;
 }
 
@@ -52,8 +48,8 @@ VPNConnector::VPNConnector(bool hidden) : NetObj()
  */
 VPNConnector::~VPNConnector()
 {
-   safe_free(m_pLocalNetList);
-   safe_free(m_pRemoteNetList);
+   delete m_localNetworks;
+   delete m_remoteNetworks;
 }
 
 /**
@@ -61,41 +57,26 @@ VPNConnector::~VPNConnector()
  */
 BOOL VPNConnector::loadFromDatabase(UINT32 dwId)
 {
-   TCHAR szQuery[256];
-   DB_RESULT hResult;
-   UINT32 i, dwNodeId;
-   NetObj *pObject;
-   BOOL bResult = FALSE;
-
    m_id = dwId;
 
    if (!loadCommonProperties())
       return FALSE;
 
    // Load network lists
-   _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask FROM vpn_connector_networks WHERE vpn_id=%d AND network_type=0"), m_id);
-   hResult = DBSelect(g_hCoreDB, szQuery);
-   if (hResult == NULL)
-      return FALSE;     // Query failed
-   m_dwNumLocalNets = DBGetNumRows(hResult);
-   m_pLocalNetList = (IP_NETWORK *)malloc(sizeof(IP_NETWORK) * m_dwNumLocalNets);
-   for(i = 0; i < m_dwNumLocalNets; i++)
-   {
-      m_pLocalNetList[i].dwAddr = DBGetFieldIPAddr(hResult, i, 0);
-      m_pLocalNetList[i].dwMask = DBGetFieldIPAddr(hResult, i, 1);
-   }
-   DBFreeResult(hResult);
-
-   _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask FROM vpn_connector_networks WHERE vpn_id=%d AND network_type=1"), m_id);
-   hResult = DBSelect(g_hCoreDB, szQuery);
+   TCHAR szQuery[256];
+   _sntprintf(szQuery, 256, _T("SELECT ip_addr,ip_netmask,network_type FROM vpn_connector_networks WHERE vpn_id=%d"), m_id);
+   DB_RESULT hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult == NULL)
       return FALSE;     // Query failed
-   m_dwNumRemoteNets = DBGetNumRows(hResult);
-   m_pRemoteNetList = (IP_NETWORK *)malloc(sizeof(IP_NETWORK) * m_dwNumRemoteNets);
-   for(i = 0; i < m_dwNumRemoteNets; i++)
+   int count = DBGetNumRows(hResult);
+   for(int i = 0; i < count; i++)
    {
-      m_pRemoteNetList[i].dwAddr = DBGetFieldIPAddr(hResult, i, 0);
-      m_pRemoteNetList[i].dwMask = DBGetFieldIPAddr(hResult, i, 1);
+      InetAddress addr = DBGetFieldInetAddr(hResult, i, 0);
+      addr.setMaskBits(DBGetFieldLong(hResult, i, 1));
+      if (DBGetFieldLong(hResult, i, 2) == 0)
+         m_localNetworks->add(new InetAddress(addr));
+      else
+         m_remoteNetworks->add(new InetAddress(addr));
    }
    DBFreeResult(hResult);
    
@@ -105,15 +86,16 @@ BOOL VPNConnector::loadFromDatabase(UINT32 dwId)
    if (hResult == NULL)
       return FALSE;     // Query failed
 
+   BOOL success = FALSE;
    if (DBGetNumRows(hResult) != 0)
    {
-      dwNodeId = DBGetFieldULong(hResult, 0, 0);
+      UINT32 dwNodeId = DBGetFieldULong(hResult, 0, 0);
       m_dwPeerGateway = DBGetFieldULong(hResult, 0, 1);
 
       // Link VPN connector to node
       if (!m_isDeleted)
       {
-         pObject = FindObjectById(dwNodeId);
+         NetObj *pObject = FindObjectById(dwNodeId);
          if (pObject == NULL)
          {
             nxlog_write(MSG_INVALID_NODE_ID_EX, NXLOG_ERROR, "dds", dwId, dwNodeId, _T("VPN connector"));
@@ -126,12 +108,12 @@ BOOL VPNConnector::loadFromDatabase(UINT32 dwId)
          {
             pObject->AddChild(this);
             AddParent(pObject);
-            bResult = TRUE;
+            success = TRUE;
          }
       }
       else
       {
-         bResult = TRUE;
+         success = TRUE;
       }
    }
 
@@ -140,7 +122,7 @@ BOOL VPNConnector::loadFromDatabase(UINT32 dwId)
    // Load access list
    loadACLFromDB();
 
-   return bResult;
+   return success;
 }
 
 /**
@@ -148,60 +130,45 @@ BOOL VPNConnector::loadFromDatabase(UINT32 dwId)
  */
 BOOL VPNConnector::saveToDatabase(DB_HANDLE hdb)
 {
-   TCHAR szQuery[1024], szIpAddr[16], szNetMask[16];
-   BOOL bNewObject = TRUE;
-   Node *pNode;
-   UINT32 i, dwNodeId;
-   DB_RESULT hResult;
-
    // Lock object's access
    lockProperties();
 
    saveCommonProperties(hdb);
 
-   // Check for object's existence in database
-   _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("SELECT id FROM vpn_connectors WHERE id=%d"), m_id);
-   hResult = DBSelect(hdb, szQuery);
-   if (hResult != 0)
-   {
-      if (DBGetNumRows(hResult) > 0)
-         bNewObject = FALSE;
-      DBFreeResult(hResult);
-   }
-
    // Determine owning node's ID
-   pNode = getParentNode();
-   if (pNode != NULL)
-      dwNodeId = pNode->getId();
-   else
-      dwNodeId = 0;
+   Node *pNode = getParentNode();
+   UINT32 dwNodeId = (pNode != NULL) ? pNode->getId() : 0;
 
    // Form and execute INSERT or UPDATE query
-   if (bNewObject)
-      _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO vpn_connectors (id,node_id,peer_gateway) VALUES (%d,%d,%d)"),
-              m_id, dwNodeId, m_dwPeerGateway);
-   else
+   TCHAR szQuery[1024];
+   if (IsDatabaseRecordExist(hdb, _T("vpn_connectors"), _T("id"), m_id))
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("UPDATE vpn_connectors SET node_id=%d,peer_gateway=%d WHERE id=%d"),
               dwNodeId, m_dwPeerGateway, m_id);
+   else
+      _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("INSERT INTO vpn_connectors (id,node_id,peer_gateway) VALUES (%d,%d,%d)"),
+              m_id, dwNodeId, m_dwPeerGateway);
    DBQuery(hdb, szQuery);
 
    // Save network list
    _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), _T("DELETE FROM vpn_connector_networks WHERE vpn_id=%d"), m_id);
    DBQuery(hdb, szQuery);
-   for(i = 0; i < m_dwNumLocalNets; i++)
+
+   int i;
+   TCHAR buffer[64];
+   for(i = 0; i < m_localNetworks->size(); i++)
    {
+      InetAddress *addr = m_localNetworks->get(i);
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR), 
-                          _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,0,'%s','%s')"),
-              m_id, IpToStr(m_pLocalNetList[i].dwAddr, szIpAddr),
-              IpToStr(m_pLocalNetList[i].dwMask, szNetMask));
+                          _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,0,'%s',%d)"),
+                 (int)m_id, addr->toString(buffer), addr->getMaskBits());
       DBQuery(hdb, szQuery);
    }
-   for(i = 0; i < m_dwNumRemoteNets; i++)
+   for(i = 0; i < m_remoteNetworks->size(); i++)
    {
+      InetAddress *addr = m_remoteNetworks->get(i);
       _sntprintf(szQuery, sizeof(szQuery) / sizeof(TCHAR),
-                               _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,1,'%s','%s')"),
-              m_id, IpToStr(m_pRemoteNetList[i].dwAddr, szIpAddr),
-              IpToStr(m_pRemoteNetList[i].dwMask, szNetMask));
+                               _T("INSERT INTO vpn_connector_networks (vpn_id,network_type,ip_addr,ip_netmask) VALUES (%d,1,'%s',%d)"),
+                 (int)m_id, addr->toString(buffer), addr->getMaskBits());
       DBQuery(hdb, szQuery);
    }
 
@@ -252,24 +219,19 @@ Node *VPNConnector::getParentNode()
  */
 void VPNConnector::fillMessage(NXCPMessage *pMsg)
 {
-   UINT32 i, dwId;
-
    NetObj::fillMessage(pMsg);
    pMsg->setField(VID_PEER_GATEWAY, m_dwPeerGateway);
-   pMsg->setField(VID_NUM_LOCAL_NETS, m_dwNumLocalNets);
-   pMsg->setField(VID_NUM_REMOTE_NETS, m_dwNumRemoteNets);
+   pMsg->setField(VID_NUM_LOCAL_NETS, (UINT32)m_localNetworks->size());
+   pMsg->setField(VID_NUM_REMOTE_NETS, (UINT32)m_remoteNetworks->size());
 
-   for(i = 0, dwId = VID_VPN_NETWORK_BASE; i < m_dwNumLocalNets; i++)
-   {
-      pMsg->setField(dwId++, m_pLocalNetList[i].dwAddr);
-      pMsg->setField(dwId++, m_pLocalNetList[i].dwMask);
-   }
+   UINT32 fieldId;
+   int i;
 
-   for(i = 0; i < m_dwNumRemoteNets; i++)
-   {
-      pMsg->setField(dwId++, m_pRemoteNetList[i].dwAddr);
-      pMsg->setField(dwId++, m_pRemoteNetList[i].dwMask);
-   }
+   for(i = 0, fieldId = VID_VPN_NETWORK_BASE; i < m_localNetworks->size(); i++)
+      pMsg->setField(fieldId++, *m_localNetworks->get(i));
+
+   for(i = 0; i < m_remoteNetworks->size(); i++)
+      pMsg->setField(fieldId++, *m_remoteNetworks->get(i));
 }
 
 /**
@@ -288,39 +250,17 @@ UINT32 VPNConnector::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocke
    if ((pRequest->isFieldExist(VID_NUM_LOCAL_NETS)) &&
        (pRequest->isFieldExist(VID_NUM_REMOTE_NETS)))
    {
-      UINT32 i, dwId = VID_VPN_NETWORK_BASE;
+      int i;
+      UINT32 fieldId = VID_VPN_NETWORK_BASE;
 
-      m_dwNumLocalNets = pRequest->getFieldAsUInt32(VID_NUM_LOCAL_NETS);
-      if (m_dwNumLocalNets > 0)
-      {
-         m_pLocalNetList = (IP_NETWORK *)realloc(m_pLocalNetList, sizeof(IP_NETWORK) * m_dwNumLocalNets);
-         for(i = 0; i < m_dwNumLocalNets; i++)
-         {
-            m_pLocalNetList[i].dwAddr = pRequest->getFieldAsUInt32(dwId++);
-            m_pLocalNetList[i].dwMask = pRequest->getFieldAsUInt32(dwId++);
-         }
-      }
-      else
-      {
-         safe_free(m_pLocalNetList);
-         m_pLocalNetList = NULL;
-      }
+      m_localNetworks->clear();
+      int count = pRequest->getFieldAsInt32(VID_NUM_LOCAL_NETS);
+      for(i = 0; i < count; i++)
+         m_localNetworks->add(new InetAddress(pRequest->getFieldAsInetAddress(fieldId++)));
 
-      m_dwNumRemoteNets = pRequest->getFieldAsUInt32(VID_NUM_REMOTE_NETS);
-      if (m_dwNumRemoteNets > 0)
-      {
-         m_pRemoteNetList = (IP_NETWORK *)realloc(m_pRemoteNetList, sizeof(IP_NETWORK) * m_dwNumRemoteNets);
-         for(i = 0; i < m_dwNumRemoteNets; i++)
-         {
-            m_pRemoteNetList[i].dwAddr = pRequest->getFieldAsUInt32(dwId++);
-            m_pRemoteNetList[i].dwMask = pRequest->getFieldAsUInt32(dwId++);
-         }
-      }
-      else
-      {
-         safe_free(m_pRemoteNetList);
-         m_pRemoteNetList = NULL;
-      }
+      count = pRequest->getFieldAsInt32(VID_NUM_REMOTE_NETS);
+      for(i = 0; i < count; i++)
+         m_remoteNetworks->add(new InetAddress(pRequest->getFieldAsInetAddress(fieldId++)));
    }
 
    return NetObj::modifyFromMessage(pRequest, TRUE);
@@ -329,58 +269,55 @@ UINT32 VPNConnector::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocke
 /**
  * Check if given address falls into one of the local nets
  */
-BOOL VPNConnector::isLocalAddr(UINT32 dwIpAddr)
+bool VPNConnector::isLocalAddr(const InetAddress& addr)
 {
-   UINT32 i;
-   BOOL bResult = FALSE;
+   bool result = false;
 
    lockProperties();
 
-   for(i = 0; i < m_dwNumLocalNets; i++)
-      if ((dwIpAddr & m_pLocalNetList[i].dwMask) == m_pLocalNetList[i].dwAddr)
+   for(int i = 0; i < m_localNetworks->size(); i++)
+      if (m_localNetworks->get(i)->contain(addr))
       {
-         bResult = TRUE;
+         result = true;
          break;
       }
 
    unlockProperties();
-   return bResult;
+   return result;
 }
 
 /**
  * Check if given address falls into one of the remote nets
  */
-BOOL VPNConnector::isRemoteAddr(UINT32 dwIpAddr)
+bool VPNConnector::isRemoteAddr(const InetAddress& addr)
 {
-   UINT32 i;
-   BOOL bResult = FALSE;
+   bool result = false;
 
    lockProperties();
 
-   for(i = 0; i < m_dwNumRemoteNets; i++)
-      if ((dwIpAddr & m_pRemoteNetList[i].dwMask) == m_pRemoteNetList[i].dwAddr)
+   for(int i = 0; i < m_remoteNetworks->size(); i++)
+      if (m_remoteNetworks->get(i)->contain(addr))
       {
-         bResult = TRUE;
+         result = true;
          break;
       }
 
    unlockProperties();
-   return bResult;
+   return result;
 }
 
 /**
  * Get address of peer gateway
  */
-UINT32 VPNConnector::getPeerGatewayAddr()
+InetAddress VPNConnector::getPeerGatewayAddr()
 {
    NetObj *pObject;
-   UINT32 dwAddr = 0;
 
    pObject = FindObjectById(m_dwPeerGateway);
    if (pObject != NULL)
    {
       if (pObject->getObjectClass() == OBJECT_NODE)
-         dwAddr = pObject->IpAddr();
+         return pObject->getIpAddress();
    }
-   return dwAddr;
+   return InetAddress();
 }
index 5bcb5f3..4a6cfd8 100644 (file)
@@ -33,9 +33,9 @@ Zone::Zone() : NetObj()
    m_agentProxy = 0;
    m_snmpProxy = 0;
        m_icmpProxy = 0;
-       m_idxNodeByAddr = new ObjectIndex;
-       m_idxInterfaceByAddr = new ObjectIndex;
-       m_idxSubnetByAddr = new ObjectIndex;
+       m_idxNodeByAddr = new InetAddressIndex;
+       m_idxInterfaceByAddr = new InetAddressIndex;
+       m_idxSubnetByAddr = new InetAddressIndex;
 }
 
 /**
@@ -49,9 +49,9 @@ Zone::Zone(UINT32 zoneId, const TCHAR *name) : NetObj()
    m_agentProxy = 0;
    m_snmpProxy = 0;
        m_icmpProxy = 0;
-       m_idxNodeByAddr = new ObjectIndex;
-       m_idxInterfaceByAddr = new ObjectIndex;
-       m_idxSubnetByAddr = new ObjectIndex;
+       m_idxNodeByAddr = new InetAddressIndex;
+       m_idxInterfaceByAddr = new InetAddressIndex;
+       m_idxSubnetByAddr = new InetAddressIndex;
 }
 
 /**
@@ -198,7 +198,7 @@ UINT32 Zone::modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked)
 /**
  * Update interface index
  */
-void Zone::updateInterfaceIndex(UINT32 oldIp, UINT32 newIp, Interface *iface)
+void Zone::updateInterfaceIndex(const InetAddress& oldIp, const InetAddress& newIp, Interface *iface)
 {
        m_idxInterfaceByAddr->remove(oldIp);
        m_idxInterfaceByAddr->put(newIp, iface);
index 7888a6f..d153613 100644 (file)
@@ -241,8 +241,7 @@ typedef void * HSNMPSESSION;
  */
 typedef struct
 {
-   UINT32 dwIpAddr;
-   UINT32 dwNetMask;
+   InetAddress ipAddr;
        UINT32 zoneId;
        BOOL ignoreFilter;
        BYTE bMacAddr[MAC_ADDR_LENGTH];
@@ -265,9 +264,7 @@ typedef struct
  */
 typedef struct
 {
-   UINT32 dwIpAddr;
-   UINT32 dwNetMask;
-   UINT32 dwSubnetAddr;
+   InetAddress ipAddr;
    UINT32 dwFlags;
    int nSNMPVersion;
    TCHAR szObjectId[MAX_OID_LEN * 4];    // SNMP OID
@@ -886,7 +883,7 @@ void WatchdogNotify(UINT32 dwId);
 void WatchdogPrintStatus(CONSOLE_CTX pCtx);
 
 void CheckForMgmtNode();
-Node NXCORE_EXPORTABLE *PollNewNode(UINT32 dwIpAddr, UINT32 dwNetMask, UINT32 dwCreationFlags, WORD agentPort,
+Node NXCORE_EXPORTABLE *PollNewNode(const InetAddress& ipAddr, UINT32 dwCreationFlags, WORD agentPort,
                                     WORD snmpPort, const TCHAR *pszName, UINT32 dwProxyNode, UINT32 dwSNMPProxy, Cluster *pCluster,
                                                                  UINT32 zoneId, bool doConfPoll, bool discoveredNode);
 
index 2a4adfb..67018c5 100644 (file)
@@ -182,6 +182,32 @@ public:
        void forEach(void (*callback)(NetObj *, void *), void *data);
 };
 
+struct InetAddressIndexEntry;
+
+/**
+ * Object index by IP address
+ */
+class NXCORE_EXPORTABLE InetAddressIndex
+{
+private:
+   InetAddressIndexEntry *m_root;
+       RWLOCK m_lock;
+
+public:
+   InetAddressIndex();
+   ~InetAddressIndex();
+
+       bool put(const InetAddress& addr, NetObj *object);
+       void remove(const InetAddress& addr);
+       NetObj *get(const InetAddress& addr);
+       NetObj *find(bool (*comparator)(NetObj *, void *), void *data);
+
+       int size();
+       ObjectArray<NetObj> *getObjects(bool updateRefCount, bool (*filter)(NetObj *, void *) = NULL, void *userData = NULL);
+
+       void forEach(void (*callback)(NetObj *, void *), void *data);
+};
+
 /**
  * Node component
  */
@@ -345,7 +371,7 @@ protected:
    MUTEX m_mutexRefCount;     // Reference counter access mutex
    RWLOCK m_rwlockParentList; // Lock for parent list
    RWLOCK m_rwlockChildList;  // Lock for child list
-   UINT32 m_dwIpAddr;
+   InetAddress m_ipAddress;
        GeoLocation m_geoLocation;
    PostalAddress *m_postalAddress;
    ClientSession *m_pollRequestor;
@@ -410,7 +436,7 @@ public:
 
    virtual int getObjectClass() { return OBJECT_GENERIC; }
 
-   UINT32 IpAddr() { return m_dwIpAddr; }
+   const InetAddress& getIpAddress() { return m_ipAddress; }
    UINT32 getId() { return m_id; }
    const TCHAR *getName() { return m_name; }
    int Status() { return m_iStatus; }
@@ -635,7 +661,6 @@ protected:
    UINT32 m_index;
    UINT32 m_type;
    UINT32 m_mtu;
-   UINT32 m_ipNetMask;
    BYTE m_macAddr[MAC_ADDR_LENGTH];
        UINT32 m_bridgePortNumber;              // 802.1D port number
        UINT32 m_slotNumber;                            // Vendor/device specific slot number
@@ -662,8 +687,8 @@ protected:
 
 public:
    Interface();
-   Interface(UINT32 dwAddr, UINT32 dwNetMask, UINT32 zoneId, bool bSyntheticMask);
-   Interface(const TCHAR *name, const TCHAR *descr, UINT32 index, UINT32 ipAddr, UINT32 ipNetMask, UINT32 ifType, UINT32 zoneId);
+   Interface(const InetAddress& addr, UINT32 zoneId, bool bSyntheticMask);
+   Interface(const TCHAR *name, const TCHAR *descr, UINT32 index, const InetAddress& addr, UINT32 ifType, UINT32 zoneId);
    virtual ~Interface();
 
    virtual int getObjectClass() { return OBJECT_INTERFACE; }
@@ -675,7 +700,6 @@ public:
    UINT32 getParentNodeId();
 
    UINT32 getZoneId() { return m_zoneId; }
-   UINT32 getIpNetMask() { return m_ipNetMask; }
    UINT32 getIfIndex() { return m_index; }
    UINT32 getIfType() { return m_type; }
    UINT32 getMTU() { return m_mtu; }
@@ -708,8 +732,8 @@ public:
    void setLastDownEventId(QWORD id) { m_lastDownEventId = id; }
 
    void setMacAddr(const BYTE *pbNewMac);
-   void setIpAddr(UINT32 dwNewAddr);
-   void setIpNetMask(UINT32 dwNewMask);
+   void setIpAddr(const InetAddress& newAddr);
+   void setIpNetMask(int maskBits);
    void setBridgePortNumber(UINT32 bpn) { m_bridgePortNumber = bpn; setModified(); }
    void setSlotNumber(UINT32 slot) { m_slotNumber = slot; setModified(); }
    void setPortNumber(UINT32 port) { m_portNumber = port; setModified(); }
@@ -781,10 +805,8 @@ class NXCORE_EXPORTABLE VPNConnector : public NetObj
 {
 protected:
    UINT32 m_dwPeerGateway;        // Object ID of peer gateway
-   UINT32 m_dwNumLocalNets;
-   IP_NETWORK *m_pLocalNetList;
-   UINT32 m_dwNumRemoteNets;
-   IP_NETWORK *m_pRemoteNetList;
+   ObjectArray<InetAddress> *m_localNetworks;
+   ObjectArray<InetAddress> *m_remoteNetworks;
 
    Node *getParentNode();
 
@@ -802,10 +824,10 @@ public:
    virtual void fillMessage(NXCPMessage *pMsg);
    virtual UINT32 modifyFromMessage(NXCPMessage *pRequest, BOOL bAlreadyLocked = FALSE);
 
-   BOOL isLocalAddr(UINT32 dwIpAddr);
-   BOOL isRemoteAddr(UINT32 dwIpAddr);
+   bool isLocalAddr(const InetAddress& addr);
+   bool isRemoteAddr(const InetAddress& addr);
    UINT32 getPeerGatewayId() { return m_dwPeerGateway; }
-   UINT32 getPeerGatewayAddr();
+   InetAddress getPeerGatewayAddr();
 };
 
 /**
@@ -938,7 +960,7 @@ public:
    AccessPointState getState() { return m_state; }
    Node *getParentNode();
 
-   void setIpAddr(UINT32 ipAddr) { lockProperties(); m_dwIpAddr = ipAddr; setModified(); unlockProperties(); }
+   void setIpAddr(const InetAddress& ipAddr) { lockProperties(); m_ipAddress = ipAddr; setModified(); unlockProperties(); }
 
        void attachToNode(UINT32 nodeId);
        void updateRadioInterfaces(ObjectArray<RadioInterfaceInfo> *ri);
@@ -953,8 +975,7 @@ class NXCORE_EXPORTABLE Cluster : public DataCollectionTarget
 {
 protected:
        UINT32 m_dwClusterType;
-   UINT32 m_dwNumSyncNets;
-   IP_NETWORK *m_pSyncNetList;
+   ObjectArray<InetAddress> *m_syncNetworks;
        UINT32 m_dwNumResources;
        CLUSTER_RESOURCE *m_pResourceList;
        UINT32 m_dwFlags;
@@ -976,8 +997,8 @@ public:
 
    virtual void unbindFromTemplate(UINT32 dwTemplateId, bool removeDCI);
 
-       bool isSyncAddr(UINT32 dwAddr);
-       bool isVirtualAddr(UINT32 dwAddr);
+       bool isSyncAddr(const InetAddress& addr);
+       bool isVirtualAddr(const InetAddress& addr);
        bool isResourceOnNode(UINT32 dwResource, UINT32 dwNode);
    UINT32 getZoneId() { return m_zoneId; }
 
@@ -1090,12 +1111,12 @@ protected:
        void addVrrpInterfaces(InterfaceList *ifList);
        BOOL resolveName(BOOL useOnlyDNS);
    void setAgentProxy(AgentConnection *pConn);
-       void setPrimaryIPAddress(UINT32 addr);
+       void setPrimaryIPAddress(const InetAddress& addr);
 
    UINT32 getInterfaceCount(Interface **ppInterface);
 
    void checkInterfaceNames(InterfaceList *pIfList);
-   Subnet *createSubnet(DWORD ipAddr, DWORD netMask, bool syntheticMask);
+   Subnet *createSubnet(const InetAddress& baseAddr, bool syntheticMask);
        void checkAgentPolicyBinding(AgentConnection *conn);
        void updatePrimaryIpAddr();
        bool confPollAgent(UINT32 dwRqId);
@@ -1125,7 +1146,7 @@ protected:
 
 public:
    Node();
-   Node(UINT32 dwAddr, UINT32 dwFlags, UINT32 agentProxy, UINT32 snmpProxy, UINT32 dwZone);
+   Node(const InetAddress& addr, UINT32 dwFlags, UINT32 agentProxy, UINT32 snmpProxy, UINT32 dwZone);
    virtual ~Node();
 
    virtual int getObjectClass() { return OBJECT_NODE; }
@@ -1181,30 +1202,30 @@ public:
        void setPrimaryName(const TCHAR *name) { nx_strncpy(m_primaryName, name, MAX_DNS_NAME); }
        void setAgentPort(WORD port) { m_agentPort = port; }
        void setSnmpPort(WORD port) { m_wSNMPPort = port; }
-   void changeIPAddress(UINT32 dwIpAddr);
+   void changeIPAddress(const InetAddress& ipAddr);
        void changeZone(UINT32 newZone);
 
    ARP_CACHE *getArpCache();
    InterfaceList *getInterfaceList();
-   Interface *findInterface(UINT32 dwIndex, UINT32 dwHostAddr);
-   Interface *findInterface(const TCHAR *name);
+   Interface *findInterfaceByIndex(UINT32 ifIndex);
+   Interface *findInterfaceByName(const TCHAR *name);
        Interface *findInterfaceByMAC(const BYTE *macAddr);
-       Interface *findInterfaceByIP(UINT32 ipAddr);
+       Interface *findInterfaceByIP(const InetAddress& addr);
        Interface *findInterfaceBySlotAndPort(UINT32 slot, UINT32 port);
        Interface *findBridgePort(UINT32 bridgePortNumber);
    AccessPoint *findAccessPointByMAC(const BYTE *macAddr);
    AccessPoint *findAccessPointByBSSID(const BYTE *bssid);
    AccessPoint *findAccessPointByRadioId(int rfIndex);
    ObjectArray<WirelessStationInfo> *getWirelessStations();
-       BOOL isMyIP(UINT32 dwIpAddr);
+       bool isMyIP(const InetAddress& addr);
    void getInterfaceStatusFromSNMP(SNMP_Transport *pTransport, UINT32 dwIndex, InterfaceAdminState *adminState, InterfaceOperState *operState);
    void getInterfaceStatusFromAgent(UINT32 dwIndex, InterfaceAdminState *adminState, InterfaceOperState *operState);
    ROUTING_TABLE *getRoutingTable();
    ROUTING_TABLE *getCachedRoutingTable() { return m_pRoutingTable; }
        LinkLayerNeighbors *getLinkLayerNeighbors();
        VlanList *getVlans();
-   bool getNextHop(UINT32 srcAddr, UINT32 destAddr, UINT32 *nextHop, UINT32 *ifIndex, bool *isVpn, TCHAR *name);
-   bool getOutwardInterface(UINT32 destAddr, UINT32 *srcAddr, UINT32 *srcIfIndex);
+   bool getNextHop(const InetAddress& srcAddr, const InetAddress& destAddr, InetAddress *nextHop, UINT32 *ifIndex, bool *isVpn, TCHAR *name);
+   bool getOutwardInterface(const InetAddress& destAddr, InetAddress *srcAddr, UINT32 *srcIfIndex);
        ComponentTree *getComponents();
    bool getLldpLocalPortInfo(BYTE *id, size_t idLen, LLDP_LOCAL_PORT_INFO *port);
 
@@ -1281,7 +1302,7 @@ public:
    UINT32 wakeUp();
 
    void addService(NetworkService *pNetSrv) { AddChild(pNetSrv); pNetSrv->AddParent(this); }
-   UINT32 checkNetworkService(UINT32 *pdwStatus, UINT32 dwIpAddr, int iServiceType, WORD wPort = 0,
+   UINT32 checkNetworkService(UINT32 *pdwStatus, const InetAddress& ipAddr, int iServiceType, WORD wPort = 0,
                               WORD wProto = 0, TCHAR *pszRequest = NULL, TCHAR *pszResponse = NULL, UINT32 *responseTime = NULL);
 
    QWORD getLastEventId(int nIndex) { return ((nIndex >= 0) && (nIndex < MAX_LAST_EVENTS)) ? m_qwLastEvents[nIndex] : 0; }