Header.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2021 The Linux Foundation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above
  10. * copyright notice, this list of conditions and the following
  11. * disclaimer in the documentation and/or other materials provided
  12. * with the distribution.
  13. * * Neither the name of The Linux Foundation nor the names of its
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  21. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  24. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  25. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  26. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  27. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #ifndef NETWORK_TRAFFIC_HEADER_H
  30. #define NETWORK_TRAFFIC_HEADER_H
  31. #include <vector>
  32. #include <climits>
  33. #include <cassert>
  34. #include <ostream>
  35. #include <bitset>
  36. #include <iostream>
  37. #include <iomanip>
  38. #include <netinet/in.h>
  39. #include "bits_utils.h"
  40. using std::vector;
  41. using std::bitset;
  42. using std::string;
  43. // make a variable name fit for member variable name convention.
  44. #define MEMBERIZE_VAR(name) m##name
  45. // declare a bitset variable with any number of bits and also an integer setter method.
  46. #define DECLARE_BITSET(name, numBits, defaultVal) \
  47. bitset<numBits> MEMBERIZE_VAR(name) {defaultVal}; \
  48. void setm##name(unsigned int name) { \
  49. for(int i = 0; i < numBits; i++){ \
  50. MEMBERIZE_VAR(name)[i] = getUintNthBit(name, i); \
  51. } \
  52. } \
  53. static_assert(true, "")
  54. class Header {
  55. /**
  56. * class Header is an abstract class that provides the interface that is needed for every protocol header.
  57. * It also provides implementation of common operations for all protocol headers.
  58. * Every protocol header class must inherit from this class directly or indirectly.
  59. */
  60. public:
  61. virtual vector<bool> asVector() const = 0;
  62. virtual void streamFields(std::ostream &out) const = 0;
  63. virtual size_t size() const = 0;
  64. virtual string name() const = 0;
  65. virtual size_t asArray(uint8_t* buf) const {
  66. vector<bool> vec = asVector();
  67. size_t resSize = vec.size() / CHAR_BIT + ((vec.size() % CHAR_BIT) > 0);
  68. for(size_t i = 0; i < vec.size(); i++){
  69. changeNthBit(buf[i/8], (i%8), vec[i]);
  70. }
  71. return resSize;
  72. }
  73. static uint16_t computeChecksum(uint16_t *buf, size_t count){
  74. uint32_t sum = 0;
  75. while(count > 1){
  76. sum += *buf++;
  77. count -= 2;
  78. }
  79. if(count > 0){
  80. sum += ((*buf)&htons(0xFF00));
  81. }
  82. while(sum >> 16u){
  83. sum = (sum & 0xffffu) + (sum >> 16u);
  84. }
  85. sum = ~sum;
  86. return htons(static_cast<uint16_t>(sum));
  87. }
  88. virtual ~Header() = default;
  89. };
  90. template<typename T>
  91. inline std::ostream& operator<< (std::ostream &out, vector<T>const& v) {
  92. out << "#Bytes=" << v.size() << std::endl;
  93. for (size_t i = 0; i < v.size(); i++)
  94. out << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(v[i]) << " ";
  95. out << std::dec;
  96. return out;
  97. }
  98. inline std::ostream& operator<< (std::ostream &out, Header const& h) {
  99. vector<bool> headerAsVec = h.asVector();
  100. size_t bufSize = headerAsVec.size() / CHAR_BIT + ((headerAsVec.size() % CHAR_BIT) > 0);
  101. uint8_t buf[bufSize];
  102. out << h.name() + " Header" << std::endl;
  103. out << "#Bytes=" << h.size() << std::endl;
  104. h.streamFields(out);
  105. memset(buf, 0, bufSize);
  106. h.asArray(buf);
  107. for (size_t i = 0; i < bufSize; i++)
  108. out << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(buf[i]) << " ";
  109. out << std::dec;
  110. return out;
  111. }
  112. #endif //NETWORK_TRAFFIC_HEADER_H