Leaked source code of windows server 2003
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.

3113 lines
89 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. eth.c
  5. Abstract:
  6. ARP1394 Ethernet emulation-related handlers.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 11-22-99 Created
  11. Adube 10-2000 Added Bridging
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. //
  16. // File-specific debugging defaults.
  17. //
  18. #define TM_CURRENT TM_ETH
  19. UINT Arp1394ToIcs = 0;
  20. //=========================================================================
  21. // L O C A L P R O T O T Y P E S
  22. //=========================================================================
  23. // These are ethernet arp specific constants
  24. //
  25. #define ARP_ETH_ETYPE_IP 0x800
  26. #define ARP_ETH_ETYPE_ARP 0x806
  27. #define ARP_ETH_REQUEST 1
  28. #define ARP_ETH_RESPONSE 2
  29. #define ARP_ETH_HW_ENET 1
  30. #define ARP_ETH_HW_802 6
  31. //
  32. // Check whether an address is multicast
  33. //
  34. #define ETH_IS_MULTICAST(Address) \
  35. (BOOLEAN)(((PUCHAR)(Address))[0] & ((UCHAR)0x01))
  36. //
  37. // Check whether an address is broadcast.
  38. //
  39. #define ETH_IS_BROADCAST(Address) \
  40. ((((PUCHAR)(Address))[0] == ((UCHAR)0xff)) && (((PUCHAR)(Address))[1] == ((UCHAR)0xff)))
  41. #pragma pack (push, 1)
  42. //* Structure of an Ethernet header (taken from ip\arpdef.h).
  43. typedef struct ENetHeader {
  44. ENetAddr eh_daddr;
  45. ENetAddr eh_saddr;
  46. USHORT eh_type;
  47. } ENetHeader;
  48. const ENetAddr BroadcastENetAddr =
  49. {
  50. {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
  51. };
  52. // Following is a template for creating Ethernet Multicast addresses
  53. // from ip multicast addresses.
  54. // The last 3 bytes are the last 3 bytes (network byte order) of the mcast
  55. // address.
  56. //
  57. const ENetAddr MulticastENetAddr =
  58. {
  59. {0x01,0x00,0x5E,0x00, 0x00, 0x00}
  60. };
  61. //
  62. // This is the Ethernet address to which the bridge sends STA packets.
  63. // STA packets are used by the bridge to detect loops
  64. //
  65. // Size of a basic UDP header
  66. #define SIZE_OF_UDP_HEADER 8 // bytes
  67. // Minimum size of the payload of a BOOTP packet
  68. #define SIZE_OF_BASIC_BOOTP_PACKET 236 // bytes
  69. // The UDP IP protocol type
  70. #define UDP_PROTOCOL 0x11
  71. // Size of Ethernet header
  72. #define ETHERNET_HEADER_SIZE (ETH_LENGTH_OF_ADDRESS * 2 ) + 2
  73. UCHAR gSTAMacAddr[ETH_LENGTH_OF_ADDRESS] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 };
  74. #define NIC1394_ETHERTYPE_STA 0x777
  75. const
  76. NIC1394_ENCAPSULATION_HEADER
  77. Arp1394_StaEncapHeader =
  78. {
  79. 0x0000, // Reserved
  80. H2N_USHORT(NIC1394_ETHERTYPE_STA)
  81. };
  82. // Structure of an Ethernet ARP packet.
  83. //
  84. typedef struct {
  85. ENetHeader header;
  86. USHORT hardware_type;
  87. USHORT protocol_type;
  88. UCHAR hw_addr_len;
  89. UCHAR IP_addr_len;
  90. USHORT opcode; // Opcode.
  91. ENetAddr sender_hw_address;
  92. IP_ADDRESS sender_IP_address;
  93. ENetAddr target_hw_address;
  94. IP_ADDRESS target_IP_address;
  95. } ETH_ARP_PKT, *PETH_ARP_PKT;
  96. #pragma pack (pop)
  97. // Parsed version of an ethernet ARP packet.
  98. //
  99. typedef struct {
  100. ENetAddr SourceEthAddress; // Ethernet source h/w address.
  101. ENetAddr DestEthAddress; // Ethernet source h/w address.
  102. UINT OpCode; // ARP_ETH_REQUEST/RESPONSE
  103. ENetAddr SenderEthAddress; // Ethernet source h/w address.
  104. IP_ADDRESS SenderIpAddress; // IP source address
  105. ENetAddr TargetEthAddress; // Ethernet destination h/w address.
  106. IP_ADDRESS TargetIpAddress; // IP target address
  107. } ETH_ARP_PKT_INFO, *PETH_ARP_PKT_INFO;
  108. #define ARP_FAKE_ETH_ADDRESS(_AdapterNum) \
  109. { \
  110. 0x02 | (((UCHAR)(_AdapterNum) & 0x3f) << 2), \
  111. ((UCHAR)(_AdapterNum) & 0x3f), \
  112. 0,0,0,0 \
  113. }
  114. #define ARP_DEF_REMOTE_ETH_ADDRESS \
  115. ARP_FAKE_ETH_ADDRESS(0xf)
  116. #define ARP_IS_BOOTP_REQUEST(_pData) (_pData[0] == 0x1) // Byte 0 is the operation; 1 for a request, 2 for a reply
  117. #define ARP_IS_BOOTP_RESPONSE(_pData) (_pData[0] == 0x2) // Byte 0 is the operation; 1 for a request, 2 for a reply
  118. typedef struct _ARP_BOOTP_INFO
  119. {
  120. ULONG Xid;
  121. BOOLEAN bIsRequest;
  122. ENetAddr requestorMAC;
  123. } ARP_BOOTP_INFO , *PARP_BOOTP_INFO;
  124. NDIS_STATUS
  125. arpIcsTranslateIpPkt(
  126. IN PARP1394_INTERFACE pIF,
  127. IN PNDIS_PACKET pOrigPkt,
  128. IN ARP_ICS_FORWARD_DIRECTION Direction,
  129. IN MYBOOL fUnicast,
  130. OUT PNDIS_PACKET *ppNewPkt,
  131. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  132. PRM_STACK_RECORD pSR
  133. );
  134. NDIS_STATUS
  135. arpGetEthHeaderFrom1394IpPkt(
  136. IN PARP1394_INTERFACE pIF,
  137. IN PVOID pvData,
  138. IN UINT cbData,
  139. IN MYBOOL fUnicast,
  140. OUT ENetHeader *pEthHdr,
  141. OUT PIP_ADDRESS pDestIpAddress, // OPTIONAL
  142. PRM_STACK_RECORD pSR
  143. );
  144. NDIS_STATUS
  145. arpGet1394HeaderFromEthIpPkt(
  146. IN PARP1394_INTERFACE pIF,
  147. IN PNDIS_BUFFER pFirstBuffer,
  148. IN PVOID pvData,
  149. IN UINT cbData,
  150. IN MYBOOL fUnicast,
  151. OUT NIC1394_ENCAPSULATION_HEADER
  152. *p1394Hdr,
  153. OUT PREMOTE_DEST_KEY pDestIpAddress, // OPTIONAL
  154. PRM_STACK_RECORD pSR
  155. );
  156. NDIS_STATUS
  157. arpGetEthAddrFromIpAddr(
  158. IN PARP1394_INTERFACE pIF,
  159. IN MYBOOL fUnicast,
  160. IN IP_ADDRESS DestIpAddress,
  161. OUT ENetAddr *pEthAddr,
  162. PRM_STACK_RECORD pSR
  163. );
  164. NDIS_STATUS
  165. arpParseEthArpPkt(
  166. IN PETH_ARP_PKT pArpPkt,
  167. IN UINT cbBufferSize,
  168. OUT PETH_ARP_PKT_INFO pPktInfo
  169. );
  170. VOID
  171. arpPrepareEthArpPkt(
  172. IN PETH_ARP_PKT_INFO pPktInfo,
  173. OUT PETH_ARP_PKT pArpPkt
  174. );
  175. MYBOOL
  176. arpIsUnicastEthDest(
  177. IN UNALIGNED ENetHeader *pEthHdr
  178. );
  179. VOID
  180. arpEthProcess1394ArpPkt(
  181. IN PARP1394_INTERFACE pIF,
  182. IN PIP1394_ARP_PKT pArpPkt,
  183. IN UINT HeaderSize
  184. );
  185. VOID
  186. arpEthProcessEthArpPkt(
  187. IN PARP1394_INTERFACE pIF,
  188. IN PETH_ARP_PKT pArpPkt,
  189. IN UINT HeaderSize
  190. );
  191. NDIS_STATUS
  192. arpConstructEthArpInfoFrom1394ArpInfo(
  193. IN PARP1394_INTERFACE pIF,
  194. IN PIP1394_ARP_PKT_INFO p1394PktInfo,
  195. OUT PETH_ARP_PKT_INFO pEthPktInfo,
  196. PRM_STACK_RECORD pSR
  197. );
  198. NDIS_STATUS
  199. arpConstruct1394ArpInfoFromEthArpInfo(
  200. IN PARP1394_INTERFACE pIF,
  201. IN PETH_ARP_PKT_INFO pEthPktInfo,
  202. OUT PIP1394_ARP_PKT_INFO p1394PktInfo,
  203. PRM_STACK_RECORD pSR
  204. );
  205. VOID
  206. arpIcsForwardIpPacket(
  207. IN PARP1394_INTERFACE pIF,
  208. IN PNDIS_PACKET pPacket,
  209. IN ARP_ICS_FORWARD_DIRECTION Direction,
  210. IN MYBOOL fUnicast,
  211. IN PRM_STACK_RECORD pSR
  212. );
  213. NDIS_STATUS
  214. arpGetSourceMacAddressFor1394Pkt (
  215. IN PARP1394_ADAPTER pAdapter,
  216. IN UCHAR SourceNodeAddress,
  217. IN BOOLEAN fIsValidSourceNodeAddress,
  218. OUT ENetAddr* pSourceMacAddress,
  219. PRM_STACK_RECORD pSR
  220. );
  221. NDIS_STATUS
  222. arpEthConstructSTAEthHeader(
  223. IN PUCHAR pvData,
  224. IN UINT cbData,
  225. OUT ENetHeader *pEthHdr
  226. );
  227. NDIS_STATUS
  228. arpEthModifyBootPPacket(
  229. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  230. IN ARP_ICS_FORWARD_DIRECTION Direction,
  231. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  232. IN PUCHAR pucNewData,
  233. IN ULONG PacketLength,
  234. IN PRM_STACK_RECORD pSR
  235. );
  236. BOOLEAN
  237. arpEthPreprocessBootPPacket(
  238. IN PARP1394_INTERFACE pIF,
  239. IN PUCHAR pPacketData,
  240. IN PUCHAR pBootPData, // Actual BOOTP packet
  241. OUT PBOOLEAN pbIsRequest,
  242. PARP_BOOTP_INFO pInfoBootP,
  243. PRM_STACK_RECORD pSR
  244. );
  245. VOID
  246. arpIcsForwardIpPacket(
  247. IN PARP1394_INTERFACE pIF,
  248. IN PNDIS_PACKET pPacket,
  249. IN ARP_ICS_FORWARD_DIRECTION Direction,
  250. IN MYBOOL fUnicast,
  251. IN PRM_STACK_RECORD pSR
  252. )
  253. /*++
  254. Routine Description:
  255. Forward a packet from the ip/1394 side to the ethernet side, or vice-versa.
  256. Arguments:
  257. --*/
  258. {
  259. NDIS_STATUS Status;
  260. PNDIS_PACKET pNewPkt = NULL;
  261. ENTER("arpIcsForwardIpPacket", 0x98630e8f)
  262. do
  263. {
  264. PARPCB_DEST pDest = NULL;
  265. //
  266. // Create the translated packet.
  267. //
  268. Status = arpIcsTranslateIpPkt(
  269. pIF,
  270. pPacket,
  271. Direction,
  272. fUnicast,
  273. &pNewPkt,
  274. NULL, // Optional pIpDestAddr
  275. pSR
  276. );
  277. if (FAIL(Status))
  278. {
  279. if (Status == NDIS_STATUS_ALREADY_MAPPED)
  280. {
  281. //
  282. // This is a loop-backed packet.
  283. //
  284. arpEthReceivePacket(
  285. pIF,
  286. pPacket
  287. );
  288. }
  289. pNewPkt = NULL;
  290. break;
  291. }
  292. // We special case unicast sends to 1394, because that requires
  293. // special treatment: we need to lookup the destination and if
  294. // required create a VC to that destination. This
  295. // is done elsewhere (in arpEthernetReceivePacket), so we assert
  296. // we never get this this case.
  297. //
  298. ASSERT(!(Direction == ARP_ICS_FORWARD_TO_1394 && fUnicast))
  299. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  300. //
  301. // Determine destination
  302. //
  303. if (Direction == ARP_ICS_FORWARD_TO_1394)
  304. {
  305. pDest = pIF->pBroadcastDest;
  306. }
  307. else
  308. {
  309. ASSERT(Direction == ARP_ICS_FORWARD_TO_ETHERNET);
  310. pDest = pIF->pEthernetDest;
  311. };
  312. arpSendControlPkt(
  313. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  314. pNewPkt,
  315. pDest,
  316. pSR
  317. );
  318. } while (FALSE);
  319. EXIT()
  320. }
  321. NDIS_STATUS
  322. arpIcsTranslateIpPkt(
  323. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  324. IN PNDIS_PACKET pOrigPkt,
  325. IN ARP_ICS_FORWARD_DIRECTION Direction,
  326. IN MYBOOL fUnicast,
  327. OUT PNDIS_PACKET *ppNewPkt,
  328. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  329. PRM_STACK_RECORD pSR
  330. )
  331. {
  332. NDIS_STATUS Status;
  333. PNDIS_PACKET pNewPkt = NULL;
  334. PVOID pvNewData = NULL;
  335. do
  336. {
  337. PNDIS_BUFFER pOrigBuf = NULL;
  338. PVOID pvOrigData = NULL;
  339. UINT OrigBufSize;
  340. PVOID pvNewHdr = NULL;
  341. UINT OrigHdrSize;
  342. UINT NewHdrSize;
  343. UINT OrigPktSize;
  344. UINT NewPktSize;
  345. UINT BytesCopied;
  346. NIC1394_ENCAPSULATION_HEADER
  347. Nic1394Hdr;
  348. ENetHeader EthHdr;
  349. // Get size of 1st buffer and pointer to it's data.
  350. // (We only bother about the 1st buffer)
  351. //
  352. NdisQueryPacket(
  353. pOrigPkt,
  354. NULL,
  355. NULL,
  356. &pOrigBuf,
  357. &OrigPktSize
  358. );
  359. if (OrigPktSize > 0)
  360. {
  361. NdisQueryBuffer(
  362. pOrigBuf,
  363. &pvOrigData,
  364. &OrigBufSize
  365. );
  366. }
  367. else
  368. {
  369. OrigBufSize = 0;
  370. }
  371. if (pvOrigData == NULL)
  372. {
  373. Status = NDIS_STATUS_FAILURE;
  374. break;
  375. }
  376. // Compute direction-specific information
  377. //
  378. if(Direction == ARP_ICS_FORWARD_TO_1394)
  379. {
  380. OrigHdrSize = sizeof(EthHdr);
  381. NewHdrSize = sizeof(Nic1394Hdr);
  382. Status = arpGet1394HeaderFromEthIpPkt(
  383. pIF,
  384. pOrigBuf,
  385. pvOrigData,
  386. OrigBufSize,
  387. fUnicast,
  388. &Nic1394Hdr,
  389. pDestAddress,
  390. pSR
  391. );
  392. pvNewHdr = (PVOID) &Nic1394Hdr;
  393. }
  394. else
  395. {
  396. ASSERT(Direction==ARP_ICS_FORWARD_TO_ETHERNET);
  397. OrigHdrSize = sizeof(Nic1394Hdr);
  398. NewHdrSize = sizeof(EthHdr);
  399. Status = arpGetEthHeaderFrom1394IpPkt(
  400. pIF,
  401. pvOrigData,
  402. OrigBufSize,
  403. fUnicast,
  404. &EthHdr,
  405. &pDestAddress->IpAddress,
  406. pSR
  407. );
  408. pvNewHdr = (PVOID) &EthHdr;
  409. };
  410. if (FAIL(Status)) break;
  411. // Make sure the 1st buffer contains enough data for the header.
  412. //
  413. if (OrigBufSize < OrigHdrSize)
  414. {
  415. ASSERT(FALSE); // We should check why we're getting
  416. // this kind of tiny 1st buffer.
  417. Status = NDIS_STATUS_FAILURE;
  418. break;
  419. }
  420. // Compute the new packet size.
  421. //
  422. NewPktSize = OrigPktSize - OrigHdrSize + NewHdrSize;
  423. // Allocate an appropriately sized control packet.
  424. //
  425. Status = arpAllocateControlPacket(
  426. pIF,
  427. NewPktSize,
  428. ARP1394_PACKET_FLAGS_ICS,
  429. &pNewPkt,
  430. &pvNewData,
  431. pSR
  432. );
  433. if (FAIL(Status))
  434. {
  435. ASSERT(FALSE); // we want to know if we hit this in regular use.
  436. pNewPkt = NULL;
  437. break;
  438. }
  439. // Copy over the new header.
  440. //
  441. NdisMoveMemory(pvNewData, pvNewHdr, NewHdrSize);
  442. // Copy the rest of the packet contents.
  443. //
  444. NdisCopyFromPacketToPacket(
  445. pNewPkt, // Dest pkt
  446. NewHdrSize, // Dest offset
  447. OrigPktSize - OrigHdrSize, // BytesToCopy
  448. pOrigPkt, // Source,
  449. OrigHdrSize, // SourceOffset
  450. &BytesCopied
  451. );
  452. if (BytesCopied != (OrigPktSize - OrigHdrSize))
  453. {
  454. ASSERT(FALSE); // Should never get here.
  455. Status = NDIS_STATUS_FAILURE;
  456. break;
  457. }
  458. // Add the Bootp code here.
  459. Status = arpEthModifyBootPPacket(pIF,
  460. Direction,
  461. pDestAddress,
  462. (PUCHAR)pvNewData,
  463. NewPktSize ,
  464. pSR);
  465. if (Status != NDIS_STATUS_SUCCESS)
  466. {
  467. ASSERT (!"TempAssert -arpEthModifyBootPPacket FAILED");
  468. break;
  469. }
  470. } while (FALSE);
  471. if (FAIL(Status) && pNewPkt != NULL)
  472. {
  473. arpFreeControlPacket(
  474. pIF,
  475. pNewPkt,
  476. pSR
  477. );
  478. *ppNewPkt = NULL;
  479. }
  480. else
  481. {
  482. *ppNewPkt = pNewPkt;
  483. }
  484. return Status;
  485. }
  486. NDIS_STATUS
  487. arpGetEthHeaderFrom1394IpPkt(
  488. IN PARP1394_INTERFACE pIF,
  489. IN PVOID pvData,
  490. IN UINT cbData,
  491. IN MYBOOL fUnicast,
  492. OUT ENetHeader *pEthHdr,
  493. OUT PIP_ADDRESS pDestIpAddress, // OPTIONAL
  494. PRM_STACK_RECORD pSR
  495. )
  496. /*++
  497. Return a fully filled ethernet header, with source and estination
  498. MAC addresses and ethertype set to IP.
  499. The source address is always the local adapter's MAC address.
  500. The destination address is set by calling arpGetEthAddrFromIpAddr
  501. --*/
  502. {
  503. ENTER("arpGetEthHeaderFrom1394IpPkt", 0x0)
  504. static
  505. ENetHeader
  506. StaticEthernetHeader =
  507. {
  508. {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // eh_daddr == BCAST
  509. ARP_DEF_REMOTE_ETH_ADDRESS,
  510. H2N_USHORT(NIC1394_ETHERTYPE_IP) // eh_type
  511. };
  512. ARP1394_ADAPTER * pAdapter;
  513. BOOLEAN fBridgeMode;
  514. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  515. PNDIS1394_UNFRAGMENTED_HEADER pHeader = (PNDIS1394_UNFRAGMENTED_HEADER)pvData;
  516. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  517. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  518. do
  519. {
  520. UNALIGNED IPHeader *pIpHdr;
  521. IP_ADDRESS IpDest;
  522. if (cbData < (sizeof(NIC1394_ENCAPSULATION_HEADER) + sizeof(IPHeader)))
  523. {
  524. //
  525. // Packet is too small.
  526. //
  527. TR_INFO(("Discarding packet because pkt too small\n"));
  528. break;
  529. }
  530. pIpHdr = (UNALIGNED IPHeader*)
  531. (((PUCHAR) pvData)+sizeof(NIC1394_ENCAPSULATION_HEADER));
  532. IpDest = pIpHdr->iph_dest;
  533. if (pDestIpAddress != NULL)
  534. {
  535. *pDestIpAddress = IpDest;
  536. }
  537. if (!fBridgeMode)
  538. {
  539. //
  540. // TODO: we currently return a hardcoded ethernet address.
  541. // Need to constuct one by looking into the actual IP packet data.
  542. //
  543. *pEthHdr = StaticEthernetHeader;
  544. Status = NDIS_STATUS_SUCCESS;
  545. break;
  546. }
  547. //
  548. // Following is specific to BRIDGE mode
  549. //
  550. // Always set the source address according to the sender.
  551. //
  552. {
  553. ENetAddr SourceMacAddress;
  554. Status = \
  555. arpGetSourceMacAddressFor1394Pkt (pAdapter,
  556. pHeader->u1.SourceAddress,
  557. pHeader->u1.fHeaderHasSourceAddress,
  558. &SourceMacAddress,
  559. pSR);
  560. if (FAIL(Status))
  561. {
  562. break;
  563. }
  564. pEthHdr->eh_saddr = SourceMacAddress ;
  565. }
  566. //
  567. // If we have a STA packet then construct the STA Header
  568. // or else construct the sender/destination specific Ethernet
  569. // Header
  570. //
  571. {
  572. if (pHeader->u1.EtherType == N2H_USHORT(NIC1394_ETHERTYPE_STA) )
  573. {
  574. arpEthConstructSTAEthHeader(pvData,cbData, pEthHdr);
  575. }
  576. else
  577. {
  578. pEthHdr->eh_type = H2N_USHORT(ARP_ETH_ETYPE_IP);
  579. Status = arpGetEthAddrFromIpAddr(
  580. pIF,
  581. fUnicast,
  582. IpDest,
  583. &pEthHdr->eh_daddr,
  584. pSR
  585. );
  586. }
  587. }
  588. } while (FALSE);
  589. return Status;
  590. }
  591. NDIS_STATUS
  592. arpGet1394HeaderFromEthIpPkt(
  593. IN PARP1394_INTERFACE pIF,
  594. IN PNDIS_BUFFER pFirstBuffer,
  595. IN PVOID pvData,
  596. IN UINT cbData,
  597. IN MYBOOL fUnicast,
  598. OUT NIC1394_ENCAPSULATION_HEADER
  599. *p1394Hdr,
  600. OUT PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  601. PRM_STACK_RECORD pSR
  602. )
  603. {
  604. MYBOOL fLoopBack = FALSE;
  605. ENetHeader *pEthHdr = (ENetHeader *) pvData;
  606. ARP1394_ADAPTER * pAdapter;
  607. BOOLEAN fBridgeMode;
  608. if (cbData < (sizeof(ENetHeader) ) )
  609. {
  610. //
  611. // Packet is too small.
  612. //
  613. return NDIS_STATUS_FAILURE; // ***** EARLY RETURN ****
  614. }
  615. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  616. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  617. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  618. &pAdapter->info.EthernetMacAddress,
  619. sizeof(ENetAddr)))
  620. {
  621. if (!fBridgeMode)
  622. {
  623. // We're not in bridge mode -- so this must be only on MILL
  624. // This is addressed to our local mac address.
  625. // We fail with special failure status
  626. // NDIS_STATUS_ALREADY_MAPPED, indicating "loopback".
  627. //
  628. fLoopBack = TRUE;
  629. }
  630. }
  631. else
  632. {
  633. //
  634. // Do nothing ... because we can get unicasts to our fictitious gateway
  635. //
  636. }
  637. if (fLoopBack)
  638. {
  639. return NDIS_STATUS_ALREADY_MAPPED;
  640. }
  641. else
  642. {
  643. BOOLEAN fIsSTAPacket ;
  644. //
  645. // We have an STA packet, if the destination is our special
  646. // Multicast Destination
  647. //
  648. fIsSTAPacket = (TRUE == NdisEqualMemory (&pEthHdr->eh_daddr,
  649. &gSTAMacAddr,
  650. ETH_LENGTH_OF_ADDRESS) );
  651. if (fIsSTAPacket == TRUE)
  652. {
  653. *p1394Hdr = Arp1394_StaEncapHeader;
  654. }
  655. else
  656. {
  657. *p1394Hdr = Arp1394_IpEncapHeader;
  658. }
  659. if (pDestAddress != NULL)
  660. {
  661. //
  662. // Extract the Enet Address to use it as part of the lookup
  663. //
  664. UNALIGNED ENetAddr *pENetDest;
  665. pENetDest = (UNALIGNED ENetAddr *)(pvData);
  666. pDestAddress->ENetAddress = *pENetDest;
  667. }
  668. return NDIS_STATUS_SUCCESS;
  669. }
  670. }
  671. VOID
  672. arpEthReceivePacket(
  673. IN ARP1394_INTERFACE * pIF,
  674. PNDIS_PACKET pNdisPacket
  675. )
  676. /*
  677. This is the connectionLESS ethernet receive packet handler.
  678. Following code adapted from the co receive packet handler.
  679. */
  680. {
  681. ENTER("arpEthReceivePacket", 0xc8afbabb)
  682. UINT TotalLength; // Total bytes in packet
  683. PNDIS_BUFFER pNdisBuffer; // Pointer to first buffer
  684. UINT BufferLength;
  685. UINT ReturnCount;
  686. PVOID pvPktHeader;
  687. ENetHeader * pEthHeader;
  688. const UINT MacHeaderLength = sizeof(ENetHeader);
  689. ARP1394_ADAPTER * pAdapter;
  690. BOOLEAN fBridgeMode;
  691. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  692. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  693. DBGMARK(0x2425d318);
  694. ReturnCount = 0;
  695. //
  696. // Discard the packet if the IP interface is not activated
  697. //
  698. do
  699. {
  700. //
  701. // Discard packet if adapter is in bridge mode.
  702. //
  703. if (fBridgeMode)
  704. {
  705. break;
  706. }
  707. //
  708. // Discard the packet if the adapter is not active
  709. //
  710. if (!CHECK_IF_ACTIVE_STATE(pIF, ARPAD_AS_ACTIVATED))
  711. {
  712. TR_INFO(("Eth:Discardning received Eth pkt because pIF 0x%p is not activated.\n", pIF));
  713. break;
  714. }
  715. NdisQueryPacket(
  716. pNdisPacket,
  717. NULL,
  718. NULL,
  719. &pNdisBuffer,
  720. &TotalLength
  721. );
  722. if (TotalLength > 0)
  723. {
  724. NdisQueryBuffer(
  725. pNdisBuffer,
  726. (PVOID *)&pvPktHeader,
  727. &BufferLength
  728. );
  729. }
  730. else
  731. {
  732. break;
  733. }
  734. pEthHeader = (ENetHeader*) pvPktHeader;
  735. TR_INFO(
  736. ("EthRcv: NDISpkt 0x%x, NDISbuf 0x%x, Buflen %d, Totlen %d, Pkthdr 0x%x\n",
  737. pNdisPacket,
  738. pNdisBuffer,
  739. BufferLength,
  740. TotalLength,
  741. pvPktHeader));
  742. if (BufferLength < MacHeaderLength || pEthHeader == NULL)
  743. {
  744. // Packet is too small, discard.
  745. //
  746. break;
  747. }
  748. //
  749. // At this point, pEthHeader contains the Ethernet header.
  750. // We look at the ethertype to decide what to do with it.
  751. //
  752. if (pEthHeader->eh_type == N2H_USHORT(ARP_ETH_ETYPE_IP))
  753. {
  754. //
  755. // The EtherType is IP, so we pass up this packet to the IP layer.
  756. // (Also we indicate all packets we receive on the broadcast channel
  757. // to the ethernet VC).
  758. //
  759. TR_INFO(
  760. ("Rcv: pPkt 0x%x: EtherType is IP, passing up.\n", pNdisPacket));
  761. ARP_IF_STAT_INCR(pIF, InNonUnicastPkts);
  762. LOGSTATS_CopyRecvs(pIF, pNdisPacket);
  763. #if MILLEN
  764. ASSERT_PASSIVE();
  765. #endif // MILLEN
  766. pIF->ip.RcvHandler(
  767. pIF->ip.Context,
  768. (PVOID)((PUCHAR)pEthHeader+sizeof(*pEthHeader)),
  769. BufferLength - MacHeaderLength,
  770. TotalLength - MacHeaderLength,
  771. (NDIS_HANDLE)pNdisPacket,
  772. MacHeaderLength,
  773. FALSE, // FALSE == NOT received via broadcast.
  774. // Important, because we are reflecting directed
  775. // packets up to IP. If we report TRUE here,
  776. // IP assumes it's not a directed packet, and
  777. // handles it differently.
  778. NULL
  779. );
  780. }
  781. else
  782. {
  783. //
  784. // Discard packet -- unknown/bad EtherType
  785. //
  786. TR_INFO(("Encap hdr 0x%x, bad EtherType 0x%x\n",
  787. pEthHeader, pEthHeader->eh_type));
  788. ARP_IF_STAT_INCR(pIF, UnknownProtos);
  789. }
  790. } while (FALSE);
  791. EXIT()
  792. return;
  793. }
  794. VOID
  795. arpEthProcess1394ArpPkt(
  796. IN PARP1394_INTERFACE pIF,
  797. IN PIP1394_ARP_PKT pArpPkt,
  798. IN UINT HeaderSize
  799. )
  800. /*++
  801. Process an ip/1394 ARP packet. We do the following:
  802. 0. Parse the paket
  803. 1. Update our local RemoteIP cache.
  804. 2. Create and send an equivalent ethernet arp pkt on the ethernet VC.
  805. (We look up the destination ethernet address in our ethernet cache)
  806. This function must only be called when the adapter is in "Bridged mode."
  807. --*/
  808. {
  809. IP1394_ARP_PKT_INFO Ip1394PktInfo;
  810. ETH_ARP_PKT_INFO EthArpInfo;
  811. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  812. ARP_DEST_PARAMS DestParams;
  813. PARP1394_ADAPTER pAdapter =(PARP1394_ADAPTER ) RM_PARENT_OBJECT(pIF);
  814. ENetAddr SenderEnetAddress;
  815. IPAddr SenderIpAddress = 0;
  816. REMOTE_DEST_KEY RemoteDestKey;
  817. ENTER("arpEthProcess1394ArpPkt", 0x0)
  818. RM_DECLARE_STACK_RECORD(Sr)
  819. ARP_ZEROSTRUCT(&DestParams);
  820. do {
  821. PNDIS_PACKET pPkt = NULL;
  822. PVOID pvData = NULL;
  823. Status = arpParseArpPkt(
  824. pArpPkt,
  825. HeaderSize,
  826. &Ip1394PktInfo
  827. );
  828. if (FAIL(Status))
  829. {
  830. TR_WARN(("Failed parse of received 1394 ARP PKT.\n"));
  831. break;
  832. }
  833. DestParams.HwAddr.AddressType = NIC1394AddressType_FIFO;
  834. DestParams.HwAddr.FifoAddress = Ip1394PktInfo.SenderHwAddr; // Struct copy
  835. REMOTE_DEST_KEY_INIT(&RemoteDestKey);
  836. if ((ARP_BRIDGE_ENABLED(pAdapter) == TRUE) &&
  837. (Ip1394PktInfo.fPktHasNodeAddress == FALSE))
  838. {
  839. // We do not have the sender's Node ID -- fail.
  840. TR_WARN (("Did not Receive Sender's Node ID in Pkt"))
  841. Status = NDIS_STATUS_FAILURE;
  842. break;
  843. }
  844. if (ARP_BRIDGE_ENABLED(pAdapter) == TRUE)
  845. {
  846. // Extract the Source Mac address using the Sender Node Address
  847. Status = arpGetSourceMacAddressFor1394Pkt(pAdapter,
  848. Ip1394PktInfo.SourceNodeAdddress,
  849. TRUE,
  850. &Ip1394PktInfo.SourceMacAddress,
  851. &Sr);
  852. RemoteDestKey.ENetAddress = Ip1394PktInfo.SourceMacAddress;
  853. }
  854. else
  855. {
  856. RemoteDestKey.IpAddress = Ip1394PktInfo.SenderIpAddress;
  857. Status = NDIS_STATUS_SUCCESS;
  858. }
  859. if (Status != NDIS_STATUS_SUCCESS)
  860. {
  861. TR_WARN (("Unable to get valid Source MAC Address from Pkt"))
  862. Status = NDIS_STATUS_SUCCESS;
  863. break;
  864. }
  865. // Update our 1394 ARP cache.
  866. //
  867. arpUpdateArpCache(
  868. pIF,
  869. RemoteDestKey.IpAddress , // Remote IP Address
  870. &RemoteDestKey.ENetAddress,
  871. &DestParams, // Remote Destination HW Address
  872. TRUE, // Update even if we don't already have an entry
  873. &Sr
  874. );
  875. Status = arpConstructEthArpInfoFrom1394ArpInfo(
  876. pIF,
  877. &Ip1394PktInfo,
  878. &EthArpInfo,
  879. &Sr
  880. );
  881. if (FAIL(Status)) break;
  882. // Allocate an appropriately sized control packet.
  883. //
  884. Status = arpAllocateControlPacket(
  885. pIF,
  886. sizeof(ETH_ARP_PKT),
  887. ARP1394_PACKET_FLAGS_ICS,
  888. &pPkt,
  889. &pvData,
  890. &Sr
  891. );
  892. if (FAIL(Status))
  893. {
  894. ASSERT(FALSE); // we want to know if we hit this in regular use.
  895. pPkt = NULL;
  896. break;
  897. }
  898. NdisInterlockedIncrement (&Arp1394ToIcs);
  899. // Fill it out..
  900. //
  901. arpPrepareEthArpPkt(
  902. &EthArpInfo,
  903. (PETH_ARP_PKT) pvData
  904. );
  905. // Send the packet over the ethernet VC...
  906. //
  907. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  908. arpSendControlPkt(
  909. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  910. pPkt,
  911. pIF->pEthernetDest,
  912. &Sr
  913. );
  914. } while (FALSE);
  915. RM_ASSERT_CLEAR(&Sr);
  916. }
  917. VOID
  918. arpEthProcessEthArpPkt(
  919. IN PARP1394_INTERFACE pIF,
  920. IN PETH_ARP_PKT pArpPkt,
  921. IN UINT HeaderSize
  922. )
  923. /*++
  924. Process an Ethernet ARP packet. We do the following:
  925. 0. Parse the packet
  926. 1. Update our local ethernet arp cache.
  927. 2. Create and send an equivalent 1394 arp pkt on the broadcast VC.
  928. (We look up the destination ethernet address in our ethernet cache)
  929. This function must only be called when the adapter is in "Bridged mode."
  930. --*/
  931. {
  932. ETH_ARP_PKT_INFO EthPktInfo;
  933. IP1394_ARP_PKT_INFO Ip1394ArpInfo;
  934. NDIS_STATUS Status;
  935. ARP_REMOTE_ETH_PARAMS CreateParams;
  936. ENTER("arpEthProcessEthArpPkt", 0x0)
  937. RM_DECLARE_STACK_RECORD(Sr)
  938. ARP_ZEROSTRUCT(&CreateParams);
  939. do {
  940. PNDIS_PACKET pPkt = NULL;
  941. PVOID pvData = NULL;
  942. Status = arpParseEthArpPkt(
  943. pArpPkt,
  944. HeaderSize,
  945. &EthPktInfo
  946. );
  947. if (FAIL(Status))
  948. {
  949. TR_WARN(("Failed parse of received Ethernet ARP PKT.\n"));
  950. break;
  951. }
  952. Status = arpConstruct1394ArpInfoFromEthArpInfo(
  953. pIF,
  954. &EthPktInfo,
  955. &Ip1394ArpInfo,
  956. &Sr
  957. );
  958. if (FAIL(Status)) break;
  959. // Allocate an appropriately sized control packet.
  960. //
  961. Status = arpAllocateControlPacket(
  962. pIF,
  963. sizeof(IP1394_ARP_PKT),
  964. ARP1394_PACKET_FLAGS_ICS,
  965. &pPkt,
  966. &pvData,
  967. &Sr
  968. );
  969. if (FAIL(Status))
  970. {
  971. ASSERT(FALSE); // we want to know if we hit this in regular use.
  972. pPkt = NULL;
  973. break;
  974. }
  975. // Fill it out..
  976. //
  977. arpPrepareArpPkt(
  978. &Ip1394ArpInfo,
  979. (PIP1394_ARP_PKT) pvData
  980. );
  981. // Send the packet over the ethernet VC...
  982. //
  983. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  984. arpSendControlPkt(
  985. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  986. pPkt,
  987. pIF->pBroadcastDest,
  988. &Sr
  989. );
  990. } while (FALSE);
  991. RM_ASSERT_CLEAR(&Sr);
  992. }
  993. NDIS_STATUS
  994. arpParseEthArpPkt(
  995. IN PETH_ARP_PKT pArpPkt,
  996. IN UINT cbBufferSize,
  997. OUT PETH_ARP_PKT_INFO pPktInfo
  998. )
  999. /*++
  1000. Routine Description:
  1001. Parse the contents of IP/Ethernet ARP packet data starting at
  1002. pArpPkt. Place the results into pPktInfo.
  1003. Arguments:
  1004. pArpPkt - Contains the unaligned contents of an ip/eth ARP Pkt.
  1005. pPktInfo - Unitialized structure to be filled with the parsed contents of the
  1006. pkt.
  1007. Return Value:
  1008. NDIS_STATUS_FAILURE if the parse failed (typically because of invalid pkt
  1009. contents.)
  1010. NDIS_STATUS_SUCCESS on successful parsing.
  1011. --*/
  1012. {
  1013. ENTER("arpParseEthArpPkt", 0x359e9bf2)
  1014. NDIS_STATUS Status;
  1015. DBGSTMT(CHAR *szError = "General failure";)
  1016. Status = NDIS_STATUS_FAILURE;
  1017. do
  1018. {
  1019. UINT OpCode;
  1020. // Verify length.
  1021. //
  1022. if (cbBufferSize < sizeof(*pArpPkt))
  1023. {
  1024. DBGSTMT(szError = "pkt size too small";)
  1025. break;
  1026. }
  1027. // Verify constant fields.
  1028. //
  1029. if (N2H_USHORT(pArpPkt->header.eh_type) != ARP_ETH_ETYPE_ARP)
  1030. {
  1031. DBGSTMT(szError = "header.eh_type!=ARP";)
  1032. break;
  1033. }
  1034. #if 0
  1035. ARP_ETH_HW_ENET OR ARP_ETH_HW_802
  1036. if (N2H_USHORT(pArpPkt->hardware_type) != IP1394_HARDWARE_TYPE)
  1037. {
  1038. DBGSTMT(szError = "Invalid hardware_type";)
  1039. break;
  1040. }
  1041. #endif // 0
  1042. // ARP_ETH_ETYPE_IP ARP_ETH_ETYPE_ARP
  1043. if (N2H_USHORT(pArpPkt->protocol_type) != ARP_ETH_ETYPE_IP)
  1044. {
  1045. DBGSTMT(szError = "Invalid protocol_type";)
  1046. break;
  1047. }
  1048. if (pArpPkt->hw_addr_len != ARP_802_ADDR_LENGTH)
  1049. {
  1050. DBGSTMT(szError = "Invalid hw_addr_len";)
  1051. break;
  1052. }
  1053. if (pArpPkt->IP_addr_len != sizeof(ULONG))
  1054. {
  1055. DBGSTMT(szError = "Invalid IP_addr_len";)
  1056. break;
  1057. }
  1058. // Opcode
  1059. //
  1060. {
  1061. OpCode = N2H_USHORT(pArpPkt->opcode);
  1062. if ( OpCode != ARP_ETH_REQUEST
  1063. && OpCode != ARP_ETH_RESPONSE)
  1064. {
  1065. DBGSTMT(szError = "Invalid opcode";)
  1066. break;
  1067. }
  1068. }
  1069. //
  1070. // Pkt appears valid, let's fill out the parsed information....
  1071. //
  1072. ARP_ZEROSTRUCT(pPktInfo);
  1073. pPktInfo->SourceEthAddress = pArpPkt->header.eh_saddr; // struct copy.
  1074. pPktInfo->DestEthAddress = pArpPkt->header.eh_daddr; // struct copy.
  1075. pPktInfo->OpCode = (USHORT) OpCode;
  1076. // These remain network byte order...
  1077. //
  1078. pPktInfo->SenderIpAddress = (IP_ADDRESS) pArpPkt->sender_IP_address;
  1079. pPktInfo->TargetIpAddress = (IP_ADDRESS) pArpPkt->target_IP_address;
  1080. pPktInfo->SenderEthAddress = pArpPkt->sender_hw_address; // struct copy
  1081. pPktInfo->TargetEthAddress = pArpPkt->target_hw_address; // struct copy
  1082. Status = NDIS_STATUS_SUCCESS;
  1083. } while (FALSE);
  1084. if (FAIL(Status))
  1085. {
  1086. TR_INFO(("Bad arp pkt data at 0x%p (%s)\n", pArpPkt, szError));
  1087. }
  1088. else
  1089. {
  1090. PUCHAR pSip = (PUCHAR)&pPktInfo->SenderIpAddress;
  1091. PUCHAR pTip = (PUCHAR)&pPktInfo->TargetIpAddress;
  1092. TR_VERB(("Received ETH ARP PKT. OP=%lu SIP=%d.%d.%d.%d TIP=%d.%d.%d.%d.\n",
  1093. pPktInfo->OpCode,
  1094. pSip[0],pSip[1],pSip[2],pSip[3],
  1095. pTip[0],pTip[1],pTip[2],pTip[3]
  1096. ));
  1097. }
  1098. EXIT()
  1099. return Status;
  1100. }
  1101. VOID
  1102. arpPrepareEthArpPkt(
  1103. IN PETH_ARP_PKT_INFO pPktInfo,
  1104. OUT PETH_ARP_PKT pArpPkt
  1105. )
  1106. /*++
  1107. Routine Description:
  1108. Use information in pArpPktInfo to prepare an ethernet arp packet starting at
  1109. pvArpPkt.
  1110. Arguments:
  1111. pPktInfo - Parsed version of the eth arp request/response packet.
  1112. pArpPkt - unitialized memory in which to store the packet contents.
  1113. This memory must have a min size of sizeof(*pArpPkt).
  1114. --*/
  1115. {
  1116. // UINT SenderMaxRec;
  1117. UINT OpCode;
  1118. ARP_ZEROSTRUCT(pArpPkt);
  1119. pArpPkt->header.eh_type = H2N_USHORT(ARP_ETH_ETYPE_ARP);
  1120. pArpPkt->header.eh_daddr = pPktInfo->DestEthAddress;
  1121. pArpPkt->header.eh_saddr = pPktInfo->SourceEthAddress;
  1122. pArpPkt->hardware_type = H2N_USHORT(ARP_ETH_HW_ENET); // TODO
  1123. // we always set the type
  1124. // to ARP_ETH_HW_ENET -- not sure
  1125. // if this a valid assumption or
  1126. // if we need to query the NIC.
  1127. pArpPkt->protocol_type = H2N_USHORT(ARP_ETH_ETYPE_IP);
  1128. pArpPkt->hw_addr_len = (UCHAR) ARP_802_ADDR_LENGTH;
  1129. pArpPkt->IP_addr_len = (UCHAR) sizeof(ULONG);
  1130. pArpPkt->opcode = H2N_USHORT(pPktInfo->OpCode);
  1131. // These are already in network byte order...
  1132. //
  1133. pArpPkt->sender_IP_address = (ULONG) pPktInfo->SenderIpAddress;
  1134. pArpPkt->target_IP_address = (ULONG) pPktInfo->TargetIpAddress;
  1135. pArpPkt->sender_hw_address = pPktInfo->SenderEthAddress; // struct copy
  1136. pArpPkt->target_hw_address = pPktInfo->TargetEthAddress; // struct copy
  1137. }
  1138. UINT
  1139. arpEthernetReceivePacket(
  1140. IN NDIS_HANDLE ProtocolBindingContext,
  1141. IN NDIS_HANDLE ProtocolVcContext,
  1142. IN PNDIS_PACKET pNdisPacket
  1143. )
  1144. /*++
  1145. NDIS Co receive packet for the ethernet VC.
  1146. We do the following:
  1147. If it's an ARP packet, we translate it and send it on the bcast channel.
  1148. Else if it was a ethernet unicast packet, we change the header
  1149. and treat it like an IP unicast packet -- SlowIpTransmit
  1150. Else we change the header and then send it on the bcast desination.
  1151. --*/
  1152. {
  1153. PARP_VC_HEADER pVcHdr;
  1154. PARPCB_DEST pDest;
  1155. PARP1394_INTERFACE pIF;
  1156. ARP1394_ADAPTER * pAdapter;
  1157. ENetHeader *pEthHdr;
  1158. UINT TotalLength; // Total bytes in packet
  1159. PNDIS_BUFFER pNdisBuffer; // Pointer to first buffer
  1160. UINT BufferLength;
  1161. PVOID pvPktHeader;
  1162. const UINT MacHeaderLength = sizeof(ENetHeader);
  1163. MYBOOL fBridgeMode;
  1164. MYBOOL fUnicast;
  1165. MYBOOL fIsSTAPacket;
  1166. ENTER("arpEthernetReceivePacket", 0x0)
  1167. RM_DECLARE_STACK_RECORD(sr)
  1168. DBGMARK(0x72435b28);
  1169. #if TESTPROGRAM
  1170. {
  1171. extern ARP1394_INTERFACE * g_pIF;
  1172. pIF = g_pIF;
  1173. }
  1174. #else // !TESTPROGRAM
  1175. pVcHdr = (PARP_VC_HEADER) ProtocolVcContext;
  1176. pDest = CONTAINING_RECORD( pVcHdr, ARPCB_DEST, VcHdr);
  1177. ASSERT_VALID_DEST(pDest);
  1178. pIF = (ARP1394_INTERFACE*) RM_PARENT_OBJECT(pDest);
  1179. #endif // TESTPROGRAM
  1180. ASSERT_VALID_INTERFACE(pIF);
  1181. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1182. fBridgeMode = ARP_BRIDGE_ENABLED(pAdapter);
  1183. do
  1184. {
  1185. if (!fBridgeMode) // This is really only for MILL
  1186. {
  1187. #if MILLEN
  1188. arpIcsForwardIpPacket(
  1189. pIF,
  1190. pNdisPacket,
  1191. ARP_ICS_FORWARD_TO_1394,
  1192. FALSE, // FALSE == NonUnicast
  1193. &sr
  1194. );
  1195. #endif // MILLEN
  1196. break;
  1197. }
  1198. NdisQueryPacket(
  1199. pNdisPacket,
  1200. NULL,
  1201. NULL,
  1202. &pNdisBuffer,
  1203. &TotalLength
  1204. );
  1205. if (TotalLength > 0)
  1206. {
  1207. NdisQueryBuffer(
  1208. pNdisBuffer,
  1209. (PVOID *)&pvPktHeader,
  1210. &BufferLength
  1211. );
  1212. }
  1213. else
  1214. {
  1215. break;
  1216. }
  1217. TR_VERB(
  1218. ("Eth Rcv: NDISpkt 0x%x, NDISbuf 0x%x, Buflen %d, Totlen %d, Pkthdr 0x%x\n",
  1219. pNdisPacket,
  1220. pNdisBuffer,
  1221. BufferLength,
  1222. TotalLength,
  1223. pvPktHeader));
  1224. if (BufferLength < MacHeaderLength)
  1225. {
  1226. // Packet is too small, discard.
  1227. //
  1228. break;
  1229. }
  1230. if (pvPktHeader == NULL)
  1231. {
  1232. break;
  1233. }
  1234. pEthHdr = (ENetHeader*) pvPktHeader;
  1235. fUnicast = arpIsUnicastEthDest(pEthHdr);
  1236. switch(N2H_USHORT(pEthHdr->eh_type))
  1237. {
  1238. case ARP_ETH_ETYPE_ARP:
  1239. {
  1240. PETH_ARP_PKT pArpPkt = (PETH_ARP_PKT) pEthHdr;
  1241. if (BufferLength < sizeof(*pArpPkt))
  1242. {
  1243. // discard packet.
  1244. break;
  1245. }
  1246. arpEthProcessEthArpPkt(pIF, pArpPkt, BufferLength);
  1247. }
  1248. break;
  1249. case ARP_ETH_ETYPE_IP:
  1250. {
  1251. //
  1252. // The EtherType is IP, so we translate the header and
  1253. // send if of on the appropriate 1394 FIFO vc.
  1254. //
  1255. if (fUnicast)
  1256. {
  1257. PNDIS_PACKET pNewPkt = NULL;
  1258. IP_ADDRESS IpDest;
  1259. NDIS_STATUS Status;
  1260. REMOTE_DEST_KEY Dest;
  1261. // is this meant for the 1394 net.
  1262. REMOTE_DEST_KEY_INIT(&Dest);
  1263. //
  1264. // Create the translated packet.
  1265. //
  1266. Status = arpIcsTranslateIpPkt(
  1267. pIF,
  1268. pNdisPacket,
  1269. ARP_ICS_FORWARD_TO_1394,
  1270. TRUE, // TRUE == fUnicast.
  1271. &pNewPkt,
  1272. &Dest,
  1273. &sr
  1274. );
  1275. if (FAIL(Status))
  1276. {
  1277. break;
  1278. }
  1279. Status = arpSlowIpTransmit(
  1280. pIF,
  1281. pNewPkt,
  1282. Dest,
  1283. NULL // RCE
  1284. );
  1285. if (!PEND(Status))
  1286. {
  1287. // We need to deallocate the packet ourselves
  1288. //
  1289. arpFreeControlPacket(
  1290. pIF,
  1291. pNewPkt,
  1292. &sr
  1293. );
  1294. }
  1295. }
  1296. else
  1297. {
  1298. // This is a broadcast or multicast IP packet -- swith
  1299. // the link-layer header and send it over the 1394
  1300. // broadcast channel.
  1301. //
  1302. arpIcsForwardIpPacket(
  1303. pIF,
  1304. pNdisPacket,
  1305. ARP_ICS_FORWARD_TO_1394,
  1306. FALSE, // FALSE == NonUnicast
  1307. &sr
  1308. );
  1309. }
  1310. }
  1311. break;
  1312. default:
  1313. //
  1314. // Last option is that it could be a Bridge STA packet.
  1315. // However the bridge does not use an Ethertype, so we
  1316. // have to check the destination mac address
  1317. //
  1318. fIsSTAPacket = (TRUE == NdisEqualMemory (&pEthHdr->eh_daddr,
  1319. &gSTAMacAddr,
  1320. ETH_LENGTH_OF_ADDRESS) );
  1321. if (fIsSTAPacket == TRUE)
  1322. {
  1323. //
  1324. // switch the link-layer header and send it over the 1394
  1325. // broadcast channel.
  1326. //
  1327. arpIcsForwardIpPacket(
  1328. pIF,
  1329. pNdisPacket,
  1330. ARP_ICS_FORWARD_TO_1394,
  1331. FALSE, // FALSE == NonUnicast
  1332. &sr );
  1333. }
  1334. break;
  1335. }
  1336. } while (FALSE);
  1337. RM_ASSERT_CLEAR(&sr);
  1338. return 0;
  1339. }
  1340. VOID
  1341. arpEthReceive1394Packet(
  1342. IN PARP1394_INTERFACE pIF,
  1343. IN PNDIS_PACKET pNdisPacket,
  1344. IN PVOID pvHeader,
  1345. IN UINT HeaderSize,
  1346. IN MYBOOL IsChannel
  1347. )
  1348. /*++
  1349. Handle an incoming packet from the 1394 side when in bridged mode.
  1350. pEncapHeader -- the 1st buffer in the packet.
  1351. --*/
  1352. {
  1353. PNIC1394_ENCAPSULATION_HEADER pEncapHeader;
  1354. ENTER("arpEthReceived1394Packet", 0xe317990b)
  1355. RM_DECLARE_STACK_RECORD(sr)
  1356. pEncapHeader = (PNIC1394_ENCAPSULATION_HEADER) pvHeader;
  1357. do
  1358. {
  1359. //
  1360. // Discard the packet if the adapter is not active
  1361. //
  1362. if (!CHECK_IF_ACTIVE_STATE(pIF, ARPAD_AS_ACTIVATED))
  1363. {
  1364. TR_INFO(("Eth:Discardning received 1394 pkt because pIF 0x%p is not activated.\n", pIF));
  1365. break;
  1366. }
  1367. if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_IP))
  1368. {
  1369. LOGSTATS_CopyRecvs(pIF, pNdisPacket);
  1370. //
  1371. // The EtherType is IP, so we translate the header and
  1372. // send it off on the ethernet vc.
  1373. //
  1374. arpIcsForwardIpPacket(
  1375. pIF,
  1376. pNdisPacket,
  1377. ARP_ICS_FORWARD_TO_ETHERNET,
  1378. !IsChannel,
  1379. &sr
  1380. );
  1381. }
  1382. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_ARP))
  1383. {
  1384. PIP1394_ARP_PKT pArpPkt = (PIP1394_ARP_PKT) pEncapHeader;
  1385. if (HeaderSize < sizeof(*pArpPkt))
  1386. {
  1387. // discard packet.
  1388. break;
  1389. }
  1390. arpEthProcess1394ArpPkt(pIF, pArpPkt, HeaderSize);
  1391. }
  1392. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_MCAP))
  1393. {
  1394. PIP1394_MCAP_PKT pMcapPkt = (PIP1394_MCAP_PKT) pEncapHeader;
  1395. arpProcessMcapPkt(
  1396. pIF,
  1397. pMcapPkt,
  1398. HeaderSize
  1399. );
  1400. }
  1401. else if (pEncapHeader->EtherType == H2N_USHORT(NIC1394_ETHERTYPE_STA))
  1402. {
  1403. //
  1404. // The EtherType is STA, so we translate the header and
  1405. // send it off on the ethernet vc.
  1406. //
  1407. arpIcsForwardIpPacket(
  1408. pIF,
  1409. pNdisPacket,
  1410. ARP_ICS_FORWARD_TO_ETHERNET,
  1411. IsChannel,
  1412. &sr
  1413. );
  1414. }
  1415. else
  1416. {
  1417. //
  1418. // Discard packet -- unknown/bad EtherType
  1419. //
  1420. TR_INFO(("Encap hdr 0x%x, bad EtherType 0x%x\n",
  1421. pEncapHeader, pEncapHeader->EtherType));
  1422. }
  1423. } while (FALSE);
  1424. EXIT()
  1425. RM_ASSERT_CLEAR(&sr);
  1426. return;
  1427. }
  1428. MYBOOL
  1429. arpIsUnicastEthDest(
  1430. IN UNALIGNED ENetHeader *pEthHdr
  1431. )
  1432. /*++
  1433. Returns TRUE IFF the packet is either ethernet broadcast or
  1434. multicast.
  1435. //
  1436. // TODO: there's probably a quicker check (single bit?).
  1437. //
  1438. --*/
  1439. {
  1440. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  1441. &BroadcastENetAddr,
  1442. sizeof(ENetAddr)))
  1443. {
  1444. // Broadcast address
  1445. //
  1446. return FALSE;
  1447. }
  1448. if (NdisEqualMemory(&pEthHdr->eh_daddr,
  1449. &MulticastENetAddr,
  1450. 3))
  1451. {
  1452. // 1st 3 bytes match our Ethernet multicast address template, so we
  1453. // conclude that this is a multicast address.
  1454. // TODO: verify this check.
  1455. //
  1456. return FALSE;
  1457. }
  1458. return TRUE;
  1459. }
  1460. NDIS_STATUS
  1461. arpGetEthAddrFromIpAddr(
  1462. IN PARP1394_INTERFACE pIF,
  1463. IN MYBOOL fUnicast,
  1464. IN IP_ADDRESS DestIpAddress,
  1465. OUT ENetAddr *pEthAddr,
  1466. PRM_STACK_RECORD pSR
  1467. )
  1468. /*++
  1469. The destination address is set as follows:
  1470. if (fUnicast)
  1471. {
  1472. We look up our ethernet arp cache (pIF->RemoteEthGroup) and
  1473. if we find an entry there, we use the MAC address in that entry.
  1474. If we don't find, we fail this function.
  1475. }
  1476. else
  1477. {
  1478. if (destination IP address is class D)
  1479. {
  1480. we create the corresponding MAC address (based on the standard
  1481. formula for mapping IPv4 multicast addresses to MAC addresses).
  1482. }
  1483. else
  1484. {
  1485. we set the destination address to broadcast (all 0xff's).
  1486. (NOTE: we easily determine if the IP address is a broadast
  1487. address because we don't have the subnet mask, so instead we
  1488. assume that it's a broadcast destination if it's not class D
  1489. and it came over the broadcast channel (i.e. fUnicast == FALSE))
  1490. }
  1491. }
  1492. --*/
  1493. {
  1494. ENTER("arpGetEthAddrFromIpAddr", 0x0)
  1495. ARP1394_ADAPTER * pAdapter;
  1496. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1497. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1498. do
  1499. {
  1500. if (fUnicast)
  1501. {
  1502. // Lookup the ethernet MAC address in the MAC arp cache.
  1503. //
  1504. *pEthAddr = pAdapter->info.EthernetMacAddress;
  1505. Status = NDIS_STATUS_SUCCESS;
  1506. }
  1507. else
  1508. {
  1509. //
  1510. // Set the destination address to Multicast if dest IP is
  1511. // class D, else multicast
  1512. //
  1513. if (CLASSD_ADDR(DestIpAddress))
  1514. {
  1515. //
  1516. // Construct the corresponding multicast ethernet address.
  1517. // This code is adapted from tcpip\arp.c
  1518. //
  1519. // Basically we copy over a "template" of the multicast
  1520. // address, and then or-in the LSB 23 bits (in network byte
  1521. // order) of the ip address.
  1522. //
  1523. #define ARP_MCAST_MASK 0xffff7f00
  1524. UINT UNALIGNED *pTmp;
  1525. *pEthAddr = MulticastENetAddr; // struct copy.
  1526. pTmp = (UINT UNALIGNED *) & pEthAddr->addr[2];
  1527. *pTmp |= (DestIpAddress & ARP_MCAST_MASK);
  1528. }
  1529. else
  1530. {
  1531. //
  1532. // We assume DestIpAddress is a broadcast address -- see
  1533. // comments at the head of this function
  1534. //
  1535. *pEthAddr = BroadcastENetAddr; // struct copy
  1536. }
  1537. }
  1538. Status = NDIS_STATUS_SUCCESS;
  1539. } while (FALSE);
  1540. return Status;
  1541. }
  1542. NDIS_STATUS
  1543. arpConstructEthArpInfoFrom1394ArpInfo(
  1544. IN PARP1394_INTERFACE pIF,
  1545. IN PIP1394_ARP_PKT_INFO p1394PktInfo,
  1546. OUT PETH_ARP_PKT_INFO pEthPktInfo,
  1547. PRM_STACK_RECORD pSR
  1548. )
  1549. /*++
  1550. Translate a parsed version of an Ethernet ARP packet into
  1551. the parsed version of an equivalent 1394 arp packet.
  1552. We ALWAYS set the source ethernet address AND the target ethernet
  1553. address to OUR ethernet MAC address. So other ethernet nodes think of
  1554. us as a a single ethernet mic which hosts a whole bunch of IP addresses.
  1555. We COULD use our proprietary algorithm to convert from EU64 ID to MAC
  1556. addresses and then use those for the target addresses, but we're not
  1557. sure of the ramifications of that in the bridge mode.
  1558. --*/
  1559. {
  1560. ENTER("arpConstructEthArpInfoFrom1394ArpInfo", 0x8214aa14)
  1561. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1562. ENetAddr SourceMacAddress;
  1563. do
  1564. {
  1565. MYBOOL fUnicast;
  1566. IP_ADDRESS IpDest;
  1567. ARP1394_ADAPTER * pAdapter;
  1568. UINT Ip1394OpCode = p1394PktInfo->OpCode;
  1569. UINT EthOpCode;
  1570. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1571. ARP_ZEROSTRUCT(pEthPktInfo);
  1572. if (Ip1394OpCode == IP1394_ARP_REQUEST)
  1573. {
  1574. fUnicast = FALSE;
  1575. IpDest = 0xFFFFFFFF; // IP broadcast address.
  1576. EthOpCode= ARP_ETH_REQUEST;
  1577. }
  1578. else
  1579. {
  1580. // TODO: We expect TargetIpAddress to contain the address
  1581. // of the arp request that resulted in this reply. This
  1582. // is not per ip/1394 spec, which says that the TargetIpAddress
  1583. // is to be ignored. However Kaz has suggested that we
  1584. // utilize this field in this way -- search for "Kaz" in
  1585. // arp.c
  1586. //
  1587. // If we can't rely on this, then we must either
  1588. // (a) BROADCAST arp replies over ethernet OR
  1589. // (b) keep track of outstanding arp requests which need replies.
  1590. //
  1591. fUnicast = TRUE;
  1592. IpDest = p1394PktInfo->TargetIpAddress;
  1593. EthOpCode= ARP_ETH_RESPONSE;
  1594. }
  1595. Status = arpGetSourceMacAddressFor1394Pkt (pAdapter,
  1596. p1394PktInfo->SourceNodeAdddress,
  1597. p1394PktInfo->fPktHasNodeAddress,
  1598. &SourceMacAddress,
  1599. pSR );
  1600. if (FAIL(Status))
  1601. {
  1602. break;
  1603. }
  1604. pEthPktInfo->SourceEthAddress = SourceMacAddress ;
  1605. pEthPktInfo->SenderEthAddress = SourceMacAddress ;
  1606. pEthPktInfo->TargetEthAddress = pAdapter->info.EthernetMacAddress;
  1607. Status = arpGetEthAddrFromIpAddr(
  1608. pIF,
  1609. fUnicast,
  1610. IpDest,
  1611. &pEthPktInfo->DestEthAddress,
  1612. pSR
  1613. );
  1614. if (FAIL(Status))
  1615. {
  1616. break;
  1617. }
  1618. pEthPktInfo->OpCode = EthOpCode;
  1619. pEthPktInfo->SenderIpAddress = p1394PktInfo->SenderIpAddress;
  1620. pEthPktInfo->TargetIpAddress = p1394PktInfo->TargetIpAddress;
  1621. Status = NDIS_STATUS_SUCCESS;
  1622. {
  1623. UCHAR pIp[4];
  1624. TR_WARN(("Received Arp - "));
  1625. if (EthOpCode == ARP_ETH_RESPONSE)
  1626. {
  1627. TR_WARN(("Response\n"));
  1628. }
  1629. else
  1630. {
  1631. TR_WARN (("Request\n"));
  1632. }
  1633. NdisMoveMemory (&pIp[0], &pEthPktInfo->SenderIpAddress, sizeof(IPAddr) );
  1634. TR_WARN(("Ethernet Source %x %x %x %x %x %x,IP source %d %d %d %d \n ",
  1635. pEthPktInfo->SourceEthAddress.addr[0],
  1636. pEthPktInfo->SourceEthAddress.addr[1],
  1637. pEthPktInfo->SourceEthAddress.addr[2],
  1638. pEthPktInfo->SourceEthAddress.addr[3],
  1639. pEthPktInfo->SourceEthAddress.addr[4],
  1640. pEthPktInfo->SourceEthAddress.addr[5],
  1641. pIp[0],
  1642. pIp[1],
  1643. pIp[2],
  1644. pIp[3]));
  1645. NdisMoveMemory (&pIp[0], &pEthPktInfo->TargetIpAddress, sizeof(IPAddr) );
  1646. TR_WARN(("Ethernet Target %x %x %x %x %x %x , IP Target %d %d %d %d \n",
  1647. pEthPktInfo->TargetEthAddress.addr[0],
  1648. pEthPktInfo->TargetEthAddress.addr[1],
  1649. pEthPktInfo->TargetEthAddress.addr[2],
  1650. pEthPktInfo->TargetEthAddress.addr[3],
  1651. pEthPktInfo->TargetEthAddress.addr[4],
  1652. pEthPktInfo->TargetEthAddress.addr[5],
  1653. pIp[0],
  1654. pIp[1],
  1655. pIp[2],
  1656. pIp[3]));
  1657. TR_WARN(("Ethernet Dest %x %x %x %x %x %x \n",
  1658. pEthPktInfo->DestEthAddress.addr[0],
  1659. pEthPktInfo->DestEthAddress.addr[1],
  1660. pEthPktInfo->DestEthAddress.addr[2],
  1661. pEthPktInfo->DestEthAddress.addr[3],
  1662. pEthPktInfo->DestEthAddress.addr[4],
  1663. pEthPktInfo->DestEthAddress.addr[5]));
  1664. TR_WARN(("Ethernet Sender %x %x %x %x %x %x \n\n",
  1665. pEthPktInfo->SenderEthAddress.addr[0],
  1666. pEthPktInfo->SenderEthAddress.addr[1],
  1667. pEthPktInfo->SenderEthAddress.addr[2],
  1668. pEthPktInfo->SenderEthAddress.addr[3],
  1669. pEthPktInfo->SenderEthAddress.addr[4],
  1670. pEthPktInfo->SenderEthAddress.addr[5]));
  1671. }
  1672. } while (FALSE);
  1673. return Status;
  1674. }
  1675. NDIS_STATUS
  1676. arpConstruct1394ArpInfoFromEthArpInfo(
  1677. IN PARP1394_INTERFACE pIF,
  1678. IN PETH_ARP_PKT_INFO pEthPktInfo,
  1679. OUT PIP1394_ARP_PKT_INFO p1394PktInfo,
  1680. PRM_STACK_RECORD pSR
  1681. )
  1682. /*++
  1683. Translate a parsed version of an IP1394 ARP packet into
  1684. the parsed version of an equivalent Ethernet arp packet.
  1685. We always report our own adapter info as the hw/specific info
  1686. in the arp packet. We do this for both arp requests and responses.
  1687. This means that we look like a single host with multiple ip addresses
  1688. to other ip/1394 nodes.
  1689. --*/
  1690. {
  1691. ARP1394_ADAPTER * pAdapter;
  1692. UINT Ip1394OpCode;
  1693. UINT EthOpCode = pEthPktInfo->OpCode;
  1694. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1695. ARP_ZEROSTRUCT(p1394PktInfo);
  1696. if (EthOpCode == ARP_ETH_REQUEST)
  1697. {
  1698. Ip1394OpCode= IP1394_ARP_REQUEST;
  1699. }
  1700. else
  1701. {
  1702. Ip1394OpCode= IP1394_ARP_RESPONSE;
  1703. }
  1704. p1394PktInfo->OpCode = Ip1394OpCode;
  1705. p1394PktInfo->SenderIpAddress = pEthPktInfo->SenderIpAddress;
  1706. p1394PktInfo->TargetIpAddress = pEthPktInfo->TargetIpAddress;
  1707. // Fill out adapter info..
  1708. //
  1709. p1394PktInfo->SenderHwAddr.UniqueID = pAdapter->info.LocalUniqueID;
  1710. p1394PktInfo->SenderHwAddr.Off_Low = pIF->recvinfo.offset.Off_Low;
  1711. p1394PktInfo->SenderHwAddr.Off_High = pIF->recvinfo.offset.Off_High;
  1712. p1394PktInfo->SenderMaxRec= pAdapter->info.MaxRec;
  1713. p1394PktInfo->SenderMaxSpeedCode= pAdapter->info.MaxSpeedCode;
  1714. return NDIS_STATUS_SUCCESS;
  1715. }
  1716. NDIS_STATUS
  1717. arpGetSourceMacAddressFor1394Pkt (
  1718. IN PARP1394_ADAPTER pAdapter,
  1719. IN UCHAR SourceNodeAddress,
  1720. IN BOOLEAN fIsValidSourceNodeAddress,
  1721. OUT ENetAddr* pSourceMacAddress,
  1722. PRM_STACK_RECORD pSR
  1723. )
  1724. /*++
  1725. If the Packet has a valid Source Node Address then return it or else fail
  1726. the function
  1727. --*/
  1728. {
  1729. ENetAddr InvalidMacAddress = {0,0,0,0,0,0};
  1730. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1731. NdisZeroMemory (pSourceMacAddress, sizeof(*pSourceMacAddress));
  1732. do
  1733. {
  1734. //
  1735. // Get the Mac Address from the Node Address
  1736. //
  1737. if (fIsValidSourceNodeAddress == TRUE)
  1738. {
  1739. *pSourceMacAddress = (pAdapter->EuidMap.Node[SourceNodeAddress].ENetAddress);
  1740. }
  1741. else
  1742. {
  1743. break;
  1744. }
  1745. //
  1746. // Is the source address all zero's
  1747. //
  1748. if (NdisEqualMemory (pSourceMacAddress, &InvalidMacAddress, sizeof (ENetAddr) ) == 1)
  1749. {
  1750. //ASSERT (NdisEqualMemory (pSourceMacAddress, &InvalidMacAddress, sizeof (ENetAddr) ) != 1);
  1751. // Get the New Topology
  1752. //
  1753. arpGetEuidTopology (pAdapter,pSR);
  1754. Status = NDIS_STATUS_FAILURE;
  1755. break;
  1756. }
  1757. //
  1758. // The SourceMacAddress should not be a broadcast or multicast address
  1759. //
  1760. if (ETH_IS_BROADCAST(pSourceMacAddress) || ETH_IS_MULTICAST(pSourceMacAddress))
  1761. {
  1762. ASSERT (ETH_IS_BROADCAST(pSourceMacAddress) == FALSE);
  1763. ASSERT (ETH_IS_MULTICAST(pSourceMacAddress) == FALSE);
  1764. Status = NDIS_STATUS_FAILURE;
  1765. break;
  1766. }
  1767. Status = NDIS_STATUS_SUCCESS;
  1768. }while (FALSE);
  1769. return Status;
  1770. }
  1771. NDIS_STATUS
  1772. arpEthConstructSTAEthHeader(
  1773. IN PUCHAR pvData,
  1774. IN UINT cbData,
  1775. OUT ENetHeader *pEthHdr
  1776. )
  1777. /*++
  1778. Constructs the Ethernet header of the STA packet .
  1779. Expects that Source Mac Address has already been filled in
  1780. Arguments:
  1781. pvData - Start of the Data packet
  1782. cbData - Length of the data
  1783. pEthHdr - output value
  1784. --*/
  1785. {
  1786. UINT LenIpData = cbData - sizeof (NIC1394_ENCAPSULATION_HEADER);
  1787. //
  1788. // First set the destination Mac address in the Ethernet Header
  1789. //
  1790. NdisMoveMemory (&pEthHdr->eh_daddr, &gSTAMacAddr, sizeof (gSTAMacAddr));
  1791. //
  1792. // Use the length of the packet to store it in the packets. Should be 0x26 or 0x7
  1793. //
  1794. pEthHdr->eh_type = H2N_USHORT(LenIpData);
  1795. return NDIS_STATUS_SUCCESS;
  1796. }
  1797. //
  1798. // the Bootp Code is take heavily from the bridge module
  1799. //
  1800. BOOLEAN
  1801. arpDecodeIPHeader(
  1802. IN PUCHAR pHeader,
  1803. OUT PARP_IP_HEADER_INFO piphi
  1804. )
  1805. /*++
  1806. Routine Description:
  1807. Decodes basic information from the IP header (no options)
  1808. Arguments:
  1809. pHeader Pointer to an IP header
  1810. piphi Receives the info
  1811. Return Value:
  1812. TRUE: header was valid
  1813. FALSE: packet is not an IP packet
  1814. --*/
  1815. {
  1816. // First nibble of the header encodes the packet version, which must be 4.
  1817. if( (*pHeader >> 4) != 0x04 )
  1818. {
  1819. return FALSE;
  1820. }
  1821. // Next nibble of the header encodes the length of the header in 32-bit words.
  1822. // This length must be at least 20 bytes or something is amiss.
  1823. piphi->headerSize = (*pHeader & 0x0F) * 4;
  1824. if( piphi->headerSize < 20 )
  1825. {
  1826. return FALSE;
  1827. }
  1828. // Retrieve the protocol byte (offset 10)
  1829. piphi->protocol = pHeader[9];
  1830. // The source IP address begins at the 12th byte (most significant byte first)
  1831. #if 0
  1832. piphi->ipSource = 0L;
  1833. piphi->ipSource |= pHeader[12] << 24;
  1834. piphi->ipSource |= pHeader[13] << 16;
  1835. piphi->ipSource |= pHeader[14] << 8;
  1836. piphi->ipSource |= pHeader[15];
  1837. // The destination IP address is next
  1838. piphi->ipTarget = 0L;
  1839. piphi->ipTarget |= pHeader[16] << 24;
  1840. piphi->ipTarget |= pHeader[17] << 16;
  1841. piphi->ipTarget |= pHeader[18] << 8;
  1842. piphi->ipTarget |= pHeader[19];
  1843. #endif
  1844. return TRUE;
  1845. }
  1846. PUCHAR
  1847. arpIsEthBootPPacket(
  1848. IN PUCHAR pPacketData,
  1849. IN UINT packetLen,
  1850. IN PARP_IP_HEADER_INFO piphi
  1851. )
  1852. /*++
  1853. Routine Description:
  1854. Determines whether a given packet is a BOOTP packet
  1855. Requires a phy length of six
  1856. Different from the Bridge Code, packetLen is length of the Ip Packet
  1857. Arguments:
  1858. pPacketData Pointer to the packet's data buffer
  1859. packetLen Amount of data at pPacketDaa
  1860. piphi Info about the IP header of this packet
  1861. Return Value:
  1862. A pointer to the BOOTP payload within the packet, or NULL if the packet was not
  1863. a BOOTP Packet.
  1864. --*/
  1865. {
  1866. ENTER("arpIsEthBootPPacket",0xbcdce2dd);
  1867. // After the IP header, there must be enough room for a UDP header and
  1868. // a basic BOOTP packet
  1869. if( packetLen < (UINT)piphi->headerSize + SIZE_OF_UDP_HEADER +
  1870. SIZE_OF_BASIC_BOOTP_PACKET)
  1871. {
  1872. return NULL;
  1873. }
  1874. // Protocol must be UDP
  1875. if( piphi->protocol != UDP_PROTOCOL )
  1876. {
  1877. return NULL;
  1878. }
  1879. // Jump to the beginning of the UDP packet by skipping the IP header
  1880. pPacketData += piphi->headerSize;
  1881. // The first two bytes are the source port and should be the
  1882. // BOOTP Client port (0x0044) or the BOOTP Server port (0x0043)
  1883. if( (pPacketData[0] != 00) ||
  1884. ((pPacketData[1] != 0x44) && (pPacketData[1] != 0x43)) )
  1885. {
  1886. return NULL;
  1887. }
  1888. // The next two bytes are the destination port and should be the BOOTP
  1889. // server port (0x0043) or the BOOTP client port (0x44)
  1890. if( (pPacketData[2] != 00) ||
  1891. ((pPacketData[3] != 0x43) && (pPacketData[3] != 0x44)) )
  1892. {
  1893. return NULL;
  1894. }
  1895. // Skip ahead to the beginning of the BOOTP packet
  1896. pPacketData += SIZE_OF_UDP_HEADER;
  1897. // The first byte is the op code and should be 0x01 for a request
  1898. // or 0x02 for a reply
  1899. if( pPacketData[0] > 0x02 )
  1900. {
  1901. return NULL;
  1902. }
  1903. // The next byte is the hardware type and should be 0x01 for Ethernet
  1904. // or 0x07 (officially arcnet) for ip1394
  1905. //
  1906. if( pPacketData[1] != 0x01 && pPacketData[1] != 0x07 )
  1907. {
  1908. return NULL;
  1909. }
  1910. // The next byte is the address length and should be 0x06 for Ethernet
  1911. if( pPacketData[2] != 0x06 )
  1912. {
  1913. return NULL;
  1914. }
  1915. // Everything checks out; this looks like a BOOTP request packet.
  1916. TR_INFO ( ("Received Bootp Packet \n"));
  1917. EXIT()
  1918. return pPacketData;
  1919. }
  1920. //
  1921. // The IP and UDP checksums treat the data they are checksumming as a
  1922. // sequence of 16-bit words. The checksum is carried as the bitwise
  1923. // inverse of the actual checksum (~C). The formula for calculating
  1924. // the new checksum as transmitted, ~C', given that a 16-bit word of
  1925. // the checksummed data has changed from w to w' is
  1926. //
  1927. // ~C' = ~C + w + ~w' (addition in ones-complement)
  1928. //
  1929. // This function returns the updated checksum given the original checksum
  1930. // and the original and new values of a word in the checksummed data.
  1931. // RFC 1141
  1932. //
  1933. USHORT
  1934. arpEthCompRecalcChecksum(
  1935. IN USHORT oldChecksum,
  1936. IN USHORT oldWord,
  1937. IN USHORT newWord
  1938. )
  1939. {
  1940. ULONG sum,XSum;
  1941. ULONG RfcSum, RfcXSum;
  1942. sum = oldChecksum + oldWord + ((~(newWord)) & 0xFFFF);
  1943. XSum = (USHORT)((sum & 0xFFFF) + (sum >> 16));
  1944. RfcSum = oldWord + ((~(newWord)) & 0xffff);
  1945. RfcSum += oldChecksum;
  1946. RfcSum = (RfcSum& 0xffff) + (RfcSum >>16);
  1947. RfcXSum = (RfcSum + (RfcSum >>16));
  1948. ASSERT (RfcXSum == XSum);
  1949. return (USHORT)RfcXSum;
  1950. }
  1951. VOID
  1952. arpEthRewriteBootPClientAddress(
  1953. IN PUCHAR pPacketData,
  1954. IN PARP_IP_HEADER_INFO piphi,
  1955. IN PUCHAR newMAC
  1956. )
  1957. /*++
  1958. Routine Description:
  1959. This function writes New MAC to the HW address embedded in the DHCP packet
  1960. Arguments:
  1961. Return Value:
  1962. --*/
  1963. {
  1964. USHORT checkSum;
  1965. PUCHAR pBootPData, pCheckSum, pDestMAC, pSrcMAC;
  1966. UINT i;
  1967. // The BOOTP packet lives right after the UDP header
  1968. pBootPData = pPacketData + piphi->IpHeaderOffset + piphi->headerSize + SIZE_OF_UDP_HEADER;
  1969. // The checksum lives at offset 7 in the UDP packet.
  1970. pCheckSum = pPacketData + piphi->IpHeaderOffset + piphi->headerSize + 6;
  1971. checkSum = 0;
  1972. checkSum = pCheckSum[0] << 8;
  1973. checkSum |= pCheckSum[1];
  1974. if (checkSum == 0xffff)
  1975. {
  1976. // Tcpip Illustrated - Vol 1 'UDP Checksum'
  1977. checkSum = 0;
  1978. }
  1979. // Replace the client's hardware address, updating the checksum as we go.
  1980. // The client's hardware address lives at offset 29 in the BOOTP packet
  1981. pSrcMAC = newMAC;
  1982. pDestMAC = &pBootPData[28];
  1983. for( i = 0 ; i < ETH_LENGTH_OF_ADDRESS / 2; i++ )
  1984. {
  1985. checkSum = arpEthCompRecalcChecksum( checkSum,
  1986. (USHORT)(pDestMAC[0] << 8 | pDestMAC[1]),
  1987. (USHORT)(pSrcMAC[0] << 8 | pSrcMAC[1]) );
  1988. pDestMAC[0] = pSrcMAC[0];
  1989. pDestMAC[1] = pSrcMAC[1];
  1990. pDestMAC += 2;
  1991. pSrcMAC += 2;
  1992. }
  1993. // Write the new checksum back out
  1994. pCheckSum[0] = (UCHAR)(checkSum >> 8);
  1995. pCheckSum[1] = (UCHAR)(checkSum & 0xFF);
  1996. }
  1997. NDIS_STATUS
  1998. arpEthBootP1394ToEth(
  1999. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2000. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2001. IN PREMOTE_DEST_KEY pDestAddress,
  2002. IN PUCHAR pucNewData,
  2003. IN PUCHAR pBootPData,
  2004. IN PARP_IP_HEADER_INFO piphi,
  2005. IN PRM_STACK_RECORD pSR
  2006. )
  2007. /*++
  2008. Routine Description:
  2009. This function handles the translation from 1394 to Eth. Essentially,
  2010. we look at the SRC MAC address in the Ethernet Packet, make sure the HW
  2011. Addr embedded is the same as the SRC MAC address.
  2012. We also make an entry in our table - XID, OldHWAddress, NewHWAddress.
  2013. The packet has already been rewritten into Ethernet by this time
  2014. Arguments:
  2015. pIF - pInterface
  2016. Direction - Eth To 1394 or 1394-To-Eth
  2017. pDestAddress - the Eth Hw address used in the translation
  2018. pucNewData - the Data in the new packet
  2019. pBootPdata - pointer to the Bootp part of the packet
  2020. piphi - ip header info
  2021. Return Value:
  2022. --*/
  2023. {
  2024. BOOLEAN bIsRequest = FALSE;
  2025. BOOLEAN bIsResponse;
  2026. ARP_BOOTP_INFO InfoBootP;
  2027. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2028. ENetHeader* pEnetHeader = (ENetHeader*)pucNewData;
  2029. ENetAddr NewMAC;
  2030. BOOLEAN bIs1394HwAlreadyInDhcpRequest;
  2031. ENTER ("arpEthBootP1394ToEth", 0x66206f0b);
  2032. NdisZeroMemory (&InfoBootP, sizeof(InfoBootP));
  2033. //
  2034. // Is this a DHCP Request
  2035. //
  2036. do
  2037. {
  2038. bIsResponse = ARP_IS_BOOTP_RESPONSE(pBootPData);
  2039. if (bIsResponse == TRUE)
  2040. {
  2041. //
  2042. // if this is a DHCP Reply , the do not touch the packet - there are no inconsistencies.
  2043. //
  2044. Status = NDIS_STATUS_SUCCESS;
  2045. break;
  2046. }
  2047. if( FALSE == arpEthPreprocessBootPPacket(pIF,pucNewData, pBootPData, &bIsRequest, &InfoBootP,pSR) )
  2048. {
  2049. // This is an invalid packet
  2050. ASSERT (FALSE);
  2051. break;
  2052. }
  2053. //
  2054. // This is a DHCP Request
  2055. //
  2056. //
  2057. // if the HWAddr and the Src Mac address the same.
  2058. // then are job is already done.
  2059. //
  2060. //At this point the 1394 packet is already in Ethernet format
  2061. NewMAC = pEnetHeader->eh_saddr;
  2062. TR_INFO(("DHCP REQUEST target MAC %x %x %x %x %x %x , SrcMAC %x %x %x %x %x %x \n",
  2063. InfoBootP.requestorMAC.addr[0],InfoBootP.requestorMAC.addr[1],InfoBootP.requestorMAC.addr[2],
  2064. InfoBootP.requestorMAC.addr[3],InfoBootP.requestorMAC.addr[4],InfoBootP.requestorMAC.addr[5],
  2065. NewMAC.addr[0],NewMAC.addr[1],NewMAC.addr[2],
  2066. NewMAC.addr[3],NewMAC.addr[4],NewMAC.addr[5]));
  2067. bIs1394HwAlreadyInDhcpRequest = NdisEqualMemory (&InfoBootP.requestorMAC, &NewMAC , sizeof (ENetAddr)) ;
  2068. if (TRUE == bIs1394HwAlreadyInDhcpRequest )
  2069. {
  2070. //
  2071. // Nothing to do , id the HW add and the src MAC are equal
  2072. //
  2073. Status = NDIS_STATUS_SUCCESS;
  2074. break;
  2075. }
  2076. //
  2077. // Make an entry into our table - consisting of the XID. OldHW Address and
  2078. // New HY address
  2079. // We've already done this.
  2080. //
  2081. // Overwrite the hw address embedded in the DHCP packet. - make sure to rewrite the
  2082. // checksum.
  2083. //
  2084. arpEthRewriteBootPClientAddress(pucNewData,piphi,&NewMAC.addr[0]);
  2085. TR_VERB (("arpEthBootP1394ToEth -Dhcp packet Rewriting BootpClient Address\n"));
  2086. Status = NDIS_STATUS_SUCCESS;
  2087. }while (FALSE);
  2088. EXIT();
  2089. return Status;;
  2090. }
  2091. NDIS_STATUS
  2092. arpEthBootPEthTo1394(
  2093. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2094. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2095. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  2096. IN PUCHAR pucNewData,
  2097. IN PUCHAR pBootPData,
  2098. IN PARP_IP_HEADER_INFO piphi,
  2099. IN PRM_STACK_RECORD pSR
  2100. )
  2101. /*++
  2102. Routine Description:
  2103. This function translates BootP packet from the Ethernet Net to 1394. if this is a dhcp reply (offer),
  2104. then we need to rewrite the Hw Addr in the DHCP packlet
  2105. Arguments:
  2106. pIF - pInterface
  2107. Direction - Eth To 1394 or 1394-To-Eth
  2108. pDestAddress - the Eth Hw address used in the translation
  2109. pucNewData - the Data in the new packet
  2110. Return Value:
  2111. --*/
  2112. {
  2113. BOOLEAN fIsBootpRequest = FALSE;
  2114. ARP_BOOTP_INFO InfoBootP;
  2115. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2116. ENetHeader* pEnetHeader = (ENetHeader*)pucNewData;
  2117. ENetAddr NewMAC;
  2118. PUCHAR pMACInPkt = NULL;
  2119. BOOLEAN bIs1394HwAlreadyInDhcpResponse = FALSE;
  2120. ENTER("arpEthBootPEthTo1394", 0x383f9e33);
  2121. NdisZeroMemory (&InfoBootP, sizeof(InfoBootP));
  2122. //
  2123. // Is this a DHCP Request
  2124. //
  2125. do
  2126. {
  2127. // Do a quick check .
  2128. fIsBootpRequest = ARP_IS_BOOTP_REQUEST(pBootPData);
  2129. if (fIsBootpRequest == TRUE)
  2130. {
  2131. //
  2132. // if this is a DHCP Request, the do not modify the packet -
  2133. // there are no inconsistencies in this code path.
  2134. //
  2135. Status = NDIS_STATUS_SUCCESS;
  2136. break;
  2137. }
  2138. if( FALSE == arpEthPreprocessBootPPacket(pIF,pucNewData, pBootPData, &fIsBootpRequest, &InfoBootP,pSR) )
  2139. {
  2140. // This is an uninteresting packet
  2141. break;
  2142. }
  2143. //
  2144. // InfoBootP has the original HW addr used in the corresponding Dhcp request.
  2145. // We'll put the hw Addr back into dhcp reply
  2146. //
  2147. //offset of the chaddr in bootp packet
  2148. //
  2149. pMACInPkt = &pBootPData[28];
  2150. TR_INFO(("DHCP RESPONSE target MAC %x %x %x %x %x %x , SrcMAC %x %x %x %x %x %x \n",
  2151. InfoBootP.requestorMAC.addr[0],InfoBootP.requestorMAC.addr[1],InfoBootP.requestorMAC.addr[2],
  2152. InfoBootP.requestorMAC.addr[3],InfoBootP.requestorMAC.addr[4],InfoBootP.requestorMAC.addr[5],
  2153. pMACInPkt[0],pMACInPkt[1],pMACInPkt[2],
  2154. pMACInPkt[3],pMACInPkt[4],pMACInPkt[5]));
  2155. //
  2156. // Is the HWAddr in the dhcp packet the correct one.
  2157. //
  2158. bIs1394HwAlreadyInDhcpResponse = NdisEqualMemory(&InfoBootP.requestorMAC, pMACInPkt, sizeof (InfoBootP.requestorMAC)) ;
  2159. if (TRUE == bIs1394HwAlreadyInDhcpResponse)
  2160. {
  2161. //
  2162. // Yes, they are equal, we do not rewrite the packet
  2163. //
  2164. Status = NDIS_STATUS_SUCCESS;
  2165. break;
  2166. }
  2167. TR_VERB( ("DHCP RESPONSE Rewriting Bootp Response pBootpData %p Before\n",pBootPData));
  2168. //
  2169. // Replace the CL Addr in the DHCP packet with the original HW addr
  2170. //
  2171. arpEthRewriteBootPClientAddress(pucNewData,piphi,&InfoBootP.requestorMAC.addr[0]);
  2172. //
  2173. // recompute the checksum
  2174. //
  2175. Status = NDIS_STATUS_SUCCESS;
  2176. } while (FALSE);
  2177. EXIT();
  2178. return Status;
  2179. }
  2180. NDIS_STATUS
  2181. arpEthModifyBootPPacket(
  2182. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  2183. IN ARP_ICS_FORWARD_DIRECTION Direction,
  2184. IN PREMOTE_DEST_KEY pDestAddress, // OPTIONAL
  2185. IN PUCHAR pucNewData,
  2186. IN ULONG PacketLength,
  2187. IN PRM_STACK_RECORD pSR
  2188. )
  2189. /*++
  2190. Routine Description:
  2191. This function contains the code to process a Bootp Packet. This basically ensures that the
  2192. MAC address entered in the DHCP packet matches the Src Mac address of the Ethernet Packet
  2193. (in the 1394 - Eth mode). In the other case (Eth-1394 mode), we replace the Ch address with
  2194. the correct CH addr (if we have to).
  2195. Arguments:
  2196. pIF - pInterface
  2197. Direction - Eth To 1394 or 1394-To-Eth
  2198. pDestAddress - the Eth Hw address used in the translation
  2199. pucNewData - the Data in the new packet
  2200. Return Value:
  2201. --*/
  2202. {
  2203. ARP_IP_HEADER_INFO iphi;
  2204. PUCHAR pBootPData = NULL;
  2205. NDIS_STATUS Status= NDIS_STATUS_FAILURE;
  2206. PARP1394_ADAPTER pAdapter = (PARP1394_ADAPTER)RM_PARENT_OBJECT(pIF);
  2207. ULONG IpHeaderOffset = 0;
  2208. PUCHAR pIPHeader = NULL;
  2209. BOOLEAN fIsIpPkt;
  2210. NdisZeroMemory(&iphi, sizeof (iphi));
  2211. do
  2212. {
  2213. //
  2214. // if we are not in bridge mode - exit.
  2215. //
  2216. if (ARP_BRIDGE_ENABLED(pAdapter) == FALSE)
  2217. {
  2218. break;
  2219. }
  2220. if (Direction == ARP_ICS_FORWARD_TO_ETHERNET)
  2221. {
  2222. // Packet is in the ethernet format
  2223. IpHeaderOffset = ETHERNET_HEADER_SIZE;
  2224. }
  2225. else
  2226. {
  2227. // Packet is in the IP 1394 format
  2228. IpHeaderOffset = sizeof (NIC1394_UNFRAGMENTED_HEADER); //4
  2229. }
  2230. iphi.IpHeaderOffset = IpHeaderOffset;
  2231. iphi.IpPktLength = PacketLength - IpHeaderOffset;
  2232. pIPHeader = pucNewData + IpHeaderOffset ;
  2233. //
  2234. // if this is not a bootp packet -exit
  2235. //
  2236. fIsIpPkt = arpDecodeIPHeader (pIPHeader , &iphi);
  2237. if (fIsIpPkt == FALSE)
  2238. {
  2239. //
  2240. // not an IP pkt
  2241. //
  2242. Status = NDIS_STATUS_SUCCESS;
  2243. break;
  2244. }
  2245. pBootPData = arpIsEthBootPPacket (pIPHeader ,PacketLength-IpHeaderOffset, &iphi);
  2246. if (pBootPData == NULL)
  2247. {
  2248. Status = NDIS_STATUS_SUCCESS;
  2249. break;
  2250. }
  2251. //
  2252. // are we doing 1394 - to- Eth
  2253. //
  2254. if (Direction == ARP_ICS_FORWARD_TO_ETHERNET)
  2255. {
  2256. Status = arpEthBootP1394ToEth(pIF, Direction,pDestAddress,pucNewData,pBootPData,&iphi, pSR);
  2257. }
  2258. else
  2259. {
  2260. //
  2261. // are we doing Eth to 1394
  2262. //
  2263. Status = arpEthBootPEthTo1394(pIF, Direction,pDestAddress,pucNewData,pBootPData , &iphi,pSR);
  2264. }
  2265. Status = NDIS_STATUS_SUCCESS;
  2266. }while (FALSE);
  2267. // else we are doing Eth to 1394
  2268. return Status;
  2269. }
  2270. //
  2271. // This function is taken verbatim from the bridge
  2272. //
  2273. BOOLEAN
  2274. arpEthPreprocessBootPPacket(
  2275. IN PARP1394_INTERFACE pIF,
  2276. IN PUCHAR pPacketData,
  2277. IN PUCHAR pBootPData, // Actual BOOTP packet
  2278. OUT PBOOLEAN pbIsRequest,
  2279. PARP_BOOTP_INFO pInfoBootP,
  2280. PRM_STACK_RECORD pSR
  2281. )
  2282. /*++
  2283. Routine Description:
  2284. Does preliminary processing of a BOOTP packet common to the inbound and outbound case
  2285. Arguments:
  2286. pPacketData Pointer to a packet's data buffer
  2287. pBootPData Pointer to the BOOTP payload within the packet
  2288. pAdapt Receiving adapter (or NULL if this packet is outbound from
  2289. the local machine)
  2290. pbIsRequest Receives a flag indicating if this is a BOOTP request
  2291. ppTargetAdapt Receives the target adapter this packet should be relayed to
  2292. (only valid if bIsRequest == FALSE and return == TRUE)
  2293. requestorMAC The MAC address this packet should be relayed to (valid under
  2294. same conditions as ppTargetAdapt)
  2295. Return Value:
  2296. TRUE : packet was processed successfully
  2297. FALSE : an error occured or something is wrong with the packet
  2298. --*/
  2299. {
  2300. PARP1394_ETH_DHCP_ENTRY pEntry= NULL;
  2301. ULONG xid;
  2302. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  2303. ENTER ("arpEthPreprocessBootPPacket",0x25427efc);
  2304. // Decode the xid (bytes 5 through 8)
  2305. xid = 0L;
  2306. xid |= pBootPData[4] << 24;
  2307. xid |= pBootPData[5] << 16;
  2308. xid |= pBootPData[6] << 8;
  2309. xid |= pBootPData[7];
  2310. // Byte 0 is the operation; 1 for a request, 2 for a reply
  2311. if( pBootPData[0] == 0x01 )
  2312. {
  2313. ULONG bIsNewEntry = FALSE;
  2314. // This is a request. We need to note the correspondence betweeen
  2315. // this client's XID and its adapter and MAC address
  2316. TR_INFO(("DHCP REQUEST XID: %x , HW %x %x %x %x %x %x \n", xid,
  2317. pBootPData[28],pBootPData[29],pBootPData[30],pBootPData[31],pBootPData[32],pBootPData[33]));
  2318. Status = RmLookupObjectInGroup(
  2319. &pIF->EthDhcpGroup,
  2320. RM_CREATE,
  2321. (PVOID) &xid, // pKey
  2322. (PVOID) &xid, // pvCreateParams
  2323. &(PRM_OBJECT_HEADER)pEntry,
  2324. &bIsNewEntry ,
  2325. pSR
  2326. );
  2327. if( pEntry != NULL )
  2328. {
  2329. if( bIsNewEntry )
  2330. {
  2331. // Initialize the entry.
  2332. // The client's hardware address is at offset 29
  2333. ETH_COPY_NETWORK_ADDRESS( &pEntry->requestorMAC.addr[0], &pBootPData[28] );
  2334. pEntry->xid = xid;
  2335. }
  2336. else
  2337. {
  2338. //
  2339. // An entry already existed for this XID. This is fine if the existing information
  2340. // matches what we're trying to record, but it's also possible that two stations
  2341. // decided independently to use the same XID, or that the same station changed
  2342. // apparent MAC address and/or adapter due to topology changes. Our scheme breaks
  2343. // down under these circumstances.
  2344. //
  2345. // Either way, use the most recent information possible; clobber the existing
  2346. // information with the latest.
  2347. //
  2348. LOCKOBJ(pEntry, pSR);
  2349. {
  2350. UINT Result;
  2351. ETH_COMPARE_NETWORK_ADDRESSES_EQ( &pEntry->requestorMAC.addr[0], &pBootPData[28], &Result );
  2352. // Warn if the data changed, as this probably signals a problem
  2353. if( Result != 0 )
  2354. {
  2355. TR_WARN(("ARP1394 WARNING: Station with MAC address %02x:%02x:%02x:%02x:%02x:%02x is using DHCP XID %x at the same time as station %02x:%02x:%02x:%02x:%02x:%02x!\n",
  2356. pBootPData[28], pBootPData[29], pBootPData[30], pBootPData[31], pBootPData[32], pBootPData[33],
  2357. xid, pEntry->requestorMAC.addr[0], pEntry->requestorMAC.addr[1], pEntry->requestorMAC.addr[2],
  2358. pEntry->requestorMAC.addr[3], pEntry->requestorMAC.addr[4], pEntry->requestorMAC.addr[5] ));
  2359. }
  2360. }
  2361. ETH_COPY_NETWORK_ADDRESS( &pEntry->requestorMAC.addr[0], &pBootPData[28] );
  2362. UNLOCKOBJ (pEntry, pSR);
  2363. }
  2364. RmTmpDereferenceObject (&pEntry->Hdr, pSR);
  2365. }
  2366. else
  2367. {
  2368. // This packet could not be processed
  2369. TR_INFO(("Couldn't create table entry for BOOTP packet!\n"));
  2370. return FALSE;
  2371. }
  2372. *pbIsRequest = TRUE;
  2373. pInfoBootP->bIsRequest = TRUE;
  2374. ETH_COPY_NETWORK_ADDRESS(&pInfoBootP->requestorMAC,&pEntry->requestorMAC);
  2375. return TRUE;
  2376. }
  2377. else if ( pBootPData[0] == 0x02 )
  2378. {
  2379. //
  2380. // NON-CREATE search
  2381. // Look up the xid for this transaction to recover the MAC address of the client
  2382. //
  2383. TR_INFO (("Seeing a DHCP response xid %x mac %x %x %x %x %x %x \n",
  2384. xid, pBootPData[28],pBootPData[29],pBootPData[30],pBootPData[31],pBootPData[32],pBootPData[33]));
  2385. Status = RmLookupObjectInGroup(
  2386. &pIF->EthDhcpGroup,
  2387. 0, // do not create
  2388. (PVOID) &xid, // pKey
  2389. (PVOID) &xid, // pvCreateParams
  2390. &(PRM_OBJECT_HEADER)pEntry,
  2391. NULL,
  2392. pSR
  2393. );
  2394. if( pEntry != NULL )
  2395. {
  2396. LOCKOBJ( pEntry, pSR);
  2397. ETH_COPY_NETWORK_ADDRESS( &pInfoBootP->requestorMAC.addr, pEntry->requestorMAC.addr );
  2398. UNLOCKOBJ( pEntry, pSR );
  2399. //
  2400. // We will use this adapter outside the table lock. NULL is a permissible
  2401. // value that indicates that the local machine is the requestor for
  2402. // this xid.
  2403. //
  2404. RmTmpDereferenceObject(&pEntry->Hdr, pSR);
  2405. }
  2406. if( pEntry != NULL )
  2407. {
  2408. *pbIsRequest = FALSE;
  2409. return TRUE;
  2410. }
  2411. else
  2412. {
  2413. TR_INFO (("DHCP Response:Could not find xid %x in DHCP table \n",xid);)
  2414. return FALSE;
  2415. }
  2416. }
  2417. else
  2418. {
  2419. // Someone passed us a crummy packet
  2420. return FALSE;
  2421. }
  2422. }
  2423. #if DBG
  2424. VOID
  2425. Dump(
  2426. IN CHAR* p,
  2427. IN ULONG cb,
  2428. IN BOOLEAN fAddress,
  2429. IN ULONG ulGroup )
  2430. // Hex dump 'cb' bytes starting at 'p' grouping 'ulGroup' bytes together.
  2431. // For example, with 'ulGroup' of 1, 2, and 4:
  2432. //
  2433. // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  2434. // 0000 0000 0000 0000 0000 0000 0000 0000 |................|
  2435. // 00000000 00000000 00000000 00000000 |................|
  2436. //
  2437. // If 'fAddress' is true, the memory address dumped is prepended to each
  2438. // line.
  2439. //
  2440. {
  2441. while (cb)
  2442. {
  2443. INT cbLine;
  2444. cbLine = (cb < DUMP_BytesPerLine) ? cb : DUMP_BytesPerLine;
  2445. DumpLine( p, cbLine, fAddress, ulGroup );
  2446. cb -= cbLine;
  2447. p += cbLine;
  2448. }
  2449. }
  2450. #endif
  2451. #if DBG
  2452. VOID
  2453. DumpLine(
  2454. IN CHAR* p,
  2455. IN ULONG cb,
  2456. IN BOOLEAN fAddress,
  2457. IN ULONG ulGroup )
  2458. {
  2459. CHAR* pszDigits = "0123456789ABCDEF";
  2460. CHAR szHex[ ((2 + 1) * DUMP_BytesPerLine) + 1 ];
  2461. CHAR* pszHex = szHex;
  2462. CHAR szAscii[ DUMP_BytesPerLine + 1 ];
  2463. CHAR* pszAscii = szAscii;
  2464. ULONG ulGrouped = 0;
  2465. if (fAddress)
  2466. DbgPrint( "A13: %p: ", p );
  2467. else
  2468. DbgPrint( "A13: " );
  2469. while (cb)
  2470. {
  2471. *pszHex++ = pszDigits[ ((UCHAR )*p) / 16 ];
  2472. *pszHex++ = pszDigits[ ((UCHAR )*p) % 16 ];
  2473. if (++ulGrouped >= ulGroup)
  2474. {
  2475. *pszHex++ = ' ';
  2476. ulGrouped = 0;
  2477. }
  2478. *pszAscii++ = (*p >= 32 && *p < 128) ? *p : '.';
  2479. ++p;
  2480. --cb;
  2481. }
  2482. *pszHex = '\0';
  2483. *pszAscii = '\0';
  2484. DbgPrint(
  2485. "%-*s|%-*s|\n",
  2486. (2 * DUMP_BytesPerLine) + (DUMP_BytesPerLine / ulGroup), szHex,
  2487. DUMP_BytesPerLine, szAscii );
  2488. }
  2489. #endif