2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ** File: interface.cpp
24 #include <ieee8021x.h>
27 * Default constructor for Interface object
29 Interface
::Interface() : NetObj()
31 m_parentInterfaceId
= 0;
32 nx_strncpy(m_description
, m_name
, MAX_DB_STRING
);
35 m_type
= IFTYPE_OTHER
;
38 m_bridgePortNumber
= 0;
42 m_peerInterfaceId
= 0;
43 m_peerDiscoveryProtocol
= LL_PROTO_UNKNOWN
;
44 m_adminState
= IF_ADMIN_STATE_UNKNOWN
;
45 m_operState
= IF_OPER_STATE_UNKNOWN
;
46 m_pendingOperState
= IF_OPER_STATE_UNKNOWN
;
47 m_confirmedOperState
= IF_OPER_STATE_UNKNOWN
;
48 m_dot1xPaeAuthState
= PAE_STATE_UNKNOWN
;
49 m_dot1xBackendAuthState
= BACKEND_STATE_UNKNOWN
;
50 memset(m_macAddr
, 0, MAC_ADDR_LENGTH
);
51 m_lastDownEventId
= 0;
53 m_statusPollCount
= 0;
54 m_operStatePollCount
= 0;
55 m_requiredPollCount
= 0; // Use system default
57 m_pingTime
= PING_TIME_TIMEOUT
;
58 m_pingLastTimeStamp
= 0;
59 m_ifTableSuffixLen
= 0;
60 m_ifTableSuffix
= NULL
;
64 * Constructor for "fake" interface object
66 Interface
::Interface(const InetAddressList
& addrList
, UINT32 zoneUIN
, bool bSyntheticMask
) : NetObj()
68 m_parentInterfaceId
= 0;
69 m_flags
= bSyntheticMask ? IF_SYNTHETIC_MASK
: 0;
70 if (addrList
.isLoopbackOnly())
71 m_flags
|= IF_LOOPBACK
;
73 _tcscpy(m_name
, _T("unknown"));
74 _tcscpy(m_description
, _T("unknown"));
76 m_ipAddressList
.add(addrList
);
78 m_type
= IFTYPE_OTHER
;
81 m_bridgePortNumber
= 0;
85 m_peerInterfaceId
= 0;
86 m_peerDiscoveryProtocol
= LL_PROTO_UNKNOWN
;
87 m_adminState
= IF_ADMIN_STATE_UNKNOWN
;
88 m_operState
= IF_OPER_STATE_UNKNOWN
;
89 m_pendingOperState
= IF_OPER_STATE_UNKNOWN
;
90 m_confirmedOperState
= IF_OPER_STATE_UNKNOWN
;
91 m_dot1xPaeAuthState
= PAE_STATE_UNKNOWN
;
92 m_dot1xBackendAuthState
= BACKEND_STATE_UNKNOWN
;
93 memset(m_macAddr
, 0, MAC_ADDR_LENGTH
);
94 m_lastDownEventId
= 0;
96 m_statusPollCount
= 0;
97 m_operStatePollCount
= 0;
98 m_requiredPollCount
= 0; // Use system default
101 m_pingTime
= PING_TIME_TIMEOUT
;
102 m_pingLastTimeStamp
= 0;
103 m_ifTableSuffixLen
= 0;
104 m_ifTableSuffix
= NULL
;
108 * Constructor for normal interface object
110 Interface
::Interface(const TCHAR
*name
, const TCHAR
*descr
, UINT32 index
, const InetAddressList
& addrList
, UINT32 ifType
, UINT32 zoneUIN
)
113 if ((ifType
== IFTYPE_SOFTWARE_LOOPBACK
) || addrList
.isLoopbackOnly())
114 m_flags
= IF_LOOPBACK
;
118 m_parentInterfaceId
= 0;
119 nx_strncpy(m_name
, name
, MAX_OBJECT_NAME
);
120 nx_strncpy(m_description
, descr
, MAX_DB_STRING
);
126 m_ipAddressList
.add(addrList
);
127 m_bridgePortNumber
= 0;
131 m_peerInterfaceId
= 0;
132 m_adminState
= IF_ADMIN_STATE_UNKNOWN
;
133 m_operState
= IF_OPER_STATE_UNKNOWN
;
134 m_pendingOperState
= IF_OPER_STATE_UNKNOWN
;
135 m_confirmedOperState
= IF_OPER_STATE_UNKNOWN
;
136 m_peerDiscoveryProtocol
= LL_PROTO_UNKNOWN
;
137 m_dot1xPaeAuthState
= PAE_STATE_UNKNOWN
;
138 m_dot1xBackendAuthState
= BACKEND_STATE_UNKNOWN
;
139 memset(m_macAddr
, 0, MAC_ADDR_LENGTH
);
140 m_lastDownEventId
= 0;
141 m_pendingStatus
= -1;
142 m_statusPollCount
= 0;
143 m_operStatePollCount
= 0;
144 m_requiredPollCount
= 0; // Use system default
147 m_pingTime
= PING_TIME_TIMEOUT
;
148 m_pingLastTimeStamp
= 0;
149 m_ifTableSuffixLen
= 0;
150 m_ifTableSuffix
= NULL
;
154 * Interface class destructor
156 Interface
::~Interface()
158 free(m_ifTableSuffix
);
162 * Returns last ping time
164 UINT32 Interface
::getPingTime()
166 if ((time(NULL
) - m_pingLastTimeStamp
) > g_dwStatusPollingInterval
)
169 nxlog_debug(7, _T("Interface::getPingTime: update ping time is required! Last ping time %d."), m_pingLastTimeStamp
);
175 * Create object from database record
177 bool Interface
::loadFromDatabase(DB_HANDLE hdb
, UINT32 dwId
)
179 bool bResult
= false;
183 if (!loadCommonProperties(hdb
))
186 DB_STATEMENT hStmt
= DBPrepare(hdb
,
187 _T("SELECT if_type,if_index,node_id,")
188 _T("mac_addr,required_polls,bridge_port,phy_slot,")
189 _T("phy_port,peer_node_id,peer_if_id,description,")
190 _T("dot1x_pae_state,dot1x_backend_state,admin_state,")
191 _T("oper_state,peer_proto,alias,mtu,speed,parent_iface,")
192 _T("iftable_suffix FROM interfaces WHERE id=?"));
195 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, m_id
);
197 DB_RESULT hResult
= DBSelectPrepared(hStmt
);
200 DBFreeStatement(hStmt
);
201 return false; // Query failed
204 if (DBGetNumRows(hResult
) != 0)
206 m_type
= DBGetFieldULong(hResult
, 0, 0);
207 m_index
= DBGetFieldULong(hResult
, 0, 1);
208 UINT32 nodeId
= DBGetFieldULong(hResult
, 0, 2);
209 DBGetFieldByteArray2(hResult
, 0, 3, m_macAddr
, MAC_ADDR_LENGTH
, 0);
210 m_requiredPollCount
= DBGetFieldLong(hResult
, 0, 4);
211 m_bridgePortNumber
= DBGetFieldULong(hResult
, 0, 5);
212 m_slotNumber
= DBGetFieldULong(hResult
, 0, 6);
213 m_portNumber
= DBGetFieldULong(hResult
, 0, 7);
214 m_peerNodeId
= DBGetFieldULong(hResult
, 0, 8);
215 m_peerInterfaceId
= DBGetFieldULong(hResult
, 0, 9);
216 DBGetField(hResult
, 0, 10, m_description
, MAX_DB_STRING
);
217 m_dot1xPaeAuthState
= (WORD
)DBGetFieldLong(hResult
, 0, 11);
218 m_dot1xBackendAuthState
= (WORD
)DBGetFieldLong(hResult
, 0, 12);
219 m_adminState
= (WORD
)DBGetFieldLong(hResult
, 0, 13);
220 m_operState
= (WORD
)DBGetFieldLong(hResult
, 0, 14);
221 m_confirmedOperState
= m_operState
;
222 m_peerDiscoveryProtocol
= (LinkLayerProtocol
)DBGetFieldLong(hResult
, 0, 15);
223 DBGetField(hResult
, 0, 16, m_alias
, MAX_DB_STRING
);
224 m_mtu
= DBGetFieldULong(hResult
, 0, 17);
225 m_speed
= DBGetFieldUInt64(hResult
, 0, 18);
226 m_parentInterfaceId
= DBGetFieldULong(hResult
, 0, 19);
228 TCHAR suffixText
[128];
229 DBGetField(hResult
, 0, 20, suffixText
, 128);
230 StrStrip(suffixText
);
231 if (suffixText
[0] == 0)
234 size_t l
= SNMPParseOID(suffixText
, suffix
, 16);
237 m_ifTableSuffixLen
= (int)l
;
238 m_ifTableSuffix
= (UINT32
*)nx_memdup(suffix
, l
* sizeof(UINT32
));
242 m_pingTime
= PING_TIME_TIMEOUT
;
243 m_pingLastTimeStamp
= 0;
245 // Link interface to node
248 NetObj
*object
= FindObjectById(nodeId
);
251 nxlog_write(MSG_INVALID_NODE_ID
, EVENTLOG_ERROR_TYPE
, "dd", dwId
, nodeId
);
253 else if (object
->getObjectClass() != OBJECT_NODE
)
255 nxlog_write(MSG_NODE_NOT_NODE
, EVENTLOG_ERROR_TYPE
, "dd", dwId
, nodeId
);
259 object
->addChild(this);
261 m_zoneUIN
= ((Node
*)object
)->getZoneUIN();
271 DBFreeResult(hResult
);
272 DBFreeStatement(hStmt
);
275 hStmt
= DBPrepare(hdb
, _T("SELECT ip_addr,ip_netmask FROM interface_address_list WHERE iface_id = ?"));
278 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, m_id
);
279 hResult
= DBSelectPrepared(hStmt
);
282 int count
= DBGetNumRows(hResult
);
283 for(int i
= 0; i
< count
; i
++)
285 InetAddress addr
= DBGetFieldInetAddr(hResult
, i
, 0);
286 addr
.setMaskBits(DBGetFieldLong(hResult
, i
, 1));
288 m_ipAddressList
.add(addr
);
290 DBFreeResult(hResult
);
292 DBFreeStatement(hStmt
);
298 // Validate loopback flag
299 if (m_type
== IFTYPE_SOFTWARE_LOOPBACK
)
301 m_flags
|= IF_LOOPBACK
;
305 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
307 for(int i
= 0; i
< list
->size(); i
++)
309 if (list
->get(i
)->isLoopback())
312 if ((count
> 0) && (count
== list
->size())) // all loopback addresses
313 m_flags
|= IF_LOOPBACK
;
315 m_flags
&= ~IF_LOOPBACK
;
322 * Save interface object to database
324 bool Interface
::saveToDatabase(DB_HANDLE hdb
)
331 if (!saveCommonProperties(hdb
))
337 // Determine owning node's ID
339 if (m_modified
& MODIFY_INTERFACE_PROPERTIES
)
341 Node
*pNode
= getParentNode();
343 dwNodeId
= pNode
->getId();
347 // Form and execute INSERT or UPDATE query
349 if (IsDatabaseRecordExist(hdb
, _T("interfaces"), _T("id"), m_id
))
351 hStmt
= DBPrepare(hdb
,
352 _T("UPDATE interfaces SET node_id=?,if_type=?,if_index=?,mac_addr=?,")
353 _T("required_polls=?,bridge_port=?,phy_slot=?,phy_port=?,")
354 _T("peer_node_id=?,peer_if_id=?,description=?,admin_state=?,")
355 _T("oper_state=?,dot1x_pae_state=?,dot1x_backend_state=?,")
356 _T("peer_proto=?,alias=?,mtu=?,speed=?,parent_iface=?,")
357 _T("iftable_suffix=? WHERE id=?"));
361 hStmt
= DBPrepare(hdb
,
362 _T("INSERT INTO interfaces (node_id,if_type,if_index,mac_addr,")
363 _T("required_polls,bridge_port,phy_slot,phy_port,peer_node_id,peer_if_id,description,")
364 _T("admin_state,oper_state,dot1x_pae_state,dot1x_backend_state,peer_proto,alias,mtu,speed,")
365 _T("parent_iface,iftable_suffix,id) ")
366 _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
374 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, dwNodeId
);
375 DBBind(hStmt
, 2, DB_SQLTYPE_INTEGER
, m_type
);
376 DBBind(hStmt
, 3, DB_SQLTYPE_INTEGER
, m_index
);
377 DBBind(hStmt
, 4, DB_SQLTYPE_VARCHAR
, BinToStr(m_macAddr
, MAC_ADDR_LENGTH
, szMacStr
), DB_BIND_STATIC
);
378 DBBind(hStmt
, 5, DB_SQLTYPE_INTEGER
, (LONG
)m_requiredPollCount
);
379 DBBind(hStmt
, 6, DB_SQLTYPE_INTEGER
, m_bridgePortNumber
);
380 DBBind(hStmt
, 7, DB_SQLTYPE_INTEGER
, m_slotNumber
);
381 DBBind(hStmt
, 8, DB_SQLTYPE_INTEGER
, m_portNumber
);
382 DBBind(hStmt
, 9, DB_SQLTYPE_INTEGER
, m_peerNodeId
);
383 DBBind(hStmt
, 10, DB_SQLTYPE_INTEGER
, m_peerInterfaceId
);
384 DBBind(hStmt
, 11, DB_SQLTYPE_VARCHAR
, m_description
, DB_BIND_STATIC
);
385 DBBind(hStmt
, 12, DB_SQLTYPE_INTEGER
, (UINT32
)m_adminState
);
386 DBBind(hStmt
, 13, DB_SQLTYPE_INTEGER
, (UINT32
)m_operState
);
387 DBBind(hStmt
, 14, DB_SQLTYPE_INTEGER
, (UINT32
)m_dot1xPaeAuthState
);
388 DBBind(hStmt
, 15, DB_SQLTYPE_INTEGER
, (UINT32
)m_dot1xBackendAuthState
);
389 DBBind(hStmt
, 16, DB_SQLTYPE_INTEGER
, (INT32
)m_peerDiscoveryProtocol
);
390 DBBind(hStmt
, 17, DB_SQLTYPE_VARCHAR
, m_alias
, DB_BIND_STATIC
);
391 DBBind(hStmt
, 18, DB_SQLTYPE_INTEGER
, m_mtu
);
392 DBBind(hStmt
, 19, DB_SQLTYPE_BIGINT
, m_speed
);
393 DBBind(hStmt
, 20, DB_SQLTYPE_INTEGER
, m_parentInterfaceId
);
394 if (m_ifTableSuffixLen
> 0)
397 DBBind(hStmt
, 21, DB_SQLTYPE_VARCHAR
, SNMPConvertOIDToText(m_ifTableSuffixLen
, m_ifTableSuffix
, buffer
, 128), DB_BIND_TRANSIENT
);
401 DBBind(hStmt
, 21, DB_SQLTYPE_VARCHAR
, NULL
, DB_BIND_STATIC
);
403 DBBind(hStmt
, 22, DB_SQLTYPE_INTEGER
, m_id
);
405 success
= DBExecute(hStmt
);
406 DBFreeStatement(hStmt
);
413 hStmt
= DBPrepare(hdb
, _T("DELETE FROM interface_address_list WHERE iface_id = ?"));
416 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, m_id
);
417 success
= DBExecute(hStmt
);
418 DBFreeStatement(hStmt
);
422 if (success
&& (m_ipAddressList
.size() > 0))
424 hStmt
= DBPrepare(hdb
, _T("INSERT INTO interface_address_list (iface_id,ip_addr,ip_netmask) VALUES (?,?,?)"));
427 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, m_id
);
428 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
429 for(int i
= 0; (i
< list
->size()) && success
; i
++)
431 InetAddress
*a
= list
->get(i
);
433 DBBind(hStmt
, 2, DB_SQLTYPE_VARCHAR
, a
->toString(buffer
), DB_BIND_STATIC
);
434 DBBind(hStmt
, 3, DB_SQLTYPE_INTEGER
, a
->getMaskBits());
435 success
= DBExecute(hStmt
);
437 DBFreeStatement(hStmt
);
452 success
= saveACLToDB(hdb
);
454 // Clear modifications flag and unlock object
463 * Delete interface object from database
465 bool Interface
::deleteFromDatabase(DB_HANDLE hdb
)
467 bool success
= NetObj
::deleteFromDatabase(hdb
);
469 success
= executeQueryOnObject(hdb
, _T("DELETE FROM interfaces WHERE id=?"));
471 success
= executeQueryOnObject(hdb
, _T("DELETE FROM interface_address_list WHERE iface_id=?"));
476 * Perform status poll on interface
478 void Interface
::statusPoll(ClientSession
*session
, UINT32 rqId
, Queue
*eventQueue
, Cluster
*cluster
, SNMP_Transport
*snmpTransport
, UINT32 nodeIcmpProxy
)
480 if (IsShutdownInProgress())
483 m_pollRequestor
= session
;
484 Node
*pNode
= getParentNode();
487 m_status
= STATUS_UNKNOWN
;
488 return; // Cannot find parent node, which is VERY strange
491 sendPollerMsg(rqId
, _T(" Starting status poll on interface %s\r\n"), m_name
);
492 sendPollerMsg(rqId
, _T(" Current interface status is %s\r\n"), GetStatusAsText(m_status
, true));
494 InterfaceAdminState adminState
= IF_ADMIN_STATE_UNKNOWN
;
495 InterfaceOperState operState
= IF_OPER_STATE_UNKNOWN
;
496 BOOL bNeedPoll
= TRUE
;
498 // Poll interface using different methods
499 if ((pNode
->getCapabilities() & NC_IS_NATIVE_AGENT
) &&
500 (!(pNode
->getFlags() & NF_DISABLE_NXCP
)) && (!(pNode
->getState() & NSF_AGENT_UNREACHABLE
)))
502 sendPollerMsg(rqId
, _T(" Retrieving interface status from NetXMS agent\r\n"));
503 pNode
->getInterfaceStatusFromAgent(m_index
, &adminState
, &operState
);
504 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new state from NetXMS agent: adinState=%d operState=%d"), m_id
, m_name
, adminState
, operState
);
505 if ((adminState
!= IF_ADMIN_STATE_UNKNOWN
) && (operState
!= IF_OPER_STATE_UNKNOWN
))
507 sendPollerMsg(rqId
, POLLER_INFO
_T(" Interface status retrieved from NetXMS agent\r\n"));
512 sendPollerMsg(rqId
, POLLER_WARNING
_T(" Unable to retrieve interface status from NetXMS agent\r\n"));
516 if (bNeedPoll
&& (pNode
->getCapabilities() & NC_IS_SNMP
) &&
517 (!(pNode
->getFlags() & NF_DISABLE_SNMP
)) && (!(pNode
->getState() & NSF_SNMP_UNREACHABLE
)) &&
518 (snmpTransport
!= NULL
))
520 sendPollerMsg(rqId
, _T(" Retrieving interface status from SNMP agent\r\n"));
521 pNode
->getInterfaceStatusFromSNMP(snmpTransport
, m_index
, m_ifTableSuffixLen
, m_ifTableSuffix
, &adminState
, &operState
);
522 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): new state from SNMP: adminState=%d operState=%d"), m_id
, m_name
, adminState
, operState
);
523 if ((adminState
!= IF_ADMIN_STATE_UNKNOWN
) && (operState
!= IF_OPER_STATE_UNKNOWN
))
525 sendPollerMsg(rqId
, POLLER_INFO
_T(" Interface status retrieved from SNMP agent\r\n"));
530 sendPollerMsg(rqId
, POLLER_WARNING
_T(" Unable to retrieve interface status from SNMP agent\r\n"));
536 // Ping cannot be used for cluster sync interfaces
537 if ((pNode
->getFlags() & NF_DISABLE_ICMP
) || isLoopback() || !m_ipAddressList
.hasValidUnicastAddress())
539 // Interface doesn't have an IP address, so we can't ping it
540 sendPollerMsg(rqId
, POLLER_WARNING
_T(" Interface status cannot be determined\r\n"));
541 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): cannot use ping for status check"), m_id
, m_name
);
545 icmpStatusPoll(rqId
, nodeIcmpProxy
, cluster
, &adminState
, &operState
);
549 // Calculate interface object status based on admin state, oper state, and expected state
550 int oldStatus
= m_status
;
552 int expectedState
= (m_flags
& IF_EXPECTED_STATE_MASK
) >> 28;
555 case IF_ADMIN_STATE_UP
:
556 case IF_ADMIN_STATE_UNKNOWN
:
559 case IF_OPER_STATE_UP
:
560 if (expectedState
== IF_EXPECTED_STATE_AUTO
)
562 DbgPrintf(5, _T("Interface::StatusPoll(%d,%s): auto expected state changed to UP"), m_id
, m_name
);
563 expectedState
= IF_EXPECTED_STATE_UP
;
564 setExpectedState(expectedState
);
566 newStatus
= ((expectedState
== IF_EXPECTED_STATE_DOWN
) ? STATUS_CRITICAL
: STATUS_NORMAL
);
568 case IF_OPER_STATE_DOWN
:
569 if (expectedState
== IF_EXPECTED_STATE_AUTO
)
571 DbgPrintf(5, _T("Interface::StatusPoll(%d,%s): auto expected state changed to DOWN"), m_id
, m_name
);
572 expectedState
= IF_EXPECTED_STATE_DOWN
;
573 setExpectedState(expectedState
);
575 newStatus
= (expectedState
== IF_EXPECTED_STATE_UP
) ? STATUS_CRITICAL
: STATUS_NORMAL
;
577 case IF_OPER_STATE_TESTING
:
578 newStatus
= STATUS_TESTING
;
580 case IF_OPER_STATE_DORMANT
:
581 newStatus
= (expectedState
== IF_EXPECTED_STATE_UP
) ? STATUS_MINOR
: STATUS_NORMAL
;
583 case IF_OPER_STATE_NOT_PRESENT
:
584 newStatus
= STATUS_DISABLED
;
587 newStatus
= STATUS_UNKNOWN
;
591 case IF_ADMIN_STATE_DOWN
:
592 if (expectedState
== IF_EXPECTED_STATE_AUTO
)
594 DbgPrintf(5, _T("Interface::StatusPoll(%d,%s): auto expected state changed to DOWN"), m_id
, m_name
);
595 expectedState
= IF_EXPECTED_STATE_DOWN
;
596 setExpectedState(expectedState
);
598 newStatus
= STATUS_DISABLED
;
600 case IF_ADMIN_STATE_TESTING
:
601 newStatus
= STATUS_TESTING
;
604 newStatus
= STATUS_UNKNOWN
;
608 // Check 802.1x state
609 if ((pNode
->getCapabilities() & NC_IS_8021X
) && isPhysicalPort() && (snmpTransport
!= NULL
))
611 DbgPrintf(5, _T("StatusPoll(%s): Checking 802.1x state for interface %s"), pNode
->getName(), m_name
);
612 paeStatusPoll(rqId
, snmpTransport
, pNode
);
613 if ((m_dot1xPaeAuthState
== PAE_STATE_FORCE_UNAUTH
) && (newStatus
< STATUS_MAJOR
))
614 newStatus
= STATUS_MAJOR
;
617 // Reset status to unknown if node has known network connectivity problems
618 if ((newStatus
== STATUS_CRITICAL
) && (pNode
->getState() & DCSF_NETWORK_PATH_PROBLEM
))
620 newStatus
= STATUS_UNKNOWN
;
621 DbgPrintf(6, _T("StatusPoll(%s): Status for interface %s reset to UNKNOWN"), pNode
->getName(), m_name
);
624 if (newStatus
== m_pendingStatus
)
630 m_pendingStatus
= newStatus
;
631 m_statusPollCount
= 1;
634 if (operState
== m_pendingOperState
)
636 m_operStatePollCount
++;
640 m_pendingOperState
= operState
;
641 m_operStatePollCount
= 1;
644 int requiredPolls
= (m_requiredPollCount
> 0) ? m_requiredPollCount
:
645 ((getParentNode()->getRequiredPolls() > 0) ?
getParentNode()->getRequiredPolls() : g_requiredPolls
);
646 sendPollerMsg(rqId
, _T(" Interface is %s for %d poll%s (%d poll%s required for status change)\r\n"),
647 GetStatusAsText(newStatus
, true), m_statusPollCount
, (m_statusPollCount
== 1) ?
_T("") : _T("s"),
648 requiredPolls
, (requiredPolls
== 1) ?
_T("") : _T("s"));
649 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): newStatus=%d oldStatus=%d pollCount=%d requiredPolls=%d"),
650 m_id
, m_name
, newStatus
, oldStatus
, m_statusPollCount
, requiredPolls
);
652 if ((operState
!= m_confirmedOperState
) && (m_operStatePollCount
>= requiredPolls
))
654 DbgPrintf(6, _T("Interface::StatusPoll(%d,%s): confirmedOperState=%d pollCount=%d requiredPolls=%d"),
655 m_id
, m_name
, (int)operState
, m_operStatePollCount
, requiredPolls
);
656 m_confirmedOperState
= operState
;
659 if ((newStatus
!= oldStatus
) && (m_statusPollCount
>= requiredPolls
) && (expectedState
!= IF_EXPECTED_STATE_IGNORE
))
661 static UINT32 statusToEvent
[] =
663 EVENT_INTERFACE_UP
, // Normal
664 EVENT_INTERFACE_UP
, // Warning
665 EVENT_INTERFACE_UP
, // Minor
666 EVENT_INTERFACE_DOWN
, // Major
667 EVENT_INTERFACE_DOWN
, // Critical
668 EVENT_INTERFACE_UNKNOWN
, // Unknown
669 EVENT_INTERFACE_UNKNOWN
, // Unmanaged
670 EVENT_INTERFACE_DISABLED
, // Disabled
671 EVENT_INTERFACE_TESTING
// Testing
673 static UINT32 statusToEventInverted
[] =
675 EVENT_INTERFACE_EXPECTED_DOWN
, // Normal
676 EVENT_INTERFACE_EXPECTED_DOWN
, // Warning
677 EVENT_INTERFACE_EXPECTED_DOWN
, // Minor
678 EVENT_INTERFACE_UNEXPECTED_UP
, // Major
679 EVENT_INTERFACE_UNEXPECTED_UP
, // Critical
680 EVENT_INTERFACE_UNKNOWN
, // Unknown
681 EVENT_INTERFACE_UNKNOWN
, // Unmanaged
682 EVENT_INTERFACE_DISABLED
, // Disabled
683 EVENT_INTERFACE_TESTING
// Testing
686 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): status changed from %d to %d"), m_id
, m_name
, m_status
, newStatus
);
687 m_status
= newStatus
;
688 m_pendingStatus
= -1; // Invalidate pending status
691 sendPollerMsg(rqId
, _T(" Interface status changed to %s\r\n"), GetStatusAsText(m_status
, true));
692 const InetAddress
& addr
= m_ipAddressList
.getFirstUnicastAddress();
693 PostEventEx(eventQueue
,
694 (expectedState
== IF_EXPECTED_STATE_DOWN
) ? statusToEventInverted
[m_status
] : statusToEvent
[m_status
],
695 pNode
->getId(), "dsAdd", m_id
, m_name
, &addr
, addr
.getMaskBits(), m_index
);
698 else if (expectedState
== IF_EXPECTED_STATE_IGNORE
)
700 m_status
= (newStatus
<= STATUS_CRITICAL
) ? STATUS_NORMAL
: newStatus
;
701 if (m_status
!= oldStatus
)
702 m_pendingStatus
= -1; // Invalidate pending status
706 if ((m_status
!= oldStatus
) || (adminState
!= (int)m_adminState
) || (operState
!= (int)m_operState
))
708 m_adminState
= (WORD
)adminState
;
709 m_operState
= (WORD
)operState
;
710 setModified(MODIFY_INTERFACE_PROPERTIES
);
714 sendPollerMsg(rqId
, _T(" Interface status after poll is %s\r\n"), GetStatusAsText(m_status
, true));
715 sendPollerMsg(rqId
, _T(" Finished status poll on interface %s\r\n"), m_name
);
719 * Updates last ping time and ping time
721 void Interface
::updatePingData()
723 Node
*pNode
= getParentNode();
726 nxlog_debug(7, _T("Interface::updatePingData: Can't find parent node"));
729 UINT32 icmpProxy
= pNode
->getIcmpProxy();
731 if (IsZoningEnabled() && (m_zoneUIN
!= 0) && (icmpProxy
== 0))
733 Zone
*zone
= FindZoneByUIN(m_zoneUIN
);
736 icmpProxy
= zone
->getProxyNodeId();
742 nxlog_debug(7, _T("Interface::updatePingData: ping via proxy [%u]"), icmpProxy
);
743 Node
*proxyNode
= (Node
*)g_idxNodeById
.get(icmpProxy
);
744 if ((proxyNode
!= NULL
) && proxyNode
->isNativeAgent() && !proxyNode
->isDown())
746 nxlog_debug(7, _T("Interface::updatePingData: proxy node found: %s"), proxyNode
->getName());
747 AgentConnection
*conn
= proxyNode
->createAgentConnection();
750 TCHAR parameter
[128], buffer
[64];
751 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
753 for(int i
= 0; (i
< list
->size()) && ((value
== 10000) || (value
== -1)); i
++)
755 const InetAddress
*a
= list
->get(i
);
756 _sntprintf(parameter
, 128, _T("Icmp.Ping(%s)"), a
->toString(buffer
));
757 if (conn
->getParameter(parameter
, 64, buffer
) == ERR_SUCCESS
)
759 nxlog_debug(7, _T("Interface::updatePingData: proxy response: \"%s\""), buffer
);
761 value
= _tcstol(buffer
, &eptr
, 10);
775 m_pingTime
= PING_TIME_TIMEOUT
;
776 nxlog_debug(7, _T("Interface::updatePingData: incorrect value or error while parsing"));
778 m_pingLastTimeStamp
= time(NULL
);
783 nxlog_debug(7, _T("Interface::updatePingData: cannot connect to agent on proxy node [%u]"), icmpProxy
);
784 m_pingTime
= PING_TIME_TIMEOUT
;
789 nxlog_debug(7, _T("Interface::updatePingData: proxy node not available [%u]"), icmpProxy
);
790 m_pingTime
= PING_TIME_TIMEOUT
;
793 else // not using ICMP proxy
795 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
796 UINT32 dwPingStatus
= ICMP_TIMEOUT
;
797 for(int i
= 0; (i
< list
->size()) && (dwPingStatus
!= ICMP_SUCCESS
); i
++)
799 const InetAddress
*a
= list
->get(i
);
800 nxlog_debug(7, _T("Interface::StatusPoll(%d,%s): calling IcmpPing(%s,3,%d,%d,%d)"),
801 m_id
, m_name
, (const TCHAR
*)a
->toString(), g_icmpPingTimeout
, m_pingTime
, g_icmpPingSize
);
802 dwPingStatus
= IcmpPing(*a
, 3, g_icmpPingTimeout
, &m_pingTime
, g_icmpPingSize
);
804 if (dwPingStatus
!= ICMP_SUCCESS
)
806 nxlog_debug(7, _T("Interface::updatePingData: error: %d"), dwPingStatus
);
807 m_pingTime
= PING_TIME_TIMEOUT
;
809 m_pingLastTimeStamp
= time(NULL
);
814 * Do ICMP part of status poll
816 void Interface
::icmpStatusPoll(UINT32 rqId
, UINT32 nodeIcmpProxy
, Cluster
*cluster
, InterfaceAdminState
*adminState
, InterfaceOperState
*operState
)
818 // Use ICMP ping as a last option
819 UINT32 icmpProxy
= nodeIcmpProxy
;
821 if (IsZoningEnabled() && (m_zoneUIN
!= 0) && (icmpProxy
== 0))
823 Zone
*zone
= FindZoneByUIN(m_zoneUIN
);
826 icmpProxy
= zone
->getProxyNodeId();
832 sendPollerMsg(rqId
, _T(" Starting ICMP ping via proxy\r\n"));
833 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): ping via proxy [%u]"), m_id
, m_name
, icmpProxy
);
834 Node
*proxyNode
= (Node
*)g_idxNodeById
.get(icmpProxy
);
835 if ((proxyNode
!= NULL
) && proxyNode
->isNativeAgent() && !proxyNode
->isDown())
837 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): proxy node found: %s"), m_id
, m_name
, proxyNode
->getName());
838 AgentConnection
*conn
= proxyNode
->createAgentConnection();
841 TCHAR parameter
[128], buffer
[64];
842 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
844 for(int i
= 0; (i
< list
->size()) && ((value
== 10000) || (value
== -1)); i
++)
846 const InetAddress
*a
= list
->get(i
);
847 if (a
->isValidUnicast() && ((cluster
== NULL
) || !cluster
->isSyncAddr(*a
)))
849 _sntprintf(parameter
, 128, _T("Icmp.Ping(%s)"), a
->toString(buffer
));
850 if (conn
->getParameter(parameter
, 64, buffer
) == ERR_SUCCESS
)
852 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): proxy response: \"%s\""), m_id
, m_name
, buffer
);
854 value
= _tcstol(buffer
, &eptr
, 10);
863 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): response time %d"), m_id
, m_name
, (int)value
);
866 m_pingTime
= (UINT32
)value
;
869 *adminState
= IF_ADMIN_STATE_UP
;
870 *operState
= IF_OPER_STATE_UP
;
874 *adminState
= IF_ADMIN_STATE_UNKNOWN
;
875 *operState
= IF_OPER_STATE_DOWN
;
878 m_pingLastTimeStamp
= time(NULL
);
883 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): cannot connect to agent on proxy node"), m_id
, m_name
);
884 sendPollerMsg(rqId
, POLLER_ERROR
_T(" Unable to establish connection with proxy node\r\n"));
889 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): proxy node not available"), m_id
, m_name
);
890 sendPollerMsg(rqId
, POLLER_ERROR
_T(" ICMP proxy not available\r\n"));
893 else // not using ICMP proxy
895 sendPollerMsg(rqId
, _T(" Starting ICMP ping\r\n"));
896 const ObjectArray
<InetAddress
> *list
= m_ipAddressList
.getList();
897 UINT32 dwPingStatus
= ICMP_TIMEOUT
;
898 for(int i
= 0; (i
< list
->size()) && (dwPingStatus
!= ICMP_SUCCESS
); i
++)
900 const InetAddress
*a
= list
->get(i
);
901 if (a
->isValidUnicast() && ((cluster
== NULL
) || !cluster
->isSyncAddr(*a
)))
903 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): calling IcmpPing(%s,3,%d,%d,%d)"),
904 m_id
, m_name
, (const TCHAR
*)a
->toString(), g_icmpPingTimeout
, m_pingTime
, g_icmpPingSize
);
905 dwPingStatus
= IcmpPing(*a
, 3, g_icmpPingTimeout
, &m_pingTime
, g_icmpPingSize
);
908 m_pingLastTimeStamp
= time(NULL
);
909 if (dwPingStatus
== ICMP_SUCCESS
)
911 *adminState
= IF_ADMIN_STATE_UP
;
912 *operState
= IF_OPER_STATE_UP
;
916 m_pingTime
= PING_TIME_TIMEOUT
;
917 *adminState
= IF_ADMIN_STATE_UNKNOWN
;
918 *operState
= IF_OPER_STATE_DOWN
;
920 DbgPrintf(7, _T("Interface::StatusPoll(%d,%s): ping result %d, adminState=%d, operState=%d"), m_id
, m_name
, dwPingStatus
, *adminState
, *operState
);
925 * PAE (802.1x) status poll
927 void Interface
::paeStatusPoll(UINT32 rqId
, SNMP_Transport
*pTransport
, Node
*node
)
929 static const TCHAR
*paeStateText
[] =
935 _T("AUTHENTICATING"),
943 static const TCHAR
*backendStateText
[] =
955 #define PAE_STATE_TEXT(x) ((((int)(x) <= PAE_STATE_RESTART) && ((int)(x) >= 0)) ? paeStateText[(int)(x)] : paeStateText[0])
956 #define BACKEND_STATE_TEXT(x) ((((int)(x) <= BACKEND_STATE_IGNORE) && ((int)(x) >= 0)) ? backendStateText[(int)(x)] : backendStateText[0])
958 sendPollerMsg(rqId
, _T(" Checking port 802.1x status...\r\n"));
961 INT32 paeState
= PAE_STATE_UNKNOWN
, backendState
= BACKEND_STATE_UNKNOWN
;
962 bool modified
= false;
964 _sntprintf(oid
, 256, _T(".1.0.8802.1.1.1.1.2.1.1.1.%d"), m_index
);
965 SnmpGet(pTransport
->getSnmpVersion(), pTransport
, oid
, NULL
, 0, &paeState
, sizeof(INT32
), 0);
967 _sntprintf(oid
, 256, _T(".1.0.8802.1.1.1.1.2.1.1.2.%d"), m_index
);
968 SnmpGet(pTransport
->getSnmpVersion(), pTransport
, oid
, NULL
, 0, &backendState
, sizeof(INT32
), 0);
970 if (m_dot1xPaeAuthState
!= (WORD
)paeState
)
972 sendPollerMsg(rqId
, _T(" Port PAE state changed to %s\r\n"), PAE_STATE_TEXT(paeState
));
976 PostEvent(EVENT_8021X_PAE_STATE_CHANGED
, node
->getId(), "dsdsds", paeState
, PAE_STATE_TEXT(paeState
),
977 (UINT32
)m_dot1xPaeAuthState
, PAE_STATE_TEXT(m_dot1xPaeAuthState
), m_id
, m_name
);
979 if (paeState
== PAE_STATE_FORCE_UNAUTH
)
981 PostEvent(EVENT_8021X_PAE_FORCE_UNAUTH
, node
->getId(), "ds", m_id
, m_name
);
986 if (m_dot1xBackendAuthState
!= (WORD
)backendState
)
988 sendPollerMsg(rqId
, _T(" Port backend state changed to %s\r\n"), BACKEND_STATE_TEXT(backendState
));
992 PostEvent(EVENT_8021X_BACKEND_STATE_CHANGED
, node
->getId(), "dsdsds", backendState
, BACKEND_STATE_TEXT(backendState
),
993 (UINT32
)m_dot1xBackendAuthState
, BACKEND_STATE_TEXT(m_dot1xBackendAuthState
), m_id
, m_name
);
995 if (backendState
== BACKEND_STATE_FAIL
)
997 PostEvent(EVENT_8021X_AUTH_FAILED
, node
->getId(), "ds", m_id
, m_name
);
999 else if (backendState
== BACKEND_STATE_TIMEOUT
)
1001 PostEvent(EVENT_8021X_AUTH_TIMEOUT
, node
->getId(), "ds", m_id
, m_name
);
1009 m_dot1xPaeAuthState
= (WORD
)paeState
;
1010 m_dot1xBackendAuthState
= (WORD
)backendState
;
1011 setModified(MODIFY_INTERFACE_PROPERTIES
);
1017 * Create NXCP message with object's data
1019 void Interface
::fillMessageInternal(NXCPMessage
*pMsg
)
1021 NetObj
::fillMessageInternal(pMsg
);
1023 m_ipAddressList
.fillMessage(pMsg
, VID_IP_ADDRESS_COUNT
, VID_IP_ADDRESS_LIST_BASE
);
1024 pMsg
->setField(VID_IF_INDEX
, m_index
);
1025 pMsg
->setField(VID_IF_TYPE
, m_type
);
1026 pMsg
->setField(VID_MTU
, m_mtu
);
1027 pMsg
->setField(VID_SPEED
, m_speed
);
1028 pMsg
->setField(VID_IF_SLOT
, m_slotNumber
);
1029 pMsg
->setField(VID_IF_PORT
, m_portNumber
);
1030 pMsg
->setField(VID_MAC_ADDR
, m_macAddr
, MAC_ADDR_LENGTH
);
1031 pMsg
->setField(VID_REQUIRED_POLLS
, (WORD
)m_requiredPollCount
);
1032 pMsg
->setField(VID_PEER_NODE_ID
, m_peerNodeId
);
1033 pMsg
->setField(VID_PEER_INTERFACE_ID
, m_peerInterfaceId
);
1034 pMsg
->setField(VID_PEER_PROTOCOL
, (INT16
)m_peerDiscoveryProtocol
);
1035 pMsg
->setField(VID_DESCRIPTION
, m_description
);
1036 pMsg
->setField(VID_ALIAS
, m_alias
);
1037 pMsg
->setField(VID_ADMIN_STATE
, m_adminState
);
1038 pMsg
->setField(VID_OPER_STATE
, m_operState
);
1039 pMsg
->setField(VID_DOT1X_PAE_STATE
, m_dot1xPaeAuthState
);
1040 pMsg
->setField(VID_DOT1X_BACKEND_STATE
, m_dot1xBackendAuthState
);
1041 pMsg
->setField(VID_ZONE_UIN
, m_zoneUIN
);
1042 pMsg
->setFieldFromInt32Array(VID_IFTABLE_SUFFIX
, m_ifTableSuffixLen
, m_ifTableSuffix
);
1043 pMsg
->setField(VID_PARENT_INTERFACE
, m_parentInterfaceId
);
1047 * Modify object from message
1049 UINT32 Interface
::modifyFromMessageInternal(NXCPMessage
*pRequest
)
1052 if (pRequest
->isFieldExist(VID_FLAGS
))
1054 UINT32 mask
= pRequest
->isFieldExist(VID_FLAGS_MASK
) ?
(pRequest
->getFieldAsUInt32(VID_FLAGS_MASK
) & IF_USER_FLAGS_MASK
) : IF_USER_FLAGS_MASK
;
1056 m_flags
|= pRequest
->getFieldAsUInt32(VID_FLAGS
) & mask
;
1059 // Number of required polls
1060 if (pRequest
->isFieldExist(VID_REQUIRED_POLLS
))
1061 m_requiredPollCount
= (int)pRequest
->getFieldAsUInt16(VID_REQUIRED_POLLS
);
1063 // Expected interface state
1064 if (pRequest
->isFieldExist(VID_EXPECTED_STATE
))
1066 setExpectedStateInternal(pRequest
->getFieldAsInt16(VID_EXPECTED_STATE
));
1069 return NetObj
::modifyFromMessageInternal(pRequest
);
1073 * Set expected state for interface
1075 void Interface
::setExpectedStateInternal(int state
)
1077 static UINT32 eventCode
[] = { EVENT_IF_EXPECTED_STATE_UP
, EVENT_IF_EXPECTED_STATE_DOWN
, EVENT_IF_EXPECTED_STATE_IGNORE
};
1079 int curr
= (m_flags
& IF_EXPECTED_STATE_MASK
) >> 28;
1082 m_flags
&= ~IF_EXPECTED_STATE_MASK
;
1083 m_flags
|= (UINT32
)state
<< 28;
1084 setModified(MODIFY_COMMON_PROPERTIES
);
1085 if (state
!= IF_EXPECTED_STATE_AUTO
)
1086 PostEvent(eventCode
[state
], getParentNodeId(), "ds", m_index
, m_name
);
1091 * Set "exclude from topology" flag
1093 void Interface
::setExcludeFromTopology(bool excluded
)
1097 m_flags
|= IF_EXCLUDE_FROM_TOPOLOGY
;
1099 m_flags
&= ~IF_EXCLUDE_FROM_TOPOLOGY
;
1100 setModified(MODIFY_COMMON_PROPERTIES
);
1105 * Wake up node bound to this interface by sending magic packet
1107 UINT32 Interface
::wakeUp()
1109 UINT32 rcc
= RCC_NO_MAC_ADDRESS
;
1111 if (memcmp(m_macAddr
, "\x00\x00\x00\x00\x00\x00", 6))
1113 const InetAddress addr
= m_ipAddressList
.getFirstUnicastAddressV4();
1116 UINT32 destAddr
= htonl(addr
.getAddressV4() | ~(0xFFFFFFFF << (32 - addr
.getMaskBits())));
1117 if (SendMagicPacket(destAddr
, m_macAddr
, 5))
1120 rcc
= RCC_COMM_FAILURE
;
1127 * Get interface's parent node
1129 Node
*Interface
::getParentNode()
1133 lockParentList(false);
1134 for(int i
= 0; i
< m_parentList
->size(); i
++)
1135 if (m_parentList
->get(i
)->getObjectClass() == OBJECT_NODE
)
1137 pNode
= (Node
*)m_parentList
->get(i
);
1145 * Get ID of parent node object
1147 UINT32 Interface
::getParentNodeId()
1149 Node
*node
= getParentNode();
1150 return (node
!= NULL
) ? node
->getId() : 0;
1154 * Update zone ID. New zone ID taken from parent node.
1156 void Interface
::updateZoneUIN()
1158 Node
*node
= getParentNode();
1161 // Unregister from old zone
1162 Zone
*zone
= FindZoneByUIN(m_zoneUIN
);
1164 zone
->removeFromIndex(this);
1167 m_zoneUIN
= node
->getZoneUIN();
1168 setModified(MODIFY_INTERFACE_PROPERTIES
);
1171 // Register in new zone
1172 zone
= FindZoneByUIN(m_zoneUIN
);
1174 zone
->addToIndex(this);
1179 * Handler for object deletion notification
1181 void Interface
::onObjectDelete(UINT32 dwObjectId
)
1183 if ((m_peerNodeId
== dwObjectId
) || (m_peerInterfaceId
== dwObjectId
))
1187 m_peerInterfaceId
= 0;
1188 setModified(MODIFY_INTERFACE_PROPERTIES
);
1191 NetObj
::onObjectDelete(dwObjectId
);
1195 * Set peer information
1197 void Interface
::setPeer(Node
*node
, Interface
*iface
, LinkLayerProtocol protocol
, bool reflection
)
1199 if ((m_peerNodeId
== node
->getId()) && (m_peerInterfaceId
== iface
->getId()) && (m_peerDiscoveryProtocol
== protocol
))
1201 if ((m_flags
& IF_PEER_REFLECTION
) && !reflection
)
1203 // set peer information as confirmed
1204 m_flags
&= ~IF_PEER_REFLECTION
;
1205 setModified(MODIFY_COMMON_PROPERTIES
);
1210 m_peerNodeId
= node
->getId();
1211 m_peerInterfaceId
= iface
->getId();
1212 m_peerDiscoveryProtocol
= protocol
;
1214 m_flags
|= IF_PEER_REFLECTION
;
1216 m_flags
&= ~IF_PEER_REFLECTION
;
1217 setModified(MODIFY_INTERFACE_PROPERTIES
| MODIFY_COMMON_PROPERTIES
);
1220 static const TCHAR
*names
[] = { _T("localIfId"), _T("localIfIndex"), _T("localIfName"),
1221 _T("localIfIP"), _T("localIfMAC"), _T("remoteNodeId"), _T("remoteNodeName"),
1222 _T("remoteIfId"), _T("remoteIfIndex"), _T("remoteIfName"), _T("remoteIfIP"),
1223 _T("remoteIfMAC"), _T("protocol") };
1224 PostEventWithNames(EVENT_IF_PEER_CHANGED
, getParentNodeId(), "ddsAhdsddsAhd", names
,
1225 m_id
, m_index
, m_name
, &m_ipAddressList
.getFirstUnicastAddress(), m_macAddr
,
1226 node
->getId(), node
->getName(), iface
->getId(), iface
->getIfIndex(), iface
->getName(),
1227 &iface
->getIpAddressList()->getFirstUnicastAddress(), iface
->getMacAddr(), protocol
);
1232 * Set MAC address for interface
1234 void Interface
::setMacAddr(const BYTE
*macAddr
, bool updateMacDB
)
1238 MacDbRemove(m_macAddr
);
1239 memcpy(m_macAddr
, macAddr
, MAC_ADDR_LENGTH
);
1241 MacDbAddInterface(this);
1242 setModified(MODIFY_INTERFACE_PROPERTIES
);
1247 * Set IP address (should be used only for fake interfaces with single IP)
1249 void Interface
::setIpAddress(const InetAddress
& addr
)
1252 if (m_ipAddressList
.size() == 1)
1254 UpdateInterfaceIndex(m_ipAddressList
.get(0), addr
, this);
1255 m_ipAddressList
.clear();
1256 m_ipAddressList
.add(addr
);
1257 setModified(MODIFY_INTERFACE_PROPERTIES
);
1263 * Get first usable IP address
1265 const InetAddress
& Interface
::getFirstIpAddress()
1267 const InetAddress
& a
= m_ipAddressList
.getFirstUnicastAddress();
1268 return a
.isValid() ? a
: m_ipAddressList
.get(0);
1274 void Interface
::addIpAddress(const InetAddress
& addr
)
1277 m_ipAddressList
.add(addr
);
1278 setModified(MODIFY_INTERFACE_PROPERTIES
);
1280 if (!isExcludedFromTopology())
1282 if (IsZoningEnabled())
1284 Zone
*zone
= FindZoneByUIN(m_zoneUIN
);
1287 zone
->addToIndex(addr
, this);
1291 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"), (int)m_zoneUIN
, m_name
, (int)m_id
);
1296 g_idxInterfaceByAddr
.put(addr
, this);
1304 void Interface
::deleteIpAddress(InetAddress addr
)
1307 m_ipAddressList
.remove(addr
);
1308 setModified(MODIFY_INTERFACE_PROPERTIES
);
1310 if (!isExcludedFromTopology())
1312 if (IsZoningEnabled())
1314 Zone
*zone
= FindZoneByUIN(m_zoneUIN
);
1317 zone
->removeFromInterfaceIndex(addr
);
1321 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"), (int)m_zoneUIN
, m_name
, (int)m_id
);
1326 g_idxInterfaceByAddr
.remove(addr
);
1332 * Change network mask for IP address
1334 void Interface
::setNetMask(const InetAddress
& addr
)
1337 m_ipAddressList
.replace(addr
);
1338 setModified(MODIFY_INTERFACE_PROPERTIES
);
1343 * Create NXSL object for this object
1345 NXSL_Value
*Interface
::createNXSLObject()
1347 return new NXSL_Value(new NXSL_Object(&g_nxslInterfaceClass
, this));
1351 * Serialize object to JSON
1353 json_t
*Interface
::toJson()
1355 json_t
*root
= NetObj
::toJson();
1356 json_object_set_new(root
, "index", json_integer(m_index
));
1357 char macAddrText
[64];
1358 json_object_set_new(root
, "macAddr", json_string(BinToStrA(m_macAddr
, MAC_ADDR_LENGTH
, macAddrText
)));
1359 json_object_set_new(root
, "ipAddressList", m_ipAddressList
.toJson());
1360 json_object_set_new(root
, "flags", json_integer(m_flags
));
1361 json_object_set_new(root
, "description", json_string_t(m_description
));
1362 json_object_set_new(root
, "alias", json_string_t(m_alias
));
1363 json_object_set_new(root
, "type", json_integer(m_type
));
1364 json_object_set_new(root
, "mtu", json_integer(m_mtu
));
1365 json_object_set_new(root
, "speed", json_integer(m_speed
));
1366 json_object_set_new(root
, "bridgePortNumber", json_integer(m_bridgePortNumber
));
1367 json_object_set_new(root
, "slotNumber", json_integer(m_slotNumber
));
1368 json_object_set_new(root
, "portNumber", json_integer(m_portNumber
));
1369 json_object_set_new(root
, "peerNodeId", json_integer(m_peerNodeId
));
1370 json_object_set_new(root
, "peerInterfaceId", json_integer(m_peerInterfaceId
));
1371 json_object_set_new(root
, "peerDiscoveryProtocol", json_integer(m_peerDiscoveryProtocol
));
1372 json_object_set_new(root
, "adminState", json_integer(m_adminState
));
1373 json_object_set_new(root
, "operState", json_integer(m_operState
));
1374 json_object_set_new(root
, "pendingOperState", json_integer(m_pendingOperState
));
1375 json_object_set_new(root
, "confirmedOperState", json_integer(m_confirmedOperState
));
1376 json_object_set_new(root
, "dot1xPaeAuthState", json_integer(m_dot1xPaeAuthState
));
1377 json_object_set_new(root
, "dot1xBackendAuthState", json_integer(m_dot1xBackendAuthState
));
1378 json_object_set_new(root
, "lastDownEventId", json_integer(m_lastDownEventId
));
1379 json_object_set_new(root
, "pendingStatus", json_integer(m_pendingStatus
));
1380 json_object_set_new(root
, "statusPollCount", json_integer(m_statusPollCount
));
1381 json_object_set_new(root
, "operStatePollCount", json_integer(m_operStatePollCount
));
1382 json_object_set_new(root
, "requiredPollCount", json_integer(m_requiredPollCount
));
1383 json_object_set_new(root
, "zoneUIN", json_integer(m_zoneUIN
));
1384 json_object_set_new(root
, "pingTime", json_integer(m_pingTime
));
1385 json_object_set_new(root
, "pingLastTimeStamp", json_integer(m_pingLastTimeStamp
));
1386 json_object_set_new(root
, "ifTableSuffixLen", json_integer(m_ifTableSuffixLen
));
1387 json_object_set_new(root
, "ifTableSuffix", json_integer_array(m_ifTableSuffix
, m_ifTableSuffixLen
));