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