Index: if.c =================================================================== --- sdk/lib/drivers/ip/transport/tcp/if.c (revision 73774) +++ sdk/lib/drivers/ip/transport/tcp/if.c (working copy) @@ -15,6 +15,8 @@ IP_PACKET Packet; IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; + ULONG Length; + ULONG TotalLength; /* The caller frees the pbuf struct */ @@ -39,7 +41,7 @@ { return ERR_RTE; } - + NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len); if (NdisStatus != NDIS_STATUS_SUCCESS) { @@ -49,19 +51,34 @@ GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.TotalSize); Packet.MappedHeader = TRUE; - if (p->tot_len != p->len || - Packet.TotalSize != p->len) + ASSERT(Packet.TotalSize == p->tot_len); + + TotalLength = p->tot_len; + Length = 0; + while (Length < TotalLength) { - DbgPrint("TCPSendDataCallback: tot_len = %u, len = %u, TotalSize = %u\n", - p->tot_len, p->len, Packet.TotalSize); - ASSERT(p->tot_len == p->len); - ASSERT(Packet.TotalSize == p->len); + if (p->len > TotalLength - Length) + { + DbgPrint("TCPSendDataCallback: invalid length in pbuf chain. TotalLength %lu, Length %lu\n", TotalLength, Length); + ASSERT(p->len <= TotalLength - Length); + } + if (p->tot_len != TotalLength - Length) + { + DbgPrint("TCPSendDataCallback: follow-up pbuf has different tot_len %u (len %u). TotalLength %lu, Length %lu\n", p->tot_len, p->len, TotalLength, Length); + ASSERT(p->tot_len == TotalLength - Length); + } + if (Length > 0) + { + DbgPrint("TCPSendDataCallback: reading from follow-up pbuf (tot_len %u, len %u). TotalLength %lu, Length %lu\n", p->tot_len, p->len, TotalLength, Length); + } + RtlCopyMemory((PCHAR)Packet.Header + Length, p->payload, p->len); + Length += p->len; + p = p->next; } + ASSERT(Length == TotalLength); - RtlCopyMemory(Packet.Header, p->payload, p->len); - Packet.HeaderSize = sizeof(IPv4_HEADER); - Packet.TotalSize = p->tot_len; + Packet.TotalSize = TotalLength; Packet.SrcAddr = LocalAddress; Packet.DstAddr = RemoteAddress; @@ -77,9 +94,9 @@ { #if 0 ULONG OperationalStatus; - + GetInterfaceConnectionStatus(IF, &OperationalStatus); - + if (OperationalStatus == MIB_IF_OPER_STATUS_OPERATIONAL) netif_set_link_up(IF->TCPContext); else