#include "precomp.h"
-
BOOLEAN UDPInitialized = FALSE;
PORT_SET UDPPorts;
NTSTATUS AddUDPHeaderIPv4(
+ PADDRESS_FILE AddrFile,
PIP_ADDRESS RemoteAddress,
USHORT RemotePort,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET IPPacket,
+ PVOID Data,
UINT DataLength)
/*
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
*/
{
PUDP_HEADER UDPHeader;
+ NTSTATUS Status;
TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
IPPacket, IPPacket->NdisPacket));
- AddGenericHeaderIPv4
- ( RemoteAddress, RemotePort,
+ Status = AddGenericHeaderIPv4
+ ( AddrFile, RemoteAddress, RemotePort,
LocalAddress, LocalPort,
IPPacket, DataLength, IPPROTO_UDP,
sizeof(UDP_HEADER), (PVOID *)&UDPHeader );
- /* Build UDP header */
- UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPPacket->Data - sizeof(UDP_HEADER));
+ if (!NT_SUCCESS(Status))
+ return Status;
+
/* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = RemotePort;
- /* FIXME: Calculate UDP checksum and put it in UDP header */
UDPHeader->Checksum = 0;
/* Length of UDP header and data */
UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER));
- IPPacket->Data = ((PCHAR)UDPHeader) + sizeof(UDP_HEADER);
+ TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
+ IPPacket->Header, IPPacket->Data,
+ (PCHAR)IPPacket->Data - (PCHAR)IPPacket->Header));
+
+ RtlCopyMemory(IPPacket->Data, Data, DataLength);
+
+ UDPHeader->Checksum = UDPv4ChecksumCalculate((PIPv4_HEADER)IPPacket->Header,
+ (PUCHAR)UDPHeader,
+ DataLength + sizeof(UDP_HEADER));
+ UDPHeader->Checksum = WH2N(UDPHeader->Checksum);
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
NTSTATUS BuildUDPPacket(
+ PADDRESS_FILE AddrFile,
PIP_PACKET Packet,
PIP_ADDRESS RemoteAddress,
USHORT RemotePort,
/* FIXME: Assumes IPv4 */
IPInitializePacket(Packet, IP_ADDRESS_V4);
- if (!Packet)
- return STATUS_INSUFFICIENT_RESOURCES;
Packet->TotalSize = sizeof(IPv4_HEADER) + sizeof(UDP_HEADER) + DataLen;
/* Prepare packet */
Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
NULL,
- Packet->TotalSize + MaxLLHeaderSize );
+ Packet->TotalSize );
if( !NT_SUCCESS(Status) ) return Status;
switch (RemoteAddress->Type) {
case IP_ADDRESS_V4:
- Status = AddUDPHeaderIPv4(RemoteAddress, RemotePort,
- LocalAddress, LocalPort, Packet, DataLen);
+ Status = AddUDPHeaderIPv4(AddrFile, RemoteAddress, RemotePort,
+ LocalAddress, LocalPort, Packet, DataBuffer, DataLen);
break;
case IP_ADDRESS_V6:
/* FIXME: Support IPv6 */
return Status;
}
- TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
- Packet->Header, Packet->Data,
- (PCHAR)Packet->Data - (PCHAR)Packet->Header));
-
- RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
-
TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
DISPLAY_IP_PACKET(Packet);
IP_PACKET Packet;
PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
IP_ADDRESS RemoteAddress;
+ IP_ADDRESS LocalAddress;
USHORT RemotePort;
NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE;
+ KIRQL OldIrql;
+
+ LockObject(AddrFile, &OldIrql);
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
- AddrFile, ConnInfo, BufferData, DataSize));
+ 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;
+ 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;
+ UnlockObject(AddrFile, OldIrql);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ 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
+ */
+ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
+ UnlockObject(AddrFile, OldIrql);
+ return STATUS_NETWORK_UNREACHABLE;
+ }
+
+ LocalAddress = NCE->Interface->Unicast;
+ }
+ else
+ {
+ if(!(NCE = NBLocateNeighbor( &LocalAddress ))) {
+ UnlockObject(AddrFile, OldIrql);
+ return STATUS_INVALID_PARAMETER;
+ }
}
- Status = BuildUDPPacket( &Packet,
- &RemoteAddress,
- RemotePort,
- &AddrFile->Address,
- AddrFile->Port,
- BufferData,
- DataSize );
+ Status = BuildUDPPacket( AddrFile,
+ &Packet,
+ &RemoteAddress,
+ RemotePort,
+ &LocalAddress,
+ AddrFile->Port,
+ BufferData,
+ DataSize );
if( !NT_SUCCESS(Status) )
- return Status;
+ {
+ UnlockObject(AddrFile, OldIrql);
+ return Status;
+ }
- if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
- return STATUS_UNSUCCESSFUL;
+ if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
+ {
+ UnlockObject(AddrFile, OldIrql);
+ FreeNdisPacket(Packet.NdisPacket);
+ return Status;
+ }
- IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL );
+ UnlockObject(AddrFile, OldIrql);
return STATUS_SUCCESS;
}
UDPHeader = (PUDP_HEADER)IPPacket->Data;
- /* FIXME: Calculate and validate UDP checksum */
+ /* Calculate and validate UDP checksum */
+ i = UDPv4ChecksumCalculate(IPv4Header,
+ (PUCHAR)UDPHeader,
+ WH2N(UDPHeader->Length));
+ if (i != DH2N(0x0000FFFF) && UDPHeader->Checksum != 0)
+ {
+ TI_DbgPrint(MIN_TRACE, ("Bad checksum on packet received.\n"));
+ return;
+ }
/* Sanity checks */
i = WH2N(UDPHeader->Length);
* Status of operation
*/
{
+ NTSTATUS Status;
+
#ifdef __NTDRIVER__
RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
#endif
- NTSTATUS Status;
-
- Status = PortsStartup( &UDPPorts, 1, 0xfffe );
+ Status = PortsStartup( &UDPPorts, 1, UDP_STARTING_PORT + UDP_DYNAMIC_PORTS );
if( !NT_SUCCESS(Status) ) return Status;