/*++ Copyright (c) 1999 Microsoft Corporation Module Name: cmd.c Abstract: IEEE1394 ARP Admin Utility. Usage: a13adm Revision History: Who When What -------- -------- --------------------------------------------- josephj 04-10-1999 Created --*/ #include "common.h" #ifndef NDIS_STATUS #define NDIS_STATUS ULONG #endif #define ANSI_ARP_CLIENT_DOS_DEVICE_NAME "\\\\.\\ARP1394" #define DUMMY 0 #define FAKE_DUMP 0 VOID DoBusInfoCmd( HANDLE DeviceHandle, PARP1394_IOCTL_COMMAND pCmd ); #if DUMMY BOOL DummyDeviceIoControl( HANDLE DeviceHandle, UINT Ioctl, PARP1394_IOCTL_COMMAND pInCmd, UINT Size, PARP1394_IOCTL_COMMAND pOutCmd, UINT OutSize, PUINT pBytesReturned, PVOID Blah ); #define DeviceIoControl DummyDeviceIoControl #endif // DUMMY HANDLE OpenDevice( CHAR *pDeviceName ); extern CHAR *g_szPacketName; VOID CloseDevice( HANDLE DeviceHandle ); VOID DumpArpCache( PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd ); VOID DumpPacketStats( PARP1394_IOCTL_GET_PACKET_STATS pStatsCmd ); VOID DumpTaskStats( PARP1394_IOCTL_GET_TASK_STATS pStatsCmd ); VOID DumpArpStats( PARP1394_IOCTL_GET_ARPCACHE_STATS pStatsCmd ); VOID DumpCallStats( PARP1394_IOCTL_GET_CALL_STATS pStatsCmd ); VOID DumpPacketCounts( PARP1394_PACKET_COUNTS pPktCounts, BOOL fRecv, char *szDescription ); VOID Dump1394UniqueID( UINT64 UniqueID ); VOID DumpNicInfo( ARP1394_IOCTL_NICINFO *pNicInfo ); #if OBSOLETE VOID DumpBusInfo( PNIC1394_BUSINFO pBi ); #endif // OBSOLETE VOID DumpChannelInfo( PNIC1394_CHANNELINFO pCi ); VOID DumpRemoteNodeInfo( PNIC1394_REMOTENODEINFO pRni ); VOID arpDumpChannelMap( char *szPrefix, UINT64 Map ); VOID arpDumpPktStats( char *szPrefix, NIC1394_PACKET_STATS *pPs ); VOID DumpEuidMapInfo( PARP1394_IOCTL_EUID_NODE_MAC_INFO pEuidInfo ); VOID DoCmd( PARP1394_IOCTL_COMMAND pCmd ) { BOOL fRet = FALSE; PUCHAR pc; HANDLE DeviceHandle; DWORD BytesReturned; BOOL fDumpNicInfo=FALSE; // Special case -- DumpNicInfo. // if (pCmd->Hdr.Op == ARP1394_IOCTL_OP_GET_NICINFO) { PNIC1394_NICINFO pNi = &pCmd->IoctlNicInfo.Info; if (pNi->Hdr.Op == NIC1394_NICINFO_OP_BUSINFO) { fDumpNicInfo = TRUE; } } pc = (PUCHAR)&pCmd->Hdr.IfIpAddress; // Open device // DeviceHandle = OpenDevice(ANSI_ARP_CLIENT_DOS_DEVICE_NAME); if (DeviceHandle == INVALID_HANDLE_VALUE) { printf("Could not access IP/1394 ARP Client module.\n"); } else if (fDumpNicInfo) { DoBusInfoCmd(DeviceHandle, pCmd); CloseDevice(DeviceHandle); } else { BOOL fResetStats = (pCmd->Hdr.Op == ARP1394_IOCTL_OP_RESET_STATS); printf("Opened handle 0x%p\n", DeviceHandle); // Submit Ioctl // fRet = DeviceIoControl( DeviceHandle, ARP_IOCTL_CLIENT_OPERATION, pCmd, sizeof(*pCmd), pCmd, sizeof(*pCmd), &BytesReturned, NULL ); // // Special case "resetstats" -- we reset both ARP and NIC stats // if (fResetStats) { ARP1394_IOCTL_COMMAND Cmd = *pCmd; PNIC1394_NICINFO pNi = &Cmd.IoctlNicInfo.Info; Cmd.Hdr.Op = ARP1394_IOCTL_OP_GET_NICINFO; pNi->Hdr.Version = NIC1394_NICINFO_VERSION; pNi->Hdr.Op = NIC1394_NICINFO_OP_RESETSTATS; // Submit Ioctl // fRet = DeviceIoControl( DeviceHandle, ARP_IOCTL_CLIENT_OPERATION, &Cmd, sizeof(Cmd), &Cmd, sizeof(Cmd), &BytesReturned, NULL ); } // Close device // CloseDevice(DeviceHandle); if (!fRet) { printf("Request failed with error code 0x%08lx\n", GetLastError()); } } if (!fRet) { return; // EARLY RETURN BytesReturned=0; } // Display results. // switch(pCmd->Hdr.Op) { case ARP1394_IOCTL_OP_GET_ARPCACHE: DumpArpCache(&pCmd->GetArpCache); break; case ARP1394_IOCTL_OP_ADD_STATIC_ENTRY: { PARP1394_IOCTL_ADD_ARP_ENTRY pAddCmd = &pCmd->AddArpEntry; printf( "Added the following static arp entry to IF %d.%d.%d.%d:\n", pc[0], pc[1], pc[2], pc[3] ); pc = (PUCHAR)&pAddCmd->IpAddress; printf( " %d.%d.%d.%d -> ", pc[0], pc[1], pc[2], pc[3] ); Dump1394UniqueID(pAddCmd->HwAddress.UniqueID); printf("\n"); } break; case ARP1394_IOCTL_OP_DEL_STATIC_ENTRY: { PARP1394_IOCTL_DEL_ARP_ENTRY pDelCmd = &pCmd->DelArpEntry; printf( "Deleted all entries from IF %d.%d.%d.%d for the following destinations:\n", pc[0], pc[1], pc[2], pc[3] ); pc = (PUCHAR)&pDelCmd->IpAddress; printf( " %d.%d.%d.%d\n", pc[0], pc[1], pc[2], pc[3] ); } break; case ARP1394_IOCTL_OP_PURGE_ARPCACHE: printf( "Purged all dynamic arp entries from IF %d.%d.%d.%d.\n\n", pc[0], pc[1], pc[2], pc[3] ); break; case ARP1394_IOCTL_OP_GET_PACKET_STATS: DumpPacketStats(&pCmd->GetPktStats); break; case ARP1394_IOCTL_OP_GET_TASK_STATS: DumpTaskStats(&pCmd->GetTaskStats); break; case ARP1394_IOCTL_OP_GET_ARPCACHE_STATS: DumpArpStats(&pCmd->GetArpStats); break; case ARP1394_IOCTL_OP_GET_CALL_STATS: DumpCallStats(&pCmd->GetCallStats); break; case ARP1394_IOCTL_OP_RESET_STATS: printf( "Reset arp and nic statistics collection on IF %d.%d.%d.%d.\n\n", pc[0], pc[1], pc[2], pc[3] ); break; case ARP1394_IOCTL_OP_REINIT_INTERFACE: printf( "Reinited IF %d.%d.%d.%d.\n\n", pc[0], pc[1], pc[2], pc[3] ); break; case ARP1394_IOCTL_OP_SEND_PACKET: printf( "Sent %lu-byte packet \"%s\" on IF %d.%d.%d.%d.\n\n", pCmd->SendPacket.PacketSize, g_szPacketName, pc[0], pc[1], pc[2], pc[3] ); break; case ARP1394_IOCTL_OP_RECV_PACKET: printf( "Simulated receive of %lu-byte packet \"%s\" on IF %d.%d.%d.%d.\n\n", pCmd->RecvPacket.PacketSize, g_szPacketName, pc[0], pc[1], pc[2], pc[3] ); break; case ARP1394_IOCTL_OP_ETHERNET_START_EMULATION: printf( "Requested ARP to START Ethernet emulation on adapter \"%s\"\n\n", g_szPacketName ); break; case ARP1394_IOCTL_OP_ETHERNET_STOP_EMULATION: printf( "Requested ARP to STOP Ethernet emulation on adapter \"%s\"\n\n", g_szPacketName ); break; case ARP1394_IOCTL_OP_GET_NICINFO: DumpNicInfo(&pCmd->IoctlNicInfo); break; case ARP1394_IOCTL_OP_GET_EUID_NODE_MAC_TABLE: DumpEuidMapInfo(&pCmd->EuidNodeMacInfo); break; default: printf("HAIII!!!\n"); break; } } VOID DumpArpCache( PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd ) { UINT u; PARP1394_ARP_ENTRY pEntry = pGetCacheCmd->Entries; PUCHAR pc; #if FAKE_DUMP pGetCacheCmd->NumEntriesInArpCache = 30; pGetCacheCmd->NumEntriesUsed = 2; pGetCacheCmd->Index = 0; ((PULONG)&(pEntry[0].HwAddress.UniqueID))[0] = 0x12; ((PULONG)&(pEntry[0].HwAddress.UniqueID))[1] = 0x34; pEntry[0].IpAddress = 0x0100000a; ((PULONG)&(pEntry[1].HwAddress.UniqueID))[0] = 0x56; ((PULONG)&(pEntry[1].HwAddress.UniqueID))[1] = 0x78; pEntry[1].IpAddress = 0x0200000a; #endif // FAKE_DUMP pc = (PUCHAR)&pGetCacheCmd->Hdr.IfIpAddress; printf("Arp Cache of IF %d.%d.%d.%d [", pc[0], pc[1], pc[2], pc[3]); Dump1394UniqueID(pGetCacheCmd->LocalHwAddress.UniqueID); printf( " (%04lx:%08lx)]\n", pGetCacheCmd->LocalHwAddress.Off_Low, pGetCacheCmd->LocalHwAddress.Off_High ); for (u=0;uNumEntriesUsed;u++,pEntry++) { PUCHAR pc = (PUCHAR)&pEntry->IpAddress; printf( " %d.%d.%d.%d -> ", pc[0], pc[1], pc[2], pc[3] ); Dump1394UniqueID(pEntry->HwAddress.UniqueID); printf("\n"); } } VOID DumpPacketStats( PARP1394_IOCTL_GET_PACKET_STATS pStatsCmd ) { PUCHAR pc; pc = (PUCHAR)&pStatsCmd->Hdr.IfIpAddress; printf("Packet stats for IF %d.%d.%d.%d\n", pc[0], pc[1], pc[2], pc[3]); printf(" Duration: %d seconds\n", pStatsCmd->StatsDuration); printf(" Total sends: %d\n", pStatsCmd->TotSends); printf(" Fast sends: %d\n", pStatsCmd->FastSends); printf(" Medium sends: %d\n", pStatsCmd->MediumSends); printf(" Slow sends: %d\n", pStatsCmd->SlowSends); printf(" Backfills: %d\n", pStatsCmd->BackFills); printf(" Header buf uses: %d\n", pStatsCmd->HeaderBufUses); printf(" Header buf cache hits: %d\n", pStatsCmd->HeaderBufCacheHits); // // Some recv stats // printf(" Total receives: %d\n", pStatsCmd->TotRecvs); printf(" No-copy receives: %d\n", pStatsCmd->NoCopyRecvs); printf(" Copy receives: %d\n", pStatsCmd->CopyRecvs); printf(" Resource receives: %d\n", pStatsCmd->ResourceRecvs); // // Packet counts // DumpPacketCounts(&pStatsCmd->SendFifoCounts, FALSE, "FIFO sends"); DumpPacketCounts(&pStatsCmd->RecvFifoCounts, TRUE, "FIFO receives"); DumpPacketCounts(&pStatsCmd->SendChannelCounts, FALSE, "Channel sends"); DumpPacketCounts(&pStatsCmd->RecvChannelCounts, TRUE, "Channel receives"); } VOID DumpTaskStats( PARP1394_IOCTL_GET_TASK_STATS pStatsCmd ) { PUCHAR pc; pc = (PUCHAR)&pStatsCmd->Hdr.IfIpAddress; printf("Task stats for IF %d.%d.%d.%d\n", pc[0], pc[1], pc[2], pc[3]); printf(" Duration: %d seconds\n", pStatsCmd->StatsDuration); printf(" Total tasks: %d\n", pStatsCmd->TotalTasks); printf(" Current tasks: %d\n", pStatsCmd->CurrentTasks); // // Task times // { int i; #if 0 |<=1us | ...100us |...1ms |...10ms | >10ms ---------+--------+----------+---------+---------+-------- |10000000| 10000000 |10000000 |10000000 | 100 |(100000)| (100000) |(100000 |(100000) | (100) #endif // 0 printf("Task times:\n"); printf(" |<=1ms |...100ms |...1s |...10s | >10s\n"); printf(" +---------+---------+---------+---------+--------\n"); printf(" "); for (i=0;iTimeCounts[i] = i*100000; #endif // FAKE_DUMP printf(" |%8lu", pStatsCmd->TimeCounts[i]); } printf("\n"); } } VOID DumpArpStats( PARP1394_IOCTL_GET_ARPCACHE_STATS pStatsCmd ) { PUCHAR pc; pc = (PUCHAR)&pStatsCmd->Hdr.IfIpAddress; printf("Arp cache stats for IF %d.%d.%d.%d\n", pc[0], pc[1], pc[2], pc[3]); printf(" Duration: %d seconds\n", pStatsCmd->StatsDuration); printf(" Total queries: %d\n", pStatsCmd->TotalQueries); printf(" Successful queries: %d\n", pStatsCmd->SuccessfulQueries); printf(" Failed queries: %d\n", pStatsCmd->FailedQueries); printf(" Total responses: %d\n", pStatsCmd->TotalResponses); printf(" Total lookups: %d\n", pStatsCmd->TotalLookups); printf(" Links per lookup: %d\n", pStatsCmd->TraverseRatio); } VOID DumpCallStats( PARP1394_IOCTL_GET_CALL_STATS pStatsCmd ) { PUCHAR pc; pc = (PUCHAR)&pStatsCmd->Hdr.IfIpAddress; printf("Call stats for IF %d.%d.%d.%d\n", pc[0], pc[1], pc[2], pc[3]); printf( " Total send FIFO make-calls: %d\n", pStatsCmd->TotalSendFifoMakeCalls ); printf( " Successful send FIFO make-calls: %d\n", pStatsCmd->SuccessfulSendFifoMakeCalls ); printf( " Failed send FIFO make-calls: %d\n", pStatsCmd->FailedSendFifoMakeCalls ); printf( " Incoming closes on send FIFOs: %d\n", pStatsCmd->IncomingClosesOnSendFifos ); printf( " Total channel make-calls: %d\n", pStatsCmd->TotalChannelMakeCalls ); printf( " Successful channel make-calls: %d\n", pStatsCmd->SuccessfulChannelMakeCalls ); printf( " Failed channel make-calls: %d\n", pStatsCmd->FailedChannelMakeCalls ); printf( " Incoming closes on channels: %d\n", pStatsCmd->IncomingClosesOnChannels ); } VOID DumpPacketCounts( PARP1394_PACKET_COUNTS pPktCounts, BOOL fRecv, char *szDescription ) { int i,j; char *rgTitles[ARP1394_NUM_PKTSIZE_SLOTS+1] = { " <= 128", " 129-256", " 257-1K ", " 1K-2K ", " > 2K ", " " }; #if 0 size\time|<=1us | ...100us |...1ms |...10ms | >10ms ---------+--------+----------+---------+---------+-------- <= 128 |10000000| 10000000 |10000000 |10000000 | 100 |(100000)| (100000) |(100000 |(100000) | (100) ...256 |10000000| 10000000 |10000000 |10000000 |10000000 |(100000)| (100000) |(100000 |(100000) | (100) ...1K |10000000| 10000000 |10000000 |10000000 |10000000 |(100000)| (100000) |(100000 |(100000) | (100) ...2K |10000000| 10000000 |10000000 |10000000 |10000000 |(100000)| (100000) |(100000 |(100000) | (100) > 2K |10000000| 10000000 |10000000 |10000000 |10000000 |(100000)| (100000) |(100000 |(100000) | (100) #endif // 0 printf("\n%s packet counts:\n", szDescription); if (fRecv) { printf(" size | \n"); printf(" ---------+---------\n"); } else { printf(" size\\time|<=100us |...1ms |...10ms |...100ms | >100ms\n"); printf(" ---------+---------+---------+---------+---------+--------\n"); } for (i=0;iGoodCounts[i][j]; BadCounts += pPktCounts->BadCounts[i][j]; } if (GoodCounts ==0 && BadCounts==0) { continue; // No packets in this size bin. } printf("%s", rgTitles[i]); for (j=0;jGoodCounts[i][j]; if (u) { printf(" |%8lu", u); } else { printf(" | "); } if (fRecv) break; } printf("\n%s",rgTitles[ARP1394_NUM_PKTSIZE_SLOTS]); for (j=0;jBadCounts[i][j]; if (u) { printf(" |(%6lu)", u); } else { printf(" | "); } if (fRecv) break; } printf("\n"); } } HANDLE OpenDevice( CHAR *pDeviceName ) { DWORD DesiredAccess; DWORD ShareMode; LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; DWORD CreationDistribution; DWORD FlagsAndAttributes; HANDLE TemplateFile; HANDLE Handle; DesiredAccess = GENERIC_READ|GENERIC_WRITE; ShareMode = 0; CreationDistribution = OPEN_EXISTING; FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; TemplateFile = (HANDLE)INVALID_HANDLE_VALUE; #if DUMMY Handle = (HANDLE) 0x1; #else // !DUMMY Handle = CreateFile( pDeviceName, DesiredAccess, ShareMode, lpSecurityAttributes, CreationDistribution, FlagsAndAttributes, TemplateFile ); #endif // !DUMMY return (Handle); } VOID CloseDevice( HANDLE DeviceHandle ) { #if !DUMMY CloseHandle(DeviceHandle); #endif } VOID Dump1394UniqueID(UINT64 UniqueID) { unsigned char *pc = (char *) &UniqueID; printf( "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx-%02lx-%02lx", pc[4], pc[5], pc[6], pc[7], pc[0], pc[1], pc[2], pc[3] ); } VOID DumpENetAddress(ENetAddr ENetAddress) { unsigned char *pc = (char *) &ENetAddress; printf( "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx", pc[0], pc[1], pc[2], pc[3],pc[4], pc[5]); } #if DUMMY BOOL nicFillBusInfo( IN OUT PNIC1394_BUSINFO pBi ); BOOL nicFillChannelInfo( IN OUT PNIC1394_CHANNELINFO pCi ); BOOL nicFillRemoteNodeInfo( IN OUT PNIC1394_REMOTENODEINFO pRni ); BOOL nicFillNicInfo ( PNIC1394_NICINFO pInNicInfo, PNIC1394_NICINFO pOutNicInfo ) { BOOL Ret = FALSE; #if 0 pBi->ChannelMapLow = (0x1<<1) | (0x1<<3) | (0x1<<5) | (0x1<<7); pBi->ChannelMapHigh = (0x1<<8) | (0x1<<10) | (0x1<<12) | (0x1<<14); pBi->NumBusResets = 12345; pBi->SecondsSinceLastBusReset = 3600; pBi->NumRemoteNodes = 3; pLi = &pBi->LocalNodeInfo; pLi->UniqueID = 0xabcd; pLi->NodeAddress = 0x31; pLi->MaxRecvBlockSize=0x32; pLi->MaxRecvSpeed =0x33; pRi = pBi->RemoteNodeInfo; u = pBi->NumRemoteNodes; for (; u; u--, pRi++) { if (u==1) pRi->Flags = ARP1394_IOCTL_REMOTEFLAGS_ACTIVE; else if (u==2) pRi->Flags = ARP1394_IOCTL_REMOTEFLAGS_LOADING; else pRi->Flags = ARP1394_IOCTL_REMOTEFLAGS_UNLOADING; pRi->UniqueID = u; pRi->NodeAddress = u+1; pRi->MaxRecvBlockSize =u+2; pRi->MaxRecvSpeed =u+3; pRi->MaxSpeedBetweenNodes=u+4; } #endif // 0 do { // // First check internal version // if (pInNicInfo->Hdr.Version != NIC1394_NICINFO_VERSION) { printf("DummyIoctl: NICINFO.Version mismatch. Want %lu got %lu\n", NIC1394_NICINFO_VERSION, pInNicInfo->Hdr.Version ); break; } // // Struct-copy the old to the new. It's wasteful, but we don't want // to dig into how much of the in buffer contains valid data. // *pOutNicInfo = *pInNicInfo; // // Rest is op-specific // switch(pOutNicInfo->Hdr.Op) { case NIC1394_NICINFO_OP_BUSINFO: Ret = nicFillBusInfo(&pOutNicInfo->BusInfo); break; case NIC1394_NICINFO_OP_REMOTENODEINFO: Ret = nicFillRemoteNodeInfo(&pOutNicInfo->RemoteNodeInfo); break; case NIC1394_NICINFO_OP_CHANNELINFO: Ret = nicFillChannelInfo(&pOutNicInfo->ChannelInfo); break; case NIC1394_NICINFO_OP_RESETSTATS: printf("DummyIoctl: RESETTING NIC STATS!\n"); Ret = TRUE; break; default: printf( "DummyIoctl: NICINFO.Op (%lu) is unknown.\n", pInNicInfo->Hdr.Op ); break; } } while (FALSE); return Ret; } NIC1394_LOCAL_NODE_INFO BogusLocalNodeInfo = { 456, //UniqueID 457, //BusGeneration 4, //NodeAddress 0, //Reserved 2, //MaxRecvBlockSize 3, //MaxRecvSpeed }; NIC1394_PACKET_STATS BogusPktStats = { 345, // TotNdisPackets 346, // NdisPacketsFailures 347, // TotBusPackets 348 // BusPacketFailures }; BOOL nicFillBusInfo( IN OUT PNIC1394_BUSINFO pBi ) { // // Fill with Dummy data // pBi->NumBusResets = 1234; pBi->SecondsSinceBusReset = 1235; pBi->Flags = NIC1394_BUSINFO_LOCAL_IS_IRM; pBi->NumOutstandingIrps = 1236; pBi->LocalNodeInfo = BogusLocalNodeInfo; // // CHANNEL RELATED INFORMATION // pBi->Channel.BusMap = 0x123; pBi->Channel.ActiveChannelMap = 0x456; pBi->Channel.Bcr = 0x790; pBi->Channel.BcSendPktStats = BogusPktStats; pBi->Channel.BcRecvPktStats = BogusPktStats; pBi->Channel.SendPktStats = BogusPktStats; pBi->Channel.RecvPktStats = BogusPktStats; // // FIFO RELATED INFORMATION. // pBi->Fifo.Recv_Off_Low = 0x1bc; pBi->Fifo.Recv_Off_High = 0xdef; pBi->Fifo.RecvPktStats = BogusPktStats; pBi->Fifo.SendPktStats = BogusPktStats; pBi->Fifo.NumFreeRecvBuffers = 33; pBi->Fifo.MinFreeRecvBuffers = 34; pBi->Fifo.NumOutstandingReassemblies = 8; pBi->Fifo.MaxOutstandingReassemblies = 9; strcpy(pBi->Private.FormatA, " 0x%08lx Gadzooks\n"); pBi->Private.A0 = 0x99; // // Information about remote nodes. More information about each of these nodes // may be queried using *OP_REMOTE_NODEINFO // pBi->NumRemoteNodes = 1; pBi->RemoteNodeUniqueIDS[0] = 0x1234; return TRUE; } BOOL nicFillChannelInfo( IN OUT PNIC1394_CHANNELINFO pCi ) { return TRUE; } BOOL nicFillRemoteNodeInfo( IN OUT PNIC1394_REMOTENODEINFO pRni ) { pRni->UniqueID = 0xabc; pRni->NodeAddress = 2; pRni->EffectiveMaxBlockSize = 3; pRni->MaxRec = 4; pRni->MaxSpeedBetweenNodes = 5; pRni->Flags = NIC1394_REMOTEINFO_ACTIVE; pRni->SendFifoPktStats = BogusPktStats; pRni->RecvFifoPktStats = BogusPktStats; pRni->RecvChannelPktStats = BogusPktStats; return TRUE; } BOOL DummyDeviceIoControl( HANDLE DeviceHandle, UINT Ioctl, PARP1394_IOCTL_COMMAND pInCmd, UINT Size, PARP1394_IOCTL_COMMAND pOutCmd, UINT OutSize, PUINT pBytesReturned, PVOID Blah ) { BOOL fRet = FALSE; if (Ioctl != ARP_IOCTL_CLIENT_OPERATION) return FALSE; switch(pInCmd->Hdr.Op) { default: printf ("UNKNOWN IOCTL!\n"); fRet = TRUE; break; case ARP1394_IOCTL_OP_RESET_STATS: printf ("RESET ARP STATS!\n"); break; case ARP1394_IOCTL_OP_SEND_PACKET: printf ("DUMMY IOCTL: Prrocessing ioctl SEND packet.\n"); fRet = TRUE; break; case ARP1394_IOCTL_OP_RECV_PACKET: printf ("DUMMY IOCTL: Prrocessing ioctl RECV packet.\n"); fRet = TRUE; break; case ARP1394_IOCTL_OP_GET_NICINFO: { fRet = nicFillNicInfo ( &pInCmd->IoctlNicInfo.Info, &pOutCmd->IoctlNicInfo.Info ); } break; } return fRet; } #endif // DUMMY VOID DumpNicInfo( ARP1394_IOCTL_NICINFO *pINi ) { PNIC1394_NICINFO pNi = &pINi->Info; unsigned char *pc = (PUCHAR)&pINi->Hdr.IfIpAddress; do { // // First check internal version // if (pNi->Hdr.Version != NIC1394_NICINFO_VERSION) { printf(" NICINFO.Version mismatch. Want %lu got %lu\n", NIC1394_NICINFO_VERSION, pNi->Hdr.Version ); break; } // // Rest is op-specific // switch(pNi->Hdr.Op) { case NIC1394_NICINFO_OP_BUSINFO: printf("\nUnexpected commande!\n"); // We handle this command earlier. break; case NIC1394_NICINFO_OP_REMOTENODEINFO: printf("\nNode information for node %lu on IF %d.%d.%d.%d\n\n", pNi->RemoteNodeInfo.NodeAddress, pc[0], pc[1], pc[2], pc[3]); DumpRemoteNodeInfo(&pNi->RemoteNodeInfo); break; case NIC1394_NICINFO_OP_CHANNELINFO: printf("\nChannel information for channel %lu on IF %d.%d.%d.%d\n\n", pNi->ChannelInfo.Channel, pc[0], pc[1], pc[2], pc[3]); DumpChannelInfo(&pNi->ChannelInfo); break; case NIC1394_NICINFO_OP_RESETSTATS: printf("\nReset NIC stats for IF %d.%d.%d.%d\n\n", pc[0], pc[1], pc[2], pc[3]); break; default: printf( " NICINFO.Op (%lu) is unknown.\n", pNi->Hdr.Op ); break; } } while (FALSE); } #if OBSOLETE VOID DumpBusInfo( PNIC1394_BUSINFO pBi ) { PUCHAR pc; printf( " Generation: %02lu; Bus resets: %02lu; Last reset: %lu seconds ago.", pBi->LocalNodeInfo.BusGeneration, pBi->NumBusResets, pBi->SecondsSinceBusReset ); printf( " Outstanding IRPs: %02lu;", pBi->NumOutstandingIrps ); // // Flags // if (pBi->Flags & NIC1394_BUSINFO_LOCAL_IS_IRM) { printf( " Flags: IRM\n" ); } else { printf( " Flags: \n" ); } // // CHANNEL INFO // printf("\n Channel information:\n"); arpDumpChannelMap(" Channels in bus map:", pBi->Channel.BusMap); arpDumpChannelMap(" Locally active channels:", pBi->Channel.ActiveChannelMap); printf( " BCR: 0x%08lx\n", pBi->Channel.Bcr ); arpDumpPktStats(" BC Sends:", &pBi->Channel.BcSendPktStats); arpDumpPktStats(" BC Recvs:", &pBi->Channel.BcRecvPktStats); // // RECV FIFO // printf("\n Recv FIFO information:\n"); printf( " Addr: 0x%lx:0x%lx; Free recv bufs:%lu (%lu max)\n", pBi->Fifo.Recv_Off_High, pBi->Fifo.Recv_Off_Low, pBi->Fifo.NumFreeRecvBuffers, pBi->Fifo.MinFreeRecvBuffers ); printf( " Recv reassemblies: %lu outstanding; %lu max outstanding; %lu aborted\n", pBi->Fifo.NumOutstandingReassemblies, pBi->Fifo.MaxOutstandingReassemblies, pBi->Fifo.NumAbortedReassemblies ); // // Private information // if (*pBi->Private.FormatA || *pBi->Private.FormatB) { printf("\n Private information:\n"); if (*pBi->Private.FormatA) { printf( pBi->Private.FormatA, pBi->Private.A0, pBi->Private.A1, pBi->Private.A2, pBi->Private.A3 ); } if (*pBi->Private.FormatB) { printf( pBi->Private.FormatB, pBi->Private.B0, pBi->Private.B1, pBi->Private.B2, pBi->Private.B3 ); } } { UINT64 *pUID; PNIC1394_LOCAL_NODE_INFO pLi; UINT u = pBi->NumRemoteNodes; printf("\n Node Information:\n"); printf( " GUID Node Size Speed SpeedTo State\n" ); pLi = &pBi->LocalNodeInfo; printf(" *"); Dump1394UniqueID(pLi->UniqueID); printf( " %02lx %02lx %02lx %s\n", pLi->NodeAddress, pLi->MaxRecvBlockSize, pLi->MaxRecvSpeed, "local" ); pUID = pBi->RemoteNodeUniqueIDS; for (; u; u--, pUID++) // pRi++ { #if 0 ARP1394_IOCTL_REMOTE_NODE_INFO Ri; PARP1394_IOCTL_REMOTE_NODE_INFO pRi = NULL; char *szState = "unknown"; printf(" "); Dump1394UniqueID(*pUID); if (GetRemoteNodeInfo( if (pRi!=NULL) { if (pRi->Flags & ARP1394_IOCTL_REMOTEFLAGS_ACTIVE) { szState = "active"; } if (pRi->Flags & ARP1394_IOCTL_REMOTEFLAGS_LOADING) { szState = "loading"; } if (pRi->Flags & ARP1394_IOCTL_REMOTEFLAGS_UNLOADING) { szState = "unloading"; } printf( " %02lx %02lx %02lx %02lx %s\n", pRi->NodeAddress, pRi->MaxRecvBlockSize, pRi->MaxRecvSpeed, pRi->MaxSpeedBetweenNodes, szState ); } printf("\n"); #endif // 0 } } } #endif // OBSOLETE VOID DumpChannelInfo( PNIC1394_CHANNELINFO pCi ) { printf("DUMP OF CHANNELINFO\n"); } VOID DumpRemoteNodeInfo( PNIC1394_REMOTENODEINFO pRni ) { printf("DUMP OF REMOTENODEINFO\n"); } VOID arpDumpChannelMap( char *szPrefix, UINT64 Map ) { UINT ChannelMapLow = (UINT) (Map & 0xffffffff); UINT ChannelMapHigh = (UINT) (Map >> 32); if (ChannelMapLow==0 && ChannelMapHigh==0) { printf ("%s \n", szPrefix); } else { UINT c; #define Bit(_Val, _Bit) (((_Val) & (1<<_Bit))!=0) printf (szPrefix); // printf("\n "); Dump1394UniqueID(Map); printf("\n "); for (c=0;c<32;c++) { if (Bit(ChannelMapLow, c)) { printf (" %lu", c); } } for (c=0;c<32;c++) { if (Bit(ChannelMapHigh, c)) { printf (" %lu", c+32); } } printf ("\n"); } } VOID arpDumpPktStats( char *szPrefix, NIC1394_PACKET_STATS *pPs ) { printf("%s ndis: %06lu total, %05lu failed; bus: %06lu total, %05lu failed\n", szPrefix, pPs->TotNdisPackets, pPs->NdisPacketsFailures, pPs->TotBusPackets, pPs->BusPacketFailures ); } VOID DoBusInfoCmd( HANDLE DeviceHandle, PARP1394_IOCTL_COMMAND pCmd ) { PNIC1394_NICINFO pNi = &pCmd->IoctlNicInfo.Info; PNIC1394_BUSINFO pBi = &pNi->BusInfo; unsigned char *pc = (PUCHAR)&pCmd->Hdr.IfIpAddress; BOOL fRet; DWORD BytesReturned; if (pCmd->Hdr.Op != ARP1394_IOCTL_OP_GET_NICINFO || pNi->Hdr.Op != NIC1394_NICINFO_OP_BUSINFO) { printf("DoBusInfoCmd: unexpected pCmd!\n"); return; } printf("\nBus information for IF %d.%d.%d.%d\n\n", pc[0], pc[1], pc[2], pc[3]); // Submit NICINFO.BUSINFO Ioctl // fRet = DeviceIoControl( DeviceHandle, ARP_IOCTL_CLIENT_OPERATION, pCmd, sizeof(*pCmd), pCmd, sizeof(*pCmd), &BytesReturned, NULL ); // // if (!fRet) { printf("Request failed with error code 0x%08lx\n", GetLastError()); return; } printf( " Generation: %02lu; Bus resets: %02lu; Last reset: %lu seconds ago.", pBi->LocalNodeInfo.BusGeneration, pBi->NumBusResets, pBi->SecondsSinceBusReset ); #if 0 printf( " Outstanding IRPs: %02lu;", pBi->NumOutstandingIrps ); #endif // 0 // // Flags // if (pBi->Flags & NIC1394_BUSINFO_LOCAL_IS_IRM) { printf( " Flags: IRM\n" ); } else { printf( " Flags: \n" ); } // // CHANNEL INFO // printf("\n Channel information:\n"); arpDumpChannelMap(" Channels in bus map:", pBi->Channel.BusMap); arpDumpChannelMap(" Locally active channels:", pBi->Channel.ActiveChannelMap); printf( " BCR: 0x%08lx\n", pBi->Channel.Bcr ); arpDumpPktStats(" BC Sends:", &pBi->Channel.BcSendPktStats); arpDumpPktStats(" BC Recvs:", &pBi->Channel.BcRecvPktStats); // // RECV FIFO // printf("\n FIFO information:\n"); printf( " Addr: 0x%lx:0x%lx; Free recv bufs:%lu (%lu max)\n", pBi->Fifo.Recv_Off_High, pBi->Fifo.Recv_Off_Low, pBi->Fifo.NumFreeRecvBuffers, pBi->Fifo.MinFreeRecvBuffers ); printf( " Recv reassemblies: %lu outstanding; %lu max outstanding; %lu aborted\n", pBi->Fifo.NumOutstandingReassemblies, pBi->Fifo.MaxOutstandingReassemblies, pBi->Fifo.NumAbortedReassemblies ); arpDumpPktStats(" FIFO Sends:", &pBi->Fifo.SendPktStats); arpDumpPktStats(" FIFO Recvs:", &pBi->Fifo.RecvPktStats); // // Private information // if (*pBi->Private.FormatA || *pBi->Private.FormatB) { printf("\n Private information:\n"); if (*pBi->Private.FormatA) { printf( pBi->Private.FormatA, pBi->Private.A0, pBi->Private.A1, pBi->Private.A2, pBi->Private.A3 ); } if (*pBi->Private.FormatB) { printf( pBi->Private.FormatB, pBi->Private.B0, pBi->Private.B1, pBi->Private.B2, pBi->Private.B3 ); } } { UINT64 *pUID; PNIC1394_LOCAL_NODE_INFO pLi; UINT u = pBi->NumRemoteNodes; printf("\n Node Information:\n"); printf( " GUID Node Maxrec SpeedTo State\n" ); pLi = &pBi->LocalNodeInfo; printf(" *"); Dump1394UniqueID(pLi->UniqueID); printf( " %02lx %02lx %02lx %s\n", pLi->NodeAddress, pLi->MaxRecvBlockSize, pLi->MaxRecvSpeed, "local" ); pUID = pBi->RemoteNodeUniqueIDS; for (; u; u--, pUID++) // pRi++ { char *szState = "unknown"; printf(" "); Dump1394UniqueID(*pUID); { ARP1394_IOCTL_COMMAND Cmd = *pCmd; PNIC1394_NICINFO pNi = &Cmd.IoctlNicInfo.Info; Cmd.Hdr.Op = ARP1394_IOCTL_OP_GET_NICINFO; pNi->Hdr.Version = NIC1394_NICINFO_VERSION; pNi->Hdr.Op = NIC1394_NICINFO_OP_REMOTENODEINFO; pNi->RemoteNodeInfo.UniqueID = *pUID; pNi->RemoteNodeInfo.NodeAddress = 0; // Submit Ioctl // fRet = DeviceIoControl( DeviceHandle, ARP_IOCTL_CLIENT_OPERATION, &Cmd, sizeof(Cmd), &Cmd, sizeof(Cmd), &BytesReturned, NULL ); if (fRet == FALSE) { printf (" \n"); } else { PNIC1394_REMOTENODEINFO pRi = &pNi->RemoteNodeInfo; if (pRi->Flags & NIC1394_REMOTEINFO_ACTIVE) { szState = "active"; } if (pRi->Flags & NIC1394_REMOTEINFO_LOADING) { szState = "loading"; } if (pRi->Flags & NIC1394_REMOTEINFO_UNLOADING) { szState = "unloading"; } printf( " %02lx %02lx %02lx %s\n", pRi->NodeAddress, pRi->MaxRec, pRi->MaxSpeedBetweenNodes, szState ); } } } } } VOID DumpEuidMapInfo( PARP1394_IOCTL_EUID_NODE_MAC_INFO pEuidInfo ) { PEUID_TOPOLOGY pMap = &pEuidInfo->Map; UINT i =0; printf ("Number of Remote Nodes = %x\n",pMap->NumberOfRemoteNodes); if (pMap->NumberOfRemoteNodes ==0) { return; } printf ("Table :-\n"); // iterate through the number of remote nodes and print them out. printf ("Node UniqueId MacAddress\n"); while (iNumberOfRemoteNodes) { // Skip this node if it is an invalid node if (pMap->Node[i].Euid ==0) { continue; } printf ("%x ",i); Dump1394UniqueID(pMap->Node[i].Euid); printf(" "); DumpENetAddress (pMap->Node[i].ENetAddress); printf("\n"); i++; } }