introduced Checksum::PseudoHeader helper.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20717 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#include <net_buffer.h>
|
||||
#include <net_datalink.h>
|
||||
|
||||
#include <netinet/in.h> // for htons
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class Checksum {
|
||||
@@ -32,6 +34,10 @@ class Checksum {
|
||||
|
||||
operator uint16();
|
||||
|
||||
static uint16 PseudoHeader(net_address_module_info *addressModule,
|
||||
net_buffer_module_info *bufferModule, net_buffer *buffer,
|
||||
uint16 protocol);
|
||||
|
||||
private:
|
||||
uint32 fSum;
|
||||
};
|
||||
@@ -77,6 +83,19 @@ inline Checksum::operator uint16() {
|
||||
}
|
||||
|
||||
|
||||
inline uint16
|
||||
Checksum::PseudoHeader(net_address_module_info *addressModule,
|
||||
net_buffer_module_info *bufferModule, net_buffer *buffer, uint16 protocol)
|
||||
{
|
||||
Checksum checksum;
|
||||
addressModule->checksum_address(&checksum, (sockaddr *)&buffer->source);
|
||||
addressModule->checksum_address(&checksum, (sockaddr *)&buffer->destination);
|
||||
checksum << (uint16)htons(protocol) << (uint16)htons(buffer->size)
|
||||
<< Checksum::BufferHelper(buffer, bufferModule);
|
||||
return checksum;
|
||||
}
|
||||
|
||||
|
||||
// helper class that prints an address (and optionally a port) into a buffer that
|
||||
// is automatically freed at end of scope:
|
||||
class AddressString {
|
||||
|
||||
@@ -161,16 +161,8 @@ add_tcp_header(tcp_segment_header &segment, net_buffer *buffer)
|
||||
TRACE(("add_tcp_header(): buffer %p, flags 0x%x, seq %lu, ack %lu, win %u\n", buffer,
|
||||
segment.flags, segment.sequence, segment.acknowledge, segment.advertised_window));
|
||||
|
||||
// compute and store checksum
|
||||
Checksum checksum;
|
||||
gAddressModule->checksum_address(&checksum, (sockaddr *)&buffer->source);
|
||||
gAddressModule->checksum_address(&checksum, (sockaddr *)&buffer->destination);
|
||||
checksum
|
||||
<< (uint16)htons(IPPROTO_TCP)
|
||||
<< (uint16)htons(buffer->size)
|
||||
<< Checksum::BufferHelper(buffer, gBufferModule);
|
||||
|
||||
*TCPChecksumField(buffer) = checksum;
|
||||
*TCPChecksumField(buffer) = Checksum::PseudoHeader(gAddressModule,
|
||||
gBufferModule, buffer, IPPROTO_TCP);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -518,15 +510,8 @@ tcp_receive_data(net_buffer *buffer)
|
||||
if (headerLength < sizeof(tcp_header))
|
||||
return B_BAD_DATA;
|
||||
|
||||
// compute checksum using a pseudo IP header
|
||||
Checksum checksum;
|
||||
gAddressModule->checksum_address(&checksum, (sockaddr *)&buffer->source);
|
||||
gAddressModule->checksum_address(&checksum, (sockaddr *)&buffer->destination);
|
||||
checksum << (uint16)htons(IPPROTO_TCP)
|
||||
<< (uint16)htons(buffer->size)
|
||||
<< Checksum::BufferHelper(buffer, gBufferModule);
|
||||
|
||||
if (checksum != 0)
|
||||
if (Checksum::PseudoHeader(gAddressModule, gBufferModule, buffer,
|
||||
IPPROTO_TCP) != 0)
|
||||
return B_BAD_DATA;
|
||||
|
||||
gAddressModule->set_port((struct sockaddr *)&buffer->source, header.source_port);
|
||||
|
||||
@@ -617,16 +617,8 @@ UdpEndpointManager::Deframe(net_buffer *buffer)
|
||||
|
||||
if (header.udp_checksum != 0) {
|
||||
// check UDP-checksum (simulating a so-called "pseudo-header"):
|
||||
Checksum udpChecksum;
|
||||
addressModule->checksum_address(&udpChecksum, source);
|
||||
addressModule->checksum_address(&udpChecksum, destination);
|
||||
udpChecksum
|
||||
<< (uint16)htons(IPPROTO_UDP)
|
||||
<< header.udp_length
|
||||
// peculiar but correct: UDP-len is used twice for checksum
|
||||
// (as it is already contained in udp_header)
|
||||
<< Checksum::BufferHelper(buffer, gBufferModule);
|
||||
uint16 sum = udpChecksum;
|
||||
uint16 sum = Checksum::PseudoHeader(addressModule, gBufferModule,
|
||||
buffer, IPPROTO_UDP);
|
||||
if (sum != 0) {
|
||||
TRACE_EPM(" Deframe(): bad checksum 0x%hx.", sum);
|
||||
return B_BAD_VALUE;
|
||||
@@ -881,20 +873,8 @@ UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route)
|
||||
|
||||
header.Sync();
|
||||
|
||||
// generate UDP-checksum (simulating a so-called "pseudo-header"):
|
||||
Checksum udpChecksum;
|
||||
AddressModule()->checksum_address(&udpChecksum,
|
||||
(sockaddr *)route->interface->address);
|
||||
AddressModule()->checksum_address(&udpChecksum,
|
||||
(sockaddr *)&buffer->destination);
|
||||
udpChecksum
|
||||
<< (uint16)htons(IPPROTO_UDP)
|
||||
<< (uint16)htons(buffer->size)
|
||||
// peculiar but correct: UDP-len is used twice for checksum
|
||||
// (as it is already contained in udp_header)
|
||||
<< Checksum::BufferHelper(buffer, gBufferModule);
|
||||
|
||||
uint16 calculatedChecksum = udpChecksum;
|
||||
uint16 calculatedChecksum = Checksum::PseudoHeader(AddressModule(),
|
||||
gBufferModule, buffer, IPPROTO_UDP);
|
||||
if (calculatedChecksum == 0)
|
||||
calculatedChecksum = 0xffff;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user