Exemple #1
0
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 or equal to 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);
    }
Exemple #2
0
int wdbEndInt
    (
    void * 		pCookie,
    long 		type, 
    M_BLK_ID 		pMblk,
    LL_HDR_INFO * 	pLinkHdrInfo, 
    void * 		pMode
    )
    {
    struct mbuf * 	pMbuf;
    int			size;
    struct udphdr * 	pUdpHdr;
    struct ip *		pIpHdr;
    WDB_END_PKT_DEV * 	pPktDev = pEndPktDev;

    /* input buffer already in use - drop this packet */

    if (wdbEndDebug)
	logMsg ("Got a packet!\n", 1, 2, 3, 4, 5, 6);

    if (pPktDev->inputBusy)
	{
        if (wdbEndDebug)
	    logMsg ("Input busy!\n", 1, 2, 3, 4, 5, 6);

	/*
	 * free the packet only if the driver is in polling mode. If not, the
	 * packet will be freed by the MUX layer.
	 */

	if ((pMode != NULL) && (*((int *)pMode) == WDB_COMM_MODE_POLL))
	     netMblkClFree (pMblk);
	return (FALSE);
	}

    pPktDev->inputBusy = TRUE;

    /* Check the type before doing anything expensive. */

    if ((type == 0x806) && (pMode != NULL) &&
    				(*((int *)pMode) == WDB_COMM_MODE_POLL))
    	{
	/*
	 * In polling mode we need to answer ARP request so that
	 * communication becomes or remains possible.
	 */

        if (wdbEndDebug)
            logMsg ("Type == 0x806\n", 1, 2, 3, 4, 5, 6);
	return (wdbEndPollArpReply (pMblk, pCookie));
	}
	
    if (type != 0x800)
        {
        if (wdbEndDebug)
            logMsg ("Type != 0x800 && Type!= 0x806\n", 1, 2, 3, 4, 5, 6);
        goto wdbEndIntError;
        }

    size = pLinkHdrInfo->dataOffset + IP_HDR_SIZE + sizeof(struct udphdr);

    if (!(pMblk->mBlkHdr.mFlags & M_PKTHDR) || (pMblk->mBlkPktHdr.len <
                                                size))
        {
        goto wdbEndIntError; 
        }

    if (pMblk->mBlkHdr.mLen < size)
        {
        if (netMblkOffsetToBufCopy (pMblk, pLinkHdrInfo->dataOffset, pInPkt,
                                    size, NULL) == 0)
            goto wdbEndIntError;

	pIpHdr = (struct ip *) pInPkt;
        pUdpHdr = (struct udphdr *)(pInPkt + IP_HDR_SIZE);
        }
    else
        {
	pIpHdr = (struct ip *) (pMblk->mBlkHdr.mData +
				pLinkHdrInfo->dataOffset);
        pUdpHdr = (struct udphdr *)(pMblk->mBlkHdr.mData +
                                    pLinkHdrInfo->dataOffset +
                                    IP_HDR_SIZE);
        }

    /* If this packet is not for the agent, ignore it */

    if ((pIpHdr->ip_p != IPPROTO_UDP) ||
	(pUdpHdr->uh_dport != htons(WDBPORT)))
        goto wdbEndIntError;

    if (pPktDev->ipAddr.s_addr != pIpHdr->ip_dst.s_addr)
    	goto wdbEndIntError;

    /*
     * Check to see whether the packet is fragmented.  WDB does not
     * handle fragmented packets.
     */

    if (pIpHdr->ip_off & htons(IP_MF|IP_OFFMASK))
    	{
	if (wdbEndDebug)
	    logMsg ("Fragmented packet\n", 0, 0, 0, 0, 0, 0);
	goto wdbEndIntError;
	}

    if ((size = netMblkOffsetToBufCopy (pMblk, pLinkHdrInfo->dataOffset,
                                        pInPkt, M_COPYALL, NULL)) == 0)
        goto wdbEndIntError;
    
    bcopy ((char *)pMblk->mBlkHdr.mData + pLinkHdrInfo->srcAddrOffset,
          (char *)pPktDev->lastHAddr->mBlkHdr.mData, 
          pLinkHdrInfo->srcSize);

    /* We're always going to send an IP packet. */

    pPktDev->lastHAddr->mBlkHdr.reserved = htons (0x800);
    
    /*
     * Fill the input buffer with the packet. Use an mbuf cluster 
     * to pass the packet on to the agent.
     */
    
    pMbuf = wdbMbufAlloc ();
    if (pMbuf == NULL)
        goto wdbEndIntError;

    wdbMbufClusterInit (pMbuf, pInPkt, size, (int (*)())wdbEndInputFree,
                        (int)pPktDev);
    if (wdbEndDebug)
        logMsg ("Passing up a packet!\n", 1, 2, 3, 4, 5, 6);
    (*pPktDev->wdbDrvIf.stackRcv) (pMbuf);  /* invoke callback */

    netMblkClFree (pMblk);
    return (TRUE); 

    wdbEndIntError:
   	 {
         /*
          * drop all non wdb packets received through the poll routine
          * When call from muxReceive pMode is actually the spare pointer
          * which is initialized in the NET_PROTOCOL structure, the spare
          * pointer is passed as the last argument to the stackRcvRtn.
          * When called from wdbEndPoll it passes a mode in the void pointer
          * This mode is used to find out whether this routine is called from
          * wdbEndPoll or muxReceive. You will not be happy camper if the
          * spare pointer is removed from NET_PROTOCOL or if the stackRcvRtn's
          * API is changed.
          */

         if ((pMode != NULL) && (*((int *)pMode) == WDB_COMM_MODE_POLL))
	     netMblkClFree (pMblk);
         
         DRIVER_RESET_INPUT(pPktDev);
         return (FALSE); 
         }
    }