Author: cgutman Date: Sun Jul 19 16:48:48 2009 New Revision: 42087
URL: http://svn.reactos.org/svn/reactos?rev=42087&view=rev Log: - Properly implement ICMP - Now Raw IP works correctly because it isn't being hacked to handle ICMP packets
Modified: trunk/reactos/drivers/network/tcpip/include/icmp.h trunk/reactos/drivers/network/tcpip/include/rawip.h trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c trunk/reactos/drivers/network/tcpip/tcpip/main.c trunk/reactos/lib/drivers/ip/network/icmp.c trunk/reactos/lib/drivers/ip/network/ip.c trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c
Modified: trunk/reactos/drivers/network/tcpip/include/icmp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/icmp.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/icmp.h [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -48,6 +48,16 @@ /* ICMP codes for ICMP_TYPE_PARAMETER */ #define ICMP_CODE_TP_POINTER 1 /* Pointer indicates the error */
+NTSTATUS ICMPSendDatagram( + PADDRESS_FILE AddrFile, + PTDI_CONNECTION_INFORMATION ConnInfo, + PCHAR BufferData, + ULONG DataSize, + PULONG DataUsed ); + +NTSTATUS ICMPStartup(); + +NTSTATUS ICMPShutdown();
VOID ICMPReceive( PIP_INTERFACE Interface,
Modified: trunk/reactos/drivers/network/tcpip/include/rawip.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/inclu... ============================================================================== --- trunk/reactos/drivers/network/tcpip/include/rawip.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/include/rawip.h [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -14,7 +14,7 @@ ULONG DataSize, PULONG DataUsed);
-VOID RawIPReceive( +VOID RawIpReceive( PIP_INTERFACE Interface, PIP_PACKET IPPacket);
Modified: trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -291,6 +291,11 @@ AddrFile->Send = UDPSendDatagram; break;
+ case IPPROTO_ICMP: + AddrFile->Port = 0; + AddrFile->Send = ICMPSendDatagram; + break; + default: /* Use raw IP for all other protocols */ AddrFile->Port = 0;
Modified: trunk/reactos/drivers/network/tcpip/tcpip/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip... ============================================================================== --- trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/tcpip/tcpip/main.c [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -646,6 +646,7 @@ TCPShutdown(); UDPShutdown(); RawIPShutdown(); + ICMPShutdown();
/* Shutdown network level protocol subsystem */ IPShutdown(); @@ -871,6 +872,23 @@
Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; + } + + Status = ICMPStartup(); + if( !NT_SUCCESS(Status) ) { + TCPShutdown(); UDPShutdown(); RawIPShutdown(); IPShutdown();
Modified: trunk/reactos/lib/drivers/ip/network/icmp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/icmp... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/icmp.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/icmp.c [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -10,6 +10,19 @@
#include "precomp.h"
+NTSTATUS ICMPStartup() +{ + IPRegisterProtocol(IPPROTO_ICMP, ICMPReceive); + + return STATUS_SUCCESS; +} + +NTSTATUS ICMPShutdown() +{ + IPRegisterProtocol(IPPROTO_ICMP, NULL); + + return STATUS_SUCCESS; +}
VOID SendICMPComplete( PVOID Context, @@ -118,6 +131,89 @@ return TRUE; }
+VOID ICMPSendPacketComplete +( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) { + FreeNdisPacket( Packet ); +} + +NTSTATUS ICMPSendDatagram( + PADDRESS_FILE AddrFile, + PTDI_CONNECTION_INFORMATION ConnInfo, + PCHAR BufferData, + ULONG DataSize, + PULONG DataUsed ) +/* + * FUNCTION: Sends an ICMP datagram to a remote address + * ARGUMENTS: + * Request = Pointer to TDI request + * ConnInfo = Pointer to connection information + * Buffer = Pointer to NDIS buffer with data + * DataSize = Size in bytes of data to be sent + * RETURNS: + * Status of operation + */ +{ + IP_PACKET Packet; + PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress; + IP_ADDRESS RemoteAddress, LocalAddress; + USHORT RemotePort; + NTSTATUS Status; + PNEIGHBOR_CACHE_ENTRY NCE; + + TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", + AddrFile, ConnInfo, BufferData, DataSize)); + TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa)); + + switch( RemoteAddressTa->Address[0].AddressType ) { + case TDI_ADDRESS_TYPE_IP: + RemoteAddress.Type = IP_ADDRESS_V4; + RemoteAddress.Address.IPv4Address = + RemoteAddressTa->Address[0].Address[0].in_addr; + RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port; + break; + + default: + return STATUS_UNSUCCESSFUL; + } + + TI_DbgPrint(MID_TRACE,("About to get route to destination\n")); + + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + return STATUS_NETWORK_UNREACHABLE; + + LocalAddress = AddrFile->Address; + if (AddrIsUnspecified(&LocalAddress)) + { + /* If the local address is unspecified (0), + * then use the unicast address of the + * interface we're sending over + */ + LocalAddress = NCE->Interface->Unicast; + } + + Status = PrepareICMPPacket( NCE->Interface, + &Packet, + &RemoteAddress, + BufferData, + DataSize ); + + if( !NT_SUCCESS(Status) ) + return Status; + + TI_DbgPrint(MID_TRACE,("About to send datagram\n")); + + if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, ICMPSendPacketComplete, NULL ))) + { + FreeNdisPacket(Packet.NdisPacket); + return Status; + } + + TI_DbgPrint(MID_TRACE,("Leaving\n")); + + return STATUS_SUCCESS; +} + +
VOID ICMPReceive( PIP_INTERFACE Interface, @@ -144,6 +240,8 @@ TI_DbgPrint(DEBUG_ICMP, ("Code (%d).\n", ICMPHeader->Code));
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum)); + + RawIpReceive(Interface, IPPacket);
/* Checksum ICMP header and data */ if (!IPv4CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
Modified: trunk/reactos/lib/drivers/ip/network/ip.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/ip.c... ============================================================================== --- trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -113,11 +113,6 @@ { /* Call the appropriate protocol handler */ (*ProtocolTable[Protocol])(Interface, IPPacket); - - /* Special case for ICMP -- ICMP can be caught by a SOCK_RAW but also - * must be handled here. */ - if( Protocol == IPPROTO_ICMP ) - ICMPReceive( Interface, IPPacket ); } }
Modified: trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/ra... ============================================================================== --- trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] Sun Jul 19 16:48:48 2009 @@ -126,7 +126,7 @@ Status = AddGenericHeaderIPv4 (RemoteAddress, RemotePort, LocalAddress, LocalPort, Packet, DataLen, - IPPROTO_ICMP, /* XXX Figure out a better way to do this */ + IPPROTO_RAW, 0, (PVOID *)&Payload ); break; case IP_ADDRESS_V6: @@ -332,7 +332,7 @@ #endif
/* Register this protocol with IP layer */ - IPRegisterProtocol(IPPROTO_ICMP, RawIpReceive); + IPRegisterProtocol(IPPROTO_RAW, RawIpReceive);
return STATUS_SUCCESS; } @@ -346,7 +346,7 @@ */ { /* Deregister this protocol with IP layer */ - IPRegisterProtocol(IPPROTO_ICMP, NULL); + IPRegisterProtocol(IPPROTO_RAW, NULL);
return STATUS_SUCCESS; }