net_buffer: preparing for better metadata management

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21210 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-23 03:48:23 +00:00
parent 57f13ad210
commit 79a0d25245
16 changed files with 109 additions and 114 deletions

View File

@ -88,8 +88,8 @@ 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);
addressModule->checksum_address(&checksum, buffer->source);
addressModule->checksum_address(&checksum, buffer->destination);
checksum << (uint16)htons(protocol) << (uint16)htons(buffer->size)
<< Checksum::BufferHelper(buffer, bufferModule);
return checksum;

View File

@ -19,8 +19,9 @@ typedef struct net_buffer {
// TODO: we should think about moving the address fields into the buffer data itself
// via associated data or something like this. Or this structure as a whole, too...
struct sockaddr_storage source;
struct sockaddr_storage destination;
struct sockaddr *source;
struct sockaddr *destination;
struct net_interface *interface;
union {
struct {

View File

@ -241,7 +241,7 @@ arp_entry::MarkValid()
TRACE((" ARP Dequeing packet %p...\n", buffer));
memcpy(&buffer->destination, &hardware_address,
memcpy(buffer->destination, &hardware_address,
hardware_address.sdl_len);
protocol->next->module->send_data(protocol->next, buffer);
}
@ -375,7 +375,7 @@ handle_arp_request(net_buffer *buffer, arp_header &header)
BenaphoreLocker locker(sCacheLock);
if (!sIgnoreReplies) {
arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0);
arp_update_entry(header.protocol_sender, (sockaddr_dl *)buffer->source, 0);
// remember the address of the sender as we might need it later
}
@ -401,9 +401,9 @@ handle_arp_request(net_buffer *buffer, arp_header &header)
header.protocol_sender = entry->protocol_address;
// exchange source and destination address
memcpy(LLADDR((sockaddr_dl *)&buffer->source), header.hardware_sender,
memcpy(LLADDR((sockaddr_dl *)buffer->source), header.hardware_sender,
ETHER_ADDRESS_LENGTH);
memcpy(LLADDR((sockaddr_dl *)&buffer->destination), header.hardware_target,
memcpy(LLADDR((sockaddr_dl *)buffer->destination), header.hardware_target,
ETHER_ADDRESS_LENGTH);
buffer->flags = 0;
@ -420,7 +420,7 @@ handle_arp_reply(net_buffer *buffer, arp_header &header)
return;
BenaphoreLocker locker(sCacheLock);
arp_update_entry(header.protocol_sender, (sockaddr_dl *)&buffer->source, 0);
arp_update_entry(header.protocol_sender, (sockaddr_dl *)buffer->source, 0);
}
@ -602,7 +602,7 @@ arp_start_resolve(net_datalink_protocol *protocol, in_addr_t address, arp_entry
// prepare source and target addresses
struct sockaddr_dl &source = *(struct sockaddr_dl *)&entry->request_buffer->source;
struct sockaddr_dl &source = *(struct sockaddr_dl *)entry->request_buffer->source;
source.sdl_len = sizeof(sockaddr_dl);
source.sdl_family = AF_DLI;
source.sdl_index = device->index;
@ -807,26 +807,26 @@ arp_send_data(net_datalink_protocol *protocol,
// TODO: this could be cached - the lookup isn't really needed at all
arp_entry *entry = arp_entry::Lookup(
((struct sockaddr_in *)&buffer->source)->sin_addr.s_addr);
((struct sockaddr_in *)buffer->source)->sin_addr.s_addr);
if (entry == NULL)
return B_ERROR;
memcpy(&buffer->source, &entry->hardware_address,
memcpy(buffer->source, &entry->hardware_address,
entry->hardware_address.sdl_len);
if (buffer->flags & MSG_MCAST) {
sockaddr_dl multicastDestination;
ipv4_to_ether_multicast(&multicastDestination,
(sockaddr_in *)&buffer->destination);
memcpy(&buffer->destination, &multicastDestination,
(sockaddr_in *)buffer->destination);
memcpy(buffer->destination, &multicastDestination,
sizeof(multicastDestination));
} else if ((buffer->flags & MSG_BCAST) == 0) {
// Lookup destination (we may need to wait for this)
entry = arp_entry::Lookup(
((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr);
((struct sockaddr_in *)buffer->destination)->sin_addr.s_addr);
if (entry == NULL) {
status_t status = arp_start_resolve(protocol,
((struct sockaddr_in *)&buffer->destination)->sin_addr.s_addr, &entry);
((struct sockaddr_in *)buffer->destination)->sin_addr.s_addr, &entry);
if (status < B_OK)
return status;
}
@ -841,7 +841,7 @@ arp_send_data(net_datalink_protocol *protocol,
return B_OK;
}
memcpy(&buffer->destination, &entry->hardware_address,
memcpy(buffer->destination, &entry->hardware_address,
entry->hardware_address.sdl_len);
}
}

View File

@ -45,8 +45,8 @@ ethernet_deframe(net_device *device, net_buffer *buffer)
ether_header &header = bufferHeader.Data();
uint16 type = ntohs(header.type);
struct sockaddr_dl &source = *(struct sockaddr_dl *)&buffer->source;
struct sockaddr_dl &destination = *(struct sockaddr_dl *)&buffer->destination;
struct sockaddr_dl &source = *(struct sockaddr_dl *)buffer->source;
struct sockaddr_dl &destination = *(struct sockaddr_dl *)buffer->destination;
source.sdl_len = sizeof(sockaddr_dl);
source.sdl_family = AF_DLI;
@ -119,8 +119,8 @@ status_t
ethernet_frame_send_data(net_datalink_protocol *protocol,
net_buffer *buffer)
{
struct sockaddr_dl &source = *(struct sockaddr_dl *)&buffer->source;
struct sockaddr_dl &destination = *(struct sockaddr_dl *)&buffer->destination;
struct sockaddr_dl &source = *(struct sockaddr_dl *)buffer->source;
struct sockaddr_dl &destination = *(struct sockaddr_dl *)buffer->destination;
if (source.sdl_family != AF_DLI || source.sdl_type != IFT_ETHER)
return B_ERROR;

View File

@ -13,6 +13,7 @@
#include <KernelExport.h>
#include <algorithm>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_media.h>
@ -157,9 +158,8 @@ loopback_receive_data(net_device *_device, net_buffer **_buffer)
if (status < B_OK)
return status;
// switch network addresses before delivering
swap_memory(&buffer->source, &buffer->destination,
max_c(buffer->source.ss_len, buffer->destination.ss_len));
// swap network addresses before delivering
std::swap(buffer->source, buffer->destination);
*_buffer = buffer;
return B_OK;

View File

@ -15,6 +15,7 @@
#include <KernelExport.h>
#include <util/list.h>
#include <algorithm>
#include <netinet/in.h>
#include <new>
#include <stdlib.h>
@ -254,7 +255,7 @@ icmp_receive_data(net_buffer *buffer)
if (buffer->interface != NULL)
domain = buffer->interface->domain;
else
domain = sStackModule->get_domain(buffer->source.ss_family);
domain = sStackModule->get_domain(buffer->source->sa_family);
if (domain == NULL || domain->module == NULL)
break;
@ -262,9 +263,7 @@ icmp_receive_data(net_buffer *buffer)
if (reply == NULL)
return B_NO_MEMORY;
// switch source/destination address
memcpy(&reply->source, &buffer->destination, buffer->destination.ss_len);
memcpy(&reply->destination, &buffer->source, buffer->source.ss_len);
std::swap(reply->source, reply->destination);
// There already is an ICMP header, and we'll reuse it
NetBufferHeaderReader<icmp_header> header(reply);

View File

@ -646,7 +646,7 @@ deliver_multicast(net_protocol_module_info *module, net_buffer *buffer,
BenaphoreLocker _(sMulticastGroupsLock);
sockaddr_in *multicastAddr = (sockaddr_in *)&buffer->destination;
sockaddr_in *multicastAddr = (sockaddr_in *)buffer->destination;
MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair(
&multicastAddr->sin_addr, buffer->interface->index));
@ -769,13 +769,14 @@ receiving_protocol(uint8 protocol)
}
static inline void
static inline sockaddr *
fill_sockaddr_in(sockaddr_in *target, in_addr_t address)
{
memset(target, 0, sizeof(sockaddr_in));
target->sin_family = AF_INET;
target->sin_len = sizeof(sockaddr_in);
target->sin_addr.s_addr = address;
return (sockaddr *)target;
}
@ -867,13 +868,8 @@ static net_interface *
get_multicast_interface(ipv4_protocol *protocol, const in_addr *address)
{
sockaddr_in groupAddr;
memset(&groupAddr, 0, sizeof(groupAddr));
groupAddr.sin_family = AF_INET;
if (address)
groupAddr.sin_addr = *address;
net_route *route = sDatalinkModule->get_route(sDomain,
(sockaddr *)&groupAddr);
fill_sockaddr_in(&groupAddr, address ? address->s_addr : INADDR_ANY));
if (route == NULL)
return NULL;
@ -891,10 +887,8 @@ ipv4_delta_membership(ipv4_protocol *protocol, int option,
interface = get_multicast_interface(protocol, groupAddr);
} else {
sockaddr_in address;
fill_sockaddr_in(&address, interfaceAddr->s_addr);
interface = sDatalinkModule->get_interface_with_address(sDomain,
(sockaddr *)&address);
fill_sockaddr_in(&address, interfaceAddr->s_addr));
}
if (interface == NULL)
@ -1255,8 +1249,8 @@ ipv4_send_routed_data(net_protocol *_protocol, struct net_route *route,
TRACE_SK(protocol, "SendRoutedData(%p, %p [%ld bytes])", route, buffer,
buffer->size);
sockaddr_in &source = *(sockaddr_in *)&buffer->source;
sockaddr_in &destination = *(sockaddr_in *)&buffer->destination;
sockaddr_in &source = *(sockaddr_in *)buffer->source;
sockaddr_in &destination = *(sockaddr_in *)buffer->destination;
bool headerIncluded = false, checksumNeeded = true;
if (protocol != NULL)
@ -1348,8 +1342,8 @@ ipv4_send_data(net_protocol *_protocol, net_buffer *buffer)
if (buffer->size < sizeof(ipv4_header))
return EINVAL;
sockaddr_in *source = (sockaddr_in *)&buffer->source;
sockaddr_in *destination = (sockaddr_in *)&buffer->destination;
sockaddr_in *source = (sockaddr_in *)buffer->source;
sockaddr_in *destination = (sockaddr_in *)buffer->destination;
fill_sockaddr_in(source, *NetBufferField<in_addr_t,
offsetof(ipv4_header, source)>(buffer));
@ -1445,8 +1439,8 @@ ipv4_receive_data(net_buffer *buffer)
if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0)
return B_BAD_DATA;
struct sockaddr_in &source = *(struct sockaddr_in *)&buffer->source;
struct sockaddr_in &destination = *(struct sockaddr_in *)&buffer->destination;
struct sockaddr_in &source = *(struct sockaddr_in *)buffer->source;
struct sockaddr_in &destination = *(struct sockaddr_in *)buffer->destination;
fill_sockaddr_in(&source, header.source);
fill_sockaddr_in(&destination, header.destination);

View File

@ -133,7 +133,7 @@ template<typename Addressing> bool
MulticastGroupInterface<Addressing>::FilterAccepts(net_buffer *buffer) const
{
bool has = fAddresses.Has(Addressing::AddressFromSockAddr(
(sockaddr *)&buffer->source));
buffer->source));
return (has && fFilterMode == kInclude)
|| (!has && fFilterMode == kExclude);

View File

@ -386,10 +386,8 @@ EndpointManager::ReplyWithReset(tcp_segment_header &segment,
if (reply == NULL)
return B_NO_MEMORY;
AddressModule()->set_to((sockaddr *)&reply->source,
(sockaddr *)&buffer->destination);
AddressModule()->set_to((sockaddr *)&reply->destination,
(sockaddr *)&buffer->source);
AddressModule()->set_to(reply->source, buffer->destination);
AddressModule()->set_to(reply->destination, buffer->source);
tcp_segment_header outSegment(TCP_FLAG_RESET);
outSegment.sequence = 0;

View File

@ -48,7 +48,7 @@
// Forward RTO-Recovery, RFC 4138
#define PrintAddress(address) \
AddressString(Domain(), (const sockaddr *)(address), true).Data()
AddressString(Domain(), address, true).Data()
//#define TRACE_TCP
//#define PROBE_TCP
@ -64,8 +64,8 @@
#ifdef PROBE_TCP
# define PROBE(buffer, window) \
dprintf("TCP PROBE %llu %s %s %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu\n", \
system_time(), PrintAddress(&buffer->source), \
PrintAddress(&buffer->destination), buffer->size, (uint32)fSendNext, \
system_time(), PrintAddress(buffer->source), \
PrintAddress(buffer->destination), buffer->size, (uint32)fSendNext, \
(uint32)fSendUnacknowledged, fCongestionWindow, fSlowStartThreshold, \
window, fSendWindow, (uint32)(fSendMax - fSendUnacknowledged), \
fSendQueue.Available(fSendNext), fSendQueue.Used(), fRetransmitTimeout)
@ -852,8 +852,8 @@ TCPEndpoint::Spawn(TCPEndpoint *parent, tcp_segment_header &segment,
fState = SYNCHRONIZE_RECEIVED;
fManager = parent->fManager;
LocalAddress().SetTo(&buffer->destination);
PeerAddress().SetTo(&buffer->source);
LocalAddress().SetTo(buffer->destination);
PeerAddress().SetTo(buffer->source);
TRACE("Spawn()");
@ -958,8 +958,8 @@ TCPEndpoint::SegmentReceived(tcp_segment_header &segment, net_buffer *buffer)
RecursiveLocker locker(fLock);
TRACE("SegmentReceived(): buffer %p (%lu bytes) address %s to %s",
buffer, buffer->size, PrintAddress(&buffer->source),
PrintAddress(&buffer->destination));
buffer, buffer->size, PrintAddress(buffer->source),
PrintAddress(buffer->destination));
TRACE(" flags 0x%x, seq %lu, ack %lu, wnd %lu",
segment.flags, segment.sequence, segment.acknowledge,
(uint32)segment.advertised_window << fSendWindowShift);
@ -1241,15 +1241,15 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
return status;
}
LocalAddress().CopyTo(&buffer->source);
PeerAddress().CopyTo(&buffer->destination);
LocalAddress().CopyTo(buffer->source);
PeerAddress().CopyTo(buffer->destination);
uint32 size = buffer->size;
segment.sequence = fSendNext;
TRACE("SendQueued(): buffer %p (%lu bytes) address %s to %s",
buffer, buffer->size, PrintAddress(&buffer->source),
PrintAddress(&buffer->destination));
buffer, buffer->size, PrintAddress(buffer->source),
PrintAddress(buffer->destination));
TRACE(" flags 0x%x, seq %lu, ack %lu, rwnd %hu, cwnd %lu"
", ssthresh %lu", segment.flags, segment.sequence,
segment.acknowledge, segment.advertised_window,

View File

@ -206,8 +206,8 @@ add_tcp_header(net_address_module_info *addressModule,
tcp_header &header = bufferHeader.Data();
header.source_port = addressModule->get_port((sockaddr *)&buffer->source);
header.destination_port = addressModule->get_port((sockaddr *)&buffer->destination);
header.source_port = addressModule->get_port(buffer->source);
header.destination_port = addressModule->get_port(buffer->destination);
header.sequence = htonl(segment.sequence);
header.acknowledge = (segment.flags & TCP_FLAG_ACKNOWLEDGE)
? htonl(segment.acknowledge) : 0;
@ -614,13 +614,12 @@ tcp_receive_data(net_buffer *buffer)
IPPROTO_TCP) != 0)
return B_BAD_DATA;
addressModule->set_port((sockaddr *)&buffer->source, header.source_port);
addressModule->set_port((sockaddr *)&buffer->destination,
header.destination_port);
addressModule->set_port(buffer->source, header.source_port);
addressModule->set_port(buffer->destination, header.destination_port);
TRACE((" Looking for: peer %s, local %s\n",
AddressString(domain, (sockaddr *)&buffer->source, true).Data(),
AddressString(domain, (sockaddr *)&buffer->destination, true).Data()));
AddressString(domain, buffer->source, true).Data(),
AddressString(domain, buffer->destination, true).Data()));
//dump_tcp_header(header);
//gBufferModule->dump(buffer);
@ -643,7 +642,7 @@ tcp_receive_data(net_buffer *buffer)
int32 segmentAction = DROP;
TCPEndpoint *endpoint = endpointManager->FindConnection(
(sockaddr *)&buffer->destination, (sockaddr *)&buffer->source);
buffer->destination, buffer->source);
if (endpoint != NULL)
segmentAction = endpoint->SegmentReceived(segment, buffer);
else if ((segment.flags & TCP_FLAG_RESET) == 0)

