1470 lines
45 KiB
C
1470 lines
45 KiB
C
/* m2IfLib.c - MIB-II interface-group counter update API */
|
|
|
|
/*
|
|
* Copyright (c) 2001-2006 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute, modify or otherwise make use
|
|
* of this software may be licensed only pursuant to the terms
|
|
* of an applicable Wind River license agreement.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01w,29sep10,h_x Fix build and coverity warnings
|
|
01v,21jun10,h_x Fix WIND00217113
|
|
01u,01apr10,h_x Fix warnings
|
|
01t,11jul08,zhr updated for apigen
|
|
01s,22may08,dlk Use malloc()/free() instead of KHEAP_ALLOC()/KHEAP_FREE().
|
|
Minor clean-up.
|
|
01r,28mar08,zhr Migrated to IPNET
|
|
02q,12jun06,wap Modify m2IfDelete() to uninstall _m2SetIfLastChange and
|
|
_m2IfTableUpdate function pointers.
|
|
02p,06dec05,dlk Correct typo in m2PollStatsIfPoll().
|
|
02o,14jul05,dlk Remove reference to IN6_IFDATA_DS_ID. Clear
|
|
pIfIndex->pIn6IfInfo after freeing.
|
|
02n,20apr05,kch Merged from comp_wn_ipv6_mld_interim-dev branch.
|
|
02m,09feb05,dlk Fix broadcast check handling for 802.4/802.5 frames
|
|
in m2If8023PacketCount().
|
|
02l,25jan05,sar Modify sysuptime to be based on 64 bit ticks
|
|
Remove code to limit counters from rolling over (SPR102459)
|
|
02k,31jan05,niq Fix bug in freeing the M2_IF node
|
|
02j,26jan05,vvv fixed build errors
|
|
02i,12jan05,vvv osdep.h cleanup
|
|
02h,11jan05,vvv made _in6_ifdata creation independent of m2 (SPR #88606)
|
|
02g,09nov04,dlk Make m2IfTableUpdate() and rcvEtherAddrAdd() \NOMANUAL.
|
|
02f,01oct04,wap fix polling stats routine for base6 (SPR #101616)
|
|
02e,19sep04,spm updated virtual stack startup and shutdown: restored use of
|
|
published routines and removed packing/unpacking parameters
|
|
02d,26aug04,vvv fixed warning
|
|
02c,26aug04,niq unified stack merge
|
|
02b,13aug04,kc Added m2Ipv6Initialized bool variable.
|
|
02a,13aug04,kc Fixed m2IfTableUpdate to check if the IPV6 MIB IF is
|
|
initialized.
|
|
01z,11aug04,niq VS data structure reorganization
|
|
01y,16jul04,niq Fix bug in if_index handling (SPR 99100)
|
|
01x,19may04,niq Check for memory allocation failure + use if_index instead of
|
|
ifIndex.
|
|
01w,21apr04,rae replace if_index (internal) with ifIndex (external)
|
|
01v,05dec03,xli change include path
|
|
01u,02dec03,zl use avlUintLib instead of avlLib
|
|
01t,20nov03,niq osdep.h cleanup
|
|
01r,06nov03,rlm Ran batch header update for header re-org
|
|
01q,20oct03,zl changed for new avlLib without GENERIC_ARGUMENT.
|
|
01p,08sep03,vvv merged from ACCORDION_BASE6_MERGE_BASELINE
|
|
01o,23jul03,vvv fixed memory leak in m2IfTableUpdate (SPR #88481)
|
|
01n,01may03,spm Tornado 2.2 CP1 merge (from ver 02b,20mar03,wap:
|
|
TOR2_2-CP1-F label, tor2_2-patch branch, /wind/river VOB)
|
|
01m,10apr03,ijm fixed diab compiler warnings
|
|
01l,10jan03,ann moved some globals from m2Ipv6IfLib.c
|
|
01k,10feb03,vvv added INET6 protection
|
|
01j,30sep02,kbw making man page edits
|
|
01i,30sep02,vvv fixed problem in nextIndex (SPR #71316)
|
|
01h,25sep02,ham split m2IfLib to m2IfLib and m2IfMgtLib
|
|
01g,06aug02,ann moved the prototype for m2If8023PacketCount into m2Lib.h
|
|
optimized the packet count algorithm, disabled
|
|
64 bit counter updates temporarily
|
|
01f,05aug02,ann removed the LOCAL decleration of m2If8023PacketCount
|
|
01e,15jul02,nee RFC 2465 Trap routine related fixes
|
|
01d,18jun02,ann corrected the incorrect freeing of pIfIndex in m2IfTableUpdate
|
|
01c,18sep01,ann commenting out the ifTable stuff temporarily
|
|
01b,18sep01,ann resolving some symbols
|
|
01a,12sep01,ann ported to clarinet from AE 1.0 version 01v
|
|
*/
|
|
/*
|
|
DESCRIPTION
|
|
This library provides MIB-II services for the interface group. It
|
|
provides routines to initialize the group, access the group scalar
|
|
variables, read the table interfaces and change the state of the interfaces.
|
|
For a broader description of MIB-II services, see the manual entry for m2Lib.
|
|
|
|
To use this library, include the INCLUDE_MIB2_IF configuration component.
|
|
|
|
USING THIS LIBRARY
|
|
This library can be initialized and deleted by calling m2IfInit() and
|
|
m2IfDelete() respectively, if only the interface group's services are
|
|
needed. If full MIB-II support is used, this group and all other groups
|
|
can be initialized and deleted by calling m2Init() and m2Delete().
|
|
|
|
The interface group supports the Simple Network Management Protocol (SNMP)
|
|
concept of traps, as specified by RFC 1215. The traps supported by this
|
|
group are "link up" and "link down." This library enables an application
|
|
to register a hook routine and an argument. This hook routine can be
|
|
called by the library when a "link up" or "link down" condition is
|
|
detected. The hook routine must have the following prototype:
|
|
.CS
|
|
void TrapGenerator (int trapType, /@ M2_LINK_DOWN_TRAP or M2_LINK_UP_TRAP @/
|
|
int interfaceIndex,
|
|
void * myPrivateArg);
|
|
.CE
|
|
|
|
The trap routine and argument can be specified at initialization time as
|
|
input parameters to the routine m2IfInit() or to the routine m2Init().
|
|
|
|
Access the interface-group global variables as follows:
|
|
.CS
|
|
M2_INTERFACE ifVars;
|
|
|
|
if (m2IfGroupInfoGet (&ifVars) == OK)
|
|
/@ values in ifVars are valid @/
|
|
.CE
|
|
|
|
INCLUDE FILES: m2Lib.h
|
|
|
|
SEE ALSO: m2Lib, m2SysLib, m2IpLib, m2IcmpLib, m2UdpLib, m2TcpLib
|
|
*/
|
|
|
|
/* includes */
|
|
|
|
#include <vxWorks.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include <errnoLib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <tickLib.h>
|
|
#include <m2Lib.h>
|
|
#include <m2IfLib.h>
|
|
#include <private/muxLibP.h>
|
|
|
|
/* defines */
|
|
|
|
#define END_OBJ_MIB 1 /* Used in ifnetToEndFieldsGet() */
|
|
#define END_OBJ_FLAGS 2 /* Used in ifnetToEndFieldsGet() */
|
|
|
|
IMPORT int m2If64BitCounters;
|
|
|
|
/*
|
|
* m2IfIncr64Bit : increment a 64 bit counter
|
|
*
|
|
* This macro is used to increment a 64-bit counter. The counter
|
|
* to update is pointed to by <pStat>, and <inc>, a 32-bit quantity,
|
|
* specifies how much to increment the counter.
|
|
*/
|
|
|
|
#define m2IfIncr64Bit(pStat, inc) \
|
|
do { \
|
|
UI64_ADD32((pStat), (inc)); \
|
|
} while (FALSE)
|
|
|
|
#define M2_POLLINCR_64(flag, counter) \
|
|
if (pDrvConf->ifValidCounters & (flag)) \
|
|
{ \
|
|
(pMib2Data->mibIfTbl.if ## counter) += \
|
|
((Mib2_Counter)(pDrvCounters->if ## counter & 0xFFFFFFFF)); \
|
|
m2IfIncr64Bit (&(pMib2Data->mibXIfTbl.ifHC ## counter), \
|
|
pDrvCounters->if ## counter & 0xFFFFFFFF); \
|
|
}
|
|
|
|
#define M2_POLLINCR_64_X(flag, counter) \
|
|
if (pDrvConf->ifValidCounters & (flag)) \
|
|
{ \
|
|
(pMib2Data->mibXIfTbl.if ## counter) += \
|
|
((Mib2_Counter)(pDrvCounters->if ## counter & 0xFFFFFFFF)); \
|
|
m2IfIncr64Bit (&(pMib2Data->mibXIfTbl.ifHC ## counter), \
|
|
pDrvCounters->if ## counter & 0xFFFFFFFF); \
|
|
}
|
|
|
|
#define M2_POLLINCR_32(flag, srcCounter, dstCounter) \
|
|
if (pDrvConf->ifValidCounters & (flag)) \
|
|
{ \
|
|
(pMib2Data->mibIfTbl.if ## dstCounter) += \
|
|
((Mib2_Counter)(pDrvCounters->if ## srcCounter & 0xFFFFFFFF)); \
|
|
}
|
|
STATUS m2IfTableUpdate ();
|
|
|
|
/* globals */
|
|
|
|
M2_IFINDEX * pm2IfTable; /* Network I/F table (Allocated Dynamically) */
|
|
int m2IfCount = 0; /* Number of network interfaces */
|
|
int ifsInList = 0; /* Actual number of interfaces in our list */
|
|
IMPORT FUNCPTR pM2TrapRtn; /* Pointer to trap routine supplied by the user */
|
|
IMPORT void * pM2TrapRtnArg; /* Pointer to trap routine argument supplied by */
|
|
/* the user */
|
|
ULONG m2IfTableLastChange;
|
|
|
|
/* last time a row was added/removed from the ifStackTable or when the
|
|
* ifStackStatus was last changed */
|
|
|
|
ULONG m2IfStackLastChange;
|
|
|
|
/* Semaphore used to protect the Interface group */
|
|
|
|
SEM_ID m2InterfaceSem = NULL;
|
|
|
|
/*
|
|
* Global variable used to keep the group startup time in 64 bit ticks.
|
|
* The functionality here is the same as the functionality provided in the
|
|
* module m2SysLib.c. It is duplicated to allow for both modules to exist
|
|
* independently.
|
|
*/
|
|
|
|
LOCAL UINT64 priv_startTicks; /* 64 bit ticks at start */
|
|
|
|
/* externals */
|
|
|
|
extern UINT64 tick64Get (void); /* This should be removed when it is added
|
|
* to tickLib.h, until then we need it to
|
|
* ensure proper processing of 64 bit ticks */
|
|
/* locals */
|
|
/*static const UI64 U64_MAX = { UINT_MAX, UINT_MAX };*/
|
|
|
|
/*
|
|
* The zero object id is used throught out the MIB-II library to fill OID
|
|
* requests when an object ID is not provided by a group variable.
|
|
*/
|
|
|
|
|
|
LOCAL void m2IfCentiSecsStart (void);
|
|
Mib2_TimeTicks m2IfCentiSecsGet (void);
|
|
STATUS rcvEtherAddrAdd (M2_IFINDEX *, unsigned char *);
|
|
|
|
LOCAL STATUS m2IfGenericPacketCount (M2_ID *, UINT, UCHAR *, UINT);
|
|
LOCAL STATUS m2IfCounterUpdate (M2_ID *, UINT, UINT);
|
|
LOCAL STATUS m2IfVariableUpdate (M2_ID *, UINT, caddr_t);
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2IfInit - initialize MIB-II interface-group routines
|
|
*
|
|
* This routine allocates the resources needed to allow access to the
|
|
* MIB-II interface-group variables. This routine must be called before any
|
|
* interface variables can be accessed. The <pTrapRtn> argument is an
|
|
* optional pointer to a user-supplied SNMP trap generator. The <pTrapArg>
|
|
* argument is an optional argument to the trap generator. Only one
|
|
* trap generator is supported.
|
|
*
|
|
* RETURNS: OK if successful
|
|
* ERROR if an error occurred
|
|
*
|
|
* ERRNO:
|
|
* S_m2Lib_CANT_CREATE_IF_SEM
|
|
*
|
|
* SEE ALSO:
|
|
* m2IfGroupInfoGet(), m2IfTblEntryGet(), m2IfTblEntrySet(), m2IfDelete()
|
|
*/
|
|
STATUS m2IfInit
|
|
(
|
|
FUNCPTR pTrapRtn, /* link up/down -trap routine */
|
|
void * pTrapArg /* trap routine arg */
|
|
)
|
|
{
|
|
#ifdef VIRTUAL_STACK
|
|
|
|
/*
|
|
* The M2_IF data structure is now part of the core VS data. Simply
|
|
* initialize the variables if this is the first call to the init routine.
|
|
*/
|
|
|
|
if (pM2IfRootPtr == NULL)
|
|
{
|
|
/*
|
|
* Perform the static initialization which the compiler provides
|
|
* automatically for the non-virtual stack.
|
|
*/
|
|
|
|
pM2IfRoot = NULL;
|
|
pM2IfRootPtr = &pM2IfRoot;
|
|
}
|
|
#endif /* VIRTUAL_STACK */
|
|
|
|
/* Register the m2 APIs with the end library */
|
|
|
|
endMibIfInit ((FUNCPTR)m2IfTblInit, (FUNCPTR)mibIfAlloc,
|
|
(FUNCPTR)m2IfFree,
|
|
(FUNCPTR)m2CounterUpdate, (FUNCPTR)m2VariableUpdate);
|
|
/* Create the Interface semaphore */
|
|
if (m2InterfaceSem == NULL)
|
|
{
|
|
m2InterfaceSem = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE |
|
|
SEM_DELETE_SAFE);
|
|
if (m2InterfaceSem == NULL)
|
|
{
|
|
#ifdef VIRTUAL_STACK
|
|
pM2IfRootPtr = NULL;
|
|
#endif /* VIRTUAL_STACK */
|
|
|
|
errnoSet (S_m2Lib_CANT_CREATE_IF_SEM);
|
|
return (ERROR);
|
|
}
|
|
}
|
|
|
|
/* Take the interface semaphore, and initialize group global variables */
|
|
|
|
semTake (m2InterfaceSem, WAIT_FOREVER);
|
|
|
|
pM2TrapRtn = pTrapRtn;
|
|
pM2TrapRtnArg = pTrapArg;
|
|
|
|
m2IfTableLastChange = 0;
|
|
m2IfStackLastChange = 0;
|
|
|
|
semGive (m2InterfaceSem);
|
|
|
|
(void) m2IfCentiSecsStart(); /* Initialize group time reference */
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* m2IfDestructor - Clean up the resources used by VS Portion of the code
|
|
*
|
|
* RETURNS: ERROR if it could not free the memory
|
|
* OK otherwise
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
#ifdef VIRTUAL_STACK
|
|
STATUS m2IfDestructor
|
|
(
|
|
VSNUM vsnum
|
|
)
|
|
{
|
|
m2IfDelete ();
|
|
|
|
return (OK);
|
|
}
|
|
#endif /* VIRTUAL_STACK */
|
|
|
|
/***************************************************************************
|
|
*
|
|
* mibIfAlloc - the generic interfaces MIB allocation routine
|
|
*
|
|
* This routine provides a very generic API to initialize the interface
|
|
* MIB structure. It expects the caller to provide the buffer in to which
|
|
* the pointer to the allocated MIB structure is stored.
|
|
*
|
|
* RETURNS: OK if successfully initialized,
|
|
* ERROR otherwise
|
|
*/
|
|
|
|
STATUS mibIfAlloc
|
|
(
|
|
M2_ID ** ppMib2Tbl, /* Buffer to store pointer to MIB */
|
|
ULONG ifType, /* If type of the interface */
|
|
UCHAR * pEnetAddr, /* Physical address of interface */
|
|
ULONG addrLen, /* Address length */
|
|
ULONG mtuSize, /* MTU of interface */
|
|
ULONG speed, /* Speed of the interface */
|
|
char * pName, /* Name of the device */
|
|
int unit /* Unit number of the device */
|
|
)
|
|
{
|
|
/* Perform a sanity check to see if the buffer is valid */
|
|
|
|
if (ppMib2Tbl == NULL)
|
|
return (ERROR);
|
|
|
|
*ppMib2Tbl = m2IfAlloc (ifType, pEnetAddr, addrLen,
|
|
mtuSize, speed, pName, unit);
|
|
|
|
if (*ppMib2Tbl == NULL)
|
|
return (ERROR);
|
|
|
|
return (OK);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfAlloc - allocate the structure for the interface table
|
|
*
|
|
* This routine is called to allocate and initialize the interface table MIB
|
|
* structure. We also set the default update routines in the M2_ID struct.
|
|
* These fields can later be overloaded using the installed routines in the
|
|
* M2_ID. Once this function returns, it is the driver's responsibility to
|
|
* set the pMib2Tbl pointer in the END object to the new M2_ID.
|
|
*
|
|
* When this call returns, the calling routine must set the END_MIB_2233
|
|
* bit of the flags field in the END object.
|
|
*
|
|
* RETURNS: Pointer to the M2_ID structure upon success,
|
|
* NULL if an error occurred.
|
|
*/
|
|
|
|
M2_ID * m2IfAlloc
|
|
(
|
|
ULONG ifType, /* If type of the interface */
|
|
UCHAR * pEnetAddr, /* Physical address of interface */
|
|
ULONG addrLen, /* Address length */
|
|
ULONG mtuSize, /* MTU of interface */
|
|
ULONG speed, /* Speed of the interface */
|
|
char * pName, /* Name of the device */
|
|
int unit /* Unit number of the device */
|
|
)
|
|
{
|
|
M2_ID * pM2Id = NULL;
|
|
|
|
/* Allocate memory for the interface table */
|
|
|
|
pM2Id = (M2_ID *)malloc(sizeof(M2_ID));
|
|
if (!pM2Id)
|
|
return (NULL);
|
|
|
|
(void)m2IfTblInit (pM2Id, ifType, pEnetAddr, addrLen,
|
|
mtuSize, speed, pName, unit);
|
|
return (pM2Id);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfTblInit - initialize the structure for the interface table
|
|
*
|
|
* This routine is called to initialize the interface table MIB
|
|
* structure. We also set the default update routines in the M2_ID struct.
|
|
* These fields can later be overloaded using the installed routines in the
|
|
* M2_ID. Once this function returns, it is the driver's responsibility to
|
|
* set the pMib2Tbl pointer in the END object to the new M2_ID.
|
|
*
|
|
* When this call returns, the calling routine must set the END_MIB_2233
|
|
* bit of the flags field in the END object.
|
|
*
|
|
* RETURNS: ERROR on an error (pM2ID is NULL)
|
|
* OK otherwise.
|
|
*/
|
|
|
|
STATUS m2IfTblInit
|
|
(
|
|
M2_ID * pM2Id, /* pointer to M2_ID interface table */
|
|
ULONG ifType, /* If type of the interface */
|
|
UCHAR * pEnetAddr, /* Physical address of interface */
|
|
ULONG addrLen, /* Address length */
|
|
ULONG mtuSize, /* MTU of interface */
|
|
ULONG speed, /* Speed of the interface */
|
|
char * pName, /* Name of the device */
|
|
int unit /* Unit number of the device */
|
|
)
|
|
{
|
|
M2_INTERFACETBL * pM2IfTbl = NULL;
|
|
M2_2233TBL * pM2XIfTbl = NULL;
|
|
|
|
if (pM2Id == NULL)
|
|
return ERROR;
|
|
|
|
bzero ((char *) pM2Id, sizeof (M2_ID));
|
|
|
|
/* Enter the values provided by the driver */
|
|
|
|
pM2IfTbl = &pM2Id->m2Data.mibIfTbl;
|
|
pM2XIfTbl = &pM2Id->m2Data.mibXIfTbl;
|
|
|
|
pM2IfTbl->ifType = (Mib2_Integer)ifType;
|
|
pM2IfTbl->ifMtu = (Mib2_Integer)mtuSize;
|
|
pM2IfTbl->ifSpeed = (Mib2_Gauge)speed;
|
|
|
|
memcpy (&pM2IfTbl->ifPhysAddress.phyAddress[0], pEnetAddr, addrLen);
|
|
pM2IfTbl->ifPhysAddress.addrLength = (Mib2_Integer)addrLen;
|
|
|
|
sprintf ((char *)&pM2XIfTbl->ifName[0], "%s%d", pName, unit);
|
|
sprintf ((char *)&pM2IfTbl->ifDescr[0], "%s%d", pName, unit);
|
|
|
|
/* Set the default update routines */
|
|
|
|
switch (ifType)
|
|
{
|
|
case M2_ifType_ethernet_csmacd:
|
|
case M2_ifType_iso88023_csmacd:
|
|
case M2_ifType_iso88024_tokenBus:
|
|
case M2_ifType_iso88025_tokenRing:
|
|
case M2_ifType_iso88026_man:
|
|
case M2_ifType_fddi:
|
|
pM2Id->m2PktCountRtn = m2If8023PacketCount;
|
|
break;
|
|
|
|
default:
|
|
pM2Id->m2PktCountRtn = m2IfGenericPacketCount;
|
|
break;
|
|
}
|
|
|
|
pM2Id->m2CtrUpdateRtn = m2IfCounterUpdate;
|
|
pM2Id->m2VarUpdateRtn = m2IfVariableUpdate;
|
|
|
|
pM2XIfTbl->ifLinkUpDownTrapEnable = M2_LINK_UP_DOWN_TRAP_DISABLED;
|
|
/*
|
|
* ifHighSpeed is measured in units of 10**6 bits/s
|
|
*/
|
|
pM2XIfTbl->ifHighSpeed = (Mib2_Gauge32)((speed + 500000) / 1000000);
|
|
pM2XIfTbl->ifPromiscuousMode = M2_PROMISCUOUS_MODE_OFF;
|
|
pM2XIfTbl->ifConnectorPresent = M2_CONNECTOR_NOT_PRESENT;
|
|
|
|
pM2Id->m2UsrCounter = NULL;
|
|
|
|
return (OK);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfFree - free an interface data structure
|
|
*
|
|
* This routine frees the memory associated with the interface's MIB
|
|
* structure.
|
|
*
|
|
* RETURNS: OK if successful,
|
|
* ERROR otherwise
|
|
*/
|
|
STATUS m2IfFree
|
|
(
|
|
M2_ID * pId /* pointer to the driver's M2_ID object */
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return (ERROR);
|
|
else
|
|
free((char *)pId);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2CounterUpdate - update the value of an interface MIB counter
|
|
*
|
|
* This is a generic function that increments the value of any interface
|
|
* MIB counter.
|
|
*
|
|
* If the <ctrl> parameter is M2_PACKET_IN or M2_PACKET_OUT, the API
|
|
* expects the <pPkt> pointer to contain a valid packet and the <value>
|
|
* field must contain the length of the packet.
|
|
*
|
|
* For all other counters, the <pPkt> field can be NULL, but the <value>
|
|
* field must contain the value to increment the counter by.
|
|
*
|
|
* RETURNS: OK upon success,
|
|
* ERROR otherwise
|
|
*/
|
|
|
|
STATUS m2CounterUpdate
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT ctrl, /* Counter to update */
|
|
UINT value, /* Value to increment by . If <ctrl> is M2_PACKET_IN */
|
|
/* or M2_PACKET_OUT, the length must be passed. */
|
|
UCHAR * pPkt /* Pointer to packet, can be NULL if <ctrl> is not */
|
|
/* is not M2_PACKET_IN or M2_PACKET_OUT */
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return (ERROR);
|
|
|
|
switch (ctrl)
|
|
{
|
|
case M2_PACKET_IN:
|
|
case M2_PACKET_OUT:
|
|
return (pId->m2PktCountRtn (pId, ctrl, pPkt, value));
|
|
|
|
default:
|
|
return (pId->m2CtrUpdateRtn (pId, ctrl, value));
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2VariableUpdate - update the value of an interface MIB variable
|
|
*
|
|
* This is a generic function that changes the value of any non-counter
|
|
* variable of the interface MIB.
|
|
*
|
|
* RETURNS: OK upon success,
|
|
* ERROR otherwise
|
|
*/
|
|
|
|
STATUS m2VariableUpdate
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT varId, /* Variable to update */
|
|
caddr_t pData /* Data to use */
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return (ERROR);
|
|
|
|
return (pId->m2VarUpdateRtn (pId, varId, pData));
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfGenericPacketCount - increment the interface packet counters
|
|
*
|
|
* This function is used to update basic interface counters for a packet. It
|
|
* has no idea of the underlying media so only the ifInOctets, ifHCInOctets,
|
|
* ifOutOctets and ifHCOutOctets variables are incremented. The ctrl
|
|
* argument specifies whether the packet is being sent or just received
|
|
* (M2_PACKET_IN or M2_PACKET_OUT).
|
|
*
|
|
* This function must never be called directly. It must be called via
|
|
* m2CounterUpdate().
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL,
|
|
* OK if the counters were updated.
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
LOCAL STATUS m2IfGenericPacketCount
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT ctrl, /* Update In or Out counters */
|
|
UCHAR * pPkt, /* The incoming/outgoing packet */
|
|
UINT pktLen /* Length of the packet */
|
|
)
|
|
{
|
|
M2_DATA * pMib2Data;
|
|
|
|
pMib2Data = &(pId->m2Data);
|
|
|
|
switch (ctrl)
|
|
{
|
|
case M2_PACKET_IN:
|
|
pMib2Data->mibIfTbl.ifInOctets += pktLen;
|
|
pMib2Data->mibIfTbl.ifInUcastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
{
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInOctets), pktLen);
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInUcastPkts), 1);
|
|
}
|
|
break;
|
|
|
|
case M2_PACKET_OUT:
|
|
pMib2Data->mibIfTbl.ifOutOctets += pktLen;
|
|
pMib2Data->mibIfTbl.ifOutUcastPkts += 1;
|
|
|
|
if (m2If64BitCounters)
|
|
{
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutOctets), pktLen);
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutUcastPkts), 1);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return ERROR;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2If8023PacketCount - increment the 802.3 device interface packet counters
|
|
*
|
|
* This function is used to update basic interface counters for a packet.
|
|
* The <ctrl> argument specifies whether the packet is being sent or just
|
|
* received (M2_PACKET_IN or M2_PACKET_OUT). This function only works for
|
|
* 802.3 devices as it understand the Ethernet packet format. The
|
|
* following counters are updated:
|
|
*
|
|
* . ifInOctets
|
|
* . ifInUcastPkts
|
|
* . ifInNUcastPkts
|
|
* . ifOutOctets
|
|
* . ifOutUcastPkts
|
|
* . ifOutNUcastPkts
|
|
* . ifInMulticastPkts
|
|
* . ifInBroadcastPkts
|
|
* . ifOutMulticastPkts
|
|
* . ifOutBroadcastPkts
|
|
* . ifHCInOctets
|
|
* . ifHCInUcastPkts
|
|
* . ifHCOutOctets
|
|
* . ifHCOutUcastPkts
|
|
* . ifHCInMulticastPkts
|
|
* . ifHCInBroadcastPkts
|
|
* . ifHCOutMulticastPkts
|
|
* . ifHCOutBroadcastPkts
|
|
* . ifCounterDiscontinuityTime
|
|
*
|
|
* The first 6 bytes in the packet must contain the destination MAC
|
|
* address and the second 6 bytes of the packet must contain the source
|
|
* MAC address.
|
|
*
|
|
* The type of MAC address (i.e. broadcast, multicast, or unicast) is
|
|
* determined by the following:
|
|
*
|
|
* . broadcast address: ff:ff:ff:ff:ff:ff
|
|
* . multicast address: first bit is set
|
|
* . unicast address: any other address not matching the above
|
|
*
|
|
* This function must not be called directly. It is called from
|
|
* m2CounterUpdate().
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL or the <ctrl> is invalid,
|
|
* OK if the counters were updated.
|
|
*/
|
|
|
|
STATUS m2If8023PacketCount
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT ctrl, /* Update In or Out counters */
|
|
UCHAR * pPkt, /* The incoming/outgoing packet */
|
|
UINT pktLen /* Length of the packet */
|
|
)
|
|
{
|
|
M2_DATA * pMib2Data;
|
|
UCHAR mcastBit = 0x01;
|
|
if (pId == NULL)
|
|
return ERROR;
|
|
|
|
pMib2Data = &(pId->m2Data);
|
|
|
|
/*
|
|
* Special handling for 802.4 and 802.5. In 802.4,
|
|
* the destination address is preceded by a single
|
|
* frame control byte. In 802.5, the destination
|
|
* address is preceded by an access control byte
|
|
* and a frame control byte.
|
|
*/
|
|
|
|
if (pMib2Data->mibIfTbl.ifType == M2_ifType_iso88024_tokenBus)
|
|
pPkt += 1;
|
|
else if (pMib2Data->mibIfTbl.ifType == M2_ifType_iso88025_tokenRing)
|
|
pPkt += 2;
|
|
switch (ctrl)
|
|
{
|
|
case M2_PACKET_IN:
|
|
{
|
|
pMib2Data->mibIfTbl.ifInOctets += pktLen;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInOctets), pktLen);
|
|
|
|
/* the first 6 bytes is the destination MAC address */
|
|
if (pPkt[0] & mcastBit) /* multicast address */
|
|
{
|
|
if (pPkt[0] == 0xff && pPkt[1] == 0xff &&
|
|
pPkt[2] == 0xff && pPkt[3] == 0xff &&
|
|
pPkt[4] == 0xff && pPkt[5] == 0xff)
|
|
{
|
|
pMib2Data->mibXIfTbl.ifInBroadcastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(
|
|
&(pMib2Data->mibXIfTbl.ifHCInBroadcastPkts), 1);
|
|
}
|
|
else
|
|
{
|
|
pMib2Data->mibXIfTbl.ifInMulticastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(
|
|
&(pMib2Data->mibXIfTbl.ifHCInMulticastPkts), 1);
|
|
}
|
|
|
|
/*
|
|
* This counter seems redundant. One could just add
|
|
* mibXIfTbl.ifInBroadcastPkts and mibXIfTbl.ifInMulticastPkts.
|
|
* Also, we could derive the 32-bit quantities from the
|
|
* low-order portions of the 64-bit quantities.
|
|
*/
|
|
pMib2Data->mibIfTbl.ifInNUcastPkts += 1;
|
|
}
|
|
else /* unicast address */
|
|
{
|
|
pMib2Data->mibIfTbl.ifInUcastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInUcastPkts), 1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case M2_PACKET_OUT:
|
|
{
|
|
pMib2Data->mibIfTbl.ifOutOctets += pktLen;
|
|
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutOctets), pktLen);
|
|
|
|
/* the first 6 bytes is the destination MAC address */
|
|
if (pPkt[0] & mcastBit) /* multicast address */
|
|
{
|
|
if (pPkt[0] == 0xff && pPkt[1] == 0xff &&
|
|
pPkt[2] == 0xff && pPkt[3] == 0xff &&
|
|
pPkt[4] == 0xff && pPkt[5] == 0xff)
|
|
{
|
|
pMib2Data->mibXIfTbl.ifOutBroadcastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->
|
|
mibXIfTbl.ifHCOutBroadcastPkts), 1);
|
|
|
|
}
|
|
else
|
|
{
|
|
pMib2Data->mibXIfTbl.ifOutMulticastPkts += 1;
|
|
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->
|
|
mibXIfTbl.ifHCOutMulticastPkts), 1);
|
|
}
|
|
|
|
pMib2Data->mibIfTbl.ifOutNUcastPkts += 1;
|
|
}
|
|
else /* unicast address */
|
|
{
|
|
pMib2Data->mibIfTbl.ifOutUcastPkts += 1;
|
|
if (m2If64BitCounters)
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutUcastPkts), 1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return ERROR;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfCounterUpdate - increment interface counters
|
|
*
|
|
* This function is used to directly update any counter. The counter
|
|
* is specified by <ctrId> and the amount to increment it is specified
|
|
* by value.
|
|
*
|
|
* This routine is called from m2CounterUpdate().
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL,
|
|
* OK if the counter was updated.
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
LOCAL STATUS m2IfCounterUpdate
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT ctrId, /* Counter to update */
|
|
UINT value /* Amount to update the counter by */
|
|
)
|
|
{
|
|
M2_DATA * pMib2Data;
|
|
|
|
if (pId == NULL)
|
|
return ERROR;
|
|
|
|
pMib2Data = &(pId->m2Data);
|
|
|
|
switch (ctrId)
|
|
{
|
|
case M2_ctrId_ifInOctets:
|
|
pMib2Data->mibIfTbl.ifInOctets += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInUcastPkts:
|
|
pMib2Data->mibIfTbl.ifInUcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInNUcastPkts:
|
|
pMib2Data->mibIfTbl.ifInNUcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInDiscards:
|
|
pMib2Data->mibIfTbl.ifInDiscards += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInErrors:
|
|
pMib2Data->mibIfTbl.ifInErrors += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInUnknownProtos:
|
|
pMib2Data->mibIfTbl.ifInUnknownProtos += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutOctets:
|
|
pMib2Data->mibIfTbl.ifOutOctets += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutUcastPkts:
|
|
pMib2Data->mibIfTbl.ifOutUcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutNUcastPkts:
|
|
pMib2Data->mibIfTbl.ifOutNUcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutDiscards:
|
|
pMib2Data->mibIfTbl.ifOutDiscards += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutErrors:
|
|
pMib2Data->mibIfTbl.ifOutErrors += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInMulticastPkts:
|
|
pMib2Data->mibXIfTbl.ifInMulticastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifInBroadcastPkts:
|
|
pMib2Data->mibXIfTbl.ifInBroadcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutMulticastPkts:
|
|
pMib2Data->mibXIfTbl.ifOutMulticastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifOutBroadcastPkts:
|
|
pMib2Data->mibXIfTbl.ifOutBroadcastPkts += value;
|
|
break;
|
|
|
|
case M2_ctrId_ifHCInOctets:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInOctets), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCInUcastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInUcastPkts), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCInMulticastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInMulticastPkts), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCInBroadcastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCInBroadcastPkts), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCOutOctets:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutOctets), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCOutUcastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutUcastPkts), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCOutMulticastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutMulticastPkts), value);
|
|
break;
|
|
|
|
case M2_ctrId_ifHCOutBroadcastPkts:
|
|
m2IfIncr64Bit(&(pMib2Data->mibXIfTbl.ifHCOutBroadcastPkts), value);
|
|
break;
|
|
|
|
default:
|
|
return ERROR;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfVariableUpdate - update the contents of an interface non-counter object
|
|
*
|
|
* This function is used to update an interface variable. The variable is
|
|
* specified by varId and the data to use is specified by pData. Note that
|
|
* different variable expect differnet types of data. Here is a list of the
|
|
* variables the the type of data expected. Therefore pData will be cast to the
|
|
* type listed below for each variable.
|
|
*
|
|
* . ifDescr char *
|
|
* . ifType UINT
|
|
* . ifMtu ULONG
|
|
* . ifSpeed ULONG
|
|
* . ifPhysAddress M2_PHYADDR *
|
|
* . ifAdminStatus ULONG
|
|
* . ifOperStatus ULONG
|
|
* . ifLastChange ULONG
|
|
* . ifOutQLen ULONG
|
|
* . ifSpecific M2_OBJECTID *
|
|
* . ifName char *
|
|
* . ifLinkUpDownTrapEnable UINT
|
|
* . ifHighSpeed ULONG
|
|
* . ifPromiscuousMode UINT
|
|
* . ifConnectorPresent UINT
|
|
* . ifAlias char *
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL, OK if the variable was updated.
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
LOCAL STATUS m2IfVariableUpdate
|
|
(
|
|
M2_ID * pId, /* The pointer to the device M2_ID object */
|
|
UINT varId, /* Variable to update */
|
|
caddr_t pData /* Data to use */
|
|
)
|
|
{
|
|
M2_DATA * pMib2Data;
|
|
|
|
if (pId == NULL || pData == NULL)
|
|
return ERROR;
|
|
|
|
pMib2Data = &(pId->m2Data);
|
|
|
|
switch (varId)
|
|
{
|
|
case M2_varId_ifDescr:
|
|
if (strlen(pData) < M2DISPLAYSTRSIZE)
|
|
strcpy((char *)(pMib2Data->mibIfTbl.ifDescr), pData);
|
|
break;
|
|
|
|
case M2_varId_ifType:
|
|
pMib2Data->mibIfTbl.ifType = (Mib2_Integer)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifMtu:
|
|
pMib2Data->mibIfTbl.ifMtu = (Mib2_Integer)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifSpeed:
|
|
pMib2Data->mibIfTbl.ifSpeed = (Mib2_Gauge)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifPhysAddress:
|
|
memcpy(&(pMib2Data->mibIfTbl.ifPhysAddress), (M2_PHYADDR *)pData,
|
|
sizeof(M2_PHYADDR));
|
|
break;
|
|
|
|
case M2_varId_ifAdminStatus:
|
|
pMib2Data->mibIfTbl.ifAdminStatus = (Mib2_Integer)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifOperStatus:
|
|
|
|
/* ifLastChange must be updated if ifOperStatus changes */
|
|
|
|
if (pMib2Data->mibIfTbl.ifOperStatus != (Mib2_Integer)(ULONG)pData)
|
|
{
|
|
pMib2Data->mibIfTbl.ifLastChange = m2IfCentiSecsGet();
|
|
pMib2Data->mibIfTbl.ifOperStatus = (Mib2_Integer)(ULONG)pData;
|
|
}
|
|
break;
|
|
|
|
case M2_varId_ifLastChange:
|
|
pMib2Data->mibIfTbl.ifLastChange = (Mib2_TimeTicks)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifOutQLen:
|
|
pMib2Data->mibIfTbl.ifOutQLen = (Mib2_Counter)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifSpecific:
|
|
memcpy(&(pMib2Data->mibIfTbl.ifSpecific), (M2_OBJECTID *)pData,
|
|
sizeof(M2_OBJECTID));
|
|
break;
|
|
|
|
case M2_varId_ifName:
|
|
if (strlen(pData) < M2DISPLAYSTRSIZE)
|
|
strcpy((char *)(pMib2Data->mibXIfTbl.ifName), pData);
|
|
break;
|
|
|
|
case M2_varId_ifLinkUpDownTrapEnable:
|
|
pMib2Data->mibXIfTbl.ifLinkUpDownTrapEnable = (Mib2_Integer)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifHighSpeed:
|
|
pMib2Data->mibXIfTbl.ifHighSpeed = (Mib2_Gauge32)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifPromiscuousMode:
|
|
pMib2Data->mibXIfTbl.ifPromiscuousMode = (Mib2_TruthValue)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifConnectorPresent:
|
|
pMib2Data->mibXIfTbl.ifConnectorPresent = (Mib2_TruthValue)(ULONG)pData;
|
|
break;
|
|
|
|
case M2_varId_ifAlias:
|
|
if (strlen(pData) < M2DISPLAYSTRSIZE)
|
|
strcpy((char *)(pMib2Data->mibXIfTbl.ifAlias), pData);
|
|
break;
|
|
|
|
default:
|
|
return ERROR;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfPktCountRtnInstall - install an interface packet counter routine
|
|
*
|
|
* This function installs a routine in the M2_ID. This routine is a packet
|
|
* counter that is able to update all the interface counters.
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL,
|
|
* OK if the routine was installed.
|
|
*/
|
|
|
|
STATUS m2IfPktCountRtnInstall
|
|
(
|
|
M2_ID * pId,
|
|
M2_PKT_COUNT_RTN pRtn
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return ERROR;
|
|
|
|
pId->m2PktCountRtn = pRtn;
|
|
return OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfCtrUpdateRtnInstall - install an interface counter update routine
|
|
*
|
|
* This function installs a routine in the M2_ID. This routine is able to
|
|
* update a single specified interface counter.
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL,
|
|
* OK if the routine was installed.
|
|
*/
|
|
|
|
STATUS m2IfCtrUpdateRtnInstall
|
|
(
|
|
M2_ID * pId,
|
|
M2_CTR_UPDATE_RTN pRtn
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return ERROR;
|
|
|
|
pId->m2CtrUpdateRtn = pRtn;
|
|
return OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* m2IfVarUpdateRtnInstall - install an interface variable update routine
|
|
*
|
|
* This function installs a routine in the M2_ID. This routine is able to
|
|
* update a single specified interface variable.
|
|
*
|
|
* RETURNS: ERROR if the M2_ID is NULL, OK if the routine was installed.
|
|
*/
|
|
STATUS m2IfVarUpdateRtnInstall
|
|
(
|
|
M2_ID * pId,
|
|
M2_VAR_UPDATE_RTN pRtn
|
|
)
|
|
{
|
|
if (pId == NULL)
|
|
return ERROR;
|
|
|
|
pId->m2VarUpdateRtn = pRtn;
|
|
return OK;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2IfCentiSecsStart - get the starting timestamp
|
|
*
|
|
* Set the timestamp we use to determine the starting point for sys up time.
|
|
*
|
|
* RETURNS: void
|
|
*
|
|
* SEE ALSO: N/A
|
|
*/
|
|
LOCAL void m2IfCentiSecsStart (void)
|
|
{
|
|
|
|
priv_startTicks = tick64Get();
|
|
return;
|
|
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2IfCentiSecsGet - get hundredths of a second
|
|
*
|
|
* The time, in hundredths of a second, since we started the network.
|
|
* m2IfCentiSecsStart is used to start the clock.
|
|
*
|
|
* RETURNS: Hundredths of a second since the group was initialized.
|
|
*
|
|
* SEE ALSO: N/A
|
|
*/
|
|
Mib2_TimeTicks m2IfCentiSecsGet (void)
|
|
{
|
|
UINT64 currCentiSecs;
|
|
|
|
currCentiSecs = ((tick64Get() - priv_startTicks) * 100) / sysClkRateGet();
|
|
|
|
return (Mib2_TimeTicks)(currCentiSecs & 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* rcvEtherAddrAdd - add a physical address into the linked list
|
|
*
|
|
* This function is a helper function for rcvEtherAddrGet. It is called to
|
|
* add a single physical address into the linked list of addresses maintained
|
|
* by the AVL node.
|
|
*
|
|
* RETURNS: OK if successful,
|
|
* ERROR otherwise
|
|
* \NOMANUAL
|
|
*/
|
|
|
|
STATUS rcvEtherAddrAdd
|
|
(
|
|
M2_IFINDEX * pIfIndexEntry, /* the avl node */
|
|
unsigned char * pEnetAddr /* the addr to be added */
|
|
)
|
|
{
|
|
M2_IFRCVADDRTBL * pIfRcvAddr = NULL;
|
|
M2_IFRCVADDRTBL ** ppTemp = &pIfIndexEntry->pRcvAddr;
|
|
|
|
if (pEnetAddr)
|
|
{
|
|
pIfRcvAddr = malloc (sizeof (M2_IFRCVADDRTBL));
|
|
if (!pIfRcvAddr)
|
|
return ERROR;
|
|
|
|
bcopy ((char *) pEnetAddr,
|
|
(char *) pIfRcvAddr->ifRcvAddrAddr.phyAddress,
|
|
ETHERADDRLEN);
|
|
pIfRcvAddr->ifRcvAddrAddr.addrLength = ETHERADDRLEN;
|
|
pIfRcvAddr->ifRcvAddrStatus = ROW_ACTIVE;
|
|
pIfRcvAddr->ifRcvAddrType = STORAGE_NONVOLATILE;
|
|
pIfRcvAddr->pNextEntry = NULL;
|
|
|
|
if (pIfIndexEntry->pRcvAddr)
|
|
{
|
|
while (*ppTemp)
|
|
{
|
|
if (memcmp (pEnetAddr, (*ppTemp)->ifRcvAddrAddr.phyAddress,
|
|
ETHERADDRLEN) > 0)
|
|
{
|
|
ppTemp = &(*ppTemp)->pNextEntry;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
pIfRcvAddr->pNextEntry = *ppTemp;
|
|
break;
|
|
}
|
|
}
|
|
*ppTemp = pIfRcvAddr;
|
|
}
|
|
else
|
|
{
|
|
pIfIndexEntry->pRcvAddr = pIfRcvAddr;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
return (ERROR);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* m2IfNodeFree - delete a node in the interface tree
|
|
*
|
|
* This routine frees memory allocated for a node in the interface tree.
|
|
* The routine assumes the AVL node is the first in M2_IFINDEX.
|
|
*
|
|
* RETURNS: OK, always
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
#if 0
|
|
LOCAL STATUS m2IfNodeFree
|
|
(
|
|
AVLU_NODE * pNode,
|
|
void * delArg
|
|
)
|
|
{
|
|
free (pNode);
|
|
return (OK);
|
|
}
|
|
#endif
|
|
/*******************************************************************************
|
|
*
|
|
* m2IfDelete - delete all resources used to access the interface group
|
|
*
|
|
* This routine frees all the resources allocated at the time the group was
|
|
* initialized. The interface group should not be accessed after this routine
|
|
* has been called.
|
|
*
|
|
* RETURNS: OK, always.
|
|
*
|
|
* SEE ALSO:
|
|
* m2IfInit(), m2IfGroupInfoGet(), m2IfTblEntryGet(), m2IfTblEntrySet()
|
|
*/
|
|
|
|
STATUS m2IfDelete (void)
|
|
{
|
|
pM2TrapRtn = NULL;
|
|
pM2TrapRtnArg = NULL;
|
|
return OK;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* m2PollStatsIfPoll - read statistics information from an interface's internal counters
|
|
*
|
|
* This function invokes the EIOCGPOLLSTATS ioctl on a specified
|
|
* interface and, if the ioctl succeeds, it updates its associated MIB2
|
|
* counters. Only those counters which are marked as valid in the
|
|
* interface's ifValidCounters field in the END_IFDRVCONF structure
|
|
* will be updated. This routine may be invoked either automatically
|
|
* via periodic watchdog timeout, or directly in order to force a
|
|
* counter update if the watchdog has not yet expired.
|
|
*
|
|
* RETURNS: ERROR if reading the counters fails, otherwise OK.
|
|
*/
|
|
|
|
STATUS m2PollStatsIfPoll
|
|
(
|
|
END_IFDRVCONF * pDrvConf
|
|
)
|
|
{
|
|
M2_ID * pId; /* The pointer to the device M2_ID object */
|
|
M2_DATA * pMib2Data;
|
|
END_IFCOUNTERS * pDrvCounters;
|
|
PROTOCOL_BINDING tmpBinding;
|
|
void * pCookie;
|
|
int error;
|
|
|
|
if (pDrvConf == NULL)
|
|
return (ERROR);
|
|
|
|
tmpBinding.pEnd = PDEVCOOKIE_TO_ENDOBJ(pDrvConf->ifMuxCookie);
|
|
|
|
if (tmpBinding.pEnd == NULL)
|
|
return(ERROR);
|
|
|
|
pCookie = (void *)&tmpBinding;
|
|
|
|
/* Get M2_ID from driver. */
|
|
|
|
error = muxIoctl (pCookie, EIOCGMIB2233, (caddr_t)&pId);
|
|
|
|
if (error)
|
|
return (error);
|
|
|
|
pMib2Data = &(pId->m2Data);
|
|
|
|
/* Get the stats info */
|
|
|
|
error = muxIoctl (pCookie, EIOCGPOLLSTATS, (caddr_t)&pDrvCounters);
|
|
|
|
if (error)
|
|
return (error);
|
|
|
|
/* Do the work */
|
|
|
|
M2_POLLINCR_64 (END_IFINUCASTPKTS_VALID, InUcastPkts);
|
|
M2_POLLINCR_64 (END_IFOUTUCASTPKTS_VALID, OutUcastPkts);
|
|
M2_POLLINCR_64 (END_IFINOCTETS_VALID, InOctets);
|
|
M2_POLLINCR_64 (END_IFOUTOCTETS_VALID, OutOctets);
|
|
|
|
M2_POLLINCR_32 (END_IFINERRORS_VALID, InErrors, InErrors);
|
|
M2_POLLINCR_32 (END_IFOUTERRORS_VALID, OutErrors, OutErrors);
|
|
M2_POLLINCR_32 (END_IFINDISCARDS_VALID, InDiscards, InDiscards);
|
|
M2_POLLINCR_32 (END_IFOUTDISCARDS_VALID, OutDiscards, OutDiscards);
|
|
M2_POLLINCR_32 (END_IFINUNKNOWNPROTOS_VALID,
|
|
InUnknownProtos, InUnknownProtos);
|
|
|
|
/*
|
|
* For the multicast and broadcast stats, we need to do the
|
|
* increment on a different table, hence the need for a separate
|
|
* macro. We also need to increment the non-unicast counters.
|
|
*/
|
|
|
|
M2_POLLINCR_64_X (END_IFINMULTICASTPKTS_VALID, InMulticastPkts);
|
|
M2_POLLINCR_32 (END_IFINMULTICASTPKTS_VALID,
|
|
InMulticastPkts, InNUcastPkts);
|
|
|
|
M2_POLLINCR_64_X (END_IFINBROADCASTPKTS_VALID, InBroadcastPkts);
|
|
M2_POLLINCR_32 (END_IFINBROADCASTPKTS_VALID,
|
|
InBroadcastPkts, InNUcastPkts);
|
|
|
|
M2_POLLINCR_64_X (END_IFOUTMULTICASTPKTS_VALID, OutMulticastPkts);
|
|
M2_POLLINCR_32 (END_IFOUTMULTICASTPKTS_VALID,
|
|
OutMulticastPkts, OutNUcastPkts);
|
|
|
|
M2_POLLINCR_64_X (END_IFOUTBROADCASTPKTS_VALID, OutBroadcastPkts);
|
|
M2_POLLINCR_32 (END_IFOUTBROADCASTPKTS_VALID,
|
|
OutBroadcastPkts, OutNUcastPkts);
|
|
|
|
return (OK);
|
|
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2IfUsrCountersInstall - install a pointer to user-defined counters
|
|
*
|
|
* This routine installs a pointer <pUsrCounters> in the M2_ID structure
|
|
* specified by <pM2Id>. The installed pointer can be used to add additional
|
|
* counters per interface to support RMON, rfc1643 or any other counters. If a
|
|
* counter already exists the installation fails. The counters can be accessed
|
|
* using the m2UsrCounter field in the M2_ID structure for the interface. The
|
|
* pointer will typically refer to a structure which contains all the counters.
|
|
* For example:
|
|
*
|
|
* .CS
|
|
* struct counters
|
|
* {
|
|
* u_long ctr1;
|
|
* u_long ctr2;
|
|
* };
|
|
* .CE
|
|
*
|
|
* It is the responsibility of the user to allocate and initialize the counter
|
|
* structure before calling this routine.
|
|
*
|
|
* RETURNS: OK, or ERROR
|
|
*
|
|
* ERRNO: S_m2Lib_INVALID_PARAMETER
|
|
*/
|
|
|
|
STATUS m2IfUsrCountersInstall
|
|
(
|
|
M2_ID * pM2Id, /* M2_ID structure for interface */
|
|
void * pUsrCounters /* pointer to structure containing counters */
|
|
)
|
|
{
|
|
if ((pM2Id == NULL) || (pUsrCounters == NULL))
|
|
{
|
|
errnoSet (S_m2Lib_INVALID_PARAMETER);
|
|
return (ERROR);
|
|
}
|
|
|
|
/* Install a new counter only if a counter does not exist. */
|
|
|
|
if (pM2Id->m2UsrCounter == NULL)
|
|
pM2Id->m2UsrCounter = pUsrCounters;
|
|
else
|
|
return (ERROR);
|
|
|
|
return (OK);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2IfUsrCountersRemove - delete the pointer to the user-defined counters
|
|
*
|
|
* This routine removes the user-defined counters associated with the interface.
|
|
* It is the responsibility of the user to free the counter structure once it
|
|
* has been deleted.
|
|
*
|
|
* RETURNS: OK, or ERROR if <pM2Id> is NULL
|
|
*
|
|
* ERRNO: S_m2Lib_INVALID_PARAMETER
|
|
*/
|
|
|
|
STATUS m2IfUsrCountersRemove
|
|
(
|
|
M2_ID * pM2Id /* M2_ID structure for interface */
|
|
)
|
|
{
|
|
if (pM2Id == NULL)
|
|
{
|
|
errnoSet (S_m2Lib_INVALID_PARAMETER);
|
|
return (ERROR);
|
|
}
|
|
|
|
pM2Id->m2UsrCounter = NULL;
|
|
return (OK);
|
|
}
|