From d5b5a2c2f8c70f0e24cdf2e3a7fc9c4faa22e4c3 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Sun, 15 Apr 2007 23:18:15 +0000 Subject: [PATCH] introduced Checksum::PseudoHeader helper. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20717 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/NetUtilities.h | 19 +++++++++++++ .../kernel/network/protocols/tcp/tcp.cpp | 23 +++------------ .../kernel/network/protocols/udp/udp.cpp | 28 +++---------------- 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/headers/private/net/NetUtilities.h b/headers/private/net/NetUtilities.h index 4c96498143..69c61f9c1c 100644 --- a/headers/private/net/NetUtilities.h +++ b/headers/private/net/NetUtilities.h @@ -9,6 +9,8 @@ #include #include +#include // for htons + #include 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 { diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp index 7497c1f875..0943c8c8ec 100644 --- a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp @@ -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); diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 0d44470bfe..de0b15d46b 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -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;