📄 loopend.c
字号:
/********************************************************************************* loIoctl - the driver I/O control routine** Process an ioctl request.*/LOCAL STATUS loIoctl ( LOEND_DEVICE *pDrvCtrl, int cmd, caddr_t data ) { STATUS error = OK; long value; if (LO_IS_DEV_STOPPED(pDrvCtrl)) return ERROR; switch (cmd) { case EIOCSADDR: return (ERROR); break; case EIOCGADDR: return (ERROR); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; /* HELP: WHY ??? */ END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* fall through */ case EIOCPOLLSTOP: error = ERROR; break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); *(int *)data = LO_MIN_FBUF; break; case EIOCGMWIDTH: if (data == NULL) return (EINVAL); *(int *)data = 0; break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = LO_HDR_LEN; break; case EIOCMULTIADD: case EIOCMULTIDEL: case EIOCMULTIGET: error = EINVAL; break; default: error = EINVAL; } return (error); }/********************************************************************************* loSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer. The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine. ** RETURNS: OK or ERROR.*/LOCAL STATUS loSend ( LOEND_DEVICE *pDrvCtrl, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { STATUS retValue = OK; if (LO_IS_DEV_STOPPED(pDrvCtrl)) retValue = ERROR; else { /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk); } return (retValue); }/********************************************************************************* loInitStringParse - parse the initialization string** Parse the input string. Fill in values in the driver control structure.* The initialization string format is:* <unit>** .IP <unit>* Device unit number, a small integer.** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS loInitStringParse ( LOEND_DEVICE* pDrvCtrl, char* initString ) { char * tok; char * pHolder = NULL; /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); return OK; }/******************************************************************************* loMCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK, or ERROR if fails to add*/LOCAL STATUS loMCastAddrAdd ( LOEND_DEVICE *pDrvCtrl, char* pAddress ) { int error; error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress); return (error); }/******************************************************************************* loMCastAddrDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK, or ERROR if fails to delete*/LOCAL STATUS loMCastAddrDel ( LOEND_DEVICE* pDrvCtrl, char* pAddress ) { int error; error = etherMultiDel (&pDrvCtrl->end.multiList, pAddress); return (error); }/******************************************************************************* loMCastAddrGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK, or ERROR if fails to get**/LOCAL STATUS loMCastAddrGet ( LOEND_DEVICE* pDrvCtrl, MULTI_TABLE* pTable ) { int error; error = etherMultiGet (&pDrvCtrl->end.multiList, pTable); return (error); }/********************************************************************************* loPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: ERROR always*/LOCAL STATUS loPollSend ( LOEND_DEVICE* pDrvCtrl, M_BLK_ID pMblk ) { return ERROR; }/********************************************************************************* loPollReceive - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: ERROR always*/LOCAL STATUS loPollReceive ( LOEND_DEVICE *pDrvCtrl, M_BLK_ID pMblk ) { return ERROR; }/******************************************************************************** loAddressForm - form an Ethernet address into a packet** This routine accepts the source and destination addressing information * through <pSrcAddr> and <pDstAddr> and returns an 'M_BLK_ID' that points * to the assembled link-level header. To do this, this routine prepends * the link-level header into the cluster associated with <pMblk> if there * is enough space available in the cluster. It then returns a pointer to * the pointer referenced in <pMblk>. However, if there is not enough space * in the cluster associated with <pMblk>, this routine reserves a * new 'mBlk'-'clBlk'-cluster construct for the header information. * It then prepends the new 'mBlk' to the 'mBlk' passed in <pMblk>. As the * function value, this routine then returns a pointer to the new 'mBlk', * which the head of a chain of 'mBlk' structures. The second element of this * chain is the 'mBlk' referenced in <pMblk>. ** RETURNS: M_BLK_ID or NULL.*/M_BLK_ID loAddressForm ( M_BLK_ID pMblk, /* pointer to packet mBlk */ M_BLK_ID pSrcAddr, /* pointer to source address */ M_BLK_ID pDstAddr /* pointer to destination address */ ) { M_PREPEND(pMblk, LO_PROTOCOL_LEN, M_DONTWAIT); if (pMblk != NULL) bcopy ((char *)&pDstAddr->mBlkHdr.reserved, pMblk->m_data, LO_PROTOCOL_LEN); return (pMblk); }/******************************************************************************** loPacketDataGet - return the beginning of the packet data** This routine fills the given <pLinkHdrInfo> with the appropriate offsets.** RETURNS: OK or ERROR.*/STATUS loPacketDataGet ( M_BLK_ID pMblk, LL_HDR_INFO * pLinkHdrInfo ) { pLinkHdrInfo->destAddrOffset = 0; pLinkHdrInfo->destSize = 0; pLinkHdrInfo->srcAddrOffset = 0; pLinkHdrInfo->srcSize = 0; pLinkHdrInfo->dataOffset = LO_PROTOCOL_LEN; bcopy (pMblk->m_data, (char *)&pLinkHdrInfo->pktType, LO_PROTOCOL_LEN); return (OK); }/******************************************************************************** loPacketAddrGet - locate the addresses in a packet** This routine takes a 'M_BLK_ID', locates the address information, and * adjusts the M_BLK_ID structures referenced in <pSrc>, <pDst>, <pESrc>, * and <pEDst> so that their pData members point to the addressing * information in the packet. The addressing information is not copied. * All 'mBlk' structures share the same cluster.** RETURNS: OK or ERROR.*/STATUS loPacketAddrGet ( M_BLK_ID pMblk, /* pointer to packet */ M_BLK_ID pSrc, /* pointer to local source address */ M_BLK_ID pDst, /* pointer to local destination address */ M_BLK_ID pESrc, /* pointer to remote source address (if any) */ M_BLK_ID pEDst /* pointer to remote destination address (if any) */ ) { if (pSrc != NULL) { pSrc->mBlkHdr.mData = NULL; pSrc->mBlkHdr.mLen = 0; } if (pDst != NULL) { pDst->mBlkHdr.mLen = 0; } if (pESrc != NULL) { pESrc->mBlkHdr.mData = NULL; pESrc->mBlkHdr.mLen = 0; } if (pEDst != NULL) { pEDst->mBlkHdr.mLen = 0; } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -