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