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:
Hugo Santos
2007-04-15 23:18:15 +00:00
parent 239fad6de1
commit d5b5a2c2f8
3 changed files with 27 additions and 43 deletions
+19
View File
@@ -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;