VOID ICMPTransmit( PIP_PACKET IPPacket, PIP_TRANSMIT_COMPLETE Complete, PVOID Context) /* * FUNCTION: Transmits an ICMP packet * ARGUMENTS: * NTE = Pointer to net table entry to use (NULL if don't care) * IPPacket = Pointer to IP packet to transmit */ { PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_ICMP, ("Called.\n")); /* Calculate checksum of ICMP header and data */ ((PICMP_HEADER)IPPacket->Data)->Checksum = (USHORT) IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0); /* Get a route to the destination address */ if ((NCE = RouteGetRouteToDestination(&IPPacket->DstAddr))) { /* Send the packet */ IPSendDatagram(IPPacket, NCE); } else { /* No route to destination (or no free resources) */ TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n", IPPacket->DstAddr.Address.IPv4Address)); IPPacket->Free(IPPacket); } }
BOOLEAN PrepareNextFragment( PIPFRAGMENT_CONTEXT IFC) /* * FUNCTION: Prepares the next fragment of an IP datagram for transmission * ARGUMENTS: * IFC = Pointer to IP fragment context * RETURNS: * TRUE if a fragment was prepared for transmission, FALSE if * there are no more fragments to send */ { UINT MaxData; UINT DataSize; PIPv4_HEADER Header; BOOLEAN MoreFragments; USHORT FragOfs; TI_DbgPrint(MAX_TRACE, ("Called. IFC (0x%X)\n", IFC)); if (IFC->BytesLeft > 0) { TI_DbgPrint(MAX_TRACE, ("Preparing 1 fragment.\n")); MaxData = IFC->PathMTU - IFC->HeaderSize; /* Make fragment a multiplum of 64bit */ MaxData -= MaxData % 8; if (IFC->BytesLeft > MaxData) { DataSize = MaxData; MoreFragments = TRUE; } else { DataSize = IFC->BytesLeft; MoreFragments = FALSE; } TI_DbgPrint(MID_TRACE,("Copying data from %x to %x (%d)\n", IFC->DatagramData, IFC->Data, DataSize)); RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize); // SAFE /* Fragment offset is in 8 byte blocks */ FragOfs = (USHORT)(IFC->Position / 8); if (MoreFragments) FragOfs |= IPv4_MF_MASK; else FragOfs &= ~IPv4_MF_MASK; Header = IFC->Header; Header->FlagsFragOfs = WH2N(FragOfs); Header->TotalLength = WH2N((USHORT)(DataSize + IFC->HeaderSize)); /* FIXME: Handle options */ /* Calculate checksum of IP header */ Header->Checksum = 0; Header->Checksum = (USHORT)IPv4Checksum(Header, IFC->HeaderSize, 0); TI_DbgPrint(MID_TRACE,("IP Check: %x\n", Header->Checksum)); /* Update pointers */ IFC->DatagramData = (PVOID)((ULONG_PTR)IFC->DatagramData + DataSize); IFC->Position += DataSize; IFC->BytesLeft -= DataSize; return TRUE; } else { TI_DbgPrint(MAX_TRACE, ("No more fragments.\n")); return FALSE; } }