📄 m2iflib.c
字号:
/* * XXX Due to inconsistant increment between ifInUnknownProtos by * muxReceive and if_noproto by do_protocol_with_type, this routine * will synchronize both statistics here. In future, these increments * should be consistantly updated at the same place. */ pIfNetEntry->if_noproto = pM2IntTblEntry->ifInUnknownProtos; /* XXX */ } return; }/******************************************************************************** m2IfTblEntrySet - set the state of a MIB-II interface entry to UP or DOWN** This routine selects the interface specified in the input parameter* <pIfReqEntry> and sets the interface parameters to the requested state. * It is the responsibility of the calling routine to set the interface* index, and to make sure that the state specified in the* `ifAdminStatus' field of the structure at <pIfTblEntry> is a valid* MIB-II state, up(1) or down(2).** The fields that can be modified by this routine are the following:* ifAdminStatus, ifAlias, ifLinkUpDownTrapEnable and ifName.** RETURNS: OK, or ERROR if the input parameter is not specified, an interface* is no longer valid, the interface index is incorrect, or the ioctl() command* to the interface fails.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND* S_m2Lib_IF_CNFG_CHANGED** SEE ALSO:* m2IfInit(), m2IfGroupInfoGet(), m2IfTblEntryGet(), m2IfDelete()*/STATUS m2IfTblEntrySet ( void * pIfReqEntry /* pointer to requested entry to change */ ) { int index; M2_IFINDEX * pIfIndexEntry = NULL; struct ifnet * pIfNetEntry = NULL; struct ifreq ifReqChange; IF_SETENTRY * pM2Entry = (IF_SETENTRY *)pIfReqEntry; M2_ID * pM2Id = NULL; semTake (m2InterfaceSem, WAIT_FOREVER); /* Validate the bounds of the requested index */ index = pM2Entry->ifIndex; if (index < 0 || index > ifsInList) { errnoSet (S_m2Lib_ENTRY_NOT_FOUND); semGive (m2InterfaceSem); return (ERROR); } /* Get the node associated with the index */ pIfIndexEntry = (M2_IFINDEX *) avlSearch (pM2IfRoot, (GENERIC_ARGUMENT)index, nextIndex); if (!pIfIndexEntry) { semGive (m2InterfaceSem); return (ERROR); } pIfNetEntry = (struct ifnet *) pIfIndexEntry->pIfStats; /* * The only supported state changes for the interface are UP and DOWN. * The TEST case is not supported by the drivers. */ if (pM2Entry->varToSet & M2_varId_ifAdminStatus) { if (pM2Entry->ifAdminStatus == M2_ifAdminStatus_up) { /* * If the driver is in the UP state, there is no need to send the * IOCTL command, otherwise format the IOCTL request. */ if ( (pIfNetEntry->if_flags & IFF_UP) == 0) ifReqChange.ifr_flags = pIfNetEntry->if_flags | IFF_UP; else pM2Entry->varToSet = pM2Entry->varToSet & ~M2_varId_ifAdminStatus; } else { /* * If the driver is in the DOWN state, there is no need to send the * IOCTL command, otherwise format the IOCTL request. */ if ((pIfNetEntry->if_flags & IFF_UP) != 0) ifReqChange.ifr_flags = pIfNetEntry->if_flags & ~IFF_UP; else pM2Entry->varToSet = pM2Entry->varToSet & ~M2_varId_ifAdminStatus; } /* Stop if no work is needed. */ if (pM2Entry->varToSet == 0) { semGive (m2InterfaceSem); return (OK); } } /* Check to see if we have to set the promiscuous mode */ if (pM2Entry->varToSet & M2_varId_ifPromiscuousMode) { if (pM2Entry->ifPromiscuousMode == M2_ifPromiscuousMode_on) ifReqChange.ifr_flags = pIfNetEntry->if_flags | IFF_PROMISC; else ifReqChange.ifr_flags = pIfNetEntry->if_flags & ~IFF_PROMISC; } /* Do we need to call the Ioctl as a result of any of the above */ if (pM2Entry->varToSet & (M2_varId_ifAdminStatus | M2_varId_ifPromiscuousMode)) { /* * The network semaphore is not taken for this operation because the * called routine takes the network semphore. Issue the IOCTL to the * driver routine, and verify that the request is honored. */ sprintf (ifReqChange.ifr_name,"%s%d", pIfNetEntry->if_name, pIfNetEntry->if_unit); if ((*pIfIndexEntry->ifIoctl)(0, SIOCSIFFLAGS, (char *)&ifReqChange) != 0) { semGive (m2InterfaceSem); return (ERROR); } if ( (pIfNetEntry->if_ioctl != NULL) && ((*pIfNetEntry->if_ioctl)(pIfNetEntry, SIOCGMIB2233, (caddr_t)&pM2Id) == OK) ) { if (pM2Entry->varToSet & M2_varId_ifAdminStatus) { (*pM2Id->m2VarUpdateRtn)(pM2Id, M2_varId_ifAdminStatus, (caddr_t)pM2Entry->ifAdminStatus); } if (pM2Entry->varToSet & M2_varId_ifPromiscuousMode) { (*pM2Id->m2VarUpdateRtn)(pM2Id, M2_varId_ifPromiscuousMode, (caddr_t)pM2Entry->ifPromiscuousMode); } } } else { /* * For the others, we have to get a pointer to the interface * table, so we call the SIOCSMIB2233 IOCTL and let the driver * call our appropriate set routine. In this case, the set * routine is m2IfSnmpSet(). */ if ( (pIfNetEntry->if_ioctl) && ((*pIfNetEntry->if_ioctl) (pIfNetEntry, SIOCSMIB2233, (caddr_t)pIfReqEntry) != 0) ) { semGive (m2InterfaceSem); return (ERROR); } } semGive (m2InterfaceSem); return (OK); }/******************************************************************************** m2IfGroupInfoGet - get the MIB-II interface-group scalar variables** This routine fills the interface-group structure at <pIfInfo> with* the values of MIB-II interface-group global variables.** RETURNS: OK, or ERROR if <pIfInfo> is not a valid pointer.** ERRNO:* S_m2Lib_INVALID_PARAMETER** SEE ALSO:* m2IfInit(), m2IfTblEntryGet(), m2IfTblEntrySet(), m2IfDelete()*/STATUS m2IfGroupInfoGet ( M2_INTERFACE * pIfInfo /* pointer to interface group structure */ ) { semTake (m2InterfaceSem, WAIT_FOREVER); /* Validate the input parameter pointer */ if (pIfInfo == NULL) { semGive (m2InterfaceSem); errnoSet (S_m2Lib_INVALID_PARAMETER); return (ERROR); } /* * Number of network interfaces in the system independent of * their state */ pIfInfo->ifNumber = m2IfCount; #ifdef VIRTUAL_STACK pIfInfo->ifTableLastChange = _ifTableLastChange; pIfInfo->ifStackLastChange = _ifStackLastChange;#else /* VIRTUAL_STACK */ pIfInfo->ifTableLastChange = ifTableLastChange; pIfInfo->ifStackLastChange = ifStackLastChange;#endif /* VIRTUAL_STACK */ semGive (m2InterfaceSem); return OK; }/******************************************************************************** m2IfStackTblUpdate - update the relationship between the sub-layers** This function must be called to setup the relationship between the* ifIndex values for each sub-layer. This information is required to * support the ifStackTable for RFC 2233. Using this data, we can easily* determine which sub-layer runs on top of which other. ** <action> is either M2_STACK_TABLE_INSERT or M2_STACK_TABLE_REMOVE.** Each AVL node keeps a linked list of all the layers that are * directly beneath it. Thus by walking through the AVL nodes in an* orderly way, we can understand the relationships between all the * interfaces.** RETURNS: OK upon successful addition* ERROR otherwise.*/STATUS m2IfStackTblUpdate ( UINT lowerIndex, /* The ifIndex of the lower sub-layer */ UINT higherIndex, /* The ifIndex of the higher sub-layer */ int action /* insert or remove */ ) { M2_IFINDEX * pIfIndexLow = NULL; M2_IFINDEX * pIfIndexHigh = NULL; M2_IFSTACKTBL * pIfStackPtr = NULL; M2_IFSTACKTBL ** ppTempPtr = NULL; /* Check to see if the indexes are within the limits */ if ( (lowerIndex < (UINT) 0) || (lowerIndex > (UINT) ifsInList) || (higherIndex < (UINT) 0) || (higherIndex > (UINT) ifsInList) ) { return (ERROR); } semTake(m2InterfaceSem, WAIT_FOREVER); /* Get the nodes associated with the interfaces */ pIfIndexLow = (M2_IFINDEX *) avlSearch (pM2IfRoot, (GENERIC_ARGUMENT)lowerIndex, nextIndex); pIfIndexHigh = (M2_IFINDEX *) avlSearch (pM2IfRoot, (GENERIC_ARGUMENT)higherIndex, nextIndex); if ( (!pIfIndexLow) || (!pIfIndexHigh) ) { semGive(m2InterfaceSem); return (ERROR); }; /* Check the slot to insert a new index */ pIfStackPtr = pIfIndexHigh->pNextLower; ppTempPtr = &pIfIndexHigh->pNextLower; if (action == M2_STACK_TABLE_INSERT) { while (pIfStackPtr && pIfStackPtr->index < lowerIndex) { ppTempPtr = &pIfStackPtr->pNextLower; pIfStackPtr = pIfStackPtr->pNextLower; } *ppTempPtr = (M2_IFSTACKTBL*) malloc(sizeof(M2_IFSTACKTBL)); (*ppTempPtr)->index = lowerIndex; (*ppTempPtr)->pNextLower = pIfStackPtr; (*ppTempPtr)->status = ROW_ACTIVE; } else { while (pIfStackPtr && pIfStackPtr->index < lowerIndex) { ppTempPtr = &pIfStackPtr->pNextLower; pIfStackPtr = pIfStackPtr->pNextLower; } if (pIfStackPtr && pIfStackPtr->index == lowerIndex) { *ppTempPtr = pIfStackPtr->pNextLower; free(pIfStackPtr); } } #ifdef VIRTUAL_STACK _ifStackLastChange = centiSecsGet();#else /* VIRTUAL_STACK */ ifStackLastChange = centiSecsGet();#endif /* VIRTUAL_STACK */ semGive(m2InterfaceSem); return (OK); }/******************************************************************************** stackEntryIsTop - test if an ifStackTable interface has no layers above** This routine returns TRUE if an interface is not below any other interface.* That is, it returns TRUE if the given interface is topmost on a stack. This* helper function is not exported.** RETURNS: * TRUE is interface is topmost* FALSE otherwise or for errors**/BOOL stackEntryIsTop ( int index /* the interface to examine */ ) { M2_IFINDEX * pIfIndexEntry; M2_IFSTACKTBL * pIfStackEntry; UINT i = 0; while ((pIfIndexEntry = (M2_IFINDEX*) avlSuccessorGet (pM2IfRoot, (GENERIC_ARGUMENT)i, nextIndex))) { pIfStackEntry = pIfIndexEntry->pNextLower; while (pIfStackEntry) { if (pIfStackEntry->index == (UINT) index) { return FALSE; } pIfStackEntry = pIfStackEntry->pNextLower; } i = pIfIndexEntry->ifIndex; } return TRUE; }/******************************************************************************** stackEntryIsBottom - test if an interface has no layers beneath it** This routine returns TRUE if an interface has no layers beneath it. This* helper function is not exported.** RETURNS: * TRUE if the interface is the bottom-most layer in a stack* FALSE otherwise or on error**/BOOL stackEntryIsBottom ( int index /* interface to examine */ ) { M2_IFINDEX * pIfIndexEntry; pIfIndexEntry = (M2_IFINDEX*) avlSearch (pM2IfRoot, (GENERIC_ARGUMENT)index, nextIndex); if (pIfIndexEntry == 0 || pIfIndexEntry->pNextLower != 0) { return FALSE; } return TRUE; }/******************************************************************************** m2IfStackEntryGet - get a MIB-II interface-group table entry** This routine maps the given high and low indexes to the interfaces in the* AVL tree. Using the <high> and <low> indexes, we retrieve the nodes in* question and walk through their linked lists to get to the right relation.* Once we get to the correct node, we can return the values based on the* M2_EXACT_VALUE and the M2_NEXT_VALUE searches.** RETU
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -