Boolean StationIsAccepted(Station* pThis, const Packet* pPacket) { unsigned i; for (i = 0; i < pPacket->routing.length; ++i) { if (pPacket->routing.path[i] == pThis->id) return FALSE; } return (IS_BROADCAST(pPacket->header.transitDstId) || (pPacket->header.transitDstId == pThis->id)) ? TRUE : FALSE; }
/************************************************************************* * Function: * * Description: * * Input: * * Output: * **************************************************************************/ extern SINT8 evtSmeCmdMsg(vmacApInfo_t *vmacSta_p,UINT8 *message) { MhsmEvent_t smMsg; macmgmtQ_SmeCmd_t * smeCmd_p; extStaDb_StaInfo_t *StaInfo_p; WLDBG_ENTER(DBG_CLASS_INFO); if (message == NULL) { return 1; } #ifdef AP_MAC_LINUX smMsg.devinfo = (void *) vmacSta_p; #endif smeCmd_p = (macmgmtQ_SmeCmd_t *)message; switch (smeCmd_p->CmdType) { case SME_CMD_DISASSOCIATE: { WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_DISASSOCIATE message received. \n"); if ((StaInfo_p = extStaDb_GetStaInfo(vmacSta_p,&smeCmd_p->Body.AssocCmd.PeerStaAddr, 1)) == NULL) { return 1; } smMsg.event = MlmeDisAssoc_Req; smMsg.pBody = (UINT8 *)&(smeCmd_p->Body.AssocCmd); mhsm_send_event((Mhsm_t *)&StaInfo_p->mgtAssoc.super, &smMsg); } break; case SME_CMD_START: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_START message received. \n"); syncMsg.opMode = infrastructure; syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.StartCmd); smMsg.event = MlmeStart_Req; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; case SME_CMD_RESET: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_RESET message received. \n"); syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.ResetCmd); smMsg.event = ResetMAC; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; #if defined(AP_SITE_SURVEY) || defined(AUTOCHANNEL) case SME_CMD_SCAN: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_SCAN message received. \n"); syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.ScanCmd); smMsg.event = MlmeScan_Req; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; #endif /* AP_SITE_SURVEY */ #ifdef IEEE80211H case SME_CMD_MREQUEST: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_MREQUEST message received. \n"); if (!IS_BROADCAST(&smeCmd_p->Body.MrequestCmd.PeerStaAddr)) { if ((StaInfo_p = extStaDb_GetStaInfo(vmacSta_p,&smeCmd_p->Body.MrequestCmd.PeerStaAddr, 1)) == NULL) { WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_MREQUEST - no station found %x:%x:%x:%x:%x:%x] \n", smeCmd_p->Body.MrequestCmd.PeerStaAddr[0], smeCmd_p->Body.MrequestCmd.PeerStaAddr[1], smeCmd_p->Body.MrequestCmd.PeerStaAddr[2], smeCmd_p->Body.MrequestCmd.PeerStaAddr[3], smeCmd_p->Body.MrequestCmd.PeerStaAddr[4], smeCmd_p->Body.MrequestCmd.PeerStaAddr[5]); return 1; } } syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.MrequestCmd); smMsg.event = MlmeMrequest_Req; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; case SME_CMD_MREPORT: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_MREPORT message received. \n"); if ((StaInfo_p = extStaDb_GetStaInfo(vmacSta_p,&smeCmd_p->Body.MrequestCmd.PeerStaAddr, 1)) == NULL) { WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SME_CMD_MREPORT - no station found %x:%x:%x:%x:%x:%x] \n", smeCmd_p->Body.MrequestCmd.PeerStaAddr[0], smeCmd_p->Body.MrequestCmd.PeerStaAddr[1], smeCmd_p->Body.MrequestCmd.PeerStaAddr[2], smeCmd_p->Body.MrequestCmd.PeerStaAddr[3], smeCmd_p->Body.MrequestCmd.PeerStaAddr[4], smeCmd_p->Body.MrequestCmd.PeerStaAddr[5]); return 1; } syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.MreportCmd); smMsg.event = MlmeMreport_Req; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; case SMC_CMD_CHANNELSWITCH_REQ: { SyncSrvApMsg syncMsg; WLDBG_INFO(DBG_LEVEL_11, "evtSmeCmdMsg: SMC_CMD_CHANNELSWITCH_REQ message received. \n"); syncMsg.mgtMsg = (UINT8 *)&(smeCmd_p->Body.ChannelSwitchCmd); smMsg.event = MlmeChannelSwitch_Req; smMsg.pBody = (unsigned char *)&syncMsg; mhsm_send_event((Mhsm_t *)&vmacSta_p->mgtSync.super, &smMsg); } break; #endif /* IEEE80211H */ default: break; } WLDBG_EXIT(DBG_CLASS_INFO); return 0; }
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); }
/* * Switch ethernet frame when in layer 3 mode (i.e. using IP * layer to do the routing). * * There is a large amount of overlap between this function and * vsw_switch_l2_frame. At some stage we need to revisit and refactor * both these functions. */ void vsw_switch_l3_frame(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg, mac_resource_handle_t mrh) { struct ether_header *ehp; mblk_t *bp = NULL; vsw_fdbe_t *fp; D1(vswp, "%s: enter (caller %d)", __func__, caller); /* * In layer 3 mode should only ever be switching packets * between IP layer and vnet devices. So make sure thats * who is invoking us. */ if ((caller != VSW_LOCALDEV) && (caller != VSW_VNETPORT)) { DERR(vswp, "%s: unexpected caller (%d)", __func__, caller); freemsgchain(mp); return; } /* process the chain of packets */ bp = mp; while (bp) { ehp = (struct ether_header *)bp->b_rptr; mp = vsw_get_same_dest_list(ehp, &bp); ASSERT(mp != NULL); D2(vswp, "%s: mblk data buffer %lld : actual data size %lld", __func__, MBLKSIZE(mp), MBLKL(mp)); /* * Find fdb entry for the destination * and hold a reference to it. */ fp = vsw_fdbe_find(vswp, &ehp->ether_dhost); if (fp != NULL) { D2(vswp, "%s: sending to target port", __func__); (void) vsw_portsend(fp->portp, mp); /* Release the reference on the fdb entry */ VSW_FDBE_REFRELE(fp); } else { /* * Destination not in FDB * * If the destination is broadcast or * multicast forward the packet to all * (VNETPORTs, PHYSDEV, LOCALDEV), * except the caller. */ if (IS_BROADCAST(ehp)) { D2(vswp, "%s: BROADCAST pkt", __func__); (void) vsw_forward_all(vswp, mp, caller, arg); } else if (IS_MULTICAST(ehp)) { D2(vswp, "%s: MULTICAST pkt", __func__); (void) vsw_forward_grp(vswp, mp, caller, arg); } else { /* * Unicast pkt from vnet that we don't have * an FDB entry for, so must be destinded for * the outside world. Attempt to send up to the * IP layer to allow it to deal with it. */ if (caller == VSW_VNETPORT) { vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_FREEMSG); } } } } D1(vswp, "%s: exit", __func__); }
/* * Switch the given ethernet frame when operating in layer 2 mode. * * vswp: pointer to the vsw instance * mp: pointer to chain of ethernet frame(s) to be switched * caller: identifies the source of this frame as: * 1. VSW_VNETPORT - a vsw port (connected to a vnet). * 2. VSW_PHYSDEV - the physical ethernet device * 3. VSW_LOCALDEV - vsw configured as a virtual interface * arg: argument provided by the caller. * 1. for VNETPORT - pointer to the corresponding vsw_port_t. * 2. for PHYSDEV - NULL * 3. for LOCALDEV - pointer to to this vsw_t(self) */ void vsw_switch_l2_frame(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *arg, mac_resource_handle_t mrh) { struct ether_header *ehp; mblk_t *bp, *ret_m; vsw_fdbe_t *fp; D1(vswp, "%s: enter (caller %d)", __func__, caller); /* * PERF: rather than breaking up the chain here, scan it * to find all mblks heading to same destination and then * pass that sub-chain to the lower transmit functions. */ /* process the chain of packets */ bp = mp; while (bp) { ehp = (struct ether_header *)bp->b_rptr; mp = vsw_get_same_dest_list(ehp, &bp); ASSERT(mp != NULL); D2(vswp, "%s: mblk data buffer %lld : actual data size %lld", __func__, MBLKSIZE(mp), MBLKL(mp)); if (ether_cmp(&ehp->ether_dhost, &vswp->if_addr) == 0) { /* * If destination is VSW_LOCALDEV (vsw as an eth * interface) and if the device is up & running, * send the packet up the stack on this host. * If the virtual interface is down, drop the packet. */ if (caller != VSW_LOCALDEV) { vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_FREEMSG); } else { freemsgchain(mp); } continue; } /* * Find fdb entry for the destination * and hold a reference to it. */ fp = vsw_fdbe_find(vswp, &ehp->ether_dhost); if (fp != NULL) { /* * If plumbed and in promisc mode then copy msg * and send up the stack. */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_COPYMSG); /* * If the destination is in FDB, the packet * should be forwarded to the correponding * vsw_port (connected to a vnet device - * VSW_VNETPORT) */ (void) vsw_portsend(fp->portp, mp); /* Release the reference on the fdb entry */ VSW_FDBE_REFRELE(fp); } else { /* * Destination not in FDB. * * If the destination is broadcast or * multicast forward the packet to all * (VNETPORTs, PHYSDEV, LOCALDEV), * except the caller. */ if (IS_BROADCAST(ehp)) { D2(vswp, "%s: BROADCAST pkt", __func__); (void) vsw_forward_all(vswp, mp, caller, arg); } else if (IS_MULTICAST(ehp)) { D2(vswp, "%s: MULTICAST pkt", __func__); (void) vsw_forward_grp(vswp, mp, caller, arg); } else { /* * If the destination is unicast, and came * from either a logical network device or * the switch itself when it is plumbed, then * send it out on the physical device and also * up the stack if the logical interface is * in promiscious mode. * * NOTE: The assumption here is that if we * cannot find the destination in our fdb, its * a unicast address, and came from either a * vnet or down the stack (when plumbed) it * must be destinded for an ethernet device * outside our ldoms. */ if (caller == VSW_VNETPORT) { /* promisc check copy etc */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_COPYMSG); if ((ret_m = vsw_tx_msg(vswp, mp, caller, arg)) != NULL) { DERR(vswp, "%s: drop mblks to " "phys dev", __func__); freemsgchain(ret_m); } } else if (caller == VSW_PHYSDEV) { /* * Pkt seen because card in promisc * mode. Send up stack if plumbed in * promisc mode, else drop it. */ vsw_mac_rx(vswp, mrh, mp, VSW_MACRX_PROMISC | VSW_MACRX_FREEMSG); } else if (caller == VSW_LOCALDEV) { /* * Pkt came down the stack, send out * over physical device. */ if ((ret_m = vsw_tx_msg(vswp, mp, caller, NULL)) != NULL) { DERR(vswp, "%s: drop mblks to " "phys dev", __func__); freemsgchain(ret_m); } } } } } D1(vswp, "%s: exit\n", __func__); }
Boolean StationIsDestination(Station* pThis, const Packet* pPacket) { return (IS_BROADCAST(pPacket->header.originalDstId)) || (pPacket->header.originalDstId == pThis->id) ? TRUE : FALSE; }