/* Send a packet to the IP stack like it was received by the virtual
   IP interface indexed by pp->ifnum_in. */
void ssh_virtual_adapter_send(SshInterceptor interceptor,
			      SshInterceptorPacket pp)
{
  SshInterceptorInternalPacket ipp;
  VxWorksVa *va;
  M_BLK_ID m;

  if (!(va = vxworks_va_find_va(pp->ifnum_out)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to send to a nonexistent ifnum %d", (int)pp->ifnum_out));

      ssh_interceptor_packet_free(pp);
      return;
    }

  if (pp->protocol != SSH_PROTOCOL_ETHERNET)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: dropping non-ethernet packet", va->name));

      ssh_interceptor_packet_free(pp);
      return;
    }

  ipp = (void *)pp;
  m = ipp->head;
  ipp->head = NULL;
  ssh_interceptor_packet_free_header(ipp);

  SSH_DEBUG(
    SSH_D_LOWOK,
    ("feeding receive packet to %s, ifnum %d", va->name, (int)va->ifnum));

  END_RCV_RTN_CALL(&va->end, m);
}
示例#2
0
文件: netdrv.c 项目: ariavie/bcm
/*
 * Send the received packet to END driver
 */
int
NetdrvSendToEnd(bcm_pkt_t *pPkt)
{
    int         len;
    M_BLK_ID    pMblk;
    char*       pCluster = NULL;
    CL_BLK_ID   pClBlk;
    END_DEVICE  *pDrvCtrl = __netDriver;

    if (pDrvCtrl == NULL) {
        return ERROR;
    }

    /* Add one to our unicast data. */
    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);

    /*
     * We implicitly are loaning here, if copying is necessary this
     * step may be skipped, but the data must be copied before being
     * passed up to the protocols.
     */
    pCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);

    if (pCluster == NULL) {
        DRV_LOG (1, "Cannot loan!\n",1,2,3,4,5,6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /* Grab a cluster block to marry to the cluster we received. */
    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) {
        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster);
        DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /*
     * OK we've got a spare, let's get an M_BLK_ID and marry it to the
     * one in the ring.
     */
    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) {
        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster);
        DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /* remove tag */
    len = pPkt->tot_len - 8;

    memcpy(pCluster + 2, (unsigned char *)(&(pPkt->_pkt_data.data[0])), 12);
    memcpy(pCluster + 14, (unsigned char *)(&(pPkt->_pkt_data.data[16])), len-12);

    /* Free buffer previously stolen */
    bcm_rx_free(pPkt->unit, pPkt->_pkt_data.data);

    /* Join the cluster to the MBlock */
    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);
    netMblkClJoin (pMblk, pClBlk);

    pMblk->mBlkHdr.mLen = len;
    pMblk->mBlkHdr.mData += 2;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = len;

    /* Send the packet to END driver */
    END_RCV_RTN_CALL(&__netDriver->end, pMblk);
    g_ulPktUp++;

    return OK;

    cleanRXD:
    return (ERROR);
}
LOCAL void mirrorEndReceive
    (
    END_CTRL*   pDrvCtrl,       /* pointer to END_CTRL structure */
    M_BLK*      pMblk
    )
    { 
    UINT16 * pTmp;
    UINT16   enetAddr[3];

    LOG_MSG("mirrorEndReceive: unit: %d, ", 
	    (int)pDrvCtrl->unit, 
	    2, 3, 4, 5, 6);
    LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ",
            *(UCHAR *)(pMblk->mBlkHdr.mData),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 1),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 2),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 3),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 4),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 5));
    LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n",
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 6),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 7),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 8),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 9),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 10),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 11));
        
   /* don't allow the packet through if in polling mode */

   if (pDrvCtrl->polling == TRUE)
       {
       netMblkClChainFree(pMblk);
       return;
       }

   /* if unit is not in promiscuous mode, filter packets to receive only
    * packets for our MAC address or broadcasts.
    */
    if (pDrvCtrl->promiscuous == FALSE)
        {
        pTmp = (UINT16 *)(pMblk->mBlkHdr.mData);
        if (((UINT32)(pTmp) & 0x01) == 0)
            {
            /* address is aligned on a 2 or 4 byte boundary */
            enetAddr[0] = pTmp[0];
            enetAddr[1] = pTmp[1];
            enetAddr[2] = pTmp[2];
            }
        else
            {
            /* address is aligned on a byte-boundary */
            bcopy((char *)pTmp, (char *)enetAddr, 6);
            }
            
        if ((MAC_ADDR_EQ(enetAddr, pDrvCtrl->enetAddr) == 0) &&
            (IS_BROADCAST(enetAddr) == 0) &&
            (isInMulticastList(pDrvCtrl, enetAddr) == FALSE))
            {
            LOG_MSG("Dest addr not my addr/broadcast/multicast - dropping!\n",
                    1, 2, 3, 4, 5, 6);
            netMblkClChainFree(pMblk);
            return;
            }
        }
   
    LOG_MSG("Sending up the packet to my network stack\n",
            1, 2, 3, 4, 5, 6);

    /* send up to protocol */
    END_RCV_RTN_CALL(&pDrvCtrl->endObject, pMblk);

    /* bump input packet counter */
    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_IN_UCAST, +1);    
    }
示例#4
0
文件: socend.c 项目: ariavie/bcm
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);
	}
    }
}