📄 muxlib.c
字号:
* (it should always of course check to make sure there is one) * before the buffer pool was set up. This would be Bad. */ lstAdd(&pNode->units, &pNew->node);#ifndef STANDALONE_AGENT /* * no receive routine for standalone agent (only polling mode * is supported). */ /* Determine if driver uses END or NPT interface. Default is END. */ pNew->receiveRtn = muxReceive; if (pNew->pFuncTable->ioctl) { if ( (pNew->pFuncTable->ioctl (pNew, EIOCGNPT, NULL)) == OK) { /* NPT device. */ pNew->receiveRtn = (FUNCPTR)muxTkReceive; } }#endif /* STANDALONE_AGENT */ pCookie = muxTkDevLoadUpdate (pNew); if (pCookie == NULL) { goto muxLoadErr; } semGive (muxLibState.lock); return (pCookie); muxLoadErr: errnoSet (S_muxLib_LOAD_FAILED); semGive (muxLibState.lock); return (NULL); }/****************************************************************************** * muxDevStart - start a device by calling its start routine** This routine starts a device that has already been initialized and loaded* into the MUX with muxDevLoad(). muxDevStart() activates the network* interfaces for a device, and calls the device's endStart() or nptStart()* routine, which registers the driver's interrupt service routine and does* whatever else is needed to allow the device to handle receiving and* transmitting. This call to endStart() or nptStart() puts the device into* a running state. * * .IP <pCookie>* Expects the pointer returned as the function value of the muxDevLoad()* call for this device. This pointer identifies the device.* .LP** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call muxDevStart() from within the kernel * protection domain only, and the data referenced in the <pCookie> * parameter must reside in the kernel protection domain. * This restriction does not apply under non-AE versions of VxWorks. ** RETURNS: OK; ENETDOWN, if <pCookie> does not represent a valid device;* or ERROR, if the start routine for the device fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxDevStart ( void * pCookie /* device identifier from muxDevLoad() routine */ ) { int error; END_OBJ * pEnd = PCOOKIE_TO_ENDOBJ(pCookie); if (pEnd == NULL) { errnoSet (S_muxLib_NO_DEVICE); error = ENETDOWN; } else { error = pEnd->pFuncTable->start(pEnd); } if (error == OK) { if (pEnd->flags & END_MIB_2233) { if ((pEnd->pMib2Tbl != NULL) && (pEnd->pMib2Tbl->m2VarUpdateRtn != NULL)) { pEnd->pMib2Tbl->m2VarUpdateRtn(pEnd->pMib2Tbl, M2_varId_ifAdminStatus, (void *)M2_ifAdminStatus_up); pEnd->pMib2Tbl->m2VarUpdateRtn(pEnd->pMib2Tbl, M2_varId_ifOperStatus, (void *)M2_ifOperStatus_up); } } else /* (RFC1213 style of counters is supported) XXX */ { pEnd->mib2Tbl.ifAdminStatus = M2_ifAdminStatus_up; pEnd->mib2Tbl.ifOperStatus = M2_ifOperStatus_up; } } return (error); }#ifndef STANDALONE_AGENT/****************************************************************************** * muxDevStop - stop a device by calling its stop routine** This routine stops the device specified in <pCookie>.* muxDevStop() calls the device's endStop() or nptStop() routine.* * .IP <pCookie> * Expects the cookie returned as the function value of the muxDevLoad() * call for this device. This cookie identifies the device.* .LP** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call muxDevStop() from within the kernel * protection domain only, and the data referenced in the <pCookie> * parameter must reside in the kernel protection domain. * This restriction does not apply under non-AE versions of VxWorks. ** RETURNS: OK; ENETDOWN, if <pCookie> does not represent a valid device; or* ERROR, if the endStop() or nptStop() routine for the device fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxDevStop ( void * pCookie /* device identifier from muxDevLoad() routine */ ) { int error; END_OBJ * pEnd = PCOOKIE_TO_ENDOBJ(pCookie); if (pEnd == NULL) { errnoSet (S_muxLib_NO_DEVICE); error = ENETDOWN; } else { error = pEnd->pFuncTable->stop(pEnd); } return (error); }/******************************************************************************** muxShow - display configuration of devices registered with the MUX** If the <pDevName> and <unit> arguments specify an existing device, this* routine reports the name and type of each protocol bound to it. Otherwise,* if <pDevName> is NULL, the routine displays the entire list of existing* devices and their associated protocols.** .IP <pDevName> * A string that contains the name of the device, or a null pointer to * indicate "all devices."* .IP <unit> * Specifies the unit number of the device (if <pDevName> is not a null * pointer).** RETURNS: N/A*/void muxShow ( char * pDevName, /* pointer to device name, or NULL for all */ int unit /* unit number for a single device */ ) { int curr; NET_PROTOCOL* pProto; END_OBJ* pEnd; END_TBL_ROW* pNode; /* Display the current packet handling mode. */ printf("Current mode: "); switch (muxLibState.mode) { case MUX_MODE_POLL: printf ("POLLING\n"); break; case MUX_MODE_NORM: printf ("NORMAL\n"); break; default: printf ("ERROR UNKNOWN MODE\n"); break; } /* If the name is not NULL then find the specific interface to show. */ if (pDevName != NULL) { pEnd = endFindByName (pDevName, unit); if (pEnd == NULL) { printf ("Device %s unit %d not found.\n", pDevName, unit); return; } printf ("Device: %s Unit: %d\n", pEnd->devObject.name, pEnd->devObject.unit); printf ("Description: %s\n", pEnd->devObject.description); /* See if there is an output protocol. */ if (pEnd->outputFilter != NULL) { printf ("Output protocol: Recv 0x%lx\n", (unsigned long)pEnd->outputFilter->stackRcvRtn); } /* List the rest of the regular protocols for the device. */ curr = 0; for (pProto = (NET_PROTOCOL *)lstFirst (&pEnd->protocols); pProto != NULL; pProto = (NET_PROTOCOL *)lstNext(&pProto->node)) { FUNCPTR netStackRcvRtn = NULL; if (pProto->type == MUX_PROTO_OUTPUT) continue; if (pProto->nptFlag) { MUX_ID muxId = (MUX_ID)pProto->pSpare; if (muxId) netStackRcvRtn = muxId->netStackRcvRtn; } else netStackRcvRtn = pProto->stackRcvRtn; printf ("Protocol: %s\tType: %ld\tRecv 0x%lx\tShutdown 0x%lx\n", pProto->name, pProto->type, (unsigned long)netStackRcvRtn, (unsigned long)pProto->stackShutdownRtn); curr++; } } else /* Show ALL configured ENDs. */ { for (pNode = (END_TBL_ROW *)lstFirst (&endList); pNode != NULL; pNode = (END_TBL_ROW *)lstNext (&pNode->node)) { for (pEnd = (END_OBJ *)lstFirst(&pNode->units); pEnd != NULL; pEnd = (END_OBJ *)lstNext(&pEnd->node)) { printf ("Device: %s Unit: %d\n", pEnd->devObject.name, pEnd->devObject.unit); printf ("Description: %s\n", pEnd->devObject.description); if (pEnd->outputFilter != NULL) { printf ("Output protocol: Recv 0x%lx\n", (unsigned long)pEnd->outputFilter->stackRcvRtn); } curr = 0; for (pProto = (NET_PROTOCOL *)lstFirst (&pEnd->protocols); pProto != NULL; pProto = (NET_PROTOCOL *)lstNext (&pProto->node)) { FUNCPTR netStackRcvRtn = NULL; if (pProto->type == MUX_PROTO_OUTPUT) continue; if (pProto->nptFlag) { MUX_ID muxId = (MUX_ID)pProto->pSpare; if (muxId) netStackRcvRtn = muxId->netStackRcvRtn; } else netStackRcvRtn = pProto->stackRcvRtn; printf ("Protocol: %s\tType: %ld\tRecv 0x%lx\tShutdown 0x%lx\n", pProto->name, pProto->type, (unsigned long)netStackRcvRtn, (unsigned long)pProto->stackShutdownRtn); curr++; } } } } }/******************************************************************************** muxBind - create a binding between a network service and an END** A network service uses this routine to bind to an END specified by the* <pName> and <unit> arguments (for example, ln and 0, ln and 1, or ei and 0).** NOTE: This routine should only be used to bind to drivers that use the* old END driver callback function prototypes. NPT drivers, or END drivers* that use the newer callback function prototypes, should use muxTkBind()* instead. See the* .I "Network Protocol Toolkit Programmer's Guide"* for more information on when to use muxBind() and muxTkBind().** The <type> argument assigns a network service to one of several classes.* Standard services receive the portion of incoming data associated* with <type> values from RFC 1700. Only one service for each RFC 1700* type value may be bound to an END.** Services with <type> MUX_PROTO_SNARF provide a mechanism for bypassing* the standard services for purposes such as firewalls. These services* will get incoming packets before any of the standard services.** Promiscuous services with <type> MUX_PROTO_PROMISC receive any packets* not consumed by the snarf or standard services. ** The MUX allows multiple snarf and promiscuous services but does not* coordinate between them. It simply delivers available packets to each* service in FIFO order. Services that consume packets may prevent* "downstream" services from receiving data if the desired packets overlap.** An output service (with <type> MUX_PROTO_OUTPUT) receives outgoing data* before it is sent to the device. This service type allows two network* services to communicate directly and provides a mechanism for loop-back* testing. Only one output service is supported for each driver.** The MUX calls the registered <stackRcvRtn> whenever it receives a packet* of the appropriate type. If that routine returns TRUE, the packet is* not offered to any remaining services (or to the driver in the case of* output services). A service (including an output service) may return* FALSE to examine a packet without consuming it. See the description of a* stackRcvRtn() in the* .I "Network Protocol Toolkit Programmer's Guide"* for additional information about the expected behavior of that routine.** The <stackShutdownRtn> argument provides a function that the MUX can use* to shut down the service. See the* .I "Network Protocol Toolkit Programmer's Guide"* for a description of how to write such a routine.* * The <pProtoName> argument provides the name of the service as a character* string. A service name is assigned internally if the argument is NULL.** The <pSpare> argument registers a pointer to data defined by the service.* The MUX includes this argument in calls to the call back routines from * this service.** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call muxBind() from within the kernel protection * domain only, and the data referenced in the <stackRcvRtn>, * <stackShutdownRtn>, <stackTxRestartRtn>, <stackErrorRtn> and <pSpare> * parameters must reside in the kernel protection domain. In addition, the * returned void pointer is valid in the kernel protection domain only. This * restriction does not apply under non-AE versions of VxWorks. ** RETURNS: A cookie identifying the binding between the service and driver;* or NULL, if an error occurred.** ERRNO: S_muxLib_NO_DEVICE, S_muxLib_ALREADY_BOUND, S_muxLib_ALLOC_FAILED*/void * muxBind ( char * pName, /* interface name, for example, ln, ei,... */ int unit, /* unit number */ BOOL (*stackRcvRtn) (void*, long, M_BLK_ID, LL_HDR_INFO *, void*), /* receive function to be called. */ STATUS (*stackShutdownRtn) (void*, void*), /* routine to call to shutdown the stack */ STATUS (*stackTxRestartRtn) (void*, void*), /* routine to tell the stack it can transmit */ void (*stackErrorRtn) (END_OBJ*, END_ERR*, void*), /* routine to call on an error. */ long type, /* protocol type from RFC1700 and many */ /* other sources (for example, 0x800 is IP) */ char * pProtoName, /* string name for protocol */ void * pSpare /* per protocol spare pointer */ ) { NET_PROTOCOL * pNew; NET_PROTOCOL * pNode = NULL; NODE * pFinal = NULL; /* Last snarf protocol, if any. */ END_OBJ * pEnd; void * pCookie = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -