MT7601u/src/common/cmm_mat_iparp.c
Murat Demirtas 612db32659 FIXED
2016-10-30 14:40:00 +00:00

695 lines
18 KiB
C

/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
cmm_mat_iparp.c
Abstract:
MAT convert engine subroutine for ip base protocols, currently now we
just handle IP/ARP protocols.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Shiang 02/26/07 Init version
*/
#ifdef MAT_SUPPORT
#include "rt_config.h"
static NDIS_STATUS MATProto_IP_Init(MAT_STRUCT *pMatCfg);
static NDIS_STATUS MATProto_IP_Exit(MAT_STRUCT *pMatCfg);
static PUCHAR MATProto_IP_Rx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
static PUCHAR MATProto_IP_Tx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
static NDIS_STATUS MATProto_ARP_Init(MAT_STRUCT *pMatCfg);
static NDIS_STATUS MATProto_ARP_Exit(MAT_STRUCT *pMatCfg);
static PUCHAR MATProto_ARP_Rx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb, PUCHAR pLayerHdr, PUCHAR pMacAddr);
static PUCHAR MATProto_ARP_Tx(MAT_STRUCT *pMatCfg, PNDIS_PACKET pSkb,PUCHAR pLayerHdr, PUCHAR pMacAddr);
#define IPV4_ADDR_LEN 4
#define NEED_UPDATE_IPMAC_TB(Mac, IP) (IS_UCAST_MAC(Mac) && IS_GOOD_IP(IP))
typedef struct _IPMacMappingEntry
{
UINT ipAddr; /* In network order */
UCHAR macAddr[MAC_ADDR_LEN];
ULONG lastTime;
struct _IPMacMappingEntry *pNext;
}IPMacMappingEntry, *PIPMacMappingEntry;
typedef struct _IPMacMappingTable
{
BOOLEAN valid;
IPMacMappingEntry *hash[MAT_MAX_HASH_ENTRY_SUPPORT+1]; /*0~63 for specific station, 64 for broadcast MacAddress */
UCHAR curMcastAddr[MAC_ADDR_LEN]; /* The multicast mac addr for currecnt received packet destined to ipv4 multicast addr */
}IPMacMappingTable;
struct _MATProtoOps MATProtoIPHandle =
{
.init = MATProto_IP_Init,
.tx = MATProto_IP_Tx,
.rx = MATProto_IP_Rx,
.exit = MATProto_IP_Exit,
};
struct _MATProtoOps MATProtoARPHandle =
{
.init = MATProto_ARP_Init,
.tx = MATProto_ARP_Tx,
.rx = MATProto_ARP_Rx,
.exit =MATProto_ARP_Exit,
};
VOID dumpIPMacTb(
IN MAT_STRUCT *pMatCfg,
IN int index)
{
IPMacMappingTable *pIPMacTable;
IPMacMappingEntry *pHead;
int startIdx, endIdx;
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
if (!pIPMacTable)
return;
if (!pIPMacTable->valid)
{
DBGPRINT(RT_DEBUG_OFF, ("%s():IPMacTable not init yet, so cannot do dump!\n", __FUNCTION__));
return;
}
if(index < 0)
{ /* dump all. */
startIdx = 0;
endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
}
else
{ /* dump specific hash index. */
startIdx = endIdx = index;
}
DBGPRINT(RT_DEBUG_OFF, ("%s():\n", __FUNCTION__));
for(; startIdx<= endIdx; startIdx++)
{
pHead = pIPMacTable->hash[startIdx];
while(pHead)
{
DBGPRINT(RT_DEBUG_OFF, ("IPMac[%d]:\n", startIdx));
DBGPRINT(RT_DEBUG_OFF, ("\t:IP=0x%x,Mac=%02x:%02x:%02x:%02x:%02x:%02x, lastTime=0x%lx, next=%p\n",
pHead->ipAddr, pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5], pHead->lastTime,
pHead->pNext));
pHead = pHead->pNext;
}
}
DBGPRINT(RT_DEBUG_OFF, ("\t----EndOfDump!\n"));
}
static inline NDIS_STATUS getDstIPFromIpPkt(
IN PUCHAR pIpHdr,
IN UINT *dstIP)
{
if (!pIpHdr)
return FALSE;
NdisMoveMemory(dstIP, (pIpHdr + 16), 4); /*shift 16 for IP header len before DstIP. */
/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Get the dstIP=0x%x\n", __FUNCTION__, *dstIP)); */
return TRUE;
}
static inline NDIS_STATUS getSrcIPFromIpPkt(
IN PUCHAR pIpHdr,
IN UINT *pSrcIP)
{
if (!pIpHdr)
return FALSE;
NdisMoveMemory(pSrcIP, (pIpHdr + 12), 4); /*shift 12 for IP header len before DstIP. */
/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Get the srcIP=0x%x\n", __FUNCTION__, *pSrcIP)); */
return TRUE;
}
static NDIS_STATUS IPMacTableUpdate(
IN MAT_STRUCT *pMatCfg,
IN PUCHAR pMacAddr,
IN UINT ipAddr)
{
UINT hashIdx;
IPMacMappingTable *pIPMacTable;
IPMacMappingEntry *pEntry = NULL, *pPrev = NULL, *pNewEntry =NULL;
ULONG now;
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
if (!pIPMacTable)
return FALSE;
if (!pIPMacTable->valid)
return FALSE;
hashIdx = MAT_IP_ADDR_HASH_INDEX(ipAddr);
pEntry = pPrev = pIPMacTable->hash[hashIdx];
while(pEntry)
{
NdisGetSystemUpTime(&now);
/* Find a existed IP-MAC Mapping entry */
if (ipAddr == pEntry->ipAddr)
{
/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): Got the Mac(%02x:%02x:%02x:%02x:%02x:%02x) of mapped IP(%d.%d.%d.%d)\n",
__FUNCTION__, pEntry->macAddr[0],pEntry->macAddr[1],pEntry->macAddr[2], pEntry->macAddr[3],pEntry->macAddr[4],
pEntry->macAddr[5], (ipAddr>>24) & 0xff, (ipAddr>>16) & 0xff, (ipAddr>>8) & 0xff, ipAddr & 0xff));
*/
/* compare is useless. So we directly copy it into the entry. */
NdisMoveMemory(pEntry->macAddr, pMacAddr, 6);
pEntry->lastTime = now;
return TRUE;
}
else
{ /* handle the age-out situation */
/*if ((Now - pEntry->lastTime) > MAT_TB_ENTRY_AGEOUT_TIME) */
if (RTMP_TIME_AFTER(now, pEntry->lastTime + MAT_TB_ENTRY_AGEOUT_TIME))
{
/* Remove the aged entry */
if (pEntry == pIPMacTable->hash[hashIdx])
{
pIPMacTable->hash[hashIdx]= pEntry->pNext;
pPrev = pIPMacTable->hash[hashIdx];
}
else
{
pPrev->pNext = pEntry->pNext;
}
MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
pMatCfg->nodeCount--;
}
else
{
pPrev = pEntry;
pEntry = pEntry->pNext;
}
}
}
/* Allocate a new IPMacMapping entry and insert into the hash */
pNewEntry = (IPMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPMacMappingEntry));
if (pNewEntry != NULL)
{
pNewEntry->ipAddr = ipAddr;
NdisMoveMemory(pNewEntry->macAddr, pMacAddr, 6);
pNewEntry->pNext = NULL;
NdisGetSystemUpTime(&pNewEntry->lastTime);
if (pIPMacTable->hash[hashIdx] == NULL)
{ /* Hash list is empty, directly assign it. */
pIPMacTable->hash[hashIdx] = pNewEntry;
}
else
{
/* Ok, we insert the new entry into the root of hash[hashIdx] */
pNewEntry->pNext = pIPMacTable->hash[hashIdx];
pIPMacTable->hash[hashIdx] = pNewEntry;
}
/*dumpIPMacTb(pMatCfg, hashIdx); //for debug */
pMatCfg->nodeCount++;
return TRUE;
}
return FALSE;
}
static PUCHAR IPMacTableLookUp(
IN MAT_STRUCT *pMatCfg,
IN UINT ipAddr)
{
IPMacMappingTable *pIPMacTable;
UINT hashIdx, ip;
IPMacMappingEntry *pEntry = NULL;
PUCHAR pGroupMacAddr;
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
if (!pIPMacTable)
return NULL;
if (!pIPMacTable->valid)
return NULL;
/*if multicast ip, need converting multicast group address to ethernet address. */
ip = ntohl(ipAddr);
if (IS_MULTICAST_IP(ip))
{
pGroupMacAddr = (PUCHAR)(&pIPMacTable->curMcastAddr);
ConvertMulticastIP2MAC((PUCHAR) &ipAddr, (UCHAR **)(&pGroupMacAddr), ETH_P_IP);
return pIPMacTable->curMcastAddr;
}
/* Use hash to find out the location of that entry and get the Mac address. */
hashIdx = MAT_IP_ADDR_HASH_INDEX(ipAddr);
/* spin_lock_irqsave(&IPMacTabLock, irqFlag); */
pEntry = pIPMacTable->hash[hashIdx];
while(pEntry)
{
if (pEntry->ipAddr == ipAddr)
{
/* DBGPRINT(RT_DEBUG_TRACE, ("%s(): dstMac=%02x:%02x:%02x:%02x:%02x:%02x for mapped dstIP(%d.%d.%d.%d)\n",
__FUNCTION__, pEntry->macAddr[0],pEntry->macAddr[1],pEntry->macAddr[2],
pEntry->macAddr[3],pEntry->macAddr[4],pEntry->macAddr[5],
(ipAddr>>24) & 0xff, (ipAddr>>16) & 0xff, (ipAddr>>8) & 0xff, ipAddr & 0xff));
*/
/*Update the lastTime to prevent the aging before pDA processed! */
NdisGetSystemUpTime(&pEntry->lastTime);
return pEntry->macAddr;
}
else
pEntry = pEntry->pNext;
}
/*
We didn't find any matched Mac address, our policy is treat it as
broadcast packet and send to all.
*/
return pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST]->macAddr;
}
static NDIS_STATUS IPMacTable_RemoveAll(
IN MAT_STRUCT *pMatCfg)
{
IPMacMappingEntry *pEntry;
IPMacMappingTable *pIPMacTable;
INT i;
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
if (!pIPMacTable)
return TRUE;
if (pIPMacTable->valid)
{
pIPMacTable->valid = FALSE;
for (i=0; i<IPMAC_TB_HASH_ENTRY_NUM; i++)
{
while((pEntry = pIPMacTable->hash[i]) != NULL)
{
pIPMacTable->hash[i] = pEntry->pNext;
MATDBEntryFree(pMatCfg, (PUCHAR)pEntry);
}
}
}
/* kfree(pIPMacTable); */
os_free_mem(NULL, pIPMacTable);
pMatCfg->MatTableSet.IPMacTable = NULL;
return TRUE;
}
static NDIS_STATUS IPMacTable_init(
IN MAT_STRUCT *pMatCfg)
{
IPMacMappingTable *pIPMacTable;
IPMacMappingEntry *pEntry = NULL;
if (pMatCfg->MatTableSet.IPMacTable != NULL)
{
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
}
else
{
/* pMatCfg->MatTableSet.IPMacTable = kmalloc(sizeof(IPMacMappingTable), GFP_KERNEL); */
os_alloc_mem_suspend(NULL, (UCHAR **)&(pMatCfg->MatTableSet.IPMacTable), sizeof(IPMacMappingTable));
if (pMatCfg->MatTableSet.IPMacTable)
{
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
NdisZeroMemory(pIPMacTable, sizeof(IPMacMappingTable));
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPMacTable failed!\n"));
return FALSE;
}
}
if (pIPMacTable->valid == FALSE)
{
/*Set the last hash entry (hash[64]) as our default broadcast Mac address */
pEntry = (IPMacMappingEntry *)MATDBEntryAlloc(pMatCfg, sizeof(IPMacMappingEntry));
if (!pEntry)
{
DBGPRINT(RT_DEBUG_ERROR, ("IPMacTable_init(): Allocate memory for IPMacTable broadcast entry failed!\n"));
return FALSE;
}
/*pEntry->ipAddr = 0; */
NdisZeroMemory(pEntry, sizeof(IPMacMappingEntry));
NdisMoveMemory(&pEntry->macAddr[0], &BROADCAST_ADDR[0], 6);
pEntry->pNext = NULL;
pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST] = pEntry;
pIPMacTable->valid = TRUE;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("%s(): IPMacTable already inited!\n", __FUNCTION__));
}
return TRUE;
}
static NDIS_STATUS MATProto_ARP_Exit(
IN MAT_STRUCT *pMatCfg)
{
INT status;
status = IPMacTable_RemoveAll(pMatCfg);
return status;
}
static PUCHAR MATProto_ARP_Rx(
IN MAT_STRUCT *pMatCfg,
IN PNDIS_PACKET pSkb,
IN PUCHAR pLayerHdr,
IN PUCHAR pMacAddr)
{
PUCHAR pArpHdr = NULL, pRealMac = NULL;
PUCHAR tgtMac, tgtIP;
BOOLEAN isUcastMac, isGoodIP;
pArpHdr = pLayerHdr;
/*dumpPkt(RTPKT_TO_OSPKT(pSkb)->data, RTPKT_TO_OSPKT(pSkb)->len); */
/* We just take care about the target(Mac/IP address) fields. */
tgtMac = pArpHdr + 18;
tgtIP = tgtMac + 6;
/* isUcastMac = !(00:00:00:00:00:00|| mcastMac); */
isUcastMac = ((tgtMac[0]|tgtMac[1]|tgtMac[2]|tgtMac[3]|tgtMac[4]|tgtMac[5])!=0);
isUcastMac &= ((tgtMac[0] & 0x1)==0);
/* isGoodIP = ip address is not 0.0.0.0 */
isGoodIP = (*(UINT *)tgtIP != 0);
if (isUcastMac && isGoodIP)
pRealMac = IPMacTableLookUp(pMatCfg, *(UINT *)tgtIP);
/*
For need replaced mac, we need to replace the targetMAC as correct one to make
the real receiver can receive that.
*/
if (isUcastMac && pRealMac)
NdisMoveMemory(tgtMac, pRealMac, MAC_ADDR_LEN);
if (pRealMac == NULL)
pRealMac = &BROADCAST_ADDR[0];
/* pRealMac = pIPMacTable->hash[IPMAC_TB_HASH_INDEX_OF_BCAST]->macAddr; */
return pRealMac;
}
static PUCHAR MATProto_ARP_Tx(
IN MAT_STRUCT *pMatCfg,
IN PNDIS_PACKET pSkb,
IN PUCHAR pLayerHdr,
IN PUCHAR pMacAddr)
{
PUCHAR pSMac, pSIP;
BOOLEAN isUcastMac, isGoodIP;
NET_PRO_ARP_HDR *arpHdr;
PUCHAR pPktHdr;
PNDIS_PACKET newSkb = NULL;
pPktHdr = GET_OS_PKT_DATAPTR(pSkb);
arpHdr = (NET_PRO_ARP_HDR *)pLayerHdr;
/*
Check the arp header.
We just handle ether type hardware address and IPv4 internet
address type and opcode is ARP reuqest/response.
*/
if ((arpHdr->ar_hrd != OS_HTONS(ARPHRD_ETHER)) || (arpHdr->ar_pro != OS_HTONS(ETH_P_IP)) ||
(arpHdr->ar_op != OS_HTONS(ARPOP_REPLY) && arpHdr->ar_op != OS_HTONS(ARPOP_REQUEST)))
return NULL;
/* We just take care about the sender(Mac/IP address) fields. */
pSMac =(PUCHAR)(pLayerHdr + 8);
pSIP = (PUCHAR)(pSMac + MAC_ADDR_LEN);
isUcastMac = IS_UCAST_MAC(pSMac);
isGoodIP = IS_GOOD_IP(get_unaligned32((PUINT) pSIP));
/*
DBGPRINT(RT_DEBUG_TRACE,("%s(): ARP Pkt=>senderIP=%d.%d.%d.%d, senderMac=%02x:%02x:%02x:%02x:%02x:%02x\n",
__FUNCTION__, pSIP[0], pSIP[1], pSIP[2], pSIP[3],
pSMac[0],pSMac[1],pSMac[2],pSMac[3],pSMac[4],pSMac[5]));
*/
if (isUcastMac && isGoodIP)
IPMacTableUpdate(pMatCfg, pSMac, get_unaligned32((PUINT) pSIP));
/*
For outgoing unicast mac, we need to replace the senderMAC as ourself to make
the receiver can send to us.
*/
if (isUcastMac)
{
if(OS_PKT_CLONED(pSkb))
{
newSkb = (PNDIS_PACKET)OS_PKT_COPY(pSkb);
if(newSkb)
{
if (IS_VLAN_PACKET(GET_OS_PKT_DATAPTR(newSkb)))
pSMac = (PUCHAR)(GET_OS_PKT_DATAPTR(newSkb) + MAT_VLAN_ETH_HDR_LEN + 8);
else
pSMac = (PUCHAR)(GET_OS_PKT_DATAPTR(newSkb) + MAT_ETHER_HDR_LEN + 8);
}
}
ASSERT(pMacAddr);
NdisMoveMemory(pSMac, pMacAddr, MAC_ADDR_LEN);
}
return (PUCHAR)newSkb;
}
static NDIS_STATUS MATProto_ARP_Init(
IN MAT_STRUCT *pMatCfg)
{
BOOLEAN status = FALSE;
status = IPMacTable_init(pMatCfg);
return status;
}
static NDIS_STATUS MATProto_IP_Exit(
IN MAT_STRUCT *pMatCfg)
{
INT status;
status = IPMacTable_RemoveAll(pMatCfg);
return status;
}
static PUCHAR MATProto_IP_Rx(
IN MAT_STRUCT *pMatCfg,
IN PNDIS_PACKET pSkb,
IN PUCHAR pLayerHdr,
IN PUCHAR pDevMacAdr)
{
PUCHAR pMacAddr;
UINT dstIP;
/* Fetch the IP addres from the packet header. */
getDstIPFromIpPkt(pLayerHdr, &dstIP);
pMacAddr = IPMacTableLookUp(pMatCfg, dstIP);
return pMacAddr;
}
static UCHAR DHCP_MAGIC[]= {0x63, 0x82, 0x53, 0x63};
static PUCHAR MATProto_IP_Tx(
IN MAT_STRUCT *pMatCfg,
IN PNDIS_PACKET pSkb,
IN PUCHAR pLayerHdr,
IN PUCHAR pDevMacAdr)
{
PUCHAR pSrcMac;
PUCHAR pSrcIP;
BOOLEAN needUpdate;
PUCHAR pPktHdr;
pPktHdr = GET_OS_PKT_DATAPTR(pSkb);
pSrcMac = pPktHdr + 6;
pSrcIP = pLayerHdr + 12;
needUpdate = NEED_UPDATE_IPMAC_TB(pSrcMac, get_unaligned32((PUINT)(pSrcIP)));
if (needUpdate)
IPMacTableUpdate(pMatCfg, pSrcMac, get_unaligned32((PUINT)(pSrcIP)));
/*For UDP packet, we need to check about the DHCP packet, to modify the flag of DHCP discovey/request as broadcast. */
if (*(pLayerHdr + 9) == 0x11)
{
PUCHAR udpHdr;
UINT16 srcPort, dstPort;
udpHdr = pLayerHdr + 20;
srcPort = OS_NTOHS(get_unaligned((PUINT16)(udpHdr)));
dstPort = OS_NTOHS(get_unaligned((PUINT16)(udpHdr+2)));
if (srcPort==68 && dstPort==67) /*It's a DHCP packet */
{
PUCHAR bootpHdr;
UINT16 bootpFlag;
bootpHdr = udpHdr + 8;
bootpFlag = OS_NTOHS(get_unaligned((PUINT16)(bootpHdr+10)));
DBGPRINT(RT_DEBUG_TRACE, ("is bootp packet! bootpFlag=0x%x\n", bootpFlag));
if (bootpFlag != 0x8000) /*check if it's a broadcast request. */
{
PUCHAR dhcpHdr;
dhcpHdr = bootpHdr + 236;
DBGPRINT(RT_DEBUG_TRACE, ("the DHCP flag is a unicast, dhcp_magic=%02x:%02x:%02x:%02x\n",
dhcpHdr[0], dhcpHdr[1], dhcpHdr[2], dhcpHdr[3]));
if (NdisEqualMemory(dhcpHdr, DHCP_MAGIC, 4))
{
DBGPRINT(RT_DEBUG_TRACE, ("dhcp magic macthed!\n"));
bootpFlag = OS_HTONS(0x8000);
NdisMoveMemory((bootpHdr+10), &bootpFlag, 2); /*Set the bootp flag as broadcast */
NdisZeroMemory((udpHdr+6), 2); /*modify the UDP chksum as zero */
}
}
}
}
return NULL;
}
static NDIS_STATUS MATProto_IP_Init(
IN MAT_STRUCT *pMatCfg)
{
BOOLEAN status;
status = IPMacTable_init(pMatCfg);
return status;
}
static inline void IPintToIPstr(int ipint, char Ipstr[20], ULONG BufLen)
{
int temp = 0;
temp = ipint & 0x000FF;
snprintf(Ipstr, BufLen, "%d.", temp);
temp = (ipint>>8) & 0x000FF;
snprintf(Ipstr, BufLen, "%s%d.", Ipstr, temp);
temp = (ipint>>16) & 0x000FF;
snprintf(Ipstr, BufLen, "%s%d.", Ipstr, temp);
temp = (ipint>>24) & 0x000FF;
snprintf(Ipstr, BufLen, "%s%d", Ipstr, temp);
}
VOID getIPMacTbInfo(
IN MAT_STRUCT *pMatCfg,
IN char *pOutBuf,
IN ULONG BufLen)
{
IPMacMappingTable *pIPMacTable;
IPMacMappingEntry *pHead;
int startIdx, endIdx;
char Ipstr[20] = {0};
pIPMacTable = (IPMacMappingTable *)pMatCfg->MatTableSet.IPMacTable;
if ((!pIPMacTable) || (!pIPMacTable->valid))
{
DBGPRINT(RT_DEBUG_TRACE, ("%s():IPMacTable not init yet!\n", __FUNCTION__));
return;
}
/* dump all. */
startIdx = 0;
endIdx = MAT_MAX_HASH_ENTRY_SUPPORT;
sprintf(pOutBuf, "\n");
sprintf(pOutBuf+strlen(pOutBuf), "%-18s%-20s\n", "IP", "MAC");
for(; startIdx< endIdx; startIdx++)
{
pHead = pIPMacTable->hash[startIdx];
while(pHead)
{
/* if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30)) */
if (RtmpOsCmdDisplayLenCheck(strlen(pOutBuf), 30) == FALSE)
break;
NdisZeroMemory(Ipstr, 20);
IPintToIPstr(pHead->ipAddr, Ipstr, sizeof(Ipstr));
sprintf(pOutBuf+strlen(pOutBuf), "%-18s%02x:%02x:%02x:%02x:%02x:%02x\n",
Ipstr, pHead->macAddr[0],pHead->macAddr[1],pHead->macAddr[2],
pHead->macAddr[3],pHead->macAddr[4],pHead->macAddr[5]);
pHead = pHead->pNext;
}
}
}
#endif /* MAT_SUPPORT */