mirror of
https://github.com/reactos/reactos.git
synced 2024-06-24 06:51:47 +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>
|
||||
|
||||
* drivers/net/tcpip/datalink/loopback.c: Reformat.
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
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
|
||||
* 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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
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
|
||||
|
||||
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
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue