2004-03-04 Casper S. Hornstrup <chorns@users.sourceforge.net>

* drivers/net/tcpip/tcpip/i386: New directory.
	* drivers/net/tcpip/tcpip/i386/checksum.S: New file.
	* drivers/net/tcpip/notes.txt: New file.
	* drivers/net/afd/afd/dispatch.c (AfdDispCompleteListen): Signal ACCEPT
	network event.
	(AfdDispEventSelect): Reference event handle.
	* drivers/net/afd/afd/tdi.c (TdiListen): Remove unused event.
	Move Iosb and RequestConnectionInfo to AFD_LISTEN_REQUEST structure.
	* drivers/net/afd/include/afd.h (AFDFCB): Replace EventObjects with
	EventObject of type PKEVENT.
	* drivers/net/tcpip/makefile (ARCH_OBJECTS): New variable.
	(TARGET_OBJECTS): Add ARCH_OBJECTS.
	* drivers/net/tcpip/include/address.h (AddrCloneAddress): New prototype.
	* drivers/net/tcpip/include/checksum.h (ChecksumFold, csum_partial): New
	prototype.
	(TCPv4Checksum): New macro.
	(CorrectChecksum): Rename to IPv4CorrectChecksum.
	(TCPv4CorrectChecksum): New macro.
	* drivers/net/tcpip/include/ip.h (IPv4_DF_MASK): New constant.
	* drivers/net/tcpip/include/tcp.h (TCP_XXX): Correct constants.
	(TCPCreateSegment, TCPFreeSegment, TCPAddSegment): Prototype.
	* drivers/net/tcpip/include/titypes.h (TCP_SEND_REQUEST): Add SequenceNumber
	and AckNumber.
	(TCP_SEGMENT): New structure.
	(CONNECTION_ENDPOINT): Add ListenRequest and ReceivedSegments.
	* drivers/net/tcpip/network/transmit.c (SendFragments): Release memory
	for Data on failure.
	* drivers/net/tcpip/tcpip/address.c (AddrCloneAddress): New function.
	* drivers/net/tcpip/tcpip/checksum.c (ChecksumFold): Factor out folding
	from ChecksumCompute.
	* drivers/net/tcpip/tcpip/dispatch.c (DispTdiListen): Support asynchronous
	operation.
	* drivers/net/tcpip/tcpip/fileobjs.c (FileOpenAddress): Don't cast to
	PTDI_ADDRESS_IP.
	Initialize ReceivedSegments.
	* drivers/net/tcpip/tcpip/routines.c (DisplayIPHeader): New function.
	(DisplayIPPacket): Call DisplayIPHeader().
	(DisplayTCPHeader): Change format strings.
	* drivers/net/tcpip/transport/tcp/tcp.c (IPIdentification,
	TCPSegmentList): Add.
	(TCPCreateSegment, TCPFreeSegment, TCPAddSegment,
	TCPBuildAndTransmitSendRequest2, TCPiSelectISS, TCPiReceiveListen,
	TCPiReceiveSynSent, TCPiReceiveSynReceived, TCPiReceiveData): New
	function.
	(TCPiBuildPacket): Build segment.
	(TCPStartup): Initialize TCPSegmentList.
	(TCPShutdown): Cleanup TCPSegmentList.

svn path=/trunk/; revision=8537
This commit is contained in:
Casper Hornstrup 2004-03-04 20:45:39 +00:00
parent 0d2b52fb76
commit 318a90741d
23 changed files with 1577 additions and 409 deletions

View file

@ -1,3 +1,53 @@
2004-03-04 Casper S. Hornstrup <chorns@users.sourceforge.net>
* drivers/net/tcpip/tcpip/i386: New directory.
* drivers/net/tcpip/tcpip/i386/checksum.S: New file.
* drivers/net/tcpip/notes.txt: New file.
* drivers/net/afd/afd/dispatch.c (AfdDispCompleteListen): Signal ACCEPT
network event.
(AfdDispEventSelect): Reference event handle.
* drivers/net/afd/afd/tdi.c (TdiListen): Remove unused event.
Move Iosb and RequestConnectionInfo to AFD_LISTEN_REQUEST structure.
* drivers/net/afd/include/afd.h (AFDFCB): Replace EventObjects with
EventObject of type PKEVENT.
* drivers/net/tcpip/makefile (ARCH_OBJECTS): New variable.
(TARGET_OBJECTS): Add ARCH_OBJECTS.
* drivers/net/tcpip/include/address.h (AddrCloneAddress): New prototype.
* drivers/net/tcpip/include/checksum.h (ChecksumFold, csum_partial): New
prototype.
(TCPv4Checksum): New macro.
(CorrectChecksum): Rename to IPv4CorrectChecksum.
(TCPv4CorrectChecksum): New macro.
* drivers/net/tcpip/include/ip.h (IPv4_DF_MASK): New constant.
* drivers/net/tcpip/include/tcp.h (TCP_XXX): Correct constants.
(TCPCreateSegment, TCPFreeSegment, TCPAddSegment): Prototype.
* drivers/net/tcpip/include/titypes.h (TCP_SEND_REQUEST): Add SequenceNumber
and AckNumber.
(TCP_SEGMENT): New structure.
(CONNECTION_ENDPOINT): Add ListenRequest and ReceivedSegments.
* drivers/net/tcpip/network/transmit.c (SendFragments): Release memory
for Data on failure.
* drivers/net/tcpip/tcpip/address.c (AddrCloneAddress): New function.
* drivers/net/tcpip/tcpip/checksum.c (ChecksumFold): Factor out folding
from ChecksumCompute.
* drivers/net/tcpip/tcpip/dispatch.c (DispTdiListen): Support asynchronous
operation.
* drivers/net/tcpip/tcpip/fileobjs.c (FileOpenAddress): Don't cast to
PTDI_ADDRESS_IP.
Initialize ReceivedSegments.
* drivers/net/tcpip/tcpip/routines.c (DisplayIPHeader): New function.
(DisplayIPPacket): Call DisplayIPHeader().
(DisplayTCPHeader): Change format strings.
* drivers/net/tcpip/transport/tcp/tcp.c (IPIdentification,
TCPSegmentList): Add.
(TCPCreateSegment, TCPFreeSegment, TCPAddSegment,
TCPBuildAndTransmitSendRequest2, TCPiSelectISS, TCPiReceiveListen,
TCPiReceiveSynSent, TCPiReceiveSynReceived, TCPiReceiveData): New
function.
(TCPiBuildPacket): Build segment.
(TCPStartup): Initialize TCPSegmentList.
(TCPShutdown): Cleanup TCPSegmentList.
2004-02-25 Casper S. Hornstrup <chorns@users.sourceforge.net>
* drivers/net/tcpip/datalink/loopback.c: Reformat.