View File

@ -454,8 +454,8 @@ UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress,
status_t
UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
{
sockaddr *peerAddr = (sockaddr *)&buffer->source;
sockaddr *broadcastAddr = (sockaddr *)&buffer->destination;
sockaddr *peerAddr = buffer->source;
sockaddr *broadcastAddr = buffer->destination;
sockaddr *mask = NULL;
if (buffer->interface)
mask = (sockaddr *)buffer->interface->mask;
@ -501,8 +501,8 @@ UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
status_t
UdpDomainSupport::_DemuxUnicast(net_buffer *buffer)
{
struct sockaddr *peerAddr = (struct sockaddr *)&buffer->source;
struct sockaddr *localAddr = (struct sockaddr *)&buffer->destination;
struct sockaddr *peerAddr = buffer->source;
struct sockaddr *localAddr = buffer->destination;
TRACE_DOMAIN("_DemuxUnicast(%p)", buffer);
@ -678,8 +678,8 @@ UdpEndpointManager::Deframe(net_buffer *buffer)
net_domain *domain = buffer->interface->domain;
net_address_module_info *addressModule = domain->address_module;
SocketAddress source(addressModule, &buffer->source);
SocketAddress destination(addressModule, &buffer->destination);
SocketAddress source(addressModule, buffer->source);
SocketAddress destination(addressModule, buffer->destination);
source.SetPort(header.source_port);
destination.SetPort(header.destination_port);
@ -863,9 +863,8 @@ UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route)
if (header.Status() < B_OK)
return header.Status();
header->source_port = AddressModule()->get_port((sockaddr *)&buffer->source);
header->destination_port = AddressModule()->get_port(
(sockaddr *)&buffer->destination);
header->source_port = AddressModule()->get_port(buffer->source);
header->destination_port = AddressModule()->get_port(buffer->destination);
header->udp_length = htons(buffer->size);
// the udp-header is already included in the buffer-size
header->udp_checksum = 0;

View File

@ -355,7 +355,7 @@ datalink_send_data(struct net_route *route, net_buffer *buffer)
// instead of the destination address:
if (route->gateway == NULL)
return B_MISMATCHED_VALUES;
memcpy(&buffer->destination, route->gateway, sizeof(sockaddr));
memcpy(buffer->destination, route->gateway, route->gateway->sa_len);
}
// this goes out to the datalink protocols

