i am working on a project of network management baseed on net-snmp.In my
situation i have to get the mac,arp,if table of a swither or a router.So a
build a object to get all the table of a device,but when the mount of the
device comes huge the time it takes too long to wait.
so i creat a single object for a deivce to get the table information.and
let the single object worked within a thread but it does't works.As follow
is my funtion to get if table
int CSnmpDeviceInfo::GetIfTable()
{
///////清空if table/////////////////////
INTERFACE_TABLE_ENTRY * pIf1,*pIf2;
pIf1 = m_ifTable;
while(pIf1 != NULL)
{
pIf2 = pIf1;
pIf1 = pIf1->next;
delete pIf2;
d_dwDeletIfEntry++;
}
m_ifTable = NULL;
///////////////////////////////////////
int iEntry = 0;
/*
* Transfer result to string
*/
u_char *buf = NULL;
size_t out_len = 0, buf_len = 0;
/*
* Select result from string
*/
CString transfer;
int begin=0;
/*
* Build table link
*/
struct INTERFACE_TABLE_ENTRY *p1,*p2;
p1=p2=new struct INTERFACE_TABLE_ENTRY;
memset(p1,0,sizeof(INTERFACE_TABLE_ENTRY_1));
int first=0;
int sequence=1;
int create=0;
int col;
netsnmp_session session, *ss;
netsnmp_pdu *pdu, *response;
netsnmp_variable_list *vars;
oid name[22][MAX_OID_LEN];
size_t name_length[22];
oid root[22][MAX_OID_LEN];
size_t rootlen[22];
int running;
int status;
// int exitval = 0;
init_snmp("SnmpDeviceInfo");
snmp_sess_init(&session);
session.version=SNMP_VERSION_1;
session.peername=m_strDeviceIP;
session.community=(unsigned char *)m_strReadCommunity;
session.community_len=strlen((const char *)session.community);
SOCK_STARTUP;
/*
* open an SNMP session
*/
ss = snmp_open(&session);
if (ss == NULL)
{
/*
* diagnose snmp_open errors with the input netsnmp_session pointer
*/
// snmp_sess_perror("SnmpDeviceInfo", &session);
AfxMessageBox("Error:Session open failed!");
SOCK_CLEANUP;
exit(1);
}
/*
* get first object to start
*/
running = 1;
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
read_objid("1.3.6.1.2.1.2.2.1.1", root[0], &rootlen[0]);
read_objid("1.3.6.1.2.1.2.2.1.2", root[1], &rootlen[1]);
read_objid("1.3.6.1.2.1.2.2.1.3", root[2], &rootlen[2]);
read_objid("1.3.6.1.2.1.2.2.1.4", root[3], &rootlen[3]);
read_objid("1.3.6.1.2.1.2.2.1.5", root[4], &rootlen[4]);
read_objid("1.3.6.1.2.1.2.2.1.6", root[5], &rootlen[5]);
read_objid("1.3.6.1.2.1.2.2.1.7", root[6], &rootlen[6]);
read_objid("1.3.6.1.2.1.2.2.1.8", root[7], &rootlen[7]);
read_objid("1.3.6.1.2.1.2.2.1.9", root[8], &rootlen[8]);
read_objid("1.3.6.1.2.1.2.2.1.10", root[9], &rootlen[9]);
read_objid("1.3.6.1.2.1.2.2.1.11", root[10], &rootlen[10]);
read_objid("1.3.6.1.2.1.2.2.1.12", root[11], &rootlen[11]);
read_objid("1.3.6.1.2.1.2.2.1.13", root[12], &rootlen[12]);
read_objid("1.3.6.1.2.1.2.2.1.14", root[13], &rootlen[13]);
read_objid("1.3.6.1.2.1.2.2.1.15", root[14], &rootlen[14]);
read_objid("1.3.6.1.2.1.2.2.1.16", root[15], &rootlen[15]);
read_objid("1.3.6.1.2.1.2.2.1.17", root[16], &rootlen[16]);
read_objid("1.3.6.1.2.1.2.2.1.18", root[17], &rootlen[17]);
read_objid("1.3.6.1.2.1.2.2.1.19", root[18], &rootlen[18]);
read_objid("1.3.6.1.2.1.2.2.1.20", root[19], &rootlen[19]);
read_objid("1.3.6.1.2.1.2.2.1.21", root[20], &rootlen[20]);
read_objid("1.3.6.1.2.1.2.2.1.22", root[21], &rootlen[21]);
for(col=0;col<22;col++)
{
memmove(name[col], root[col], rootlen[col] * sizeof(oid));
name_length[col] = rootlen[col];
snmp_add_null_var(pdu, root[col], rootlen[col]);
}
/*
* Get next while not end
*/
while (running)
{
/*
* create PDU for GETNEXT request and add object name to request
* the first has ben created so jump this
*/
if(first!=0)
{
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
for(col=0;col<22;col++)
snmp_add_null_var(pdu, name[col],
name_length[col]);
}
int x=0;
/*
* do the request
*/
status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS)
{
if (response->errstat == SNMP_ERR_NOERROR)
{
/*
* check resulting variables
*/
col=-1;
sequence=0;
for (vars = response->variables; vars;vars =
vars->next_variable)
{
col++;
sequence++;
/*
* compare the the vars oid (except
index part) with the root oid
* to see wheather it's the part of the
table
*/
if ((vars->name_length < rootlen[col])
|| (memcmp(root[col], vars->name, rootlen[col] *
sizeof(oid))!= 0))
{
/*
* not part of this subtree
*/
running = 0;
continue;
}
/*
* fatch the result and fill the table
link
*/
buf = NULL;
out_len=buf_len = 0;
sprint_realloc_variable(&buf, &buf_len, &out_len, 1,vars->name,
vars->name_length, vars);
transfer.Format("%s",buf);
begin=transfer.Find('=')+2;
transfer=transfer.Mid(begin,transfer.GetLength()-begin);
begin=transfer.Find(':')+2;
switch(sequence)
{
case 1:
p1->ifIndex=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 2:
strcpy(p1->ifDescr,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 3:
strcpy(p1->ifType,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 4:
p1->ifMtu=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 5:
strcpy(p1->ifSpeed,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 6:
strcpy(p1->ifPhysAddress,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 7:
strcpy(p1->ifAdminStatus,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 8:
strcpy(p1->ifOperStatus,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 9:
strcpy(p1->ifLastChange,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 10:
p1->ifInOctests=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 11:
p1->ifInUcastPkts=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 12:
p1->ifInNUcastPkts=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 13:
p1->ifInDiscards=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 14:
p1->ifInErrors=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 15:
p1->ifInUnknownProtos=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 16:
p1->ifOutOctets=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 17:
p1->ifOutUcastPkts=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 18:
p1->ifOutNUcastPkts=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 19:
p1->ifOutDiscards=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 20:
p1->ifOutErrors=atoi(transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 21:
strcpy(p1->ifOutQLen,transfer.Mid(begin,transfer.GetLength()-begin));
break;
case 22:
strcpy(p1->ifSpecific,transfer.Mid(begin,transfer.GetLength()-begin));
break;
default:
break;
}
create=1;
/*
* give the next request oid to the
manager for snmpgetnex
*/
if ((vars->type != SNMP_ENDOFMIBVIEW) &&
(vars->type != SNMP_NOSUCHOBJECT) &&
(vars->type != SNMP_NOSUCHINSTANCE))
{
memmove((char *) name[col], (char
*) vars->name,
vars->name_length * sizeof(oid));
name_length[col] = vars->name_length;
}
else
/*
* an exception value, so stop
*/
running = 0;
} //end of for(vars;vars->next)
if(create==1)
{
iEntry++;
/*
* Generate table link
*/
if(first==0)
{
m_ifTable=p1;
first=1;
}
else
p2->next=p1;
p2=p1;
p2->next=NULL;
p1=new struct INTERFACE_TABLE_ENTRY;
create=0;
d_dwNewIfEntry++; //2006.05.29
}
} //end of if(response is right)
else
{
/*
* error in response, print it
*/
running = 0;
if (response->errstat == SNMP_ERR_NOSUCHNAME)
strcpy(p1->ifDescr,"End of MIB");
else
{
strcpy(p1->ifDescr,"Error in packet");
// exitval = 2;
}
}
}//end of if(status is succeed)
else if (status == STAT_TIMEOUT)
{
strcpy(p1->ifDescr,"Time out");
running = 0;
// exitval = 1;
}
else
{
/* status == STAT_ERROR */
strcpy(p1->ifDescr,"snmpwalk error");
running = 0;
// exitval = 1;
}
if (response)
{
snmp_free_pdu(response);
}
}//end of while have next
snmp_close(ss);
SOCK_CLEANUP;
return iEntry;
}
it works under vs2005+winxp
it always happened that one thread can works well,and the others all stop
at the line
status = snmp_synch_response(ss, pdu, &response);
does the function support multithread? or anyone who has done the same work
please help me!
regards for all your help
_________________________________________________________________
免费下载 MSN Explorer: http://explorer.msn.com/lccn/
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders