1/*
2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef NET_UTILITIES_H
6#define NET_UTILITIES_H
7
8
9#include <netinet/in.h>
10#include <stdlib.h>
11
12#include <net_buffer.h>
13#include <net_datalink.h>
14
15
16class Checksum {
17public:
18	struct BufferHelper {
19		BufferHelper(net_buffer* _buffer, net_buffer_module_info* _bufferModule)
20			:
21			buffer(_buffer),
22			bufferModule(_bufferModule)
23		{
24		}
25
26		net_buffer* buffer;
27		net_buffer_module_info* bufferModule;
28	};
29
30	Checksum()
31		:
32		fSum(0)
33	{
34	}
35
36	inline Checksum& operator<<(uint8 value)
37	{
38#if B_HOST_IS_LENDIAN
39		fSum += value;
40#else
41		fSum += (uint16)value << 8;
42#endif
43		return *this;
44	}
45
46	inline Checksum& operator<<(uint16 value)
47	{
48		fSum += value;
49		return *this;
50	}
51
52	inline Checksum& operator<<(uint32 value)
53	{
54		fSum += (value & 0xffff) + (value >> 16);
55		return *this;
56	}
57
58	inline Checksum& operator<<(const BufferHelper& bufferHelper)
59	{
60		net_buffer* buffer = bufferHelper.buffer;
61		fSum += bufferHelper.bufferModule->checksum(buffer, 0, buffer->size,
62			false);
63		return *this;
64	}
65
66	inline operator uint16()
67	{
68		while (fSum >> 16) {
69			fSum = (fSum & 0xffff) + (fSum >> 16);
70		}
71		uint16 result = (uint16)fSum;
72		result ^= 0xFFFF;
73		return result;
74	}
75
76	static uint16 PseudoHeader(net_address_module_info* addressModule,
77		net_buffer_module_info* bufferModule, net_buffer* buffer,
78		uint16 protocol);
79
80private:
81	uint32 fSum;
82};
83
84
85inline uint16
86Checksum::PseudoHeader(net_address_module_info* addressModule,
87	net_buffer_module_info* bufferModule, net_buffer* buffer, uint16 protocol)
88{
89	Checksum checksum;
90	addressModule->checksum_address(&checksum, buffer->source);
91	addressModule->checksum_address(&checksum, buffer->destination);
92	checksum << (uint16)htons(protocol) << (uint16)htons(buffer->size)
93		<< Checksum::BufferHelper(buffer, bufferModule);
94	return checksum;
95}
96
97
98/*!	Helper class that prints an address (and optionally a port) into a buffer
99	that is automatically freed at end of scope.
100*/
101class AddressString {
102public:
103	AddressString(net_domain* domain, const sockaddr* address,
104		bool printPort = false)
105		:
106		fBuffer(NULL)
107	{
108		domain->address_module->print_address(address, &fBuffer, printPort);
109	}
110
111	AddressString(net_domain* domain, const sockaddr& address,
112		bool printPort = false)
113		:
114		fBuffer(NULL)
115	{
116		domain->address_module->print_address(&address, &fBuffer, printPort);
117	}
118
119	AddressString(net_address_module_info* address_module,
120		const sockaddr* address, bool printPort = false)
121		:
122		fBuffer(NULL)
123	{
124		address_module->print_address(address, &fBuffer, printPort);
125	}
126
127	~AddressString()
128	{
129		free(fBuffer);
130	}
131
132	const char* Data() const
133	{
134		return fBuffer;
135	}
136
137private:
138	char* fBuffer;
139};
140
141
142#endif	// NET_UTILITIES_H
143