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/incl…
==============================================================================
--- 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/incl…
==============================================================================
--- 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/tcpi…
==============================================================================
--- 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/tcpi…
==============================================================================
--- 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/icm…
==============================================================================
--- 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.…
==============================================================================
--- 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/r…
==============================================================================
--- 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;
}