xref: /haiku/headers/private/net/NetUtilities.h (revision e4f401b349cd8f848b4c09f5180caf1506ebf0de)
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 
16 class Checksum {
17 public:
18 	struct BufferHelper {
BufferHelperBufferHelper19 		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 
Checksum()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 
uint16()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 
80 private:
81 	uint32 fSum;
82 };
83 
84 
85 inline uint16
PseudoHeader(net_address_module_info * addressModule,net_buffer_module_info * bufferModule,net_buffer * buffer,uint16 protocol)86 Checksum::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 */
101 class AddressString {
102 public:
103 	AddressString(net_domain* domain, const sockaddr* address,
104 		bool printPort = false)
105 		:
fBuffer(NULL)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 		:
fBuffer(NULL)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 		:
fBuffer(NULL)122 		fBuffer(NULL)
123 	{
124 		address_module->print_address(address, &fBuffer, printPort);
125 	}
126 
~AddressString()127 	~AddressString()
128 	{
129 		free(fBuffer);
130 	}
131 
Data()132 	const char* Data() const
133 	{
134 		return fBuffer;
135 	}
136 
137 private:
138 	char* fBuffer;
139 };
140 
141 
142 #endif	// NET_UTILITIES_H
143