Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1524 lines
29 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. ipfwadm.c -- actually calls down the the ip/1394 arp module.
  5. Revision History:
  6. Who When What
  7. -------- -------- ---------------------------------------------
  8. josephj 04-12-1999 Created
  9. --*/
  10. #include "common.h"
  11. #define NUM_ARPENTRIES_TO_GET 10
  12. #define PROGRAM "ipfwadm"
  13. typedef struct
  14. {
  15. ARP1394_IOCTL_COMMAND Cmd;
  16. // MUST IMMEDIATELY follow Cmd -- space for Cmd.GetArpCache.Entries
  17. //
  18. ARP1394_ARP_ENTRY Reserved[NUM_ARPENTRIES_TO_GET];
  19. } OPTIONS;
  20. HANDLE
  21. OpenDevice(
  22. CHAR *pDeviceName
  23. );
  24. VOID
  25. CloseDevice(
  26. HANDLE DeviceHandle
  27. );
  28. BOOL
  29. ParseCmdLine(
  30. int argc,
  31. char * argv[]
  32. );
  33. BOOL
  34. ParseIpAddress(
  35. PCHAR buf,
  36. PULONG pIpAddress
  37. );
  38. BOOL
  39. ParseHwAddress(
  40. PCHAR buf,
  41. PARP1394_IOCTL_HW_ADDRESS pHwAddr
  42. );
  43. BOOL
  44. ValidateCommand(PARP1394_IOCTL_COMMAND pCmd);
  45. BOOL
  46. ParsePacket(
  47. PCHAR buf,
  48. UCHAR *data,
  49. UINT cbData,
  50. UINT *pcbPacketSize
  51. );
  52. BOOL
  53. ParseAdapter(
  54. PCHAR buf,
  55. UCHAR *data,
  56. UINT cbData,
  57. UINT *pcbAdapterSize
  58. );
  59. OPTIONS g;
  60. void
  61. Usage(void);
  62. VOID __cdecl
  63. main(
  64. INT argc,
  65. CHAR *argv[]
  66. )
  67. {
  68. //
  69. // Parse args, determine if this is concerns the arp client or server.
  70. //
  71. if (!ParseCmdLine(argc, argv))
  72. {
  73. return;
  74. }
  75. DoCmd(&g.Cmd);
  76. }
  77. void
  78. Usage(void)
  79. {
  80. //
  81. // Also hidden compat options: -s, -d, -g
  82. //
  83. printf( "\nWindows 2000 IP/1394 Utility\n\n");
  84. printf(
  85. PROGRAM " -a\n"
  86. PROGRAM " -add inet_addr hw_addr [-n if_addr]\n"
  87. PROGRAM " -del inet_addr [-n if_addr]\n"
  88. PROGRAM " -stats [arp|call|pkts|tsks] [-n if_addr]\n"
  89. PROGRAM " -resetstats [-n if_addr]\n"
  90. PROGRAM " -purgecache [-n if_addr]\n"
  91. PROGRAM " -reinit [-n if_addr]\n"
  92. PROGRAM " -send pkt [-n if_addr]\n"
  93. PROGRAM " -recv pkt [-n if_addr]\n"
  94. PROGRAM " -bstart adapter\n"
  95. PROGRAM " -bstop adapter\n"
  96. PROGRAM " -nicinfo [a|n node|c channel|reset] [-n if_addr]\n"
  97. PROGRAM " -- [-n if_addr]\n"
  98. PROGRAM " -euidmap\n"
  99. "\n"
  100. );
  101. printf(
  102. " -a Displays current ARP entries. If more than one ip/1394 network\n"
  103. " interface exist, entries for each ARP table are displayed.\n"
  104. );
  105. printf(
  106. " -add Adds the host and associates the Internet address inet_addr\n"
  107. " with the Physical address hw_addr. The entry is permanent.\n"
  108. );
  109. printf(
  110. " -del Deletes the host specified by inet_addr.\n"
  111. );
  112. printf(
  113. " -stats Displays arp/call/packet/task statistics.\n"
  114. );
  115. printf(
  116. " -resetstats Resets statistics collection.\n"
  117. );
  118. printf(
  119. " -purgecache Deletes all dynamic arp entries.\n"
  120. );
  121. printf(
  122. " -reinit Deactivates and then reactivates the interface.\n"
  123. );
  124. printf(
  125. " -send pkt Sends the specified packet on the broadcast channel.\n"
  126. );
  127. printf(
  128. " -recv pkt Simulates a receive of the specified packet on the.\n"
  129. " broadcast channel.\n"
  130. );
  131. printf(
  132. " -nicinfo Displays information about the 1394 network adapter.\n"
  133. " -a displays adapter-wide information\n"
  134. " -n node displays information about the node with node ID \"node\"\n"
  135. " -c channel displays information about channel \"channel\"\n"
  136. );
  137. printf(
  138. " -bstart adapter Starts Ethernet emulation (bridging) on the specified adapter.\n"
  139. );
  140. printf(
  141. " -bstop adapter Stops Ethernet emulation (bridging) on the specified adapter.\n"
  142. );
  143. printf(
  144. " -- Takes commands from standard input. Commands are options\n"
  145. " without the '-' prefix. Use ^C or 'q' to exit the program.\n"
  146. );
  147. printf(
  148. " -n if_addr Displays information for the network interface specified\n"
  149. " by if_addr. If not present, the first applicable interface will\n"
  150. " be used.\n"
  151. );
  152. printf(
  153. " inet_addr Specifies an internet address.\n"
  154. );
  155. printf(
  156. " hw_addr Specifies a physical address (64-bit Unique ID). The Physical\n"
  157. " address is given as 8 hexadecimal bytes separated by hyphens.\n"
  158. );
  159. printf(
  160. " pkt Specifies the key name under the [Packets] section of\n"
  161. " " PROGRAM ".INI. The value of the key contains the packet data.\n"
  162. );
  163. printf(
  164. " euidmap Prints The Euid, Node Address and Fake Mac Address \n"
  165. " assigned to a Remote Node\n"
  166. );
  167. printf(
  168. "\nExample:\n"
  169. " > " PROGRAM " -s 157.55.85.212 00-aa-00-62-c6-09-01-02 .... Adds a static entry.\n"
  170. " > " PROGRAM " -a .... Displays the arp table.\n"
  171. " > " PROGRAM " -stats arp -n 10.0.0.1 .... Displays arp statistics\n"
  172. " for interface 10.0.0.1.\n"
  173. );
  174. }
  175. UINT FindOption(
  176. char *lptOpt,
  177. char **ppVal,
  178. BOOL fCmdLine
  179. );
  180. enum
  181. {
  182. DO_DISP_HELP,
  183. DO_GET_ARPCACHE,
  184. DO_ADD_ARPENTRY,
  185. DO_DEL_ARPENTRY,
  186. DO_PURGE_ARPCACHE,
  187. DO_GET_STATS,
  188. DO_RESET_STATS,
  189. DO_REINIT_IF,
  190. DO_SWITCH_TO_STDIN,
  191. DO_SPECIFIC_IF,
  192. DO_GET_NICINFO,
  193. DO_SEND_PACKET,
  194. DO_RECV_PACKET,
  195. DO_X_ARP,
  196. DO_X_CALL,
  197. DO_X_TSKS,
  198. DO_X_PKTS,
  199. DO_X_ALL,
  200. DO_NI_CHANNELINFO,
  201. DO_BSTART,
  202. DO_BSTOP,
  203. DO_EUIDMAP,
  204. UNKNOWN_OPTION,
  205. // Put the at the end
  206. //
  207. DO_NI_BUSINFO = DO_GET_ARPCACHE, // Because both are "a"
  208. DO_NI_NODEINFO = DO_SPECIFIC_IF,
  209. };
  210. struct _CmdOptions {
  211. char * lptOption;
  212. UINT uOpt;
  213. } CmdOptions[] =
  214. {
  215. {"?" , DO_DISP_HELP },
  216. {"a" , DO_GET_ARPCACHE }, // Also DO_NI_BUSINFO
  217. {"s" , DO_ADD_ARPENTRY },
  218. {"g" , DO_ADD_ARPENTRY },
  219. {"add" , DO_ADD_ARPENTRY },
  220. {"del" , DO_DEL_ARPENTRY },
  221. {"purgecache" , DO_PURGE_ARPCACHE },
  222. {"stats" , DO_GET_STATS },
  223. {"resetstats" , DO_RESET_STATS },
  224. {"reinit" , DO_REINIT_IF },
  225. {"-" , DO_SWITCH_TO_STDIN },
  226. {"n" , DO_SPECIFIC_IF }, // Also DO_NI_NODEINFO
  227. {"send" , DO_SEND_PACKET },
  228. {"recv" , DO_RECV_PACKET },
  229. {"nicinfo" , DO_GET_NICINFO },
  230. {"bstart" , DO_BSTART },
  231. {"bstop" , DO_BSTOP },
  232. {"euidmap" , DO_EUIDMAP },
  233. // Following are sub-options of /stats...
  234. //
  235. {"arp" , DO_X_ARP },
  236. {"call" , DO_X_CALL },
  237. {"tsks" , DO_X_TSKS },
  238. {"pkts" , DO_X_PKTS },
  239. {"pkt" , DO_X_PKTS },
  240. // Following are sub-options of /nicinfo...
  241. //
  242. // {"b" , DO_NI_BUSINFO },
  243. // {"n" , DO_NI_NODEINFO },
  244. {"c" , DO_NI_CHANNELINFO }
  245. };
  246. INT iCmdOptionsCounts = sizeof(CmdOptions)/sizeof(struct _CmdOptions);
  247. BOOL
  248. ParseCmdLine(
  249. int argc,
  250. char * argv[]
  251. )
  252. {
  253. BOOL bRetVal = TRUE;
  254. int iIndx=1;
  255. UINT uOpt;
  256. char *pVal;
  257. ZeroMemory(&g.Cmd, sizeof(g.Cmd));
  258. ZeroMemory(&g.Reserved, sizeof(g.Reserved));
  259. while(bRetVal && iIndx < argc)
  260. {
  261. uOpt = FindOption(argv[iIndx++], &pVal, TRUE);
  262. switch(uOpt)
  263. {
  264. case DO_GET_ARPCACHE:
  265. //
  266. // "arp13 -a\n"
  267. //
  268. {
  269. PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd = &g.Cmd.GetArpCache;
  270. if (argc != 2)
  271. {
  272. printf("Too many arguments for '-a'\n");
  273. bRetVal = FALSE;
  274. break;
  275. }
  276. pGetCacheCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  277. pGetCacheCmd->Hdr.Op = ARP1394_IOCTL_OP_GET_ARPCACHE;
  278. pGetCacheCmd->NumEntriesAvailable = NUM_ARPENTRIES_TO_GET;
  279. }
  280. break;
  281. case DO_ADD_ARPENTRY:
  282. //
  283. // "arp13 -add inet_addr hw_addr"
  284. //
  285. {
  286. PARP1394_IOCTL_ADD_ARP_ENTRY pAddCmd = &g.Cmd.AddArpEntry;
  287. bRetVal = FALSE;
  288. if ((iIndx+1) < argc)
  289. {
  290. bRetVal = ParseIpAddress(argv[iIndx++], &pAddCmd->IpAddress);
  291. if (!bRetVal) break;
  292. bRetVal = ParseHwAddress(argv[iIndx++], &pAddCmd->HwAddress);
  293. }
  294. else
  295. {
  296. printf("Not enough arguments for '-add'\n");
  297. }
  298. if (!bRetVal) break;
  299. pAddCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  300. pAddCmd->Hdr.Op = ARP1394_IOCTL_OP_ADD_STATIC_ENTRY;
  301. }
  302. break;
  303. case DO_DEL_ARPENTRY:
  304. //
  305. // "arp13 -del inet_addr"
  306. //
  307. {
  308. PARP1394_IOCTL_DEL_ARP_ENTRY pDelCmd = &g.Cmd.DelArpEntry;
  309. bRetVal = FALSE;
  310. if (iIndx < argc)
  311. {
  312. bRetVal = ParseIpAddress(argv[iIndx++], &pDelCmd->IpAddress);
  313. }
  314. else
  315. {
  316. printf("Not enough arguments for '-del'\n");
  317. }
  318. if (!bRetVal) break;
  319. pDelCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  320. pDelCmd->Hdr.Op = ARP1394_IOCTL_OP_DEL_STATIC_ENTRY;
  321. }
  322. break;
  323. case DO_PURGE_ARPCACHE:
  324. //
  325. // "arp13 -purgecache"
  326. //
  327. {
  328. PARP1394_IOCTL_PURGE_ARPCACHE pPurgeCmd = &g.Cmd.PurgeArpCache;
  329. pPurgeCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  330. pPurgeCmd->Hdr.Op = ARP1394_IOCTL_OP_PURGE_ARPCACHE;
  331. }
  332. break;
  333. break;
  334. case DO_GET_STATS:
  335. //
  336. // "arp13 -stats [arp|call|tsks|pkts]"
  337. //
  338. {
  339. PARP1394_IOCTL_COMMAND pCmd = &g.Cmd;
  340. INT StatsOp;
  341. if (iIndx >= argc)
  342. {
  343. StatsOp = DO_X_ARP;
  344. }
  345. else
  346. {
  347. StatsOp = FindOption(argv[iIndx++], &pVal, FALSE);
  348. }
  349. pCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  350. switch(StatsOp)
  351. {
  352. case DO_X_ARP:
  353. pCmd->Hdr.Op = ARP1394_IOCTL_OP_GET_ARPCACHE_STATS;
  354. break;
  355. case DO_X_CALL:
  356. pCmd->Hdr.Op = ARP1394_IOCTL_OP_GET_CALL_STATS;
  357. break;
  358. break;
  359. case DO_X_TSKS:
  360. pCmd->Hdr.Op = ARP1394_IOCTL_OP_GET_TASK_STATS;
  361. break;
  362. break;
  363. case DO_X_PKTS:
  364. pCmd->Hdr.Op = ARP1394_IOCTL_OP_GET_PACKET_STATS;
  365. break;
  366. default:
  367. // Assume default and put parsed value back.
  368. //
  369. StatsOp = DO_X_ARP;
  370. iIndx--;
  371. break;
  372. }
  373. }
  374. break;
  375. case DO_RESET_STATS:
  376. //
  377. // "arp13 -resetstats"
  378. //
  379. {
  380. PARP1394_IOCTL_RESET_STATS pResetStatsCmd = &g.Cmd.ResetStats;
  381. pResetStatsCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  382. pResetStatsCmd->Hdr.Op = ARP1394_IOCTL_OP_RESET_STATS;
  383. }
  384. break;
  385. case DO_REINIT_IF:
  386. //
  387. // "arp13 -reinit"
  388. //
  389. {
  390. PARP1394_IOCTL_REINIT_INTERFACE pReinitIfCmd;
  391. pReinitIfCmd = &g.Cmd.ReinitInterface;
  392. pReinitIfCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  393. pReinitIfCmd->Hdr.Op = ARP1394_IOCTL_OP_REINIT_INTERFACE;
  394. }
  395. break;
  396. case DO_SEND_PACKET:
  397. //
  398. // "arp13 -send pkt"
  399. //
  400. {
  401. PARP1394_IOCTL_SEND_PACKET pSendCmd = &g.Cmd.SendPacket;
  402. bRetVal = FALSE;
  403. if (iIndx < argc)
  404. {
  405. bRetVal = ParsePacket(
  406. argv[iIndx++],
  407. pSendCmd->Data,
  408. sizeof(pSendCmd->Data),
  409. &pSendCmd->PacketSize
  410. );
  411. }
  412. else
  413. {
  414. printf("Not enough arguments for '-send pkt'\n");
  415. }
  416. if (!bRetVal) break;
  417. pSendCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  418. pSendCmd->Hdr.Op = ARP1394_IOCTL_OP_SEND_PACKET;
  419. }
  420. break;
  421. case DO_RECV_PACKET:
  422. //
  423. // "arp13 -recv pkt"
  424. //
  425. {
  426. PARP1394_IOCTL_RECV_PACKET pRecvCmd = &g.Cmd.RecvPacket;
  427. bRetVal = FALSE;
  428. if (iIndx < argc)
  429. {
  430. bRetVal = ParsePacket(
  431. argv[iIndx++],
  432. pRecvCmd->Data,
  433. sizeof(pRecvCmd->Data),
  434. &pRecvCmd->PacketSize
  435. );
  436. }
  437. else
  438. {
  439. printf("Not enough arguments for '-recv pkt'\n");
  440. }
  441. if (!bRetVal) break;
  442. pRecvCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  443. pRecvCmd->Hdr.Op = ARP1394_IOCTL_OP_RECV_PACKET;
  444. }
  445. break;
  446. case DO_BSTART:
  447. case DO_BSTOP:
  448. //
  449. // "arp13 -bstart adapter"
  450. //
  451. {
  452. UINT Size;
  453. PARP1394_IOCTL_ETHERNET_NOTIFICATION pEthCmd =
  454. &g.Cmd.EthernetNotification;
  455. bRetVal = FALSE;
  456. if (iIndx < argc)
  457. {
  458. bRetVal = ParseAdapter(
  459. argv[iIndx++],
  460. (PUCHAR) pEthCmd->AdapterName,
  461. sizeof(pEthCmd->AdapterName)-sizeof(WCHAR),
  462. &Size
  463. );
  464. pEthCmd->AdapterName[Size/2]=0;
  465. }
  466. else
  467. {
  468. printf("Not enough arguments for '-send pkt'\n");
  469. }
  470. if (!bRetVal) break;
  471. pEthCmd->Hdr.Version = ARP1394_IOCTL_VERSION;
  472. if (uOpt == DO_BSTART)
  473. {
  474. // printf("BRIDGE START\n");
  475. pEthCmd->Hdr.Op = ARP1394_IOCTL_OP_ETHERNET_START_EMULATION;
  476. }
  477. else
  478. {
  479. // printf("BRIDGE STOP\n");
  480. pEthCmd->Hdr.Op = ARP1394_IOCTL_OP_ETHERNET_STOP_EMULATION;
  481. }
  482. }
  483. break;
  484. case DO_GET_NICINFO:
  485. //
  486. // ipfwadm -nicinfo [a|n node_id |c channel_number]
  487. //
  488. {
  489. PNIC1394_NICINFO pNi = &g.Cmd.IoctlNicInfo.Info;
  490. INT NicOp;
  491. UINT Num;
  492. if (iIndx >= argc)
  493. {
  494. NicOp = DO_NI_BUSINFO; // Default
  495. }
  496. else
  497. {
  498. NicOp = FindOption(argv[iIndx++], &pVal, FALSE);
  499. }
  500. g.Cmd.Hdr.Version = ARP1394_IOCTL_VERSION;
  501. g.Cmd.Hdr.Op = ARP1394_IOCTL_OP_GET_NICINFO;
  502. pNi->Hdr.Version = NIC1394_NICINFO_VERSION;
  503. //
  504. // Parse the sub-command
  505. //
  506. switch(NicOp)
  507. {
  508. default:
  509. // Assume default and put parsed value back.
  510. //
  511. iIndx--;
  512. // FALL THROUGH
  513. case DO_NI_BUSINFO:
  514. pNi->Hdr.Op = NIC1394_NICINFO_OP_BUSINFO;
  515. break;
  516. case DO_NI_NODEINFO:
  517. pNi->Hdr.Op = NIC1394_NICINFO_OP_REMOTENODEINFO;
  518. // Read mandatory node number
  519. //
  520. bRetVal = FALSE;
  521. if (iIndx < argc)
  522. {
  523. if (sscanf(argv[iIndx++], "%d", &Num)==1)
  524. {
  525. bRetVal = TRUE;
  526. }
  527. }
  528. if (bRetVal)
  529. {
  530. pNi->RemoteNodeInfo.NodeAddress = (USHORT) Num;
  531. }
  532. else
  533. {
  534. printf("Missing node id\n");
  535. }
  536. break;
  537. case DO_NI_CHANNELINFO:
  538. pNi->Hdr.Op = NIC1394_NICINFO_OP_CHANNELINFO;
  539. // Read mandatory channel number
  540. //
  541. bRetVal = FALSE;
  542. if (iIndx < argc)
  543. {
  544. if (sscanf(argv[iIndx++], "%d", &Num)==1)
  545. {
  546. bRetVal = TRUE;
  547. }
  548. }
  549. if (bRetVal)
  550. {
  551. pNi->ChannelInfo.Channel = Num;
  552. }
  553. else
  554. {
  555. printf("Missing channel number\n");
  556. }
  557. break;
  558. }
  559. }
  560. break;
  561. case DO_EUIDMAP:
  562. {
  563. PARP1394_IOCTL_EUID_NODE_MAC_INFO pMapInfo = &g.Cmd.EuidNodeMacInfo;
  564. pMapInfo->Hdr.Version = ARP1394_IOCTL_VERSION;
  565. pMapInfo->Hdr.Op = ARP1394_IOCTL_OP_GET_EUID_NODE_MAC_TABLE;
  566. printf("Receved EuidMap");
  567. }
  568. break;
  569. case DO_SWITCH_TO_STDIN:
  570. //
  571. // "arp13 --"
  572. //
  573. printf("Switch to stdin UNIMPLEMENTED.\n");
  574. bRetVal = FALSE;
  575. break;
  576. case DO_SPECIFIC_IF:
  577. //
  578. // "-n if_addr"
  579. //
  580. {
  581. PARP1394_IOCTL_HEADER pHdr = &g.Cmd.Hdr;
  582. bRetVal = ParseIpAddress(argv[iIndx++], &pHdr->IfIpAddress);
  583. if (!bRetVal) break;
  584. }
  585. break;
  586. default:
  587. printf("Unknown option: %s\n", argv[iIndx-1]); // fall through
  588. //
  589. // FALL THROUGH...
  590. //
  591. case DO_DISP_HELP:
  592. Usage();
  593. bRetVal = FALSE;
  594. break;
  595. }
  596. }
  597. if (argc<=1)
  598. {
  599. //
  600. // Display help...
  601. //
  602. Usage();
  603. }
  604. if (bRetVal)
  605. {
  606. bRetVal = ValidateCommand(&g.Cmd);
  607. }
  608. return bRetVal;
  609. }
  610. UINT FindOption(
  611. char *lptOpt,
  612. char **ppVal,
  613. BOOL fCmdLine
  614. )
  615. {
  616. int i;
  617. UINT iLen;
  618. char c = *lptOpt;
  619. // if (fCmdLine), expect, and skip past the '-', or '/'...
  620. //
  621. if (fCmdLine)
  622. {
  623. if (c == '-' || c == '/')
  624. {
  625. lptOpt++;
  626. }
  627. else
  628. {
  629. return UNKNOWN_OPTION; // EARLY RETURN
  630. }
  631. }
  632. for(i = 0; i < iCmdOptionsCounts; i++)
  633. {
  634. if(strlen(lptOpt) >= (iLen = strlen(CmdOptions[i].lptOption)))
  635. {
  636. if(0 == strcmp(lptOpt, CmdOptions[i].lptOption))
  637. {
  638. *ppVal = lptOpt + iLen;
  639. return CmdOptions[i].uOpt;
  640. }
  641. }
  642. }
  643. return UNKNOWN_OPTION;
  644. }
  645. BOOL
  646. ParseIpAddress(
  647. PCHAR buf,
  648. PULONG pIpAddress
  649. )
  650. /*++
  651. Routine Description:
  652. Parse IP address in buf the form a.b.c.d and return the parsed value
  653. in *pIpAddress in network byte order.
  654. Return Value:
  655. TRUE iff correctly formed IP address. False otherwise.
  656. --*/
  657. {
  658. BOOL fRet = FALSE;
  659. do
  660. {
  661. INT rgi[4];
  662. INT i;
  663. i = sscanf(buf, "%d.%d.%d.%d", rgi+0, rgi+1, rgi+2, rgi+3);
  664. if (i<4) break;
  665. fRet = TRUE;
  666. for (i=0; i<4; i++)
  667. {
  668. INT iTmp = rgi[i];
  669. if (iTmp == -1)
  670. {
  671. iTmp = 255;
  672. }
  673. if (iTmp<0 || iTmp>255)
  674. {
  675. fRet = FALSE;
  676. break;
  677. }
  678. rgi[i] = iTmp;
  679. }
  680. if (!fRet) break;
  681. // Construct IP address in network byte order.
  682. //
  683. {
  684. ULONG u = (ULONG) rgi[0];
  685. u |= ((ULONG)rgi[1])<<8;
  686. u |= ((ULONG)rgi[2])<<16;
  687. u |= ((ULONG)rgi[3])<<24;
  688. *pIpAddress = u;
  689. }
  690. #if 0
  691. printf(
  692. "(%d.%d.%d.%d)->0x%08lx\n",
  693. rgi[0], rgi[1], rgi[2], rgi[3], *pIpAddress
  694. );
  695. #endif // 0
  696. } while (FALSE);
  697. if (!fRet)
  698. {
  699. printf("Invalid IP address: %s\n", buf);
  700. }
  701. return fRet;
  702. }
  703. BOOL
  704. ParseHwAddress(
  705. PCHAR buf,
  706. PARP1394_IOCTL_HW_ADDRESS pHwAddr
  707. )
  708. /*++
  709. Routine Description:
  710. Parse IEEE1394 HW address in buf the form of 8 bytes separated by hyphens.
  711. Return the parsed value in *pHwAddr in network byte order.
  712. Return Value:
  713. TRUE iff correctly formed HW address. False otherwise.
  714. --*/
  715. {
  716. BOOL fRet = FALSE;
  717. do
  718. {
  719. ULONG rgu[8];
  720. INT i;
  721. i = sscanf(
  722. buf,
  723. "%lx-%lx-%lx-%lx-%lx-%lx-%lx-%lx",
  724. rgu+0, rgu+1, rgu+2, rgu+3,
  725. rgu+4, rgu+5, rgu+6, rgu+7
  726. );
  727. if (i<8) break;
  728. fRet = TRUE;
  729. for (i=0; i<8; i++)
  730. {
  731. ULONG u = rgu[i];
  732. if (u>255)
  733. {
  734. fRet = FALSE;
  735. break;
  736. }
  737. ((PUCHAR)(&pHwAddr->UniqueID))[i] = (UCHAR) u;
  738. }
  739. if (!fRet) break;
  740. #if 0
  741. printf(
  742. "(%d-%d-%d-%d-%d-%d-%d-%d) -> 0x%08lx:0x%08lx\n",
  743. rgu[0], rgu[1], rgu[2], rgu[3],
  744. rgu[4], rgu[5], rgu[6], rgu[7],
  745. ((PULONG)(&pHwAddr->UniqueID))[0],
  746. ((PULONG)(&pHwAddr->UniqueID))[1]
  747. );
  748. #endif // 0
  749. } while (FALSE);
  750. if (!fRet)
  751. {
  752. printf("Invalid HW address: %s\n", buf);
  753. }
  754. return fRet;
  755. }
  756. BOOL
  757. ValidateCommand(PARP1394_IOCTL_COMMAND pCmd)
  758. {
  759. BOOL fRet = FALSE;
  760. if (pCmd->Hdr.Version != ARP1394_IOCTL_VERSION) return FALSE; // EARLY RETURN
  761. switch(pCmd->Hdr.Op)
  762. {
  763. case ARP1394_IOCTL_OP_GET_ARPCACHE:
  764. {
  765. PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd = &pCmd->GetArpCache;
  766. #if 0
  767. printf(
  768. "CMD = \n{"
  769. " Op = GET_ARPCACHE;\n"
  770. " IpIf = 0x%08lx;\n"
  771. " NumAvail = %lu;\n"
  772. "};\n",
  773. pGetCacheCmd->Hdr.IfIpAddress,
  774. pGetCacheCmd->NumEntriesAvailable
  775. );
  776. #endif // 0
  777. fRet = TRUE;
  778. }
  779. break;
  780. case ARP1394_IOCTL_OP_ADD_STATIC_ENTRY:
  781. {
  782. PARP1394_IOCTL_ADD_ARP_ENTRY pAddCmd = &pCmd->AddArpEntry;
  783. #if 0
  784. printf(
  785. "CMD = \n{"
  786. " Op = ADD_ENTRY;\n"
  787. " IpIf = 0x%08lx;\n"
  788. " IpAddress = 0x%08lx;\n"
  789. " HwAddress = 0x%08lx:0x%08lx;\n"
  790. "};\n",
  791. pAddCmd->Hdr.IfIpAddress,
  792. pAddCmd->IpAddress,
  793. ((PULONG)&pAddCmd->HwAddress)[0],
  794. ((PULONG)&pAddCmd->HwAddress)[1]
  795. );
  796. #endif // 0
  797. fRet = TRUE;
  798. }
  799. break;
  800. case ARP1394_IOCTL_OP_DEL_STATIC_ENTRY:
  801. {
  802. PARP1394_IOCTL_DEL_ARP_ENTRY pDelCmd = &pCmd->DelArpEntry;
  803. #if 0
  804. printf(
  805. "CMD = \n{"
  806. " Op = DEL_ENTRY;\n"
  807. " IpIf = 0x%08lx;\n"
  808. " IpAddress = 0x%08lx;\n"
  809. "};\n",
  810. pDelCmd->Hdr.IfIpAddress,
  811. pDelCmd->IpAddress
  812. );
  813. #endif // 0
  814. fRet = TRUE;
  815. }
  816. break;
  817. case ARP1394_IOCTL_OP_PURGE_ARPCACHE:
  818. {
  819. PARP1394_IOCTL_PURGE_ARPCACHE pPurgeCmd = &pCmd->PurgeArpCache;
  820. #if 0
  821. printf(
  822. "CMD = \n{"
  823. " Op = GET_PURGE_ARPCACHE;\n"
  824. " IpIf = 0x%08lx;\n"
  825. "};\n",
  826. pPurgeCmd->Hdr.IfIpAddress
  827. );
  828. #endif // 0
  829. fRet = TRUE;
  830. }
  831. break;
  832. case ARP1394_IOCTL_OP_GET_PACKET_STATS:
  833. {
  834. PARP1394_IOCTL_GET_PACKET_STATS pStatsCmd = &pCmd->GetPktStats;
  835. #if 0
  836. printf(
  837. "CMD = \n{"
  838. " Op = GET_PACKET_STATS;\n"
  839. " IpIf = 0x%08lx;\n"
  840. "};\n",
  841. pStatsCmd->Hdr.IfIpAddress
  842. );
  843. #endif // 0
  844. fRet = TRUE;
  845. }
  846. break;
  847. case ARP1394_IOCTL_OP_GET_TASK_STATS:
  848. {
  849. PARP1394_IOCTL_GET_TASK_STATS pStatsCmd = &pCmd->GetTaskStats;
  850. #if 0
  851. printf(
  852. "CMD = \n{"
  853. " Op = GET_TASK_STATS;\n"
  854. " IpIf = 0x%08lx;\n"
  855. "};\n",
  856. pStatsCmd->Hdr.IfIpAddress
  857. );
  858. #endif // 0
  859. fRet = TRUE;
  860. }
  861. break;
  862. case ARP1394_IOCTL_OP_GET_ARPCACHE_STATS:
  863. {
  864. PARP1394_IOCTL_GET_ARPCACHE_STATS pStatsCmd = &pCmd->GetArpStats;
  865. #if 0
  866. printf(
  867. "CMD = \n{"
  868. " Op = GET_ARPCACHE_STATS;\n"
  869. " IpIf = 0x%08lx;\n"
  870. "};\n",
  871. pStatsCmd->Hdr.IfIpAddress
  872. );
  873. #endif // 0
  874. fRet = TRUE;
  875. }
  876. break;
  877. case ARP1394_IOCTL_OP_GET_CALL_STATS:
  878. {
  879. PARP1394_IOCTL_GET_CALL_STATS pStatsCmd = &pCmd->GetCallStats;
  880. #if 0
  881. printf(
  882. "CMD = \n{"
  883. " Op = GET_CALL_STATS;\n"
  884. " IpIf = 0x%08lx;\n"
  885. "};\n",
  886. pStatsCmd->Hdr.IfIpAddress
  887. );
  888. #endif // 0
  889. fRet = TRUE;
  890. }
  891. break;
  892. case ARP1394_IOCTL_OP_RESET_STATS:
  893. {
  894. PARP1394_IOCTL_RESET_STATS pStatsCmd = &pCmd->ResetStats;
  895. #if 0
  896. printf(
  897. "CMD = \n{"
  898. " Op = GET_RESET_STATS;\n"
  899. " IpIf = 0x%08lx;\n"
  900. "};\n",
  901. pStatsCmd->Hdr.IfIpAddress
  902. );
  903. #endif // 0
  904. fRet = TRUE;
  905. }
  906. break;
  907. case ARP1394_IOCTL_OP_REINIT_INTERFACE:
  908. {
  909. PARP1394_IOCTL_REINIT_INTERFACE pReinitCmd = &pCmd->ReinitInterface;
  910. #if 0
  911. printf(
  912. "CMD = \n{"
  913. " Op = GET_REINIT_INTERFACE;\n"
  914. " IpIf = 0x%08lx;\n"
  915. "};\n",
  916. pReinitCmd->Hdr.IfIpAddress
  917. );
  918. #endif // 0
  919. fRet = TRUE;
  920. }
  921. break;
  922. case ARP1394_IOCTL_OP_SEND_PACKET:
  923. {
  924. PARP1394_IOCTL_SEND_PACKET pSendCmd = &pCmd->SendPacket;
  925. #if 0
  926. printf(
  927. "CMD = \n{"
  928. " Op = SEND_PACKET;\n"
  929. " Pkt = %s;\n"
  930. " IpIf = 0x%08lx;\n"
  931. "};\n",
  932. g_szPacketName,
  933. pSendCmd->Hdr.IfIpAddress
  934. );
  935. #endif // 0
  936. fRet = TRUE;
  937. }
  938. break;
  939. case ARP1394_IOCTL_OP_RECV_PACKET:
  940. {
  941. PARP1394_IOCTL_RECV_PACKET pRecvCmd = &pCmd->RecvPacket;
  942. #if 0
  943. printf(
  944. "CMD = \n{"
  945. " Op = RECV_PACKET;\n"
  946. " Pkt = %s;\n"
  947. " IpIf = 0x%08lx;\n"
  948. "};\n",
  949. g_szPacketName,
  950. pRecvCmd->Hdr.IfIpAddress
  951. );
  952. #endif // 0
  953. fRet = TRUE;
  954. }
  955. break;
  956. case ARP1394_IOCTL_OP_ETHERNET_START_EMULATION:
  957. case ARP1394_IOCTL_OP_ETHERNET_STOP_EMULATION:
  958. {
  959. fRet = TRUE;
  960. }
  961. break;
  962. case ARP1394_IOCTL_OP_GET_NICINFO:
  963. {
  964. PARP1394_IOCTL_NICINFO pNicInfoCmd = &pCmd->IoctlNicInfo;
  965. #if 0
  966. printf(
  967. "CMD = \n{"
  968. " Op = NICINFO;\n"
  969. " IpIf = 0x%08lx;\n"
  970. "};\n",
  971. pNicInfoCmd->Hdr.IfIpAddress
  972. );
  973. #endif // 0
  974. fRet = TRUE;
  975. }
  976. break;
  977. case ARP1394_IOCTL_OP_GET_EUID_NODE_MAC_TABLE:
  978. {
  979. fRet = TRUE;
  980. }
  981. default:
  982. break;
  983. }
  984. return fRet;
  985. };
  986. CHAR *g_szPacketName;
  987. BOOL
  988. ParsePacket(
  989. PCHAR buf,
  990. UCHAR *data,
  991. UINT cbData,
  992. UINT *pcbPacketSize
  993. )
  994. {
  995. char Path[256];
  996. UINT u;
  997. BOOL fRet = FALSE;
  998. g_szPacketName = buf;
  999. u = GetCurrentDirectory(sizeof(Path), Path);
  1000. if (u==0)
  1001. {
  1002. printf("Couldn't get current directory.\n");
  1003. return FALSE;
  1004. }
  1005. strcat(Path, "\\");
  1006. strcat(Path, PROGRAM);
  1007. strcat(Path, ".ini");
  1008. // printf("INI file location = %s\n", Path);
  1009. fRet = GetBinaryData(
  1010. Path,
  1011. "Packets",
  1012. buf,
  1013. data,
  1014. cbData,
  1015. pcbPacketSize
  1016. );
  1017. #if 0
  1018. static IP1394_MCAP_PKT Pkt =
  1019. {
  1020. {
  1021. H2N_USHORT(0), // Node id
  1022. H2N_USHORT(NIC1394_ETHERTYPE_MCAP)
  1023. },
  1024. H2N_USHORT(
  1025. sizeof(IP1394_MCAP_PKT) - sizeof(NIC1394_UNFRAGMENTED_HEADER)),
  1026. 0, // reserved
  1027. IP1394_MCAP_OP_ADVERTISE, // IP1394_MCAP_OP_SOLICIT
  1028. {
  1029. sizeof(IP1394_MCAP_GD),
  1030. IP1394_MCAP_GD_TYPE_V1,
  1031. 0, // reserved;
  1032. 60, // expiration;
  1033. 2, // channel
  1034. 2, // speed
  1035. 0, // reserved2;
  1036. 0, // bandwidth;
  1037. 0x010000e1 // IP multicast group address 225.0.0.1
  1038. }
  1039. };
  1040. PIP1394_MCAP_PKT pPkt;
  1041. pPkt = &Pkt;
  1042. if (cbData >= sizeof(Pkt))
  1043. {
  1044. printf ("ParsePacket: MCAP packet of size %lu.\n", sizeof(Pkt));
  1045. *(PIP1394_MCAP_PKT) data = *pPkt;
  1046. *pcbPacketSize = sizeof (Pkt);
  1047. fRet = TRUE;
  1048. }
  1049. else
  1050. {
  1051. printf ("ParsePacket: buffer size too small.\n");
  1052. }
  1053. #endif // 0
  1054. return fRet;
  1055. }
  1056. BOOL
  1057. ParseAdapter(
  1058. PCHAR buf,
  1059. UCHAR *data,
  1060. UINT cbData,
  1061. UINT *pcbAdapterSize
  1062. )
  1063. {
  1064. char Path[256];
  1065. UINT u;
  1066. BOOL fRet = FALSE;
  1067. g_szPacketName = buf;
  1068. u = GetCurrentDirectory(sizeof(Path), Path);
  1069. if (u==0)
  1070. {
  1071. printf("Couldn't get current directory.\n");
  1072. return FALSE;
  1073. }
  1074. strcat(Path, "\\");
  1075. strcat(Path, PROGRAM);
  1076. strcat(Path, ".ini");
  1077. // printf("INI file location = %s\n", Path);
  1078. fRet = GetBinaryData(
  1079. Path,
  1080. "Adapters",
  1081. buf,
  1082. data,
  1083. cbData,
  1084. pcbAdapterSize
  1085. );
  1086. return fRet;
  1087. }
  1088. typedef struct
  1089. {
  1090. IP1394_MCAP_PKT Pkt;
  1091. IP1394_MCAP_GD Gd2;
  1092. } MYPKT2;
  1093. typedef struct
  1094. {
  1095. IP1394_MCAP_PKT Pkt;
  1096. IP1394_MCAP_GD Gd2;
  1097. IP1394_MCAP_GD Gd3;
  1098. } MYPKT3;
  1099. typedef struct
  1100. {
  1101. IP1394_MCAP_PKT Pkt;
  1102. IP1394_MCAP_GD Gd2;
  1103. IP1394_MCAP_GD Gd3;
  1104. IP1394_MCAP_GD Gd4;
  1105. } MYPKT4;
  1106. #define SWAPBYTES_USHORT(Val) \
  1107. ((((Val) & 0xff) << 8) | (((Val) & 0xff00) >> 8))
  1108. #define H2N_USHORT(Val) SWAPBYTES_USHORT(Val)
  1109. IP1394_MCAP_PKT Pkt1 =
  1110. {
  1111. {
  1112. H2N_USHORT(0), // Node id
  1113. H2N_USHORT(NIC1394_ETHERTYPE_MCAP)
  1114. },
  1115. H2N_USHORT(
  1116. sizeof(IP1394_MCAP_PKT) - sizeof(NIC1394_UNFRAGMENTED_HEADER)),
  1117. 0, // reserved
  1118. IP1394_MCAP_OP_ADVERTISE, // IP1394_MCAP_OP_SOLICIT
  1119. {
  1120. sizeof(IP1394_MCAP_GD),
  1121. IP1394_MCAP_GD_TYPE_V1,
  1122. 0, // reserved;
  1123. 60, // expiration;
  1124. 2, // channel
  1125. 2, // speed
  1126. 0, // reserved2;
  1127. 0, // bandwidth;
  1128. 0x010000e1 // IP multicast group address 225.0.0.1
  1129. }
  1130. };
  1131. MYPKT2 Pkt2 =
  1132. {
  1133. {
  1134. {
  1135. H2N_USHORT(0), // Node id
  1136. H2N_USHORT(NIC1394_ETHERTYPE_MCAP)
  1137. },
  1138. H2N_USHORT(
  1139. sizeof(MYPKT2) - sizeof(NIC1394_UNFRAGMENTED_HEADER)),
  1140. 0, // reserved
  1141. IP1394_MCAP_OP_ADVERTISE, // IP1394_MCAP_OP_SOLICIT
  1142. {
  1143. sizeof(IP1394_MCAP_GD),
  1144. IP1394_MCAP_GD_TYPE_V1,
  1145. 0, // reserved;
  1146. 60, // expiration;
  1147. 2, // channel
  1148. 2, // speed
  1149. 0, // reserved2;
  1150. 0, // bandwidth;
  1151. 0x010000e1 // IP multicast group address 225.0.0.1
  1152. }
  1153. },
  1154. {
  1155. sizeof(IP1394_MCAP_GD),
  1156. IP1394_MCAP_GD_TYPE_V1,
  1157. 0, // reserved;
  1158. 60, // expiration;
  1159. 2, // channel
  1160. 2, // speed
  1161. 0, // reserved2;
  1162. 0, // bandwidth;
  1163. 0x020000e1 // IP multicast group address 225.0.0.2
  1164. }
  1165. };
  1166. MYPKT3 Pkt3 =
  1167. {
  1168. {
  1169. {
  1170. H2N_USHORT(0), // Node id
  1171. H2N_USHORT(NIC1394_ETHERTYPE_MCAP)
  1172. },
  1173. H2N_USHORT(
  1174. sizeof(MYPKT3) - sizeof(NIC1394_UNFRAGMENTED_HEADER)),
  1175. 0, // reserved
  1176. IP1394_MCAP_OP_ADVERTISE, // IP1394_MCAP_OP_SOLICIT
  1177. {
  1178. sizeof(IP1394_MCAP_GD),
  1179. IP1394_MCAP_GD_TYPE_V1,
  1180. 0, // reserved;
  1181. 60, // expiration;
  1182. 2, // channel
  1183. 2, // speed
  1184. 0, // reserved2;
  1185. 0, // bandwidth;
  1186. 0x010000e1 // IP multicast group address 225.0.0.1
  1187. }
  1188. },
  1189. {
  1190. sizeof(IP1394_MCAP_GD),
  1191. IP1394_MCAP_GD_TYPE_V1,
  1192. 0, // reserved;
  1193. 60, // expiration;
  1194. 2, // channel
  1195. 2, // speed
  1196. 0, // reserved2;
  1197. 0, // bandwidth;
  1198. 0x020000e1 // IP multicast group address 225.0.0.2
  1199. },
  1200. {
  1201. sizeof(IP1394_MCAP_GD),
  1202. IP1394_MCAP_GD_TYPE_V1,
  1203. 0, // reserved;
  1204. 60, // expiration;
  1205. 2, // channel
  1206. 2, // speed
  1207. 0, // reserved2;
  1208. 0, // bandwidth;
  1209. 0x030000e1 // IP multicast group address 225.0.0.3
  1210. }
  1211. };
  1212. MYPKT4 Pkt4 =
  1213. {
  1214. {
  1215. {
  1216. H2N_USHORT(0), // Node id
  1217. H2N_USHORT(NIC1394_ETHERTYPE_MCAP)
  1218. },
  1219. H2N_USHORT(
  1220. sizeof(MYPKT4) - sizeof(NIC1394_UNFRAGMENTED_HEADER)),
  1221. 0, // reserved
  1222. IP1394_MCAP_OP_ADVERTISE, // IP1394_MCAP_OP_SOLICIT
  1223. {
  1224. sizeof(IP1394_MCAP_GD),
  1225. IP1394_MCAP_GD_TYPE_V1,
  1226. 0, // reserved;
  1227. 60, // expiration;
  1228. 2, // channel
  1229. 2, // speed
  1230. 0, // reserved2;
  1231. 0, // bandwidth;
  1232. 0x010000e1 // IP multicast group address 225.0.0.1
  1233. }
  1234. },
  1235. {
  1236. sizeof(IP1394_MCAP_GD),
  1237. IP1394_MCAP_GD_TYPE_V1,
  1238. 0, // reserved;
  1239. 60, // expiration;
  1240. 2, // channel
  1241. 2, // speed
  1242. 0, // reserved2;
  1243. 0, // bandwidth;
  1244. 0x020000e1 // IP multicast group address 225.0.0.2
  1245. },
  1246. {
  1247. sizeof(IP1394_MCAP_GD),
  1248. IP1394_MCAP_GD_TYPE_V1,
  1249. 0, // reserved;
  1250. 60, // expiration;
  1251. 2, // channel
  1252. 2, // speed
  1253. 0, // reserved2;
  1254. 0, // bandwidth;
  1255. 0x030000e1 // IP multicast group address 225.0.0.3
  1256. },
  1257. {
  1258. sizeof(IP1394_MCAP_GD),
  1259. IP1394_MCAP_GD_TYPE_V1,
  1260. 0, // reserved;
  1261. 60, // expiration;
  1262. 2, // channel
  1263. 2, // speed
  1264. 0, // reserved2;
  1265. 0, // bandwidth;
  1266. 0x040000e1 // IP multicast group address 225.0.0.4
  1267. }
  1268. };