Advertisement
Gistrec

ОСИ 5

Dec 9th, 2018
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.36 KB | None | 0 0
  1. #ifndef UTILS
  2. #define UTILS
  3.  
  4. #include <string>
  5. #include <fstream>
  6. #include <sstream>
  7.  
  8.  
  9. namespace Utils {
  10.  
  11. /**
  12. * Функция читает 6 байт из файла и возвращает строку с MAC адресом
  13. * @param file - файл
  14. * @return строка с MAC адресом
  15. */
  16. std::string readMAC(std::fstream &file) {
  17. char MAC[6];
  18. file.read(MAC, 6);
  19.  
  20. std::ostringstream ss;
  21. for (int i = 0; i < 6; ++i) {
  22. if (i != 0) ss << ':';
  23. ss.width(2); //< Два символа для каждого байта
  24. ss.fill('0'); //< Дополняем нулем, если не хватает нужного количества символов
  25. ss << std::hex << (MAC[i] & 0xFF);
  26. }
  27.  
  28. // TODO: FIX IT! Пустой MAC
  29. if (ss.str() == "00:00:00:00:00:00") return Utils::readMAC(file);
  30. else return (ss.str());
  31. }
  32.  
  33. /**
  34. * Функция читает 2 байта из файла и определяет тип кадра
  35. * 0x0800 - IPv4, 0x8060 - ARP
  36. * @param file - файл
  37. * @return строка - тип
  38. */
  39. std::string getFrameType(std::fstream &file) {
  40. char type[2];
  41. file.read(type, 2);
  42.  
  43. if (type[0] == 8 && type[1] == 0) return std::string("IPv4");
  44. if (type[0] == 8 && type[1] == 6) return std::string("ARP");
  45.  
  46.  
  47. return std::string("Unknown");
  48. }
  49.  
  50. std::string readIP(std::fstream &file) {
  51. char ip[4];
  52. file.read(ip, 4);
  53.  
  54. std::ostringstream ss;
  55. for (int i = 0; i < 4; ++i) {
  56. if (i != 0) ss << '.';
  57. ss << std::dec << (ip[i] & 0xFF);
  58. }
  59.  
  60. return ss.str();
  61. }
  62.  
  63. /**
  64. * Функция читает два байта и возвращает число
  65. * @param file - файл
  66. * @return целове число
  67. */
  68. int readShort(std::fstream &file) {
  69. char bytes[2];
  70. file.read(bytes, 2);
  71.  
  72. // return (unsigned char)bytes[1] << 0 | (unsigned char)bytes[0] << 8;
  73. return (unsigned char)bytes[0] << 8 | (unsigned char)bytes[1] << 0;
  74. }
  75.  
  76. /**
  77. * Функция читает байт и определяет по нему тип пакета
  78. * 0x01 - ICMP, 0x06 - TCP, 0x17 - UDP
  79. * @return строка - тип пакета
  80. */
  81. std::string getPacketType(std::fstream &file) {
  82. char byte;
  83. file.read(&byte, 1);
  84.  
  85. switch (byte) {
  86. case 0x01: return std::string("ICMP");
  87. case 0x06: return std::string("TCP");
  88. case 0x11: return std::string("UDP");
  89. default: return std::string("Unknown");
  90. }
  91. }
  92.  
  93. }
  94.  
  95. #endif //UTILS
  96.  
  97. #ifndef PACKETS
  98. #define PACKETS
  99.  
  100. #include <fstream>
  101. #include <string>
  102. #include <iostream>
  103.  
  104. using std::string;
  105. using std::cout;
  106. using std::endl;
  107.  
  108.  
  109. namespace Packets {
  110.  
  111. /**
  112. * Функция парсит IPv4 пакет и выводит его данные
  113. * @link https://en.wikipedia.org/wiki/IPv4#Header
  114. * @param file - файл
  115. */
  116. void IPv4(std::fstream &file) {
  117. file.ignore(2); // Пропускаем 2 байта (Version, IHL, DSCP, ECN)
  118.  
  119. int packetSize = Utils::readShort(file); // 2 байта - Размер IPv4 пакета
  120. cout << "IPv4 packet size: " << packetSize << endl;
  121.  
  122. file.ignore(5); // Пропускаем 5 байт (Identification, Flags, Fragment Offset, TTL)
  123.  
  124. cout << "Packet type: " << Utils::getPacketType(file) << endl; // 1 байт - Протокол
  125.  
  126. file.ignore(2); // Пропускаем 2 байта (Header Checksum)
  127.  
  128. cout << "Source IP4 : " << Utils::readIP(file) << endl; // 4 байта
  129. cout << "Destination IP4: " << Utils::readIP(file) << endl; // 4 байта
  130.  
  131. file.ignore(packetSize - 20); // Пропускаем данные пакета (размер пакета - 20 байт на Header)
  132. }
  133.  
  134. // Размер ARP пакета меньше 46 байт
  135. // Но т.к. минимальное значение пакета должно быть 46 байт
  136. // То пропускаем 46!
  137. void ARP(std::fstream &file) {
  138. file.ignore(46);
  139. }
  140.  
  141. }
  142.  
  143. #endif //PACKETS
  144.  
  145. #include <iostream>
  146. #include <string>
  147. #include <fstream>
  148.  
  149.  
  150. using std::string;
  151. using std::cout;
  152. using std::endl;
  153.  
  154.  
  155. int main() {
  156. string filePath = "C:/Users/Alex/Downloads/ethers/ethers08.bin";
  157.  
  158. std::fstream file(filePath, std::ios::in | std::ios::binary);
  159.  
  160. int frameNumber = 1;
  161. while (file.good() && !file.eof()) {
  162. // cout << "File pointer:" << file.tellg() << endl;
  163. cout << "Frame number: " << frameNumber++ << endl;
  164. // Читаем два MAC адреса из файла
  165. cout << "Destination MAC: " << Utils::readMAC(file) << endl;
  166. cout << "Source MAC: " << Utils::readMAC(file) << endl;
  167.  
  168.  
  169. string frameType = Utils::getFrameType(file);
  170.  
  171. // !! string frameDescriptor = Utils::getFrameDescriptor(file);
  172.  
  173. cout << "Frame type: " << frameType << endl;
  174.  
  175. if (frameType == "IPv4") {
  176. Packets::IPv4(file);
  177. } else if (frameType == "ARP") {
  178. Packets::ARP(file);
  179. } else if (frameType == "Unknown") {
  180. // Вернуться на 2 байта назад
  181. file.seekg(-2, std::ios_base::cur);
  182. int packetSize = Utils::readShort(file);
  183. cout << "Packet size: " << packetSize << endl;
  184. file.seekg(packetSize, std::ios_base::cur);
  185. }
  186. // TODO: Legacy code: eof ставится только после попытки чтения
  187. file.ignore(1);
  188. if (file.eof()) {
  189. system("pause");
  190. return 0;
  191. }
  192. file.seekg(-1, std::ios_base::cur);
  193.  
  194. cout << endl << endl;
  195. }
  196. system("pause");
  197. return 0;
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement