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 { 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 80 private: 81 uint32 fSum; 82 }; 83 84 85 inline uint16 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 : 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 137 private: 138 char* fBuffer; 139 }; 140 141 142 #endif // NET_UTILITIES_H 143