mirror of
https://review.haiku-os.org/haiku
synced 2025-01-21 05:53:46 +01:00
6c35350908
- IPv4 now assumes the addresses it is supplied in send_routed_data are already the appropriate ones. - made the Data(), operator* and operator-> methods in NetBufferFieldReader const so we can use them in the same expression as the constructor. - fixed an issue with UDP where the wrong source address could be used in the calculating the checksum. - changed ipv4_print_address to use the more common 0.0.0.0 format. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20660 a95241bf-73f2-0310-859d-f6bbb57e9c96
151 lines
2.9 KiB
C++
151 lines
2.9 KiB
C++
/*
|
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef NET_BUFFER_UTILITIES_H
|
|
#define NET_BUFFER_UTILITIES_H
|
|
|
|
|
|
#include <net_buffer.h>
|
|
|
|
|
|
extern net_buffer_module_info *gBufferModule;
|
|
|
|
class NetBufferModuleGetter {
|
|
public:
|
|
static net_buffer_module_info *Get() { return gBufferModule; }
|
|
};
|
|
|
|
//! A class to access a field safely across node boundaries
|
|
template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
|
|
class NetBufferFieldReader {
|
|
public:
|
|
NetBufferFieldReader(net_buffer *buffer)
|
|
:
|
|
fBuffer(buffer)
|
|
{
|
|
fStatus = Module::Get()->direct_access(fBuffer, Offset,
|
|
sizeof(Type), (void **)&fData);
|
|
if (fStatus != B_OK) {
|
|
fStatus = Module::Get()->read(fBuffer, Offset,
|
|
&fDataBuffer, sizeof(Type));
|
|
fData = &fDataBuffer;
|
|
}
|
|
}
|
|
|
|
status_t
|
|
Status() const
|
|
{
|
|
return fStatus;
|
|
}
|
|
|
|
Type &
|
|
Data() const
|
|
{
|
|
return *fData;
|
|
}
|
|
|
|
Type *
|
|
operator->() const
|
|
{
|
|
return fData;
|
|
}
|
|
|
|
Type &
|
|
operator*() const
|
|
{
|
|
return *fData;
|
|
}
|
|
|
|
void
|
|
Sync()
|
|
{
|
|
if (fBuffer == NULL || fStatus < B_OK)
|
|
return;
|
|
|
|
if (fData == &fDataBuffer)
|
|
Module::Get()->write(fBuffer, Offset, fData, sizeof(Type));
|
|
|
|
fBuffer = NULL;
|
|
}
|
|
|
|
protected:
|
|
NetBufferFieldReader() {}
|
|
|
|
net_buffer *fBuffer;
|
|
status_t fStatus;
|
|
Type *fData;
|
|
Type fDataBuffer;
|
|
};
|
|
|
|
template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
|
|
class NetBufferField : public NetBufferFieldReader<Type, Offset, Module> {
|
|
public:
|
|
NetBufferField(net_buffer *buffer)
|
|
: NetBufferFieldReader<Type, Offset, Module>(buffer)
|
|
{}
|
|
|
|
~NetBufferField()
|
|
{
|
|
Sync();
|
|
}
|
|
};
|
|
|
|
template<typename Type, typename Module = NetBufferModuleGetter>
|
|
class NetBufferHeaderReader : public NetBufferFieldReader<Type, 0, Module> {
|
|
public:
|
|
NetBufferHeaderReader(net_buffer *buffer)
|
|
: NetBufferFieldReader<Type, 0, Module>(buffer)
|
|
{}
|
|
|
|
void
|
|
Remove()
|
|
{
|
|
Remove(sizeof(Type));
|
|
}
|
|
|
|
void
|
|
Remove(size_t bytes)
|
|
{
|
|
if (fBuffer != NULL) {
|
|
Module::Get()->remove_header(fBuffer, bytes);
|
|
fBuffer = NULL;
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename Type, typename Module = NetBufferModuleGetter>
|
|
class NetBufferHeaderRemover : public NetBufferHeaderReader<Type, Module> {
|
|
public:
|
|
NetBufferHeaderRemover(net_buffer *buffer)
|
|
: NetBufferHeaderReader<Type, Module>(buffer)
|
|
{}
|
|
|
|
~NetBufferHeaderRemover()
|
|
{
|
|
Remove();
|
|
}
|
|
};
|
|
|
|
//! A class to add a header to a buffer
|
|
template<typename Type, typename Module = NetBufferModuleGetter>
|
|
class NetBufferPrepend : public NetBufferFieldReader<Type, 0, Module> {
|
|
public:
|
|
NetBufferPrepend(net_buffer *buffer, size_t size = sizeof(Type))
|
|
{
|
|
fBuffer = buffer;
|
|
|
|
fStatus = Module::Get()->prepend_size(buffer, size,
|
|
(void **)&fData);
|
|
if (fStatus == B_OK && fData == NULL)
|
|
fData = &fDataBuffer;
|
|
}
|
|
|
|
~NetBufferPrepend()
|
|
{
|
|
Sync();
|
|
}
|
|
};
|
|
|
|
#endif // NET_BUFFER_UTILITIES_H
|