View File

@ -62,6 +62,11 @@ struct data_header {
struct net_buffer_private : net_buffer {
struct list buffers;
data_node first_node;
struct {
struct sockaddr_storage source;
struct sockaddr_storage destination;
} storage;
};
@ -328,8 +333,12 @@ create_buffer(size_t headerSpace)
list_init(&buffer->buffers);
list_add_item(&buffer->buffers, &buffer->first_node);
buffer->source.ss_len = 0;
buffer->destination.ss_len = 0;
buffer->source = (sockaddr *)&buffer->storage.source;
buffer->destination = (sockaddr *)&buffer->storage.destination;
buffer->storage.source.ss_len = 0;
buffer->storage.destination.ss_len = 0;
buffer->interface = NULL;
buffer->offset = 0;
buffer->flags = 0;
@ -355,6 +364,22 @@ free_buffer(net_buffer *_buffer)
}
static void
copy_metadata(net_buffer *destination, const net_buffer *source)
{
memcpy(destination->source, source->source,
min_c(source->source->sa_len, sizeof(sockaddr_storage)));
memcpy(destination->destination, source->destination,
min_c(source->destination->sa_len, sizeof(sockaddr_storage)));
destination->flags = source->flags;
destination->interface = source->interface;
destination->offset = source->offset;
destination->size = source->size;
destination->protocol = source->protocol;
}
/*! Creates a duplicate of the \a buffer. The new buffer does not share internal
storage; they are completely independent from each other.
*/
@ -381,18 +406,7 @@ duplicate_buffer(net_buffer *_buffer)
break;
}
// copy meta data from source buffer
memcpy(&duplicate->source, &buffer->source,
min_c(buffer->source.ss_len, sizeof(sockaddr_storage)));
memcpy(&duplicate->destination, &buffer->destination,
min_c(buffer->destination.ss_len, sizeof(sockaddr_storage)));
duplicate->flags = buffer->flags;
duplicate->interface = buffer->interface;
duplicate->offset = buffer->offset;
duplicate->size = buffer->size;
duplicate->protocol = buffer->protocol;
copy_metadata(duplicate, buffer);
return duplicate;
}
@ -423,6 +437,9 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
return NULL;
}
clone->source = (sockaddr *)&clone->storage.source;
clone->destination = (sockaddr *)&clone->storage.destination;
list_init(&clone->buffers);
// grab reference to this buffer - all additional nodes will get
@ -465,18 +482,7 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
}
}
// copy meta data from source buffer
memcpy(&clone->source, &buffer->source,
min_c(buffer->source.ss_len, sizeof(sockaddr_storage)));
memcpy(&clone->destination, &buffer->destination,
min_c(buffer->destination.ss_len, sizeof(sockaddr_storage)));
clone->flags = buffer->flags;
clone->interface = buffer->interface;
clone->offset = buffer->offset;
clone->size = buffer->size;
clone->protocol = buffer->protocol;
copy_metadata(clone, buffer);
return clone;
}

