📄 endlib.c
字号:
pEndObj->devObject.unit = unit; pEndObj->pFuncTable = pFuncTable; /* Clear multicast info. */ lstInit (&pEndObj->multiList); pEndObj->nMulti = 0; pEndObj->snarfCount = 0; return OK; }/********************************************************************************* endObjFlagSet - set the `flags' member of an END_OBJ structure** As input, this routine expects a pointer to an END_OBJ structure * (the <pEnd> parameter) and a flags value (the <flags> parameter).* This routine sets the 'flags' member of the END_OBJ structure* to the value of the <flags> parameter. ** Because this routine assumes that the driver interface is now up, * this routine also sets the 'attached' member of the referenced END_OBJ* structure to TRUE. ** RETURNS: OK*/STATUS endObjFlagSet ( END_OBJ * pEnd, UINT flags ) { pEnd->attached = TRUE; pEnd->flags = flags; return OK; }/******************************************************************************** end8023AddressForm - form an 802.3 address into a packet** This routine accepts the source and destination addressing information* through <pSrcAddr> and <pDstAddr> mBlks and returns an M_BLK_ID to the* assembled link level header. If the <bcastFlag> argument is TRUE, it* sets the destination address to the link-level broadcast address and* ignores the <pDstAddr> contents. This routine prepends the link level header* into <pMblk> if there is enough space available or it allocates a new* mBlk/clBlk/cluster and prepends the new mBlk to the mBlk chain passed in* <pMblk>. This routine returns a pointer to an mBlk which contains the* link level header information.** RETURNS: M_BLK_ID or NULL.** NOMANUAL*/M_BLK_ID end8023AddressForm ( M_BLK_ID pMblk, M_BLK_ID pSrcAddr, M_BLK_ID pDstAddr, BOOL bcastFlag ) { short dataLen; /* length of data including LLC */ short etherType; /* Ethernet network type code */ struct llc * pLlc; /* link layer control header */ dataLen = pMblk->mBlkPktHdr.len + LLC_SNAP_FRAMELEN; dataLen = htons (dataLen); M_PREPEND(pMblk, SIZEOF_ETHERHEADER + LLC_SNAP_FRAMELEN, M_DONTWAIT); if (pMblk != NULL) { if (bcastFlag) bcopy (etherbroadcastaddr, pMblk->m_data, 6); else bcopy (pDstAddr->m_data, pMblk->m_data, pDstAddr->m_len); bcopy (pSrcAddr->m_data, pMblk->m_data + pDstAddr->m_len, pSrcAddr->m_len); bcopy ((char *) &dataLen, pMblk->m_data + pDstAddr->m_len + pSrcAddr->m_len, sizeof (short)); /* Fill in LLC using SNAP values */ pLlc = (struct llc *) (pMblk->m_data + pDstAddr->m_len + pSrcAddr->m_len + sizeof (short)); pLlc->llc_dsap = LLC_SNAP_LSAP; pLlc->llc_ssap = LLC_SNAP_LSAP; pLlc->llc_un.type_snap.control = LLC_UI; bzero (pLlc->llc_un.type_snap.org_code, sizeof (pLlc->llc_un.type_snap.org_code)); /* Enter ethernet network type code into the LLC snap field */ etherType = htons (pDstAddr->mBlkHdr.reserved); bcopy ((char *) ðerType, (char *) &(pLlc->llc_un.type_snap.ether_type), sizeof (short)); } return (pMblk); }/******************************************************************************** endEtherAddressForm - 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 endEtherAddressForm ( M_BLK_ID pMblk, /* pointer to packet mBlk */ M_BLK_ID pSrcAddr, /* pointer to source address */ M_BLK_ID pDstAddr, /* pointer to destination address */ BOOL bcastFlag /* use link-level broadcast? */ ) { M_PREPEND(pMblk, SIZEOF_ETHERHEADER, M_DONTWAIT); if (pMblk != NULL) { if (bcastFlag) bcopy (etherbroadcastaddr, pMblk->m_data, 6); else bcopy (pDstAddr->m_data, pMblk->m_data, 6); bcopy (pSrcAddr->m_data, pMblk->m_data + 6, 6); ((struct ether_header *)pMblk->m_data)->ether_type = pDstAddr->mBlkHdr.reserved; } return (pMblk); }/******************************************************************************** endEtherPacketDataGet - return the beginning of the packet data** This routine fills the given <pLinkHdrInfo> with the appropriate offsets.** RETURNS: OK or ERROR.*/STATUS endEtherPacketDataGet ( M_BLK_ID pMblk, LL_HDR_INFO * pLinkHdrInfo ) { struct ether_header * pEnetHdr; struct ether_header enetHdr; struct llc * pLLCHdr; struct llc llcHdr; USHORT etherType; pLinkHdrInfo->destAddrOffset = 0; pLinkHdrInfo->destSize = 6; pLinkHdrInfo->srcAddrOffset = 6; pLinkHdrInfo->srcSize = 6; /* Try for RFC 894 first as it's the most common. */ /* * make sure entire ether_header is in first M_BLK * if not then copy the data to a temporary buffer */ if (pMblk->mBlkHdr.mLen < SIZEOF_ETHERHEADER) { pEnetHdr = &enetHdr; if (netMblkOffsetToBufCopy (pMblk, 0, (char *) pEnetHdr, SIZEOF_ETHERHEADER, (FUNCPTR) bcopy) < SIZEOF_ETHERHEADER) { return (ERROR); } } else pEnetHdr = (struct ether_header *)pMblk->mBlkHdr.mData; etherType = ntohs(pEnetHdr->ether_type); /* Deal with 802.3 addressing. */ /* Here is the algorithm. */ /* If the etherType is less than the MTU then we know that */ /* this is an 802.x address from RFC 1700. */ if (etherType < ETHERMTU) { /* * make sure entire ether_header + llc_hdr is in first M_BLK * if not then copy the data to a temporary buffer */ if (pMblk->mBlkHdr.mLen < SIZEOF_ETHERHEADER + LLC_SNAP_FRAMELEN) { pLLCHdr = &llcHdr; if (netMblkOffsetToBufCopy (pMblk, SIZEOF_ETHERHEADER, (char *) pLLCHdr, LLC_SNAP_FRAMELEN, (FUNCPTR) bcopy) < LLC_SNAP_FRAMELEN) { return (ERROR); } } else pLLCHdr = (struct llc *)((char *)pEnetHdr + SIZEOF_ETHERHEADER); /* Now it may be IP over 802.x so we check to see if the */ /* destination SAP is IP, if so we snag the ethertype from the */ /* proper place. */ /* Now if it's NOT IP over 802.x then we just used the DSAP as */ /* the etherType. */ if (pLLCHdr->llc_dsap == LLC_SNAP_LSAP) { etherType = ntohs(pLLCHdr->llc_un.type_snap.ether_type); pLinkHdrInfo->dataOffset = SIZEOF_ETHERHEADER + 8; } else { /* no SNAP header */ pLinkHdrInfo->dataOffset = SIZEOF_ETHERHEADER + 3; etherType = pLLCHdr->llc_dsap; } } else { pLinkHdrInfo->dataOffset = SIZEOF_ETHERHEADER; } pLinkHdrInfo->pktType = etherType; return (OK); }/******************************************************************************** endEtherPacketAddrGet - 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 endEtherPacketAddrGet ( 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 = netMblkDup (pMblk, pSrc); pSrc->mBlkHdr.mData += 6; pSrc->mBlkHdr.mLen = 6; } if (pDst != NULL) { pDst = netMblkDup (pMblk, pDst); pDst->mBlkHdr.mLen = 6; } if (pESrc != NULL) { pESrc = netMblkDup (pMblk, pESrc); pESrc->mBlkHdr.mData += 6; pESrc->mBlkHdr.mLen = 6; } if (pEDst != NULL) { pEDst = netMblkDup (pMblk, pEDst); pEDst->mBlkHdr.mLen = 6; } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -