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_buffer.h>
|
||||||
#include <net_datalink.h>
|
#include <net_datalink.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h> // for htons
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
class Checksum {
|
class Checksum {
|
||||||
@@ -32,6 +34,10 @@ class Checksum {
|
|||||||
|
|
||||||
operator uint16();
|
operator uint16();
|
||||||
|
|
||||||
|
static uint16 PseudoHeader(net_address_module_info *addressModule,
|
||||||
|
net_buffer_module_info *bufferModule, net_buffer *buffer,
|
||||||
|
uint16 protocol);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 fSum;
|
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
|
// helper class that prints an address (and optionally a port) into a buffer that
|
||||||
// is automatically freed at end of scope:
|
// is automatically freed at end of scope:
|
||||||
class AddressString {
|
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,
|
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));
|
segment.flags, segment.sequence, segment.acknowledge, segment.advertised_window));
|
||||||
|
|
||||||
// compute and store checksum
|
*TCPChecksumField(buffer) = Checksum::PseudoHeader(gAddressModule,
|
||||||
Checksum checksum;
|
gBufferModule, buffer, IPPROTO_TCP);
|
||||||
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;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -518,15 +510,8 @@ tcp_receive_data(net_buffer *buffer)
|
|||||||
if (headerLength < sizeof(tcp_header))
|
if (headerLength < sizeof(tcp_header))
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
// compute checksum using a pseudo IP header
|
if (Checksum::PseudoHeader(gAddressModule, gBufferModule, buffer,
|
||||||
Checksum checksum;
|
IPPROTO_TCP) != 0)
|
||||||
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)
|
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
gAddressModule->set_port((struct sockaddr *)&buffer->source, header.source_port);
|
gAddressModule->set_port((struct sockaddr *)&buffer->source, header.source_port);
|
||||||
|
|||||||
@@ -617,16 +617,8 @@ UdpEndpointManager::Deframe(net_buffer *buffer)
|
|||||||
|
|
||||||
if (header.udp_checksum != 0) {
|
if (header.udp_checksum != 0) {
|
||||||
// check UDP-checksum (simulating a so-called "pseudo-header"):
|
// check UDP-checksum (simulating a so-called "pseudo-header"):
|
||||||
Checksum udpChecksum;
|
uint16 sum = Checksum::PseudoHeader(addressModule, gBufferModule,
|
||||||
addressModule->checksum_address(&udpChecksum, source);
|
buffer, IPPROTO_UDP);
|
||||||
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;
|
|
||||||
if (sum != 0) {
|
if (sum != 0) {
|
||||||
TRACE_EPM(" Deframe(): bad checksum 0x%hx.", sum);
|
TRACE_EPM(" Deframe(): bad checksum 0x%hx.", sum);
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@@ -881,20 +873,8 @@ UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route)
|
|||||||
|
|
||||||
header.Sync();
|
header.Sync();
|
||||||
|
|
||||||
// generate UDP-checksum (simulating a so-called "pseudo-header"):
|
uint16 calculatedChecksum = Checksum::PseudoHeader(AddressModule(),
|
||||||
Checksum udpChecksum;
|
gBufferModule, buffer, IPPROTO_UDP);
|
||||||
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;
|
|
||||||
if (calculatedChecksum == 0)
|
if (calculatedChecksum == 0)
|
||||||
calculatedChecksum = 0xffff;
|
calculatedChecksum = 0xffff;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user