View File

@ -176,8 +176,8 @@ socket_writev(net_socket *socket, const iovec *vecs, size_t vecCount, size_t *_l
}
}
memcpy(&buffer->source, &socket->address, socket->address.ss_len);
memcpy(&buffer->destination, &socket->peer, socket->peer.ss_len);
memcpy(buffer->source, &socket->address, socket->address.ss_len);
memcpy(buffer->destination, &socket->peer, socket->peer.ss_len);
size_t size = buffer->size;
ssize_t bytesWritten = socket->first_info->send_data(socket->first_protocol,
@ -840,8 +840,8 @@ socket_receive(net_socket *socket, msghdr *header, void *data, size_t length,
}
if (header->msg_name != NULL) {
header->msg_namelen = min_c(nameLen, buffer->source.ss_len);
memcpy(header->msg_name, &buffer->source, header->msg_namelen);
header->msg_namelen = min_c(nameLen, buffer->source->sa_len);
memcpy(header->msg_name, buffer->source, header->msg_namelen);
}
}
@ -929,8 +929,8 @@ socket_send(net_socket *socket, msghdr *header, const void *data,
}
buffer->flags = flags;
memcpy(&buffer->source, &socket->address, socket->address.ss_len);
memcpy(&buffer->destination, address, addressLength);
memcpy(buffer->source, &socket->address, socket->address.ss_len);
memcpy(buffer->destination, address, addressLength);
status_t status = socket->first_info->send_data(socket->first_protocol,
buffer);

View File

@ -542,13 +542,12 @@ get_buffer_route(net_domain *_domain, net_buffer *buffer, net_route **_route)
BenaphoreLocker _(domain->lock);
net_route *route = get_route_internal(domain,
(sockaddr *)&buffer->destination);
net_route *route = get_route_internal(domain, buffer->destination);
if (route == NULL)
return ENETUNREACH;
status_t status = B_OK;
sockaddr *source = (sockaddr *)&buffer->source;
sockaddr *source = buffer->source;
// TODO we are quite relaxed in the address checking here
// as we might proceed with srcaddr=INADDR_ANY.