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