View file

@ -139,9 +139,25 @@ AfdDispCompleteListen(
{
PAFD_LISTEN_REQUEST ListenRequest = (PAFD_LISTEN_REQUEST) Context;
AFD_DbgPrint(MAX_TRACE, ("Called. ListenRequest (0x%X).\n", ListenRequest));
/* FIXME: Protect ListenRequest->Fcb->ListenRequestQueue */
RemoveEntryList(&ListenRequest->ListEntry);
AFD_DbgPrint(MAX_TRACE, ("Fcb (0x%X).\n", ListenRequest->Fcb));
AFD_DbgPrint(MAX_TRACE, ("Completed ListenRequest at (0x%X).\n", ListenRequest));
if (NT_SUCCESS(ListenRequest->Iosb.Status))
{
if (ListenRequest->Fcb->EventObject != NULL)
{
/* FIXME: Protect ListenRequest->Fcb */
ListenRequest->Fcb->NetworkEvents.lNetworkEvents |= FD_ACCEPT;
ListenRequest->Fcb->NetworkEvents.iErrorCode[FD_ACCEPT_BIT] = NO_ERROR;
KeSetEvent(ListenRequest->Fcb->EventObject, EVENT_INCREMENT, FALSE);
}
}
ExFreePool(ListenRequest->RequestConnectionInfo);
ListenRequest->RequestConnectionInfo = NULL;
ExFreePool(ListenRequest);
return STATUS_SUCCESS;
}
@ -197,14 +213,14 @@ NTSTATUS AfdDispListen(
if (NT_SUCCESS(Status))
{
ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
if (ListenRequest != NULL)
{
ListenRequest->Fcb = FCB;
/* FIXME: Protect ListenRequestQueue */
InsertTailList(&FCB->ListenRequestQueue, &ListenRequest->ListEntry);
Status = TdiListen(FCB->TdiConnectionObject, AfdDispCompleteListen, ListenRequest);
Status = TdiListen(ListenRequest, AfdDispCompleteListen, ListenRequest);
if ((Status == STATUS_PENDING) || NT_SUCCESS(Status))
{
if (Status != STATUS_PENDING)
@ -630,8 +646,8 @@ NTSTATUS AfdDispEventSelect(
UINT OutputBufferLength;
PFILE_REQUEST_EVENTSELECT Request;
PFILE_REPLY_EVENTSELECT Reply;
PKEVENT Event;
PAFDFCB FCB;
ULONG i;
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
@ -644,20 +660,32 @@ NTSTATUS AfdDispEventSelect(
Request = (PFILE_REQUEST_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
FCB->NetworkEvents.lNetworkEvents = Request->lNetworkEvents;
for (i = 0; i < FD_MAX_EVENTS; i++) {
if ((Request->lNetworkEvents & (1 << i)) > 0) {
FCB->EventObjects[i] = Request->hEventObject;
} else {
/* The effect of any previous call to this function is cancelled */
FCB->EventObjects[i] = (WSAEVENT)0;
}
}
/* FIXME: Need to ObDereferenceObject(FCB->EventObject) this somewhere */
Status = ObReferenceObjectByHandle(
Request->hEventObject,
0,
ExEventObjectType,
UserMode,
(PVOID*)&Event,
NULL);
if (NT_SUCCESS(Status)) {
FCB->NetworkEvents.lNetworkEvents = Request->lNetworkEvents;
FCB->EventObject = Event;
Reply->Status = NO_ERROR;
Status = STATUS_SUCCESS;
}
else
{
AFD_DbgPrint(MID_TRACE, ("Bad event handle (0x%X).\n", Status));
Reply->Status = NO_ERROR;
Status = STATUS_SUCCESS;
} else
Reply->Status = WSAEINVAL;
Status = STATUS_SUCCESS;
}
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));

View file

@ -199,6 +199,7 @@ NTSTATUS TdiOpenAddressFileIPv4(
EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
TdiBuildAddressIPv4(Address, Name);
Status = TdiOpenDevice(DeviceName,
EaLength,
EaInfo,
@ -414,13 +415,13 @@ NTSTATUS TdiAssociateAddressFile(
NTSTATUS TdiListen(
PFILE_OBJECT ConnectionObject,
PAFD_LISTEN_REQUEST ListenRequest,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
* FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
* ARGUMENTS:
* ConnectionObject = Pointer to connection endpoint file object
* ListenRequest = Pointer to listen request object
* CompletionRoutine = Routine to be called when IRP is completed
* CompletionContext = Context for CompletionRoutine
* RETURNS:
@ -428,35 +429,34 @@ NTSTATUS TdiListen(
* May return STATUS_PENDING
*/
{
PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
//PTDI_CONNECTION_INFORMATION ReturnConnectionInfo;
PFILE_OBJECT ConnectionObject;
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
ConnectionObject = ListenRequest->Fcb->TdiConnectionObject;
assert(ConnectionObject);
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
Status = TdiBuildNullConnectionInfo(&RequestConnectionInfo, TDI_ADDRESS_TYPE_IP);
Status = TdiBuildNullConnectionInfo(&ListenRequest->RequestConnectionInfo,
TDI_ADDRESS_TYPE_IP);
if (!NT_SUCCESS(Status))
return Status;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
return Status;
Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
&Event, /* Event */
&Iosb); /* Status */
if (!Irp) {
ExFreePool(RequestConnectionInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
NULL, /* Event */
&ListenRequest->Iosb); /* Status */
if (Irp == NULL)
{
ExFreePool(ListenRequest->RequestConnectionInfo);
ListenRequest->RequestConnectionInfo = NULL;
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildListen(Irp, /* IRP */
DeviceObject, /* Device object */
@ -464,13 +464,10 @@ NTSTATUS TdiListen(
CompletionRoutine, /* Completion routine */
CompletionContext, /* Completion routine context */
0, /* Flags */
RequestConnectionInfo, /* Request connection information */
ListenRequest->RequestConnectionInfo, /* Request connection information */
NULL /* ReturnConnectionInfo */); /* Return connection information */
Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &Iosb);
ExFreePool(RequestConnectionInfo);
//ExFreePool(ReturnConnectionInfo);
Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &ListenRequest->Iosb);
return Status;
}

View file

@ -75,7 +75,7 @@ typedef struct _AFDFCB {
LIST_ENTRY ListenRequestQueue;
/* For WSAEventSelect() */
WSANETWORKEVENTS NetworkEvents;
WSAEVENT EventObjects[FD_MAX_EVENTS];
PKEVENT EventObject;
} AFDFCB, *PAFDFCB;
/* Socket states */
@ -99,6 +99,8 @@ typedef struct _AFD_READ_REQUEST {
typedef struct _AFD_LISTEN_REQUEST {
LIST_ENTRY ListEntry;
PAFDFCB Fcb;
PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
IO_STATUS_BLOCK Iosb;
} AFD_LISTEN_REQUEST, *PAFD_LISTEN_REQUEST;
typedef struct IPSNMP_INFO {
@ -363,7 +365,7 @@ NTSTATUS TdiAssociateAddressFile(
PFILE_OBJECT ConnectionObject);
NTSTATUS TdiListen(
PFILE_OBJECT ConnectionObject,
PAFD_LISTEN_REQUEST Request,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);

View file

@ -61,6 +61,9 @@ BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address);
PIP_ADDRESS AddrCloneAddress(
PIP_ADDRESS Address);
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address);

View file

@ -8,20 +8,39 @@
#define __CHECKSUM_H
ULONG ChecksumFold(
ULONG Sum);
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed);
#define IPv4Checksum(Data, Count, Seed)(ChecksumCompute(Data, Count, Seed))
unsigned int
csum_partial(
const unsigned char * buff,
int len,
unsigned int sum);
#define IPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(csum_partial(Data, Count, Seed)))
//#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
/*
* Macro to check for a correct checksum
* BOOLEAN CorrectChecksum(PVOID Data, UINT Count)
* BOOLEAN IPv4CorrectChecksum(PVOID Data, UINT Count)
*/
#define CorrectChecksum(Data, Count) \
#define IPv4CorrectChecksum(Data, Count) \
(BOOLEAN)(IPv4Checksum(Data, Count, 0) == DH2N(0x0000FFFF))
#endif /* __CHECKSUM_H */
/*
* Macro to check for a correct checksum
* BOOLEAN TCPv4CorrectChecksum(PTCPv4_PSEUDO_HEADER TcpPseudoHeader,
* PVOID Data, UINT Count)
*/
#define TCPv4CorrectChecksum(TcpPseudoHeader, Data, Count) \
(BOOLEAN)(TCPv4Checksum(Data, Count, \
TCPv4Checksum(TcpPseudoHeader, sizeof(TCPv4_PSEUDO_HEADER), \
0)) == DH2N(0x0000FFFF))
/* EOF */
#endif /* __CHECKSUM_H */

View file

@ -49,8 +49,9 @@ typedef struct IPv4_HEADER {
IPv4_RAW_ADDRESS DstAddr; /* Destination Address */
} IPv4_HEADER, *PIPv4_HEADER;
#define IPv4_FRAGOFS_MASK 0x1FFF
#define IPv4_MF_MASK 0x2000
#define IPv4_FRAGOFS_MASK 0x1FFF /* Fragment offset mask (host byte order) */
#define IPv4_MF_MASK 0x2000 /* More fragments (host byte order) */
#define IPv4_DF_MASK 0x4000 /* Don't fragment (host byte order) */
#define IPv4_MAX_HEADER_SIZE 60
/* Packet completion handler prototype */
@ -60,7 +61,7 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)(
NDIS_STATUS NdisStatus);
/* Structure for an IP packet */
typedef struct IP_PACKET {
typedef struct _IP_PACKET {
DEFINE_TAG
ULONG RefCount; /* Reference count for this object */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
@ -81,7 +82,7 @@ typedef struct IP_PACKET {
/* Packet context */
typedef struct PACKET_CONTEXT {
typedef struct _PACKET_CONTEXT {
PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */
PVOID Context; /* Context information for handler */
PACKET_COMPLETION_ROUTINE DLComplete; /* Data link level completion handler. Also

View file

@ -7,27 +7,26 @@
#ifndef __TCP_H
#define __TCP_H
/* TCPv4 header structure */
typedef struct TCP_HEADER {
USHORT SourcePort; /* Source port */
USHORT DestPort; /* Destination port */
USHORT SeqNum; /* Sequence number */
USHORT AckNum; /* Acknowledgment number */
UCHAR DataOfs; /* Data offset (leftmost 4 bits) */
UCHAR Flags; /* Control bits (rightmost 6 bits) */
USHORT Window; /* Maximum acceptable receive window */
USHORT Checksum; /* Checksum of segment */
USHORT Urgent; /* Pointer to urgent data */
} __attribute__((packed)) TCP_HEADER, *PTCP_HEADER;
typedef struct TCPv4_HEADER {
USHORT SourcePort; /* Source port */
USHORT DestinationPort; /* Destination port */
ULONG SequenceNumber; /* Sequence number */
ULONG AckNumber; /* Acknowledgement number */
UCHAR DataOffset; /* Data offset; 32-bit words (leftmost 4 bits) */
UCHAR Flags; /* Control bits (rightmost 6 bits) */
USHORT Window; /* Maximum acceptable receive window */
USHORT Checksum; /* Checksum of segment */
USHORT Urgent; /* Pointer to urgent data */
} __attribute__((packed)) TCPv4_HEADER, *PTCPv4_HEADER;
/* TCPv4 header flags */
#define TCP_URG 0x04
#define TCP_ACK 0x08
#define TCP_PSH 0x10
#define TCP_RST 0x20
#define TCP_SYN 0x40
#define TCP_FIN 0x80
#define TCP_URG 0x20
#define TCP_ACK 0x10
#define TCP_PSH 0x08
#define TCP_RST 0x04
#define TCP_SYN 0x02
#define TCP_FIN 0x01
#define TCPOPT_END_OF_LIST 0x0
@ -38,13 +37,13 @@ typedef struct TCP_HEADER {
/* TCPv4 pseudo header */
typedef struct TCP_PSEUDO_HEADER {
ULONG SourceAddress; /* Source address */
ULONG DestAddress; /* Destination address */
UCHAR Zero; /* Reserved */
UCHAR Protocol; /* Protocol */
USHORT TCPLength; /* Size of TCP segment */
} __attribute__((packed)) TCP_PSEUDO_HEADER, *PTCP_PSEUDO_HEADER;
typedef struct TCPv4_PSEUDO_HEADER {
ULONG SourceAddress; /* Source address */
ULONG DestinationAddress; /* Destination address */
UCHAR Zero; /* Reserved */
UCHAR Protocol; /* Protocol */
USHORT TCPLength; /* Size of TCP segment */
} __attribute__((packed)) TCPv4_PSEUDO_HEADER, *PTCPv4_PSEUDO_HEADER;
/* Retransmission timeout constants */
@ -72,6 +71,18 @@ typedef struct TCP_PSEUDO_HEADER {
#define SRF_FIN TCP_FIN
PTCP_SEGMENT TCPCreateSegment(
PIP_PACKET IPPacket,
ULONG SequenceNumber,
ULONG SegmentLength);
VOID TCPFreeSegment(
PTCP_SEGMENT Segment);
VOID TCPAddSegment(
PCONNECTION_ENDPOINT Connection,
PTCP_SEGMENT Segment);
inline NTSTATUS TCPBuildSendRequest(
PTCP_SEND_REQUEST *SendRequest,
PDATAGRAM_SEND_REQUEST *DGSendRequest,
@ -113,5 +124,3 @@ NTSTATUS TCPShutdown(
VOID);
#endif /* __TCP_H */
/* EOF */

View file

@ -266,6 +266,8 @@ typedef struct _TCP_SEND_REQUEST {
PVOID Context; /* Pointer to context information */
PVOID ProtocolContext; /* Protocol specific context */
ULONG Flags; /* Protocol specific flags */
ULONG SequenceNumber; /* Sequence number (network byte order) */
ULONG AckNumber; /* Acknowledgement number (network byte order) */
} TCP_SEND_REQUEST, *PTCP_SEND_REQUEST;
#define InitializeTCPSendRequest( \
@ -296,6 +298,15 @@ typedef enum {
} CONNECTION_STATE, *PCONNECTION_STATE;
/* Structure for an TCP segment */
typedef struct _TCP_SEGMENT {
LIST_ENTRY ListEntry;
PIP_PACKET IPPacket; /* Pointer to IP packet */
ULONG SequenceNumber; /* Sequence number of first byte in segment */
ULONG Length; /* Number of bytes in segment */
} TCP_SEGMENT, *PTCP_SEGMENT;
/* Transport connection context structure A.K.A. Transmission Control Block
(TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
to this structure */
@ -324,14 +335,21 @@ typedef struct _CONNECTION_ENDPOINT {
ULONG SendISS; /* Initial send sequence number */
/* Receive sequence variables */
ULONG RecvNext; /* Sequence number of last data block received */
ULONG RecvWindow; /* Maximum allowed number of octets in a segment */
ULONG RecvUrgentPointer; /* Sequence number of start of urgent data */
ULONG RecvIRS; /* Initial receive sequence number */
ULONG ReceiveNext; /* Sequence number of last data block received */
ULONG ReceiveWindow; /* Maximum allowed number of octets in a segment */
ULONG ReceiveUrgentPointer; /* Sequence number of start of urgent data */
ULONG ReceiveIRS; /* Initial receive sequence number */
/* Statistics for computing the retransmission timeout */
ULONG TimestampSend; /* Timestamp when sending a segment */
ULONG TimestampAck; /* Timestamp when receiving acknowledgment */
/* Requests */
PTDI_REQUEST ListenRequest; /* Queued listen request */
/* Queues */
LIST_ENTRY ReceivedSegments;
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.15 2004/03/02 18:18:14 navaraf Exp $
# $Id: makefile,v 1.16 2004/03/04 20:45:38 chorns Exp $
PATH_TO_TOP = ../../..
@ -34,6 +34,7 @@ TCP_OBJECTS = transport/tcp/tcp.o transport/tcp/tcpcore.o \
transport/tcp/tcp_input.o transport/tcp/tcp_ipv4.o \
transport/tcp/tcp_output.o transport/tcp/tcp_timer.o
UDP_OBJECTS = transport/udp/udp.o
ARCH_OBJECTS = tcpip/i386/checksum.o
TARGET_OBJECTS = \
$(TCPIP_OBJECTS) \
@ -42,7 +43,8 @@ TARGET_OBJECTS = \
$(DATAGRAM_OBJECTS) \
$(RAWIP_OBJECTS) \
$(TCP_OBJECTS) \
$(UDP_OBJECTS)
$(UDP_OBJECTS) \
$(ARCH_OBJECTS)
include $(PATH_TO_TOP)/rules.mak

View file

@ -182,7 +182,7 @@ VOID ICMPReceive(
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
/* Checksum ICMP header and data */
if (!CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
if (!IPv4CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n"));
/* Discard packet */
return;

View file

@ -552,7 +552,7 @@ VOID IPv4Receive(
}
/* Checksum IPv4 header */
if (!CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
if (!IPv4CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
/* Discard packet */

View file

@ -104,13 +104,13 @@ NTSTATUS SendFragments(
IPPacket, NCE, PathMTU));
IFC = ExAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
if (!IFC)
if (IFC == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
/* We allocate a buffer for a PathMTU sized packet and reuse
it for all fragments */
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (!IFC->Header) {
if (Data == NULL) {
ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -118,7 +118,7 @@ NTSTATUS SendFragments(
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
//ExFreePool(Data); // RobD - why are we trying to free this here?, not allocated yet!
ExFreePool(Data);
ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}

View file

@ -0,0 +1,27 @@
RFC 791 - Internet Protocol
http://www.faqs.org/rfcs/rfc791.html
RFC 792 - Internet Control Message Protocol
http://www.faqs.org/rfcs/rfc792.html
RFC 793 - Transmission Control Protocol
http://www.faqs.org/rfcs/rfc793.html
RFC 826 - Ethernet Address Resolution Protocol
http://www.faqs.org/rfcs/rfc826.html
RFC 1122 - Requirements for Internet Hosts - Communication Layers
http://www.faqs.org/rfcs/rfc1122.html
RFC 1123 - Requirements for Internet Hosts - Application and Support
http://www.faqs.org/rfcs/rfc1123.html
RFC 2398 - Some Testing Tools for TCP Implementors
http://www.faqs.org/rfcs/rfc2398.html
RFC 2525 - Known TCP Implementation Problems
http://www.faqs.org/rfcs/rfc2525.html
RFC 2581 - TCP Congestion Control
http://www.faqs.org/rfcs/rfc2581.html

View file

@ -289,7 +289,7 @@ BOOLEAN AddrIsEqualIPv4(
/*
* FUNCTION: Build an IPv4 style address
* ARGUMENTS:
* Address = Raw IPv4 address
* Address = Raw IPv4 address (network byte order)
* RETURNS:
* Pointer to IP address structure, NULL if there was not enough free
* non-paged memory
@ -300,7 +300,7 @@ PIP_ADDRESS AddrBuildIPv4(
PIP_ADDRESS IPAddress;
IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
if (IPAddress) {
if (IPAddress != NULL) {
IPAddress->RefCount = 1;
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
@ -311,6 +311,29 @@ PIP_ADDRESS AddrBuildIPv4(
}
/*
* FUNCTION: Clone an IP address
* ARGUMENTS:
* IPAddress = Pointer to IP address
* RETURNS:
* Pointer to new IP address structure, NULL if there was not enough free
* non-paged memory
*/
PIP_ADDRESS AddrCloneAddress(
PIP_ADDRESS Address)
{
if (Address->Type == IP_ADDRESS_V4)
{
return AddrBuildIPv4(Address->Address.IPv4Address);
}
else
{
TI_DbgPrint(MIN_TRACE, ("Cannot clone IPv6 address.\n"));
return NULL;
}
}
/*
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
* ARGUMENTS:

View file

@ -12,10 +12,22 @@
#include <checksum.h>
ULONG ChecksumFold(
ULONG Sum)
{
/* Fold 32-bit sum to 16 bits */
while (Sum >> 16)
{
Sum = (Sum & 0xFFFF) + (Sum >> 16);
}
return Sum;
}
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed)
PVOID Data,
UINT Count,
ULONG Seed)
/*
* FUNCTION: Calculate checksum of a buffer
* ARGUMENTS:
@ -26,25 +38,20 @@ ULONG ChecksumCompute(
* Checksum of buffer
*/
{
/* FIXME: This should be done in assembler */
register ULONG Sum = Seed;
register ULONG Sum = Seed;
while (Count > 1) {
Sum += *(PUSHORT)Data;
Count -= 2;
(ULONG_PTR)Data += 2;
while (Count > 1)
{
Sum += *(PUSHORT)Data;
Count -= 2;
(ULONG_PTR)Data += 2;
}
/* Add left-over byte, if any */
if (Count > 0)
Sum += *(PUCHAR)Data;
/* Add left-over byte, if any */
if (Count > 0)
{
Sum += *(PUCHAR)Data;
}
/* Fold 32-bit sum to 16 bits */
while (Sum >> 16)
Sum = (Sum & 0xFFFF) + (Sum >> 16);
return ~Sum;
return Sum;
}
/* EOF */

View file

@ -529,8 +529,9 @@ NTSTATUS DispTdiListen(
PTDI_REQUEST_KERNEL Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
TDI_REQUEST Request;
PTDI_REQUEST Request;
NTSTATUS Status;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@ -539,28 +540,51 @@ NTSTATUS DispTdiListen(
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
if (TranContext == NULL)
{
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_CONNECTION;
}
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
if (!Connection) {
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
if (Connection == NULL)
{
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
return STATUS_INVALID_CONNECTION;
}
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
/* Initialize a connect request */
Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
Request.RequestNotifyObject = DispDataRequestComplete;
Request.RequestContext = Irp;
/* Initialize a listen request */
Request = (PTDI_REQUEST) ExAllocatePool(NonPagedPool, sizeof(TDI_REQUEST));
if (Request == NULL)
{
return STATUS_NO_MEMORY;
}
Status = TCPListen(
&Request,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation);
Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
if (NT_SUCCESS(Status))
{
Request->Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
Request->RequestNotifyObject = DispDataRequestComplete;
Request->RequestContext = Irp;
Status = TCPListen(
Request,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation);
if (Status != STATUS_PENDING)
{
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldIrql);
}
}
if (Status != STATUS_PENDING)
{
ExFreePool(Request);
}
return Status;
}

View file

@ -296,13 +296,13 @@ NTSTATUS FileOpenAddress(
switch (Protocol) {
case IPPROTO_TCP:
/* FIXME: If specified port is 0, a port is chosen dynamically */
AddrFile->Port = ((PTDI_ADDRESS_IP)Address->Address)->sin_port;
AddrFile->Port = Address->Address[0].Address[0].sin_port;
AddrFile->Send = TCPSendDatagram;
break;
case IPPROTO_UDP:
/* FIXME: If specified port is 0, a port is chosen dynamically */
AddrFile->Port = ((PTDI_ADDRESS_IP)Address->Address)->sin_port;
AddrFile->Port = Address->Address[0].Address[0].sin_port;
AddrFile->Send = UDPSendDatagram;
break;
@ -449,6 +449,9 @@ NTSTATUS FileOpenConnection(
/* Save client context pointer */
Connection->ClientContext = ClientContext;
/* Initialize receive queue */
InitializeListHead(&Connection->ReceivedSegments);
/* Return connection endpoint file object */
Request->Handle.ConnectionContext = Connection;

View file

@ -0,0 +1,249 @@
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* IP/TCP/UDP checksumming routines
*
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Tom May, <ftom@netcom.com>
* Pentium Pro/II routines:
* Alexander Kjeldaas <astor@guardian.no>
* Finn Arne Gangstad <finnag@guardian.no>
* Lots of code moved from tcp.c and ip.c; see those files
* for more names.
*
* Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
* handling.
* Andi Kleen, add zeroing on error
* converted to pure assembler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
/*
* computes a partial checksum, e.g. for TCP/UDP fragments
*/
/*
unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
*/
.text
.align 4
.globl _csum_partial
#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
/*
* Experiments with Ethernet and SLIP connections show that buff
* is aligned on either a 2-byte or 4-byte boundary. We get at
* least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
* Fortunately, it is easy to convert 2-byte alignment to 4-byte
* alignment for the unrolled loop.
*/
_csum_partial:
pushl %esi
pushl %ebx
movl 20(%esp),%eax # Function arg: unsigned int sum
movl 16(%esp),%ecx # Function arg: int len
movl 12(%esp),%esi # Function arg: unsigned char *buff
testl $3, %esi # Check alignment.
jz 2f # Jump if alignment is ok.
testl $1, %esi # Check alignment.
jz 10f # Jump if alignment is boundary of 2bytes.
# buf is odd
dec %ecx
jl 8f
movzbl (%esi), %ebx
adcl %ebx, %eax
roll $8, %eax
inc %esi
testl $2, %esi
jz 2f
10:
subl $2, %ecx # Alignment uses up two bytes.
jae 1f # Jump if we had at least two bytes.
addl $2, %ecx # ecx was < 2. Deal with it.
jmp 4f
1: movw (%esi), %bx
addl $2, %esi
addw %bx, %ax
adcl $0, %eax
2:
movl %ecx, %edx
shrl $5, %ecx
jz 2f
testl %esi, %esi
1: movl (%esi), %ebx
adcl %ebx, %eax
movl 4(%esi), %ebx
adcl %ebx, %eax
movl 8(%esi), %ebx
adcl %ebx, %eax
movl 12(%esi), %ebx
adcl %ebx, %eax
movl 16(%esi), %ebx
adcl %ebx, %eax
movl 20(%esi), %ebx
adcl %ebx, %eax
movl 24(%esi), %ebx
adcl %ebx, %eax
movl 28(%esi), %ebx
adcl %ebx, %eax
lea 32(%esi), %esi
dec %ecx
jne 1b
adcl $0, %eax
2: movl %edx, %ecx
andl $0x1c, %edx
je 4f
shrl $2, %edx # This clears CF
3: adcl (%esi), %eax
lea 4(%esi), %esi
dec %edx
jne 3b
adcl $0, %eax
4: andl $3, %ecx
jz 7f
cmpl $2, %ecx
jb 5f
movw (%esi),%cx
leal 2(%esi),%esi
je 6f
shll $16,%ecx
5: movb (%esi),%cl
6: addl %ecx,%eax
adcl $0, %eax
7:
testl $1, 12(%esp)
jz 8f
roll $8, %eax
8:
popl %ebx
popl %esi
ret
#else
/* Version for PentiumII/PPro */
csum_partial:
pushl %esi
pushl %ebx
movl 20(%esp),%eax # Function arg: unsigned int sum
movl 16(%esp),%ecx # Function arg: int len
movl 12(%esp),%esi # Function arg: const unsigned char *buf
testl $3, %esi
jnz 25f
10:
movl %ecx, %edx
movl %ecx, %ebx
andl $0x7c, %ebx
shrl $7, %ecx
addl %ebx,%esi
shrl $2, %ebx
negl %ebx
lea 45f(%ebx,%ebx,2), %ebx
testl %esi, %esi
jmp *%ebx
# Handle 2-byte-aligned regions
20: addw (%esi), %ax
lea 2(%esi), %esi
adcl $0, %eax
jmp 10b
25:
testl $1, %esi
jz 30f
# buf is odd
dec %ecx
jl 90f
movzbl (%esi), %ebx
addl %ebx, %eax
adcl $0, %eax
roll $8, %eax
inc %esi
testl $2, %esi
jz 10b
30: subl $2, %ecx
ja 20b
je 32f
addl $2, %ecx
jz 80f
movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
addl %ebx, %eax
adcl $0, %eax
jmp 80f
32:
addw (%esi), %ax # csumming 2 bytes, 2-aligned
adcl $0, %eax
jmp 80f
40:
addl -128(%esi), %eax
adcl -124(%esi), %eax
adcl -120(%esi), %eax
adcl -116(%esi), %eax
adcl -112(%esi), %eax
adcl -108(%esi), %eax
adcl -104(%esi), %eax
adcl -100(%esi), %eax
adcl -96(%esi), %eax
adcl -92(%esi), %eax
adcl -88(%esi), %eax
adcl -84(%esi), %eax
adcl -80(%esi), %eax
adcl -76(%esi), %eax
adcl -72(%esi), %eax
adcl -68(%esi), %eax
adcl -64(%esi), %eax
adcl -60(%esi), %eax
adcl -56(%esi), %eax
adcl -52(%esi), %eax
adcl -48(%esi), %eax
adcl -44(%esi), %eax
adcl -40(%esi), %eax
adcl -36(%esi), %eax
adcl -32(%esi), %eax
adcl -28(%esi), %eax
adcl -24(%esi), %eax
adcl -20(%esi), %eax
adcl -16(%esi), %eax
adcl -12(%esi), %eax
adcl -8(%esi), %eax
adcl -4(%esi), %eax
45:
lea 128(%esi), %esi
adcl $0, %eax
dec %ecx
jge 40b
movl %edx, %ecx
50: andl $3, %ecx
jz 80f
# Handle the last 1-3 bytes without jumping
notl %ecx # 1->2, 2->1, 3->0, higher bits are masked
movl $0xffffff,%ebx # by the shll and shrl instructions
shll $3,%ecx
shrl %cl,%ebx
andl -128(%esi),%ebx # esi is 4-aligned so should be ok
addl %ebx,%eax
adcl $0,%eax
80:
testl $1, 12(%esp)
jz 90f
roll $8, %eax
90:
popl %ebx
popl %esi
ret
#endif

View file

@ -480,6 +480,33 @@ UINT ResizePacket(
#ifdef DBG
static VOID DisplayIPHeader(
PUCHAR Header,
UINT Length)
{
/* FIXME: IPv4 only */
PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
DbgPrint("IPv4 header:\n");
DbgPrint("VerIHL: 0x%x (version 0x%x, length %d 32-bit words)\n",
IPHeader->VerIHL, (IPHeader->VerIHL & 0xF0) >> 4, IPHeader->VerIHL & 0x0F);
DbgPrint(" Tos: %d\n", IPHeader->Tos);
DbgPrint(" TotalLength: %d\n", WN2H(IPHeader->TotalLength));
DbgPrint(" Id: %d\n", WN2H(IPHeader->Id));
DbgPrint(" FlagsFragOfs: 0x%x (offset 0x%x)\n", WN2H(IPHeader->FlagsFragOfs), WN2H(IPHeader->FlagsFragOfs) & IPv4_FRAGOFS_MASK);
if ((WN2H(IPHeader->FlagsFragOfs) & IPv4_DF_MASK) > 0) DbgPrint(" IPv4_DF - Don't fragment\n");
if ((WN2H(IPHeader->FlagsFragOfs) & IPv4_MF_MASK) > 0) DbgPrint(" IPv4_MF - More fragments\n");
DbgPrint(" Ttl: %d\n", IPHeader->Ttl);
DbgPrint(" Protocol: %d\n", IPHeader->Protocol);
DbgPrint(" Checksum: 0x%x\n", WN2H(IPHeader->Checksum));
DbgPrint(" SrcAddr: %d.%d.%d.%d\n",
((IPHeader->SrcAddr >> 0) & 0xFF), ((IPHeader->SrcAddr >> 8) & 0xFF),
((IPHeader->SrcAddr >> 16) & 0xFF), ((IPHeader->SrcAddr >> 24) & 0xFF));
DbgPrint(" DstAddr: %d.%d.%d.%d\n",
((IPHeader->DstAddr >> 0) & 0xFF), ((IPHeader->DstAddr >> 8) & 0xFF),
((IPHeader->DstAddr >> 16) & 0xFF), ((IPHeader->DstAddr >> 24) & 0xFF));
}
VOID DisplayIPPacket(
PIP_PACKET IPPacket)
{
@ -488,6 +515,7 @@ VOID DisplayIPPacket(
UINT Length;
PNDIS_BUFFER Buffer;
PNDIS_BUFFER NextBuffer;
PUCHAR CharBuffer;
if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_IP)) != (DEBUG_BUFFER | DEBUG_IP)) {
return;
@ -528,6 +556,19 @@ VOID DisplayIPPacket(
}
DbgPrint("\n");
}
if (IPPacket->NdisPacket) {
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
Length -= MaxLLHeaderSize;
CharBuffer = ExAllocatePool(NonPagedPool, Length);
Length = CopyPacketToBuffer(CharBuffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
DisplayIPHeader(CharBuffer, Length);
ExFreePool(CharBuffer);
} else {
CharBuffer = IPPacket->Header;
Length = IPPacket->ContigSize;
DisplayIPHeader(CharBuffer, Length);
}
}
@ -537,32 +578,31 @@ static VOID DisplayTCPHeader(
{
/* FIXME: IPv4 only */
PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
PTCP_HEADER TCPHeader;
PTCPv4_HEADER TCPHeader;
if (IPHeader->Protocol != IPPROTO_TCP) {
DbgPrint("This is not a TCP datagram. Protocol is %d\n", IPHeader->Protocol);
return;
}
DbgPrint("VerIHL: 0x%x\n", IPHeader->VerIHL);
TCPHeader = (PTCP_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
TCPHeader = (PTCPv4_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
DbgPrint("TCP header:\n");
DbgPrint(" SourcePort: %d\n", WN2H(TCPHeader->SourcePort));
DbgPrint(" DestPort: %d\n", WN2H(TCPHeader->DestPort));
DbgPrint(" SeqNum: %d\n", WN2H(TCPHeader->SeqNum));
DbgPrint(" AckNum: %d\n", WN2H(TCPHeader->AckNum));
DbgPrint(" DataOfs: %d (%d)\n", TCPHeader->DataOfs, TCPHeader->DataOfs & 0x0F);
DbgPrint(" DestinationPort: %d\n", WN2H(TCPHeader->DestinationPort));
DbgPrint(" SequenceNumber: 0x%x\n", DN2H(TCPHeader->SequenceNumber));
DbgPrint(" AckNumber: 0x%x\n", DN2H(TCPHeader->AckNumber));
DbgPrint(" DataOffset: 0x%x (0x%x) 32-bit words\n", TCPHeader->DataOffset, TCPHeader->DataOffset >> 4);
DbgPrint(" Flags: 0x%x (0x%x)\n", TCPHeader->Flags, TCPHeader->Flags & 0x3F);
if ((TCPHeader->Flags & TCP_URG) > 0) DbgPrint(" TCP_URG - Urgent Pointer field significant\n");
if ((TCPHeader->Flags & TCP_ACK) > 0) DbgPrint(" TCP_ACK - Acknowledgment field significant\n");
if ((TCPHeader->Flags & TCP_ACK) > 0) DbgPrint(" TCP_ACK - Acknowledgement field significant\n");
if ((TCPHeader->Flags & TCP_PSH) > 0) DbgPrint(" TCP_PSH - Push Function\n");
if ((TCPHeader->Flags & TCP_RST) > 0) DbgPrint(" TCP_RST - Reset the connection\n");
if ((TCPHeader->Flags & TCP_SYN) > 0) DbgPrint(" TCP_SYN - Synchronize sequence numbers\n");
if ((TCPHeader->Flags & TCP_FIN) > 0) DbgPrint(" TCP_FIN - No more data from sender\n");
DbgPrint(" Window: %d\n", WN2H(TCPHeader->Window));
DbgPrint(" Checksum: %d\n", WN2H(TCPHeader->Checksum));
DbgPrint(" Urgent: %d\n", WN2H(TCPHeader->Urgent));
DbgPrint(" Window: 0x%x\n", WN2H(TCPHeader->Window));
DbgPrint(" Checksum: 0x%x\n", WN2H(TCPHeader->Checksum));
DbgPrint(" Urgent: 0x%x\n", WN2H(TCPHeader->Urgent));
}
@ -592,8 +632,9 @@ VOID DisplayTCPPacket(
if (IPPacket->NdisPacket) {
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
Length -= MaxLLHeaderSize;
Buffer = ExAllocatePool(NonPagedPool, Length);
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length);
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
DisplayTCPHeader(Buffer, Length);
ExFreePool(Buffer);
} else {

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,13 @@
#include <afd/shared.h>
#include <debug.h>
/*typedef _MSAFD_LISTEN_REQUEST
{
LIST_ENTRY ListEntry;
HANDLE Socket;
} MSAFD_LISTEN_REQUEST, *PMSAFD_LISTEN_REQUEST;*/
extern HANDLE GlobalHeap;
extern WSPUPCALLTABLE Upcalls;
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;

View file

@ -23,6 +23,9 @@ DWORD DebugTraceLevel = MIN_TRACE;
/* To make the linker happy */
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
/* FIXME: Protect me */
static LIST_ENTRY MsAfdListenRequests; /* Queue of listen reqests */
HANDLE GlobalHeap;
WSPUPCALLTABLE Upcalls;
@ -358,6 +361,7 @@ WSPListen(
* 0, or SOCKET_ERROR if the socket could not be bound
*/
{
//PAFD_LISTEN_REQUEST MsafdRequest;
FILE_REQUEST_LISTEN Request;
FILE_REPLY_LISTEN Reply;
IO_STATUS_BLOCK Iosb;
@ -365,28 +369,38 @@ WSPListen(
AFD_DbgPrint(MAX_TRACE, ("s (0x%X) backlog (%d).\n", s, backlog));
/* MsafdRequest = (PMSAFD_LISTEN_REQUEST)HeapAlloc(
GlobalHeap, 0, sizeof(MSAFD_LISTEN_REQUEST));
if (MsafdRequest == NULL)
{
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}*/
Request.Backlog = backlog;
Status = NtDeviceIoControlFile(
(HANDLE)s,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_AFD_LISTEN,
&Request,
sizeof(FILE_REQUEST_LISTEN),
&Reply,
sizeof(FILE_REPLY_LISTEN));
if (Status == STATUS_PENDING) {
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
/* FIXME: Wait only for blocking sockets */
Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
}
if (!NT_SUCCESS(Status)) {
NULL,
NULL,
&Iosb,
IOCTL_AFD_LISTEN,
&Request,
sizeof(FILE_REQUEST_LISTEN),
&Reply,
sizeof(FILE_REPLY_LISTEN));
if (Status == STATUS_PENDING)
{
//AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
//InsertTailList(&MsAfdListenRequests, &MsafdRequest->ListEntry);
}
else if (!NT_SUCCESS(Status))
{
//HeapFree(GlobalHeap, 0, MsafdRequest);
*lpErrno = Reply.Status;
return SOCKET_ERROR;
return SOCKET_ERROR;
}
return 0;
@ -841,10 +855,13 @@ WSPStartup(
*/
{
HMODULE hWS2_32;
INT Status;
NTSTATUS Status;
INT Error;
AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
Status = NO_ERROR;
EnterCriticalSection(&InitCriticalSection);
Upcalls = UpcallTable;
@ -859,17 +876,22 @@ WSPStartup(
lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST)
GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest");
if (lpWPUCompleteOverlappedRequest != NULL) {
Status = NO_ERROR;
StartupCount++;
} else {
AFD_DbgPrint(MIN_TRACE, ("GetProcAddress() failed for WPUCompleteOverlappedRequest\n"));
CloseCommandChannel();
Error = WSASYSNOTREADY;
}
} else {
AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n"));
CloseCommandChannel();
Error = WSASYSNOTREADY;
}
} else {
AFD_DbgPrint(MIN_TRACE, ("Cannot open afd.sys\n"));
Error = WSASYSNOTREADY;
}
} else {
Status = NO_ERROR;
StartupCount++;
}
@ -969,6 +991,8 @@ DllMain(HANDLE hInstDll,
InitializeCriticalSection(&InitCriticalSection);
InitializeListHead(&MsAfdListenRequests);
GlobalHeap = GetProcessHeap();
CreateHelperDLLDatabase();