mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 23:18:39 +00:00
- Properly implement ICMP
- Now Raw IP works correctly because it isn't being hacked to handle ICMP packets svn path=/trunk/; revision=42087
This commit is contained in:
parent
a86419a500
commit
b43fbb516b
7 changed files with 135 additions and 9 deletions
|
@ -48,6 +48,16 @@ typedef struct ICMP_HEADER {
|
||||||
/* ICMP codes for ICMP_TYPE_PARAMETER */
|
/* ICMP codes for ICMP_TYPE_PARAMETER */
|
||||||
#define ICMP_CODE_TP_POINTER 1 /* Pointer indicates the error */
|
#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(
|
VOID ICMPReceive(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
|
|
|
@ -14,7 +14,7 @@ NTSTATUS RawIPSendDatagram(
|
||||||
ULONG DataSize,
|
ULONG DataSize,
|
||||||
PULONG DataUsed);
|
PULONG DataUsed);
|
||||||
|
|
||||||
VOID RawIPReceive(
|
VOID RawIpReceive(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PIP_PACKET IPPacket);
|
PIP_PACKET IPPacket);
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,11 @@ NTSTATUS FileOpenAddress(
|
||||||
AddrFile->Send = UDPSendDatagram;
|
AddrFile->Send = UDPSendDatagram;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
AddrFile->Port = 0;
|
||||||
|
AddrFile->Send = ICMPSendDatagram;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Use raw IP for all other protocols */
|
/* Use raw IP for all other protocols */
|
||||||
AddrFile->Port = 0;
|
AddrFile->Port = 0;
|
||||||
|
|
|
@ -646,6 +646,7 @@ VOID NTAPI TiUnload(
|
||||||
TCPShutdown();
|
TCPShutdown();
|
||||||
UDPShutdown();
|
UDPShutdown();
|
||||||
RawIPShutdown();
|
RawIPShutdown();
|
||||||
|
ICMPShutdown();
|
||||||
|
|
||||||
/* Shutdown network level protocol subsystem */
|
/* Shutdown network level protocol subsystem */
|
||||||
IPShutdown();
|
IPShutdown();
|
||||||
|
@ -885,6 +886,23 @@ DriverEntry(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = ICMPStartup();
|
||||||
|
if( !NT_SUCCESS(Status) ) {
|
||||||
|
TCPShutdown();
|
||||||
|
UDPShutdown();
|
||||||
|
RawIPShutdown();
|
||||||
|
IPShutdown();
|
||||||
|
ChewShutdown();
|
||||||
|
IoDeleteDevice(IPDeviceObject);
|
||||||
|
IoDeleteDevice(RawIPDeviceObject);
|
||||||
|
IoDeleteDevice(UDPDeviceObject);
|
||||||
|
IoDeleteDevice(TCPDeviceObject);
|
||||||
|
exFreePool(EntityList);
|
||||||
|
NdisFreePacketPool(GlobalPacketPool);
|
||||||
|
NdisFreeBufferPool(GlobalBufferPool);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Use direct I/O */
|
/* Use direct I/O */
|
||||||
IPDeviceObject->Flags |= DO_DIRECT_IO;
|
IPDeviceObject->Flags |= DO_DIRECT_IO;
|
||||||
RawIPDeviceObject->Flags |= DO_DIRECT_IO;
|
RawIPDeviceObject->Flags |= DO_DIRECT_IO;
|
||||||
|
|
|
@ -10,6 +10,19 @@
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
|
NTSTATUS ICMPStartup()
|
||||||
|
{
|
||||||
|
IPRegisterProtocol(IPPROTO_ICMP, ICMPReceive);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS ICMPShutdown()
|
||||||
|
{
|
||||||
|
IPRegisterProtocol(IPPROTO_ICMP, NULL);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VOID SendICMPComplete(
|
VOID SendICMPComplete(
|
||||||
PVOID Context,
|
PVOID Context,
|
||||||
|
@ -118,6 +131,89 @@ BOOLEAN PrepareICMPPacket(
|
||||||
return TRUE;
|
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(
|
VOID ICMPReceive(
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
|
@ -145,6 +241,8 @@ VOID ICMPReceive(
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
|
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
|
||||||
|
|
||||||
|
RawIpReceive(Interface, IPPacket);
|
||||||
|
|
||||||
/* Checksum ICMP header and data */
|
/* Checksum ICMP header and data */
|
||||||
if (!IPv4CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
|
if (!IPv4CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
|
||||||
TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n"));
|
TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n"));
|
||||||
|
|
|
@ -113,11 +113,6 @@ VOID IPDispatchProtocol(
|
||||||
{
|
{
|
||||||
/* Call the appropriate protocol handler */
|
/* Call the appropriate protocol handler */
|
||||||
(*ProtocolTable[Protocol])(Interface, IPPacket);
|
(*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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ NTSTATUS BuildRawIpPacket(
|
||||||
Status = AddGenericHeaderIPv4
|
Status = AddGenericHeaderIPv4
|
||||||
(RemoteAddress, RemotePort,
|
(RemoteAddress, RemotePort,
|
||||||
LocalAddress, LocalPort, Packet, DataLen,
|
LocalAddress, LocalPort, Packet, DataLen,
|
||||||
IPPROTO_ICMP, /* XXX Figure out a better way to do this */
|
IPPROTO_RAW,
|
||||||
0, (PVOID *)&Payload );
|
0, (PVOID *)&Payload );
|
||||||
break;
|
break;
|
||||||
case IP_ADDRESS_V6:
|
case IP_ADDRESS_V6:
|
||||||
|
@ -332,7 +332,7 @@ NTSTATUS RawIPStartup(VOID)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Register this protocol with IP layer */
|
/* Register this protocol with IP layer */
|
||||||
IPRegisterProtocol(IPPROTO_ICMP, RawIpReceive);
|
IPRegisterProtocol(IPPROTO_RAW, RawIpReceive);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ NTSTATUS RawIPShutdown(VOID)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Deregister this protocol with IP layer */
|
/* Deregister this protocol with IP layer */
|
||||||
IPRegisterProtocol(IPPROTO_ICMP, NULL);
|
IPRegisterProtocol(IPPROTO_RAW, NULL);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue