artifacts_tests.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include "artifacts_tests.h"
  5. using namespace Tins;
  6. /**
  7. * Creates a new artifacts_tests object.
  8. */
  9. artifacts_tests::artifacts_tests() {
  10. }
  11. /*
  12. **************************************************************************
  13. Function: tcp_sum_calc()
  14. **************************************************************************
  15. Description:
  16. Calculate TCP checksum
  17. ***************************************************************************
  18. */
  19. typedef unsigned short u16;
  20. typedef unsigned long u32;
  21. u16 tcp_sum_calc(u16 len_tcp, u16 src_addr[],u16 dest_addr[], bool padding, u16 buff[])
  22. {
  23. u16 prot_tcp=6;
  24. u16 padd=0;
  25. u16 word16;
  26. u32 sum;
  27. // Find out if the length of data is even or odd number. If odd,
  28. // add a padding byte = 0 at the end of packet
  29. //if ((padding&1)==1){
  30. if(padding){
  31. padd=1;
  32. buff[len_tcp]=0;
  33. }
  34. //initialize sum to zero
  35. sum=0;
  36. // make 16 bit words out of every two adjacent 8 bit words and
  37. // calculate the sum of all 16 vit words
  38. for (int i=0;i<len_tcp+padd;i=i+2){
  39. word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
  40. sum = sum + (unsigned long)word16;
  41. }
  42. // add the TCP pseudo header which contains:
  43. // the IP source and destinationn addresses,
  44. for (int i=0;i<4;i=i+2){
  45. word16 =((src_addr[i]<<8)&0xFF00)+(src_addr[i+1]&0xFF);
  46. sum=sum+word16;
  47. }
  48. for (int i=0;i<4;i=i+2){
  49. word16 =((dest_addr[i]<<8)&0xFF00)+(dest_addr[i+1]&0xFF);
  50. sum=sum+word16;
  51. }
  52. // the protocol number and the length of the TCP packet
  53. sum = sum + prot_tcp + len_tcp;
  54. // keep only the last 16 bits of the 32 bit calculated sum and add the carries
  55. while (sum>>16)
  56. sum = (sum & 0xFFFF)+(sum >> 16);
  57. // Take the one's complement of sum
  58. sum = ~sum;
  59. return ((unsigned short) sum);
  60. }
  61. void convertIPv4toArray(std::string IP, unsigned short IP_bytes[]){
  62. std::vector<std::string> temp_v;
  63. split_str(IP,'.',temp_v);
  64. IP_bytes[0] = std::stoi(temp_v[0]);
  65. IP_bytes[1] = std::stoi(temp_v[1]);
  66. IP_bytes[2] = std::stoi(temp_v[2]);
  67. IP_bytes[3] = std::stoi(temp_v[3]);
  68. }
  69. /**
  70. * Checks the TCP checksum of a given packet.
  71. * @param tcpPkt The packet to get checked.
  72. */
  73. void artifacts_tests::check_checksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt){
  74. uint16_t checksum = tcpPkt.checksum();
  75. unsigned short calculatedChecsum = 0;
  76. int headerSize = tcpPkt.header_size();
  77. std::vector<uint8_t> bufferArray_8 = tcpPkt.serialize();
  78. std::vector<unsigned short> bufferArray_16;
  79. for(int i=0; (unsigned)i<bufferArray_8.size();i++){
  80. bufferArray_16.push_back(bufferArray_8[i]);
  81. }
  82. /*for(int i=0; i<bufferArray_8.size();i+=2){
  83. uint8_t temp[2];
  84. temp[0] = bufferArray_8[i];
  85. if(i!=(bufferArray_8.size()-1))
  86. temp[1] = bufferArray_8[i+1];
  87. else
  88. temp[1] = 0;
  89. unsigned short n;
  90. memcpy(&n, temp, sizeof(unsigned short));
  91. bufferArray_16.push_back(n);
  92. } */
  93. unsigned short* buff_16 = &bufferArray_16[0];
  94. unsigned short ipAddressSender_bytes[4];
  95. unsigned short ipAddressReceiver_bytes[4];
  96. convertIPv4toArray(ipAddressSender, ipAddressSender_bytes);
  97. convertIPv4toArray(ipAddressReceiver, ipAddressReceiver_bytes);
  98. //tcp_sum_calc(unsigned short len_tcp, unsigned short src_addr[],unsigned short dest_addr[], bool padding, unsigned short buff[])
  99. bool padding = false;
  100. int dataSize = bufferArray_8.size() - headerSize;
  101. if(dataSize != 0)
  102. if(dataSize % 2 != 0)
  103. padding = true; // padding if the data size is odd
  104. calculatedChecsum = tcp_sum_calc(bufferArray_8.size(), ipAddressSender_bytes, ipAddressReceiver_bytes, padding, buff_16);
  105. if(calculatedChecsum == checksum)
  106. correctChecksum++;
  107. else{
  108. std::cout<<"Sender:"<<ipAddressSender<<", Receiver:"<<ipAddressReceiver<<"\n";
  109. std::cout<<"Packet checksum:"<<checksum<<"\n";
  110. std::cout<<"Calculated checksum:"<<calculatedChecsum<<"\n";
  111. incorrectChecksum++;
  112. }
  113. }
  114. /**
  115. * Gets the ratio of incorrect TCP checksums to total number of TCP packets.
  116. */
  117. float artifacts_tests::get_checksum_incorrect_ratio(){
  118. int totalPktsNum = incorrectChecksum+correctChecksum;
  119. float ratio = 0;
  120. if(totalPktsNum!=0)
  121. ratio = (float)incorrectChecksum/totalPktsNum;
  122. std::cout<<"Incorrect checksums: "<<incorrectChecksum<<"\n";
  123. std::cout<<"Total TCP packets: "<<incorrectChecksum+correctChecksum<<"\n";
  124. std::cout<<"get_checksum_incorrect_ratio: "<<ratio<<"\n";
  125. return ratio;
  126. }