SNMPGetInterfaceList changed to prevent possible creation of incomplete interface...
[public/netxms.git] / src / server / core / snmp.cpp
CommitLineData
d7d76e50
VK
1/*
2** Project X - Network Management System
3** Copyright (C) 2003 Victor Kirhenshtein
4**
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.
9**
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.
14**
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.
18**
19** $module: snmp.cpp
20**
21**/
22
a551fe4d 23#include "nxcore.h"
d7d76e50
VK
24
25
18e26ff8
VK
26//
27// OID translation structure
28//
29
30struct OID_TABLE
31{
32 TCHAR *pszOid;
33 DWORD dwNodeType;
34 DWORD dwNodeFlags;
35};
36
37
38//
39// Static data
40//
41
42static OID_TABLE *m_pOidTable = NULL;
43static DWORD m_dwOidTableSize = 0;
7fd85a01 44static DWORD m_dwRequestId = 1;
18e26ff8
VK
45
46
be0a5a53
VK
47//
48// Initialize SNMP subsystem
49//
50
51void SnmpInit(void)
52{
18e26ff8
VK
53 DB_RESULT hResult;
54 DWORD i;
55
18e26ff8
VK
56 // Load OID to type translation table
57 hResult = DBSelect(g_hCoreDB, _T("SELECT snmp_oid,node_type,node_flags FROM oid_to_type ORDER BY pair_id"));
58 if (hResult != NULL)
59 {
60 m_dwOidTableSize = DBGetNumRows(hResult);
61 m_pOidTable = (OID_TABLE *)malloc(sizeof(OID_TABLE) * m_dwOidTableSize);
62 for(i = 0; i < m_dwOidTableSize; i++)
63 {
64 m_pOidTable[i].pszOid = _tcsdup(DBGetField(hResult, i, 0));
65 m_pOidTable[i].dwNodeType = DBGetFieldULong(hResult, i, 1);
66 m_pOidTable[i].dwNodeFlags = DBGetFieldULong(hResult, i, 2);
67 }
68 DBFreeResult(hResult);
69 }
70}
71
72
73//
74// Determine node type by OID
75//
76
77DWORD OidToType(TCHAR *pszOid, DWORD *pdwFlags)
78{
79 DWORD i;
80
81 for(i = 0; i < m_dwOidTableSize; i++)
82 if (MatchString(m_pOidTable[i].pszOid, pszOid, TRUE))
83 {
84 if (pdwFlags != NULL)
85 *pdwFlags = m_pOidTable[i].dwNodeFlags;
86 return m_pOidTable[i].dwNodeType;
87 }
88
fd5aa295 89 *pdwFlags = 0;
18e26ff8 90 return NODE_TYPE_GENERIC;
be0a5a53
VK
91}
92
93
d7d76e50
VK
94//
95// Get value for SNMP variable
96// If szOidStr is not NULL, string representation of OID is used, otherwise -
80de4676 97// binary representation from oidBinary and dwOidLen
d7d76e50
VK
98//
99
80de4676
VK
100DWORD SnmpGet(DWORD dwVersion, DWORD dwAddr, const char *szCommunity, const char *szOidStr,
101 const DWORD *oidBinary, DWORD dwOidLen, void *pValue,
102 DWORD dwBufferSize, BOOL bVerbose, BOOL bStringResult)
d7d76e50 103{
3d1cb7d6
VK
104 SNMP_Transport *pTransport;
105 SNMP_PDU *pRqPDU, *pRespPDU;
106 DWORD dwNameLen, pdwVarName[MAX_OID_LEN], dwResult;
d7d76e50
VK
107
108 // Open SNMP session
3d1cb7d6 109 pTransport = new SNMP_Transport;
80de4676
VK
110 dwResult = pTransport->CreateUDPTransport(NULL, htonl(dwAddr));
111 if (dwResult != SNMP_ERR_SUCCESS)
d7d76e50 112 {
3d1cb7d6 113 WriteLog(MSG_SNMP_TRANSPORT_FAILED, EVENTLOG_ERROR_TYPE, NULL);
d7d76e50
VK
114 }
115 else
116 {
a7b85168 117 // Create PDU and send request
3d1cb7d6 118 pRqPDU = new SNMP_PDU(SNMP_GET_REQUEST, (char *)szCommunity, m_dwRequestId++, dwVersion);
a7b85168 119 if (szOidStr != NULL)
d7d76e50 120 {
3d1cb7d6
VK
121 dwNameLen = SNMPParseOID(szOidStr, pdwVarName, MAX_OID_LEN);
122 if (dwNameLen == 0)
d7d76e50 123 {
a7b85168 124 WriteLog(MSG_OID_PARSE_ERROR, EVENTLOG_ERROR_TYPE, "s", szOidStr);
80de4676 125 dwResult = SNMP_ERR_BAD_OID;
d7d76e50
VK
126 }
127 }
a7b85168 128 else
d7d76e50 129 {
3d1cb7d6
VK
130 memcpy(pdwVarName, oidBinary, dwOidLen * sizeof(DWORD));
131 dwNameLen = dwOidLen;
d7d76e50 132 }
a7b85168 133
80de4676 134 if (dwResult == SNMP_ERR_SUCCESS) // Still no errors
d7d76e50 135 {
3d1cb7d6
VK
136 pRqPDU->BindVariable(new SNMP_Variable(pdwVarName, dwNameLen));
137 dwResult = pTransport->DoRequest(pRqPDU, &pRespPDU, 1000, 3);
a7b85168
VK
138
139 // Analyze response
3d1cb7d6 140 if (dwResult == SNMP_ERR_SUCCESS)
a7b85168 141 {
80de4676
VK
142 if ((pRespPDU->GetNumVariables() > 0) &&
143 (pRespPDU->GetErrorCode() == 0))
a7b85168 144 {
3d1cb7d6
VK
145 SNMP_Variable *pVar = pRespPDU->GetVariable(0);
146
80de4676
VK
147 if ((pVar->GetType() != ASN_NO_SUCH_OBJECT) &&
148 (pVar->GetType() != ASN_NO_SUCH_INSTANCE))
a7b85168 149 {
80de4676
VK
150 if (bStringResult)
151 {
152 pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize);
153 }
154 else
155 {
156 switch(pVar->GetType())
157 {
158 case ASN_INTEGER:
159 case ASN_UINTEGER32:
160 case ASN_COUNTER32:
161 case ASN_GAUGE32:
162 case ASN_TIMETICKS:
163 *((long *)pValue) = pVar->GetValueAsInt();
164 break;
165 case ASN_IP_ADDR:
166 *((long *)pValue) = ntohl(pVar->GetValueAsUInt());
167 break;
168 case ASN_OCTET_STRING:
169 pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize);
170 break;
171 case ASN_OBJECT_ID:
172 pVar->GetValueAsString((TCHAR *)pValue, dwBufferSize);
173 break;
174 default:
175 WriteLog(MSG_SNMP_UNKNOWN_TYPE, EVENTLOG_ERROR_TYPE, "x", pVar->GetType());
176 dwResult = SNMP_ERR_BAD_TYPE;
177 break;
178 }
179 }
3d1cb7d6
VK
180 }
181 else
182 {
80de4676 183 dwResult = SNMP_ERR_NO_OBJECT;
a7b85168 184 }
a7b85168
VK
185 }
186 else
187 {
80de4676 188 dwResult = SNMP_ERR_AGENT;
a7b85168 189 }
3d1cb7d6
VK
190 delete pRespPDU;
191 }
192 else
193 {
194 if (bVerbose)
195 WriteLog(MSG_SNMP_GET_ERROR, EVENTLOG_ERROR_TYPE, "d", dwResult);
a7b85168 196 }
d7d76e50 197 }
d7d76e50 198
3d1cb7d6 199 delete pRqPDU;
a7b85168 200 }
d7d76e50 201
3d1cb7d6 202 delete pTransport;
80de4676 203 return dwResult;
d7d76e50 204}
530dc946
VK
205
206
207//
208// Enumerate multiple values by walking throgh MIB, starting at given root
209//
210
80de4676
VK
211DWORD SnmpEnumerate(DWORD dwVersion, DWORD dwAddr, const char *szCommunity,
212 const char *szRootOid,
213 void (* pHandler)(DWORD, DWORD, const char *, SNMP_Variable *, void *),
214 void *pUserArg, BOOL bVerbose)
530dc946 215{
3d1cb7d6
VK
216 DWORD pdwRootName[MAX_OID_LEN], dwRootLen, pdwName[MAX_OID_LEN], dwNameLen, dwResult;
217 SNMP_PDU *pRqPDU, *pRespPDU;
218 SNMP_Transport *pTransport;
80de4676 219 BOOL bRunning = TRUE;
530dc946
VK
220
221 // Open SNMP session
3d1cb7d6 222 pTransport = new SNMP_Transport;
80de4676
VK
223 dwResult = pTransport->CreateUDPTransport(NULL, htonl(dwAddr));
224 if (dwResult != SNMP_ERR_SUCCESS)
530dc946 225 {
3d1cb7d6 226 WriteLog(MSG_SNMP_TRANSPORT_FAILED, EVENTLOG_ERROR_TYPE, NULL);
530dc946 227 }
3d1cb7d6 228 else
530dc946 229 {
3d1cb7d6
VK
230 // Get root
231 dwRootLen = SNMPParseOID(szRootOid, pdwRootName, MAX_OID_LEN);
232 if (dwRootLen == 0)
530dc946 233 {
3d1cb7d6 234 WriteLog(MSG_OID_PARSE_ERROR, EVENTLOG_ERROR_TYPE, "s", szRootOid);
80de4676 235 dwResult = SNMP_ERR_BAD_OID;
530dc946
VK
236 }
237 else
238 {
3d1cb7d6
VK
239 memcpy(pdwName, pdwRootName, dwRootLen * sizeof(DWORD));
240 dwNameLen = dwRootLen;
241
242 // Walk the MIB
243 while(bRunning)
530dc946 244 {
3d1cb7d6
VK
245 pRqPDU = new SNMP_PDU(SNMP_GET_NEXT_REQUEST, (char *)szCommunity, m_dwRequestId++, dwVersion);
246 pRqPDU->BindVariable(new SNMP_Variable(pdwName, dwNameLen));
247 dwResult = pTransport->DoRequest(pRqPDU, &pRespPDU, 1000, 3);
530dc946 248
3d1cb7d6
VK
249 // Analyze response
250 if (dwResult == SNMP_ERR_SUCCESS)
251 {
80de4676
VK
252 if ((pRespPDU->GetNumVariables() > 0) &&
253 (pRespPDU->GetErrorCode() == 0))
3d1cb7d6
VK
254 {
255 SNMP_Variable *pVar = pRespPDU->GetVariable(0);
256
80de4676
VK
257 if ((pVar->GetType() != ASN_NO_SUCH_OBJECT) &&
258 (pVar->GetType() != ASN_NO_SUCH_INSTANCE))
259 {
260 // Should we stop walking?
261 if ((pVar->GetName()->Length() < dwRootLen) ||
262 (memcmp(pdwRootName, pVar->GetName()->GetValue(), dwRootLen * sizeof(DWORD))))
263 {
264 bRunning = FALSE;
265 delete pRespPDU;
266 delete pRqPDU;
267 break;
268 }
269 memcpy(pdwName, pVar->GetName()->GetValue(),
270 pVar->GetName()->Length() * sizeof(DWORD));
271 dwNameLen = pVar->GetName()->Length();
272
273 // Call user's callback function for processing
274 pHandler(dwVersion, dwAddr, szCommunity, pVar, pUserArg);
275 }
276 else
3d1cb7d6 277 {
80de4676 278 dwResult = SNMP_ERR_NO_OBJECT;
3d1cb7d6 279 bRunning = FALSE;
3d1cb7d6 280 }
3d1cb7d6
VK
281 }
282 else
283 {
80de4676 284 dwResult = SNMP_ERR_AGENT;
3d1cb7d6
VK
285 bRunning = FALSE;
286 }
287 delete pRespPDU;
288 }
289 else
290 {
291 if (bVerbose)
292 WriteLog(MSG_SNMP_GET_ERROR, EVENTLOG_ERROR_TYPE, "d", dwResult);
3d1cb7d6
VK
293 bRunning = FALSE;
294 }
295 delete pRqPDU;
296 }
530dc946
VK
297 }
298 }
299
3d1cb7d6 300 delete pTransport;
80de4676 301 return dwResult;
a0495b6e
VK
302}
303
304
5811233f
VK
305//
306// Handler for enumerating indexes
307//
308
3d1cb7d6
VK
309static void HandlerIndex(DWORD dwVersion, DWORD dwAddr, const char *szCommunity,
310 SNMP_Variable *pVar, void *pArg)
5811233f
VK
311{
312 if (((INTERFACE_LIST *)pArg)->iEnumPos < ((INTERFACE_LIST *)pArg)->iNumEntries)
3d1cb7d6 313 ((INTERFACE_LIST *)pArg)->pInterfaces[((INTERFACE_LIST *)pArg)->iEnumPos].dwIndex = pVar->GetValueAsUInt();
5811233f
VK
314 ((INTERFACE_LIST *)pArg)->iEnumPos++;
315}
316
317
a0495b6e
VK
318//
319// Handler for enumerating IP addresses
320//
321
3d1cb7d6
VK
322static void HandlerIpAddr(DWORD dwVersion, DWORD dwAddr, const char *szCommunity,
323 SNMP_Variable *pVar, void *pArg)
a0495b6e 324{
3d1cb7d6
VK
325 DWORD dwIndex, dwNetMask, dwNameLen;
326 DWORD oidName[MAX_OID_LEN];
a0495b6e 327
3d1cb7d6
VK
328 dwNameLen = pVar->GetName()->Length();
329 memcpy(oidName, pVar->GetName()->GetValue(), dwNameLen * sizeof(DWORD));
330 oidName[dwNameLen - 5] = 3; // Retrieve network mask for this IP
80de4676
VK
331 if (SnmpGet(dwVersion, dwAddr, szCommunity, NULL, oidName, dwNameLen,
332 &dwNetMask, sizeof(DWORD), FALSE, FALSE) != SNMP_ERR_SUCCESS)
9437ca82
VK
333 return;
334
3d1cb7d6
VK
335 oidName[dwNameLen - 5] = 2; // Retrieve interface index for this IP
336 if (SnmpGet(dwVersion, dwAddr, szCommunity, NULL, oidName, dwNameLen,
80de4676 337 &dwIndex, sizeof(DWORD), FALSE, FALSE) == SNMP_ERR_SUCCESS)
a0495b6e
VK
338 {
339 int i;
340
341 for(i = 0; i < ((INTERFACE_LIST *)pArg)->iNumEntries; i++)
342 if (((INTERFACE_LIST *)pArg)->pInterfaces[i].dwIndex == dwIndex)
343 {
9437ca82
VK
344 if (((INTERFACE_LIST *)pArg)->pInterfaces[i].dwIpAddr != 0)
345 {
346 // This interface entry already filled, so we have additional IP addresses
347 // on a single interface
348 ((INTERFACE_LIST *)pArg)->iNumEntries++;
9d72bde1 349 ((INTERFACE_LIST *)pArg)->pInterfaces = (INTERFACE_INFO *)realloc(((INTERFACE_LIST *)pArg)->pInterfaces,
9437ca82
VK
350 sizeof(INTERFACE_INFO) * ((INTERFACE_LIST *)pArg)->iNumEntries);
351 memcpy(&(((INTERFACE_LIST *)pArg)->pInterfaces[((INTERFACE_LIST *)pArg)->iNumEntries - 1]),
352 &(((INTERFACE_LIST *)pArg)->pInterfaces[i]), sizeof(INTERFACE_INFO));
353 if (strlen(((INTERFACE_LIST *)pArg)->pInterfaces[i].szName) < MAX_OBJECT_NAME - 4)
354 {
355 char szBuffer[8];
356
357 sprintf(szBuffer,":%d", ((INTERFACE_LIST *)pArg)->pInterfaces[i].iNumSecondary++);
358 strcat(((INTERFACE_LIST *)pArg)->pInterfaces[((INTERFACE_LIST *)pArg)->iNumEntries - 1].szName, szBuffer);
359 }
360 i = ((INTERFACE_LIST *)pArg)->iNumEntries - 1;
361 }
3d1cb7d6 362 ((INTERFACE_LIST *)pArg)->pInterfaces[i].dwIpAddr = ntohl(pVar->GetValueAsUInt());
9437ca82 363 ((INTERFACE_LIST *)pArg)->pInterfaces[i].dwIpNetMask = dwNetMask;
a0495b6e
VK
364 break;
365 }
366 }
367}
368
369
a0495b6e
VK
370//
371// Get interface list via SNMP
372//
373
3d1cb7d6
VK
374INTERFACE_LIST *SnmpGetInterfaceList(DWORD dwVersion, DWORD dwAddr,
375 const char *szCommunity, DWORD dwNodeType)
a0495b6e
VK
376{
377 long i, iNumIf;
b50f1100 378 char szOid[128], szBuffer[256];
a0495b6e 379 INTERFACE_LIST *pIfList = NULL;
79d11ecc 380 BOOL bSuccess = FALSE;
a0495b6e
VK
381
382 // Get number of interfaces
80de4676
VK
383 if (SnmpGet(dwVersion, dwAddr, szCommunity, ".1.3.6.1.2.1.2.1.0", NULL, 0,
384 &iNumIf, sizeof(long), FALSE, FALSE) != SNMP_ERR_SUCCESS)
a0495b6e
VK
385 return NULL;
386
387 // Create empty list
9d72bde1 388 pIfList = (INTERFACE_LIST *)malloc(sizeof(INTERFACE_LIST));
a0495b6e 389 pIfList->iNumEntries = iNumIf;
5811233f 390 pIfList->iEnumPos = 0;
9d72bde1 391 pIfList->pInterfaces = (INTERFACE_INFO *)malloc(sizeof(INTERFACE_INFO) * iNumIf);
a0495b6e
VK
392 memset(pIfList->pInterfaces, 0, sizeof(INTERFACE_INFO) * pIfList->iNumEntries);
393
5811233f 394 // Gather interface indexes
79d11ecc
VK
395 if (SnmpEnumerate(dwVersion, dwAddr, szCommunity, ".1.3.6.1.2.1.2.2.1.1",
396 HandlerIndex, pIfList, FALSE) == SNMP_ERR_SUCCESS)
a0495b6e 397 {
79d11ecc
VK
398 // Enumerate interfaces
399 for(i = 0; i < iNumIf; i++)
400 {
401 // Interface name
402 sprintf(szOid, ".1.3.6.1.2.1.2.2.1.2.%d", pIfList->pInterfaces[i].dwIndex);
403 if (SnmpGet(dwVersion, dwAddr, szCommunity, szOid, NULL, 0,
404 pIfList->pInterfaces[i].szName, MAX_OBJECT_NAME,
405 FALSE, FALSE) != SNMP_ERR_SUCCESS)
406 break;
a0495b6e 407
79d11ecc
VK
408 // Interface type
409 sprintf(szOid, ".1.3.6.1.2.1.2.2.1.3.%d", pIfList->pInterfaces[i].dwIndex);
410 if (SnmpGet(dwVersion, dwAddr, szCommunity, szOid, NULL, 0,
411 &pIfList->pInterfaces[i].dwType, sizeof(DWORD),
412 FALSE, FALSE) != SNMP_ERR_SUCCESS)
413 break;
a0495b6e 414
79d11ecc
VK
415 // MAC address
416 sprintf(szOid, ".1.3.6.1.2.1.2.2.1.6.%d", pIfList->pInterfaces[i].dwIndex);
417 memset(szBuffer, 0, MAC_ADDR_LENGTH);
418 if (SnmpGet(dwVersion, dwAddr, szCommunity, szOid, NULL, 0,
419 szBuffer, 256, FALSE, TRUE) != SNMP_ERR_SUCCESS)
420 break;
421 memcpy(pIfList->pInterfaces[i].bMacAddr, szBuffer, MAC_ADDR_LENGTH);
422 }
423
424 if (i == iNumIf)
425 {
426 // Interface IP address'es and netmasks
427 if (SnmpEnumerate(dwVersion, dwAddr, szCommunity, ".1.3.6.1.2.1.4.20.1.1",
428 HandlerIpAddr, pIfList, FALSE) == SNMP_ERR_SUCCESS)
429 {
430 // Handle special cases
431 if (dwNodeType == NODE_TYPE_NORTEL_ACCELAR)
432 GetAccelarVLANIfList(dwVersion, dwAddr, szCommunity, pIfList);
433 bSuccess = TRUE;
434 }
435 }
436 }
18e26ff8 437
79d11ecc
VK
438 if (bSuccess)
439 {
440 CleanInterfaceList(pIfList);
441 }
442 else
443 {
444 DestroyInterfaceList(pIfList);
445 }
5811233f 446
a0495b6e
VK
447 return pIfList;
448}
ce19c304
VK
449
450
451//
452// Handler for ARP enumeration
453//
454
3d1cb7d6
VK
455static void HandlerArp(DWORD dwVersion, DWORD dwAddr, const char *szCommunity,
456 SNMP_Variable *pVar,void *pArg)
ce19c304 457{
3d1cb7d6 458 DWORD oidName[MAX_OID_LEN], dwNameLen, dwIndex = 0;
ce19c304
VK
459 BYTE bMac[64];
460
3d1cb7d6
VK
461 dwNameLen = pVar->GetName()->Length();
462 memcpy(oidName, pVar->GetName()->GetValue(), dwNameLen * sizeof(DWORD));
48b1c0ac 463
3d1cb7d6
VK
464 oidName[dwNameLen - 6] = 1; // Retrieve interface index
465 SnmpGet(dwVersion, dwAddr, szCommunity, NULL, oidName, dwNameLen, &dwIndex,
f92869c9 466 sizeof(DWORD), FALSE, FALSE);
48b1c0ac 467
3d1cb7d6
VK
468 oidName[dwNameLen - 6] = 2; // Retrieve MAC address for this IP
469 if (SnmpGet(dwVersion, dwAddr, szCommunity, NULL, oidName, dwNameLen, bMac,
80de4676 470 64, FALSE, FALSE) == SNMP_ERR_SUCCESS)
ce19c304
VK
471 {
472 ((ARP_CACHE *)pArg)->dwNumEntries++;
9d72bde1 473 ((ARP_CACHE *)pArg)->pEntries = (ARP_ENTRY *)realloc(((ARP_CACHE *)pArg)->pEntries,
ce19c304 474 sizeof(ARP_ENTRY) * ((ARP_CACHE *)pArg)->dwNumEntries);
3d1cb7d6 475 ((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].dwIpAddr = ntohl(pVar->GetValueAsUInt());
ce19c304 476 memcpy(((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].bMacAddr, bMac, 6);
48b1c0ac 477 ((ARP_CACHE *)pArg)->pEntries[((ARP_CACHE *)pArg)->dwNumEntries - 1].dwIndex = dwIndex;
ce19c304
VK
478 }
479}
480
481
482//
483// Get ARP cache via SNMP
484//
485
37c4d6aa 486ARP_CACHE *SnmpGetArpCache(DWORD dwVersion, DWORD dwAddr, const char *szCommunity)
ce19c304
VK
487{
488 ARP_CACHE *pArpCache;
489
9d72bde1 490 pArpCache = (ARP_CACHE *)malloc(sizeof(ARP_CACHE));
ce19c304
VK
491 if (pArpCache == NULL)
492 return NULL;
493
494 pArpCache->dwNumEntries = 0;
495 pArpCache->pEntries = NULL;
496
80de4676
VK
497 if (SnmpEnumerate(dwVersion, dwAddr, szCommunity, ".1.3.6.1.2.1.4.22.1.3",
498 HandlerArp, pArpCache, FALSE) != SNMP_ERR_SUCCESS)
ce19c304
VK
499 {
500 DestroyArpCache(pArpCache);
501 pArpCache = NULL;
502 }
503 return pArpCache;
504}
80de4676
VK
505
506
507//
508// Get interface status via SNMP
509// Possible return values can be NORMAL, CRITICAL, DISABLED, TESTING and UNKNOWN
510//
511
512int SnmpGetInterfaceStatus(DWORD dwNodeAddr, DWORD dwVersion, char *pszCommunity, DWORD dwIfIndex)
513{
514 DWORD dwAdminStatus = 0, dwOperStatus = 0;
515 int iStatus;
516 char szOid[256];
517
518 // Interface administrative status
519 sprintf(szOid, ".1.3.6.1.2.1.2.2.1.7.%ld", dwIfIndex);
520 SnmpGet(dwVersion, dwNodeAddr, pszCommunity, szOid, NULL, 0,
521 &dwAdminStatus, sizeof(DWORD), FALSE, FALSE);
522
523 switch(dwAdminStatus)
524 {
525 case 3:
526 iStatus = STATUS_TESTING;
527 break;
528 case 2:
529 iStatus = STATUS_DISABLED;
530 break;
531 case 1: // Interface administratively up, check operational status
532 // Get interface operational status
533 sprintf(szOid, ".1.3.6.1.2.1.2.2.1.8.%ld", dwIfIndex);
534 SnmpGet(dwVersion, dwNodeAddr, pszCommunity, szOid, NULL, 0,
535 &dwOperStatus, sizeof(DWORD), FALSE, FALSE);
536 switch(dwOperStatus)
537 {
538 case 3:
539 iStatus = STATUS_TESTING;
540 break;
541 case 2: // Interface is down
542 iStatus = STATUS_CRITICAL;
543 break;
544 case 1:
545 iStatus = STATUS_NORMAL;
546 break;
547 default:
548 iStatus = STATUS_UNKNOWN;
549 break;
550 }
551 break;
552 default:
553 iStatus = STATUS_UNKNOWN;
554 break;
555 }
556 return iStatus;
557}