Exemple #1
0
LOCAL BOOL wdbEndPollArpReply
    (
    struct mbuf *	pMblk,
    void *		pCookie
    )
    {
    struct ether_header * pEh;
    struct ether_arp *	  pEa;
    WDB_END_PKT_DEV * 	  pPktDev = pEndPktDev;
    int			  op;

    pEh = mtod(pMblk, struct ether_header *);
    pEa = (struct ether_arp *) ((char *)pEh + sizeof (struct ether_header));
    op = ntohs(pEa->arp_op);

    /* test if the request is for us */

    if ((bcmp ((caddr_t)&pPktDev->ipAddr.s_addr,
    		(caddr_t)&pEa->arp_tpa, pEa->arp_pln) == 0) &&
		(op == ARPOP_REQUEST))
	{
        /* build the reply */

	/* fill the ethernet header */

	bcopy (pEh->ether_shost, pEh->ether_dhost, sizeof(pEh->ether_shost));
	bcopy (pPktDev->srcAddr->mBlkHdr.mData, pEh->ether_shost,
               sizeof(pEh->ether_shost));
	
	/* fill the ARP Frame */

        bcopy (pEh->ether_dhost, pEa->arp_tha, pEa->arp_hln);
	bcopy (pEa->arp_spa, pEa->arp_tpa, pEa->arp_pln);
	bcopy (pEh->ether_shost, pEa->arp_sha, pEa->arp_hln);
	bcopy ((char *)&pPktDev->ipAddr.s_addr, pEa->arp_spa, pEa->arp_pln);
	pEa->arp_op = htons (ARPOP_REPLY);

        /* send the reply */

	muxPollSend (pCookie, pMblk);

	netMblkClFree (pMblk);
	DRIVER_RESET_INPUT(pPktDev);
	return (TRUE);
	}

    netMblkClFree (pMblk);
    DRIVER_RESET_INPUT(pPktDev);
    return (FALSE);
    }
Exemple #2
0
LOCAL STATUS
NetdrvPollSend(END_DEVICE* pDrvCtrl, /* device to be polled */
               M_BLK_ID    pMblk     /* packet to send */)
{
    int     len;
    u_short stat;

#ifdef BOOTROM_DEBUG
    printf("\r\nNetdrvPollSend");
#endif

    
    stat = NetdrvStatusRead(pDrvCtrl); /* dummy code */
    if((stat & NETDRV_TINT) == 0) {
        return ((STATUS) EAGAIN);
    }

    

    len = max(ETHERSMALL, pMblk->m_len);

    

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);

    /* Free the data if it was accepted by device */

    netMblkClFree (pMblk);

#ifdef BOOTROM_DEBUG
    printf("\r\nleaving NetdrvPollSend");
#endif

    return (OK);
}
Exemple #3
0
void
socend_receive_netjob(int pi, int pckti, int pckt_size)
/*
 * Function: 	socend_receive_netjob
 * Purpose:	Called from netjob after packet arrives.
 * Parameters:	p - pointer to (se), cookied passed on registration
 *		pckpi - pointer to packet data (int form).
 *		pckt_size - received length of packet.
 * Returns:	Nothing
 */
{
    socend_t		*se = (socend_t *)pi;
    struct end_object 	*eo = &se->se_eo;
    void		*pckt = (void *)pckti;
    bcm_vlan_t		vid;
    CL_BLK_ID		cb = NULL;
    M_BLK_ID		mb = NULL;

    /* Check the DCB for errors */
#if defined(BROADCOM_DEBUG)			/* Only compile in for debug */
    if (LOG_CHECK(BSL_LS_SYS_END | BSL_INFO) &&
        LOG_CHECK(BSL_LS_SOC_PACKET | BSL_INFO)) {
	d_packet_format("socend RX", DECODE_ETHER, pckt, pckt_size, NULL);
    }
#endif /* BROADCOM_DEBUG */
    /*
     * Build Cluster - then attach to mblks, 1 for each interface that
     * should get the packet. Broadcast/Multicast packets go up all the stacks.
     *
     * For multicast, it should only go up stacks that have registered for that
     * address, but for now, this will allow multiple interfaces to work.
     */

    if ((NULL == (cb = netClBlkGet(eo->pNetPool, M_DONTWAIT)))) {
	if (mb) netMblkFree(eo->pNetPool, mb);
	netClFree(eo->pNetPool, pckt);	/* Free packet */
	END_ERR_ADD(eo, MIB2_IN_ERRS, +1);
	return;
    }

#if defined(__mips__)
    if (SOC_IS_ESW(se->se_unit)) 
    {
        seu_t *seu = &socend_seu[se->se_unit];
        void  *tmp;
	
        sal_memcpy((UINT8 *)seu->pkt_align_buf + 2, (UINT8 *)pckt, pckt_size);
	
        tmp = seu->pkt_align_buf;
        seu->pkt_align_buf = pckt;
        pckt = tmp;
    }
#endif /* __mips__ */

    /* 1 MBLK for each interface */

    if ((mb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA))) {
	netClBlkJoin(cb, pckt, SOC_END_PK_SZ, NULL, 0, 0, 0);
	netMblkClJoin(mb, cb);
	mb->mBlkPktHdr.len = mb->mBlkHdr.mLen = pckt_size;
	mb->mBlkHdr.mFlags |= M_PKTHDR;
#if defined(__mips__)
        if (SOC_IS_ESW(se->se_unit)) {
            mb->mBlkHdr.mData +=2;
        }
#endif /* __mips__ */
	vid = VLAN_CTRL_ID(soc_ntohs(((enet_hdr_t *)mb->mBlkHdr.mData)->en_tag_ctrl));
        if (SOC_IS_ESW(se->se_unit)) {
            socend_untag(mb);		/* Untag packet for now */
        } else {
            robo_socend_untag(mb);		/* Untag packet for now */
        }
    } else {
	netClBlkFree(eo->pNetPool, cb);
	netClFree(eo->pNetPool, pckt);	/* Free packet */
	return;
    }

    {
	M_BLK_ID	tmb, fmb = mb;
	seu_t		*seu = &socend_seu[se->se_unit];
	/*
	 * Duplicate MBLK, and point to same cluster.
	 */
	for (se = seu->seu_devices; se != NULL; se = se->se_next) {

	    if (vid != se->se_vlan) {
		continue;
	    }

	    eo = &se->se_eo;

	    if (se->se_next != NULL) {
		tmb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA);
		netMblkDup(mb, tmb);
	    } else {
		fmb = NULL;
		tmb = mb;
	    }

	    END_RCV_RTN_CALL(eo, tmb);
	}

	if (fmb) {
	    netMblkClFree(fmb);
	}
    }
}
Exemple #4
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); 
         }
    }