mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 08:51:29 +00:00
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:
parent
0d2b52fb76
commit
318a90741d
|
@ -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>
|
2004-02-25 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||||
|
|
||||||
* drivers/net/tcpip/datalink/loopback.c: Reformat.
|
* drivers/net/tcpip/datalink/loopback.c: Reformat.
|
||||||
|
|
|
@ -139,9 +139,25 @@ AfdDispCompleteListen(
|
||||||
{
|
{
|
||||||
PAFD_LISTEN_REQUEST ListenRequest = (PAFD_LISTEN_REQUEST) Context;
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -197,14 +213,14 @@ NTSTATUS AfdDispListen(
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
|
ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
|
||||||
if (ListenRequest != NULL)
|
if (ListenRequest != NULL)
|
||||||
{
|
{
|
||||||
ListenRequest->Fcb = FCB;
|
ListenRequest->Fcb = FCB;
|
||||||
/* FIXME: Protect ListenRequestQueue */
|
/* FIXME: Protect ListenRequestQueue */
|
||||||
InsertTailList(&FCB->ListenRequestQueue, &ListenRequest->ListEntry);
|
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) || NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (Status != STATUS_PENDING)
|
if (Status != STATUS_PENDING)
|
||||||
|
@ -630,8 +646,8 @@ NTSTATUS AfdDispEventSelect(
|
||||||
UINT OutputBufferLength;
|
UINT OutputBufferLength;
|
||||||
PFILE_REQUEST_EVENTSELECT Request;
|
PFILE_REQUEST_EVENTSELECT Request;
|
||||||
PFILE_REPLY_EVENTSELECT Reply;
|
PFILE_REPLY_EVENTSELECT Reply;
|
||||||
|
PKEVENT Event;
|
||||||
PAFDFCB FCB;
|
PAFDFCB FCB;
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
@ -644,20 +660,32 @@ NTSTATUS AfdDispEventSelect(
|
||||||
Request = (PFILE_REQUEST_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
|
Request = (PFILE_REQUEST_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||||
Reply = (PFILE_REPLY_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
|
Reply = (PFILE_REPLY_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
FCB->NetworkEvents.lNetworkEvents = Request->lNetworkEvents;
|
/* FIXME: Need to ObDereferenceObject(FCB->EventObject) this somewhere */
|
||||||
for (i = 0; i < FD_MAX_EVENTS; i++) {
|
Status = ObReferenceObjectByHandle(
|
||||||
if ((Request->lNetworkEvents & (1 << i)) > 0) {
|
Request->hEventObject,
|
||||||
FCB->EventObjects[i] = Request->hEventObject;
|
0,
|
||||||
} else {
|
ExEventObjectType,
|
||||||
/* The effect of any previous call to this function is cancelled */
|
UserMode,
|
||||||
FCB->EventObjects[i] = (WSAEVENT)0;
|
(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;
|
Reply->Status = WSAEINVAL;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
} else
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,7 @@ NTSTATUS TdiOpenAddressFileIPv4(
|
||||||
EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
|
EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
|
||||||
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
|
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
|
||||||
TdiBuildAddressIPv4(Address, Name);
|
TdiBuildAddressIPv4(Address, Name);
|
||||||
|
|
||||||
Status = TdiOpenDevice(DeviceName,
|
Status = TdiOpenDevice(DeviceName,
|
||||||
EaLength,
|
EaLength,
|
||||||
EaInfo,
|
EaInfo,
|
||||||
|
@ -414,13 +415,13 @@ NTSTATUS TdiAssociateAddressFile(
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS TdiListen(
|
NTSTATUS TdiListen(
|
||||||
PFILE_OBJECT ConnectionObject,
|
PAFD_LISTEN_REQUEST ListenRequest,
|
||||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||||
PVOID CompletionContext)
|
PVOID CompletionContext)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
|
* FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* ConnectionObject = Pointer to connection endpoint file object
|
* ListenRequest = Pointer to listen request object
|
||||||
* CompletionRoutine = Routine to be called when IRP is completed
|
* CompletionRoutine = Routine to be called when IRP is completed
|
||||||
* CompletionContext = Context for CompletionRoutine
|
* CompletionContext = Context for CompletionRoutine
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
|
@ -428,35 +429,34 @@ NTSTATUS TdiListen(
|
||||||
* May return STATUS_PENDING
|
* May return STATUS_PENDING
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
|
PFILE_OBJECT ConnectionObject;
|
||||||
//PTDI_CONNECTION_INFORMATION ReturnConnectionInfo;
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK Iosb;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KEVENT Event;
|
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
||||||
|
|
||||||
|
ConnectionObject = ListenRequest->Fcb->TdiConnectionObject;
|
||||||
assert(ConnectionObject);
|
assert(ConnectionObject);
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
||||||
|
|
||||||
Status = TdiBuildNullConnectionInfo(&RequestConnectionInfo, TDI_ADDRESS_TYPE_IP);
|
Status = TdiBuildNullConnectionInfo(&ListenRequest->RequestConnectionInfo,
|
||||||
|
TDI_ADDRESS_TYPE_IP);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
|
|
||||||
Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
|
Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
|
||||||
DeviceObject, /* Device object */
|
DeviceObject, /* Device object */
|
||||||
ConnectionObject, /* File object */
|
ConnectionObject, /* File object */
|
||||||
&Event, /* Event */
|
NULL, /* Event */
|
||||||
&Iosb); /* Status */
|
&ListenRequest->Iosb); /* Status */
|
||||||
if (!Irp) {
|
if (Irp == NULL)
|
||||||
ExFreePool(RequestConnectionInfo);
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
ExFreePool(ListenRequest->RequestConnectionInfo);
|
||||||
}
|
ListenRequest->RequestConnectionInfo = NULL;
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
TdiBuildListen(Irp, /* IRP */
|
TdiBuildListen(Irp, /* IRP */
|
||||||
DeviceObject, /* Device object */
|
DeviceObject, /* Device object */
|
||||||
|
@ -464,13 +464,10 @@ NTSTATUS TdiListen(
|
||||||
CompletionRoutine, /* Completion routine */
|
CompletionRoutine, /* Completion routine */
|
||||||
CompletionContext, /* Completion routine context */
|
CompletionContext, /* Completion routine context */
|
||||||
0, /* Flags */
|
0, /* Flags */
|
||||||
RequestConnectionInfo, /* Request connection information */
|
ListenRequest->RequestConnectionInfo, /* Request connection information */
|
||||||
NULL /* ReturnConnectionInfo */); /* Return connection information */
|
NULL /* ReturnConnectionInfo */); /* Return connection information */
|
||||||
|
|
||||||
Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &Iosb);
|
Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &ListenRequest->Iosb);
|
||||||
|
|
||||||
ExFreePool(RequestConnectionInfo);
|
|
||||||
//ExFreePool(ReturnConnectionInfo);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ typedef struct _AFDFCB {
|
||||||
LIST_ENTRY ListenRequestQueue;
|
LIST_ENTRY ListenRequestQueue;
|
||||||
/* For WSAEventSelect() */
|
/* For WSAEventSelect() */
|
||||||
WSANETWORKEVENTS NetworkEvents;
|
WSANETWORKEVENTS NetworkEvents;
|
||||||
WSAEVENT EventObjects[FD_MAX_EVENTS];
|
PKEVENT EventObject;
|
||||||
} AFDFCB, *PAFDFCB;
|
} AFDFCB, *PAFDFCB;
|
||||||
|
|
||||||
/* Socket states */
|
/* Socket states */
|
||||||
|
@ -99,6 +99,8 @@ typedef struct _AFD_READ_REQUEST {
|
||||||
typedef struct _AFD_LISTEN_REQUEST {
|
typedef struct _AFD_LISTEN_REQUEST {
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PAFDFCB Fcb;
|
PAFDFCB Fcb;
|
||||||
|
PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
|
||||||
|
IO_STATUS_BLOCK Iosb;
|
||||||
} AFD_LISTEN_REQUEST, *PAFD_LISTEN_REQUEST;
|
} AFD_LISTEN_REQUEST, *PAFD_LISTEN_REQUEST;
|
||||||
|
|
||||||
typedef struct IPSNMP_INFO {
|
typedef struct IPSNMP_INFO {
|
||||||
|
@ -363,7 +365,7 @@ NTSTATUS TdiAssociateAddressFile(
|
||||||
PFILE_OBJECT ConnectionObject);
|
PFILE_OBJECT ConnectionObject);
|
||||||
|
|
||||||
NTSTATUS TdiListen(
|
NTSTATUS TdiListen(
|
||||||
PFILE_OBJECT ConnectionObject,
|
PAFD_LISTEN_REQUEST Request,
|
||||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||||
PVOID CompletionContext);
|
PVOID CompletionContext);
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@ BOOLEAN AddrIsEqualIPv4(
|
||||||
PIP_ADDRESS AddrBuildIPv4(
|
PIP_ADDRESS AddrBuildIPv4(
|
||||||
IPv4_RAW_ADDRESS Address);
|
IPv4_RAW_ADDRESS Address);
|
||||||
|
|
||||||
|
PIP_ADDRESS AddrCloneAddress(
|
||||||
|
PIP_ADDRESS Address);
|
||||||
|
|
||||||
PADDRESS_ENTRY AddrLocateADEv4(
|
PADDRESS_ENTRY AddrLocateADEv4(
|
||||||
IPv4_RAW_ADDRESS Address);
|
IPv4_RAW_ADDRESS Address);
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,39 @@
|
||||||
#define __CHECKSUM_H
|
#define __CHECKSUM_H
|
||||||
|
|
||||||
|
|
||||||
|
ULONG ChecksumFold(
|
||||||
|
ULONG Sum);
|
||||||
|
|
||||||
ULONG ChecksumCompute(
|
ULONG ChecksumCompute(
|
||||||
PVOID Data,
|
PVOID Data,
|
||||||
UINT Count,
|
UINT Count,
|
||||||
ULONG Seed);
|
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
|
* 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))
|
(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 */
|
||||||
|
|
|
@ -49,8 +49,9 @@ typedef struct IPv4_HEADER {
|
||||||
IPv4_RAW_ADDRESS DstAddr; /* Destination Address */
|
IPv4_RAW_ADDRESS DstAddr; /* Destination Address */
|
||||||
} IPv4_HEADER, *PIPv4_HEADER;
|
} IPv4_HEADER, *PIPv4_HEADER;
|
||||||
|
|
||||||
#define IPv4_FRAGOFS_MASK 0x1FFF
|
#define IPv4_FRAGOFS_MASK 0x1FFF /* Fragment offset mask (host byte order) */
|
||||||
#define IPv4_MF_MASK 0x2000
|
#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
|
#define IPv4_MAX_HEADER_SIZE 60
|
||||||
|
|
||||||
/* Packet completion handler prototype */
|
/* Packet completion handler prototype */
|
||||||
|
@ -60,7 +61,7 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)(
|
||||||
NDIS_STATUS NdisStatus);
|
NDIS_STATUS NdisStatus);
|
||||||
|
|
||||||
/* Structure for an IP packet */
|
/* Structure for an IP packet */
|
||||||
typedef struct IP_PACKET {
|
typedef struct _IP_PACKET {
|
||||||
DEFINE_TAG
|
DEFINE_TAG
|
||||||
ULONG RefCount; /* Reference count for this object */
|
ULONG RefCount; /* Reference count for this object */
|
||||||
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
|
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
|
||||||
|
@ -81,7 +82,7 @@ typedef struct IP_PACKET {
|
||||||
|
|
||||||
|
|
||||||
/* Packet context */
|
/* Packet context */
|
||||||
typedef struct PACKET_CONTEXT {
|
typedef struct _PACKET_CONTEXT {
|
||||||
PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */
|
PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */
|
||||||
PVOID Context; /* Context information for handler */
|
PVOID Context; /* Context information for handler */
|
||||||
PACKET_COMPLETION_ROUTINE DLComplete; /* Data link level completion handler. Also
|
PACKET_COMPLETION_ROUTINE DLComplete; /* Data link level completion handler. Also
|
||||||
|
|
|
@ -7,27 +7,26 @@
|
||||||
#ifndef __TCP_H
|
#ifndef __TCP_H
|
||||||
#define __TCP_H
|
#define __TCP_H
|
||||||
|
|
||||||
|
|
||||||
/* TCPv4 header structure */
|
/* TCPv4 header structure */
|
||||||
typedef struct TCP_HEADER {
|
typedef struct TCPv4_HEADER {
|
||||||
USHORT SourcePort; /* Source port */
|
USHORT SourcePort; /* Source port */
|
||||||
USHORT DestPort; /* Destination port */
|
USHORT DestinationPort; /* Destination port */
|
||||||
USHORT SeqNum; /* Sequence number */
|
ULONG SequenceNumber; /* Sequence number */
|
||||||
USHORT AckNum; /* Acknowledgment number */
|
ULONG AckNumber; /* Acknowledgement number */
|
||||||
UCHAR DataOfs; /* Data offset (leftmost 4 bits) */
|
UCHAR DataOffset; /* Data offset; 32-bit words (leftmost 4 bits) */
|
||||||
UCHAR Flags; /* Control bits (rightmost 6 bits) */
|
UCHAR Flags; /* Control bits (rightmost 6 bits) */
|
||||||
USHORT Window; /* Maximum acceptable receive window */
|
USHORT Window; /* Maximum acceptable receive window */
|
||||||
USHORT Checksum; /* Checksum of segment */
|
USHORT Checksum; /* Checksum of segment */
|
||||||
USHORT Urgent; /* Pointer to urgent data */
|
USHORT Urgent; /* Pointer to urgent data */
|
||||||
} __attribute__((packed)) TCP_HEADER, *PTCP_HEADER;
|
} __attribute__((packed)) TCPv4_HEADER, *PTCPv4_HEADER;
|
||||||
|
|
||||||
/* TCPv4 header flags */
|
/* TCPv4 header flags */
|
||||||
#define TCP_URG 0x04
|
#define TCP_URG 0x20
|
||||||
#define TCP_ACK 0x08
|
#define TCP_ACK 0x10
|
||||||
#define TCP_PSH 0x10
|
#define TCP_PSH 0x08
|
||||||
#define TCP_RST 0x20
|
#define TCP_RST 0x04
|
||||||
#define TCP_SYN 0x40
|
#define TCP_SYN 0x02
|
||||||
#define TCP_FIN 0x80
|
#define TCP_FIN 0x01
|
||||||
|
|
||||||
|
|
||||||
#define TCPOPT_END_OF_LIST 0x0
|
#define TCPOPT_END_OF_LIST 0x0
|
||||||
|
@ -38,13 +37,13 @@ typedef struct TCP_HEADER {
|
||||||
|
|
||||||
|
|
||||||
/* TCPv4 pseudo header */
|
/* TCPv4 pseudo header */
|
||||||
typedef struct TCP_PSEUDO_HEADER {
|
typedef struct TCPv4_PSEUDO_HEADER {
|
||||||
ULONG SourceAddress; /* Source address */
|
ULONG SourceAddress; /* Source address */
|
||||||
ULONG DestAddress; /* Destination address */
|
ULONG DestinationAddress; /* Destination address */
|
||||||
UCHAR Zero; /* Reserved */
|
UCHAR Zero; /* Reserved */
|
||||||
UCHAR Protocol; /* Protocol */
|
UCHAR Protocol; /* Protocol */
|
||||||
USHORT TCPLength; /* Size of TCP segment */
|
USHORT TCPLength; /* Size of TCP segment */
|
||||||
} __attribute__((packed)) TCP_PSEUDO_HEADER, *PTCP_PSEUDO_HEADER;
|
} __attribute__((packed)) TCPv4_PSEUDO_HEADER, *PTCPv4_PSEUDO_HEADER;
|
||||||
|
|
||||||
|
|
||||||
/* Retransmission timeout constants */
|
/* Retransmission timeout constants */
|
||||||
|
@ -72,6 +71,18 @@ typedef struct TCP_PSEUDO_HEADER {
|
||||||
#define SRF_FIN TCP_FIN
|
#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(
|
inline NTSTATUS TCPBuildSendRequest(
|
||||||
PTCP_SEND_REQUEST *SendRequest,
|
PTCP_SEND_REQUEST *SendRequest,
|
||||||
PDATAGRAM_SEND_REQUEST *DGSendRequest,
|
PDATAGRAM_SEND_REQUEST *DGSendRequest,
|
||||||
|
@ -113,5 +124,3 @@ NTSTATUS TCPShutdown(
|
||||||
VOID);
|
VOID);
|
||||||
|
|
||||||
#endif /* __TCP_H */
|
#endif /* __TCP_H */
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
|
|
@ -266,6 +266,8 @@ typedef struct _TCP_SEND_REQUEST {
|
||||||
PVOID Context; /* Pointer to context information */
|
PVOID Context; /* Pointer to context information */
|
||||||
PVOID ProtocolContext; /* Protocol specific context */
|
PVOID ProtocolContext; /* Protocol specific context */
|
||||||
ULONG Flags; /* Protocol specific flags */
|
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;
|
} TCP_SEND_REQUEST, *PTCP_SEND_REQUEST;
|
||||||
|
|
||||||
#define InitializeTCPSendRequest( \
|
#define InitializeTCPSendRequest( \
|
||||||
|
@ -296,6 +298,15 @@ typedef enum {
|
||||||
} CONNECTION_STATE, *PCONNECTION_STATE;
|
} 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
|
/* Transport connection context structure A.K.A. Transmission Control Block
|
||||||
(TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
|
(TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
|
||||||
to this structure */
|
to this structure */
|
||||||
|
@ -324,14 +335,21 @@ typedef struct _CONNECTION_ENDPOINT {
|
||||||
ULONG SendISS; /* Initial send sequence number */
|
ULONG SendISS; /* Initial send sequence number */
|
||||||
|
|
||||||
/* Receive sequence variables */
|
/* Receive sequence variables */
|
||||||
ULONG RecvNext; /* Sequence number of last data block received */
|
ULONG ReceiveNext; /* Sequence number of last data block received */
|
||||||
ULONG RecvWindow; /* Maximum allowed number of octets in a segment */
|
ULONG ReceiveWindow; /* Maximum allowed number of octets in a segment */
|
||||||
ULONG RecvUrgentPointer; /* Sequence number of start of urgent data */
|
ULONG ReceiveUrgentPointer; /* Sequence number of start of urgent data */
|
||||||
ULONG RecvIRS; /* Initial receive sequence number */
|
ULONG ReceiveIRS; /* Initial receive sequence number */
|
||||||
|
|
||||||
/* Statistics for computing the retransmission timeout */
|
/* Statistics for computing the retransmission timeout */
|
||||||
ULONG TimestampSend; /* Timestamp when sending a segment */
|
ULONG TimestampSend; /* Timestamp when sending a segment */
|
||||||
ULONG TimestampAck; /* Timestamp when receiving acknowledgment */
|
ULONG TimestampAck; /* Timestamp when receiving acknowledgment */
|
||||||
|
|
||||||
|
/* Requests */
|
||||||
|
PTDI_REQUEST ListenRequest; /* Queued listen request */
|
||||||
|
|
||||||
|
/* Queues */
|
||||||
|
LIST_ENTRY ReceivedSegments;
|
||||||
|
|
||||||
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
|
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 = ../../..
|
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_input.o transport/tcp/tcp_ipv4.o \
|
||||||
transport/tcp/tcp_output.o transport/tcp/tcp_timer.o
|
transport/tcp/tcp_output.o transport/tcp/tcp_timer.o
|
||||||
UDP_OBJECTS = transport/udp/udp.o
|
UDP_OBJECTS = transport/udp/udp.o
|
||||||
|
ARCH_OBJECTS = tcpip/i386/checksum.o
|
||||||
|
|
||||||
TARGET_OBJECTS = \
|
TARGET_OBJECTS = \
|
||||||
$(TCPIP_OBJECTS) \
|
$(TCPIP_OBJECTS) \
|
||||||
|
@ -42,7 +43,8 @@ TARGET_OBJECTS = \
|
||||||
$(DATAGRAM_OBJECTS) \
|
$(DATAGRAM_OBJECTS) \
|
||||||
$(RAWIP_OBJECTS) \
|
$(RAWIP_OBJECTS) \
|
||||||
$(TCP_OBJECTS) \
|
$(TCP_OBJECTS) \
|
||||||
$(UDP_OBJECTS)
|
$(UDP_OBJECTS) \
|
||||||
|
$(ARCH_OBJECTS)
|
||||||
|
|
||||||
include $(PATH_TO_TOP)/rules.mak
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ VOID ICMPReceive(
|
||||||
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
|
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
|
||||||
|
|
||||||
/* Checksum ICMP header and data */
|
/* 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"));
|
TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n"));
|
||||||
/* Discard packet */
|
/* Discard packet */
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -552,7 +552,7 @@ VOID IPv4Receive(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checksum IPv4 header */
|
/* 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",
|
TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
|
||||||
WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
|
WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
|
||||||
/* Discard packet */
|
/* Discard packet */
|
||||||
|
|
|
@ -104,13 +104,13 @@ NTSTATUS SendFragments(
|
||||||
IPPacket, NCE, PathMTU));
|
IPPacket, NCE, PathMTU));
|
||||||
|
|
||||||
IFC = ExAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
|
IFC = ExAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
|
||||||
if (!IFC)
|
if (IFC == NULL)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* We allocate a buffer for a PathMTU sized packet and reuse
|
/* We allocate a buffer for a PathMTU sized packet and reuse
|
||||||
it for all fragments */
|
it for all fragments */
|
||||||
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
|
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
|
||||||
if (!IFC->Header) {
|
if (Data == NULL) {
|
||||||
ExFreePool(IFC);
|
ExFreePool(IFC);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ NTSTATUS SendFragments(
|
||||||
/* Allocate NDIS packet */
|
/* Allocate NDIS packet */
|
||||||
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
|
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
|
||||||
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
||||||
//ExFreePool(Data); // RobD - why are we trying to free this here?, not allocated yet!
|
ExFreePool(Data);
|
||||||
ExFreePool(IFC);
|
ExFreePool(IFC);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
27
reactos/drivers/net/tcpip/notes.txt
Normal file
27
reactos/drivers/net/tcpip/notes.txt
Normal 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
|
|
@ -289,7 +289,7 @@ BOOLEAN AddrIsEqualIPv4(
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Build an IPv4 style address
|
* FUNCTION: Build an IPv4 style address
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Address = Raw IPv4 address
|
* Address = Raw IPv4 address (network byte order)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Pointer to IP address structure, NULL if there was not enough free
|
* Pointer to IP address structure, NULL if there was not enough free
|
||||||
* non-paged memory
|
* non-paged memory
|
||||||
|
@ -300,7 +300,7 @@ PIP_ADDRESS AddrBuildIPv4(
|
||||||
PIP_ADDRESS IPAddress;
|
PIP_ADDRESS IPAddress;
|
||||||
|
|
||||||
IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
|
IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
|
||||||
if (IPAddress) {
|
if (IPAddress != NULL) {
|
||||||
IPAddress->RefCount = 1;
|
IPAddress->RefCount = 1;
|
||||||
IPAddress->Type = IP_ADDRESS_V4;
|
IPAddress->Type = IP_ADDRESS_V4;
|
||||||
IPAddress->Address.IPv4Address = Address;
|
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
|
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
|
|
@ -12,10 +12,22 @@
|
||||||
#include <checksum.h>
|
#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(
|
ULONG ChecksumCompute(
|
||||||
PVOID Data,
|
PVOID Data,
|
||||||
UINT Count,
|
UINT Count,
|
||||||
ULONG Seed)
|
ULONG Seed)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Calculate checksum of a buffer
|
* FUNCTION: Calculate checksum of a buffer
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -26,25 +38,20 @@ ULONG ChecksumCompute(
|
||||||
* Checksum of buffer
|
* Checksum of buffer
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* FIXME: This should be done in assembler */
|
register ULONG Sum = Seed;
|
||||||
|
|
||||||
register ULONG Sum = Seed;
|
while (Count > 1)
|
||||||
|
{
|
||||||
while (Count > 1) {
|
Sum += *(PUSHORT)Data;
|
||||||
Sum += *(PUSHORT)Data;
|
Count -= 2;
|
||||||
Count -= 2;
|
(ULONG_PTR)Data += 2;
|
||||||
(ULONG_PTR)Data += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add left-over byte, if any */
|
/* Add left-over byte, if any */
|
||||||
if (Count > 0)
|
if (Count > 0)
|
||||||
Sum += *(PUCHAR)Data;
|
{
|
||||||
|
Sum += *(PUCHAR)Data;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fold 32-bit sum to 16 bits */
|
return Sum;
|
||||||
while (Sum >> 16)
|
|
||||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
|
||||||
|
|
||||||
return ~Sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
|
|
@ -529,8 +529,9 @@ NTSTATUS DispTdiListen(
|
||||||
PTDI_REQUEST_KERNEL Parameters;
|
PTDI_REQUEST_KERNEL Parameters;
|
||||||
PTRANSPORT_CONTEXT TranContext;
|
PTRANSPORT_CONTEXT TranContext;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
TDI_REQUEST Request;
|
PTDI_REQUEST Request;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
||||||
|
|
||||||
|
@ -539,28 +540,51 @@ NTSTATUS DispTdiListen(
|
||||||
/* Get associated connection endpoint file object. Quit if none exists */
|
/* Get associated connection endpoint file object. Quit if none exists */
|
||||||
|
|
||||||
TranContext = IrpSp->FileObject->FsContext;
|
TranContext = IrpSp->FileObject->FsContext;
|
||||||
if (!TranContext) {
|
if (TranContext == NULL)
|
||||||
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
{
|
||||||
return STATUS_INVALID_CONNECTION;
|
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
||||||
}
|
return STATUS_INVALID_CONNECTION;
|
||||||
|
}
|
||||||
|
|
||||||
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
||||||
if (!Connection) {
|
if (Connection == NULL)
|
||||||
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
{
|
||||||
return STATUS_INVALID_CONNECTION;
|
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
||||||
}
|
return STATUS_INVALID_CONNECTION;
|
||||||
|
}
|
||||||
|
|
||||||
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
||||||
|
|
||||||
/* Initialize a connect request */
|
/* Initialize a listen request */
|
||||||
Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
|
Request = (PTDI_REQUEST) ExAllocatePool(NonPagedPool, sizeof(TDI_REQUEST));
|
||||||
Request.RequestNotifyObject = DispDataRequestComplete;
|
if (Request == NULL)
|
||||||
Request.RequestContext = Irp;
|
{
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
Status = TCPListen(
|
Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
|
||||||
&Request,
|
if (NT_SUCCESS(Status))
|
||||||
Parameters->RequestConnectionInformation,
|
{
|
||||||
Parameters->ReturnConnectionInformation);
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,13 +296,13 @@ NTSTATUS FileOpenAddress(
|
||||||
switch (Protocol) {
|
switch (Protocol) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
/* FIXME: If specified port is 0, a port is chosen dynamically */
|
/* 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;
|
AddrFile->Send = TCPSendDatagram;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
/* FIXME: If specified port is 0, a port is chosen dynamically */
|
/* 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;
|
AddrFile->Send = UDPSendDatagram;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -449,6 +449,9 @@ NTSTATUS FileOpenConnection(
|
||||||
/* Save client context pointer */
|
/* Save client context pointer */
|
||||||
Connection->ClientContext = ClientContext;
|
Connection->ClientContext = ClientContext;
|
||||||
|
|
||||||
|
/* Initialize receive queue */
|
||||||
|
InitializeListHead(&Connection->ReceivedSegments);
|
||||||
|
|
||||||
/* Return connection endpoint file object */
|
/* Return connection endpoint file object */
|
||||||
Request->Handle.ConnectionContext = Connection;
|
Request->Handle.ConnectionContext = Connection;
|
||||||
|
|
||||||
|
|
249
reactos/drivers/net/tcpip/tcpip/i386/checksum.S
Normal file
249
reactos/drivers/net/tcpip/tcpip/i386/checksum.S
Normal 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
|
|
@ -480,6 +480,33 @@ UINT ResizePacket(
|
||||||
|
|
||||||
#ifdef DBG
|
#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(
|
VOID DisplayIPPacket(
|
||||||
PIP_PACKET IPPacket)
|
PIP_PACKET IPPacket)
|
||||||
{
|
{
|
||||||
|
@ -488,6 +515,7 @@ VOID DisplayIPPacket(
|
||||||
UINT Length;
|
UINT Length;
|
||||||
PNDIS_BUFFER Buffer;
|
PNDIS_BUFFER Buffer;
|
||||||
PNDIS_BUFFER NextBuffer;
|
PNDIS_BUFFER NextBuffer;
|
||||||
|
PUCHAR CharBuffer;
|
||||||
|
|
||||||
if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_IP)) != (DEBUG_BUFFER | DEBUG_IP)) {
|
if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_IP)) != (DEBUG_BUFFER | DEBUG_IP)) {
|
||||||
return;
|
return;
|
||||||
|
@ -528,6 +556,19 @@ VOID DisplayIPPacket(
|
||||||
}
|
}
|
||||||
DbgPrint("\n");
|
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 */
|
/* FIXME: IPv4 only */
|
||||||
PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
|
PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
|
||||||
PTCP_HEADER TCPHeader;
|
PTCPv4_HEADER TCPHeader;
|
||||||
|
|
||||||
if (IPHeader->Protocol != IPPROTO_TCP) {
|
if (IPHeader->Protocol != IPPROTO_TCP) {
|
||||||
DbgPrint("This is not a TCP datagram. Protocol is %d\n", IPHeader->Protocol);
|
DbgPrint("This is not a TCP datagram. Protocol is %d\n", IPHeader->Protocol);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("VerIHL: 0x%x\n", IPHeader->VerIHL);
|
TCPHeader = (PTCPv4_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
|
||||||
TCPHeader = (PTCP_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
|
|
||||||
|
|
||||||
DbgPrint("TCP header:\n");
|
DbgPrint("TCP header:\n");
|
||||||
DbgPrint(" SourcePort: %d\n", WN2H(TCPHeader->SourcePort));
|
DbgPrint(" SourcePort: %d\n", WN2H(TCPHeader->SourcePort));
|
||||||
DbgPrint(" DestPort: %d\n", WN2H(TCPHeader->DestPort));
|
DbgPrint(" DestinationPort: %d\n", WN2H(TCPHeader->DestinationPort));
|
||||||
DbgPrint(" SeqNum: %d\n", WN2H(TCPHeader->SeqNum));
|
DbgPrint(" SequenceNumber: 0x%x\n", DN2H(TCPHeader->SequenceNumber));
|
||||||
DbgPrint(" AckNum: %d\n", WN2H(TCPHeader->AckNum));
|
DbgPrint(" AckNumber: 0x%x\n", DN2H(TCPHeader->AckNumber));
|
||||||
DbgPrint(" DataOfs: %d (%d)\n", TCPHeader->DataOfs, TCPHeader->DataOfs & 0x0F);
|
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);
|
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_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_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_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_SYN) > 0) DbgPrint(" TCP_SYN - Synchronize sequence numbers\n");
|
||||||
if ((TCPHeader->Flags & TCP_FIN) > 0) DbgPrint(" TCP_FIN - No more data from sender\n");
|
if ((TCPHeader->Flags & TCP_FIN) > 0) DbgPrint(" TCP_FIN - No more data from sender\n");
|
||||||
DbgPrint(" Window: %d\n", WN2H(TCPHeader->Window));
|
DbgPrint(" Window: 0x%x\n", WN2H(TCPHeader->Window));
|
||||||
DbgPrint(" Checksum: %d\n", WN2H(TCPHeader->Checksum));
|
DbgPrint(" Checksum: 0x%x\n", WN2H(TCPHeader->Checksum));
|
||||||
DbgPrint(" Urgent: %d\n", WN2H(TCPHeader->Urgent));
|
DbgPrint(" Urgent: 0x%x\n", WN2H(TCPHeader->Urgent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -592,8 +632,9 @@ VOID DisplayTCPPacket(
|
||||||
|
|
||||||
if (IPPacket->NdisPacket) {
|
if (IPPacket->NdisPacket) {
|
||||||
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
|
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
|
||||||
|
Length -= MaxLLHeaderSize;
|
||||||
Buffer = ExAllocatePool(NonPagedPool, Length);
|
Buffer = ExAllocatePool(NonPagedPool, Length);
|
||||||
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length);
|
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
|
||||||
DisplayTCPHeader(Buffer, Length);
|
DisplayTCPHeader(Buffer, Length);
|
||||||
ExFreePool(Buffer);
|
ExFreePool(Buffer);
|
||||||
} else {
|
} else {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,6 +18,13 @@
|
||||||
#include <afd/shared.h>
|
#include <afd/shared.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/*typedef _MSAFD_LISTEN_REQUEST
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
HANDLE Socket;
|
||||||
|
} MSAFD_LISTEN_REQUEST, *PMSAFD_LISTEN_REQUEST;*/
|
||||||
|
|
||||||
|
|
||||||
extern HANDLE GlobalHeap;
|
extern HANDLE GlobalHeap;
|
||||||
extern WSPUPCALLTABLE Upcalls;
|
extern WSPUPCALLTABLE Upcalls;
|
||||||
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
|
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
|
||||||
|
|
|
@ -23,6 +23,9 @@ DWORD DebugTraceLevel = MIN_TRACE;
|
||||||
/* To make the linker happy */
|
/* To make the linker happy */
|
||||||
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
|
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
|
||||||
|
|
||||||
|
/* FIXME: Protect me */
|
||||||
|
static LIST_ENTRY MsAfdListenRequests; /* Queue of listen reqests */
|
||||||
|
|
||||||
|
|
||||||
HANDLE GlobalHeap;
|
HANDLE GlobalHeap;
|
||||||
WSPUPCALLTABLE Upcalls;
|
WSPUPCALLTABLE Upcalls;
|
||||||
|
@ -358,6 +361,7 @@ WSPListen(
|
||||||
* 0, or SOCKET_ERROR if the socket could not be bound
|
* 0, or SOCKET_ERROR if the socket could not be bound
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
//PAFD_LISTEN_REQUEST MsafdRequest;
|
||||||
FILE_REQUEST_LISTEN Request;
|
FILE_REQUEST_LISTEN Request;
|
||||||
FILE_REPLY_LISTEN Reply;
|
FILE_REPLY_LISTEN Reply;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
|
@ -365,28 +369,38 @@ WSPListen(
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("s (0x%X) backlog (%d).\n", s, backlog));
|
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;
|
Request.Backlog = backlog;
|
||||||
|
|
||||||
Status = NtDeviceIoControlFile(
|
Status = NtDeviceIoControlFile(
|
||||||
(HANDLE)s,
|
(HANDLE)s,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&Iosb,
|
&Iosb,
|
||||||
IOCTL_AFD_LISTEN,
|
IOCTL_AFD_LISTEN,
|
||||||
&Request,
|
&Request,
|
||||||
sizeof(FILE_REQUEST_LISTEN),
|
sizeof(FILE_REQUEST_LISTEN),
|
||||||
&Reply,
|
&Reply,
|
||||||
sizeof(FILE_REPLY_LISTEN));
|
sizeof(FILE_REPLY_LISTEN));
|
||||||
if (Status == STATUS_PENDING) {
|
if (Status == STATUS_PENDING)
|
||||||
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
|
{
|
||||||
/* FIXME: Wait only for blocking sockets */
|
//AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
|
||||||
Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
|
//InsertTailList(&MsAfdListenRequests, &MsafdRequest->ListEntry);
|
||||||
}
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
if (!NT_SUCCESS(Status)) {
|
{
|
||||||
|
//HeapFree(GlobalHeap, 0, MsafdRequest);
|
||||||
*lpErrno = Reply.Status;
|
*lpErrno = Reply.Status;
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -841,10 +855,13 @@ WSPStartup(
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
HMODULE hWS2_32;
|
HMODULE hWS2_32;
|
||||||
INT Status;
|
NTSTATUS Status;
|
||||||
|
INT Error;
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
|
AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
|
||||||
|
|
||||||
|
Status = NO_ERROR;
|
||||||
|
|
||||||
EnterCriticalSection(&InitCriticalSection);
|
EnterCriticalSection(&InitCriticalSection);
|
||||||
|
|
||||||
Upcalls = UpcallTable;
|
Upcalls = UpcallTable;
|
||||||
|
@ -859,17 +876,22 @@ WSPStartup(
|
||||||
lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST)
|
lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST)
|
||||||
GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest");
|
GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest");
|
||||||
if (lpWPUCompleteOverlappedRequest != NULL) {
|
if (lpWPUCompleteOverlappedRequest != NULL) {
|
||||||
Status = NO_ERROR;
|
|
||||||
StartupCount++;
|
StartupCount++;
|
||||||
|
} else {
|
||||||
|
AFD_DbgPrint(MIN_TRACE, ("GetProcAddress() failed for WPUCompleteOverlappedRequest\n"));
|
||||||
|
CloseCommandChannel();
|
||||||
|
Error = WSASYSNOTREADY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n"));
|
AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n"));
|
||||||
|
CloseCommandChannel();
|
||||||
|
Error = WSASYSNOTREADY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Cannot open afd.sys\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Cannot open afd.sys\n"));
|
||||||
|
Error = WSASYSNOTREADY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Status = NO_ERROR;
|
|
||||||
StartupCount++;
|
StartupCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,6 +991,8 @@ DllMain(HANDLE hInstDll,
|
||||||
|
|
||||||
InitializeCriticalSection(&InitCriticalSection);
|
InitializeCriticalSection(&InitCriticalSection);
|
||||||
|
|
||||||
|
InitializeListHead(&MsAfdListenRequests);
|
||||||
|
|
||||||
GlobalHeap = GetProcessHeap();
|
GlobalHeap = GetProcessHeap();
|
||||||
|
|
||||||
CreateHelperDLLDatabase();
|
CreateHelperDLLDatabase();
|
||||||
|
|
Loading…
Reference in a new issue