|
| 1 | +#include "config/interface.h" |
| 2 | +#include "parsers/ethernet.h" |
| 3 | +#include "parsers/ipv4.h" |
| 4 | +#include "utils/decIPv4.h" |
| 5 | +#include "parsers/arp.h" |
| 6 | +#include "utils/decEthernet.h" |
| 7 | +#include "parsers/tcp.h" |
| 8 | +#include "parsers/http.h" |
| 9 | +#include "utils/decHttp.h" |
| 10 | + |
| 11 | + |
| 12 | +#include <iostream> |
| 13 | +#include <unistd.h> |
| 14 | +#include <cstring> |
| 15 | +#include <sys/socket.h> |
| 16 | +#include <netinet/in.h> |
| 17 | +#include <linux/if_packet.h> |
| 18 | +#include <arpa/inet.h> |
| 19 | +#include <iomanip> |
| 20 | + |
| 21 | +int run_entry() { |
| 22 | + // Create and bind socket |
| 23 | + int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); |
| 24 | + if (sock < 0) { |
| 25 | + perror("[-] Failed to create socket"); |
| 26 | + return 1; |
| 27 | + } |
| 28 | + |
| 29 | + // Load interface from config file in build/config/interface.cfg |
| 30 | + config::Interface iface; |
| 31 | + std::string iface_name = iface.get_interface(); |
| 32 | + |
| 33 | + if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface_name.c_str(), iface_name.length()) < 0) { |
| 34 | + perror(("[-] Failed to bind to interface: " + iface_name).c_str()); |
| 35 | + close(sock); |
| 36 | + return 1; |
| 37 | + } |
| 38 | + |
| 39 | + std::cout << "[+] Listening on interface: " << iface_name << "\n"; |
| 40 | + |
| 41 | + int packet_number = 0; |
| 42 | + |
| 43 | + // Step 2: Capture and parse packets |
| 44 | + uint8_t buffer[65536]; |
| 45 | + while (true) { |
| 46 | + ssize_t len = recvfrom(sock, buffer, sizeof(buffer), 0, nullptr, nullptr); |
| 47 | + if (len < 0) { |
| 48 | + perror("[-] Packet receive failed"); |
| 49 | + break; |
| 50 | + } |
| 51 | + |
| 52 | + packet_number++; |
| 53 | + |
| 54 | + // Step 3: Parse Ethernet frame (which dispatches to IPv4, etc.) |
| 55 | + parsers::EthernetHeader eth = parsers::parse_ethernet_header(buffer, len); |
| 56 | + |
| 57 | + if (eth.eth_proto == "IPv4") { |
| 58 | + parsers::IPv4Header ipv4 = parsers::parse_ipv4_header(eth.payload, eth.payload_len); |
| 59 | + |
| 60 | + |
| 61 | + std::cout << "[+] Packet # " << packet_number << " " << parsers::ipv4_to_string(ipv4.src_ip) << " ==> " << parsers::ipv4_to_string(ipv4.dest_ip) << "\n"; |
| 62 | + std::cout << " Ethernet Frame:\n"; |
| 63 | + std::cout << " Destination MAC: " << eth.dest_mac_str << "\n"; |
| 64 | + std::cout << " Source MAC: " << eth.src_mac_str << "\n"; |
| 65 | + std::cout << " EtherType: " << eth.eth_type_str << " (" << eth.eth_proto << ")\n"; |
| 66 | + std::cout << " IPv4 Packet:\n"; |
| 67 | + std::cout << " Version: " << decoders::version_to_string(static_cast<int>(ipv4.version)) << "\n"; |
| 68 | + std::cout << " Internet Header Length: " << decoders::ihl_to_string(static_cast<int>(ipv4.ihl)) << "\n"; |
| 69 | + std::cout << " Type Of Service: " << (static_cast<int>(ipv4.tos)) << "\n"; |
| 70 | + std::cout << " Total Length: " << decoders::total_length_to_string(ipv4.total_length) << "\n"; |
| 71 | + std::cout << " Identification: " << decoders::identification_to_string(ipv4.identification) << "\n"; |
| 72 | + std::cout << " Flags: " << decoders::flags_to_string((ipv4.flags_fragment_offset)) << "\n"; |
| 73 | + std::cout << " Fragment Offset: " << decoders::fragment_offset_to_string((ipv4.flags_fragment_offset)) << "\n"; |
| 74 | + std::cout << " Time To Live: " << decoders::ttl_to_string(static_cast<int>(ipv4.ttl)) << "\n"; |
| 75 | + std::cout << " Protocol: " << decoders::protocol_to_string(static_cast<int>(ipv4.protocol)) << "\n"; |
| 76 | + std::cout << " Header Checksum: " << decoders::checksum_to_string(ipv4.header_checksum)<< "\n"; |
| 77 | + std::cout << " Source IP: " << parsers::ipv4_to_string(ipv4.src_ip) << "\n"; |
| 78 | + std::cout << " Destination IP: " << parsers::ipv4_to_string(ipv4.dest_ip) << "\n"; |
| 79 | + std::cout << " Payload Length: " << ipv4.payload_length << " bytes\n"; |
| 80 | + // if (ipv4.payload_length > 0) { |
| 81 | + // std::cout << " Payload (hex): \n"; |
| 82 | + // std::cout << " "; |
| 83 | + // for (size_t i = 0; i < ipv4.payload_length && i < 64; ++i) { |
| 84 | + // std::cout << std::hex << std::setw(2) << std::setfill('0') |
| 85 | + // << static_cast<int>(ipv4.payload[i]) << " "; |
| 86 | + // if ((i + 1) % 16 == 0) std::cout << "\n "; |
| 87 | + // } |
| 88 | + // std::cout << "\n"; |
| 89 | + // } else { |
| 90 | + // std::cout << " No Payload\n"; |
| 91 | + // } |
| 92 | + |
| 93 | + if ((ipv4.protocol) == 6) { |
| 94 | + parsers::TCPHeader tcp = parsers::parse_tcp_header(ipv4.payload, ipv4.payload_length); |
| 95 | + |
| 96 | + std::cout << " TCP Packet: \n"; |
| 97 | + std::cout << " Source Port: " << tcp.src_port << "\n"; |
| 98 | + std::cout << " Destination Port: " << tcp.dest_port << "\n"; |
| 99 | + std::cout << " Sequence Number: " << tcp.seq_num << "\n"; |
| 100 | + std::cout << " Acknowledgment Number: " << tcp.ack_num << "\n"; |
| 101 | + std::cout << " Data Offset (header length in bytes): " << (tcp.data_offset * 4) << "\n"; |
| 102 | + |
| 103 | + // Print flags individually |
| 104 | + std::cout << " Flags:\n"; |
| 105 | + std::cout << " NS: " << tcp.ns_flag << "\n"; |
| 106 | + std::cout << " CWR: " << tcp.cwr_flag << "\n"; |
| 107 | + std::cout << " ECE: " << tcp.ece_flag << "\n"; |
| 108 | + std::cout << " URG: " << tcp.urg_flag << "\n"; |
| 109 | + std::cout << " ACK: " << tcp.ack_flag << "\n"; |
| 110 | + std::cout << " PSH: " << tcp.psh_flag << "\n"; |
| 111 | + std::cout << " RST: " << tcp.rst_flag << "\n"; |
| 112 | + std::cout << " SYN: " << tcp.syn_flag << "\n"; |
| 113 | + std::cout << " FIN: " << tcp.fin_flag << "\n"; |
| 114 | + |
| 115 | + std::cout << " Window Size: " << tcp.window_size << "\n"; |
| 116 | + std::cout << " Checksum: " << decoders::checksum_to_string(tcp.checksum) << "\n"; |
| 117 | + std::cout << " Urgent Pointer: " << tcp.urgent_pointer << "\n"; |
| 118 | + std::cout << " Options Length: " << static_cast<int>(tcp.options_length) << "\n"; |
| 119 | + |
| 120 | + if (tcp.options_length > 0) { |
| 121 | + std::cout << " Options (hex): "; |
| 122 | + for (size_t i = 0; i < tcp.options.size(); ++i) { |
| 123 | + std::cout << std::hex << std::setw(2) << std::setfill('0') |
| 124 | + << static_cast<int>(tcp.options[i]) << " "; |
| 125 | + } |
| 126 | + std::cout << std::dec << "\n"; // reset stream to decimal |
| 127 | + } else { |
| 128 | + std::cout << " No TCP Options\n"; |
| 129 | + } |
| 130 | +// HTTP parsing if any TCP payload exists |
| 131 | +if (tcp.payload_length > 0 && tcp.payload != nullptr) { |
| 132 | + parsers::HTTPHeader http = parsers::parse_http_header(tcp.payload, tcp.payload_length); |
| 133 | + if (http.is_http) { |
| 134 | + std::cout << http.to_string(); |
| 135 | + } |
| 136 | +} |
| 137 | + |
| 138 | + |
| 139 | + } |
| 140 | + } |
| 141 | + // ARP Protocol Implementation |
| 142 | + else if (eth.eth_proto == "ARP") { |
| 143 | + parsers::ARPHeader arp = parsers::parse_arp_header(eth.payload, eth.payload_len); |
| 144 | + |
| 145 | + std::cout << "[+] Packet #" << packet_number << " ARP " << arp.sender_ip << " ==> " << arp.target_ip << "\n"; |
| 146 | + std::cout << " Ethernet Frame:\n"; |
| 147 | + std::cout << " Destination MAC: " << eth.dest_mac_str << "\n"; |
| 148 | + std::cout << " Source MAC: " << eth.src_mac_str << "\n"; |
| 149 | + std::cout << " EtherType: " << eth.eth_type_str << " (" << eth.eth_proto << ")\n"; |
| 150 | + |
| 151 | + std::cout << " ARP Packet:\n"; |
| 152 | + std::cout << " Hardware Type: " << arp.hardware_type_str << "\n"; |
| 153 | + std::cout << " Protocol Type: " << arp.protocol_type_str << "\n"; |
| 154 | + std::cout << " Hardware Size: " << static_cast<int>(arp.hardware_size) << "\n"; |
| 155 | + std::cout << " Protocol Size: " << static_cast<int>(arp.protocol_size) << "\n"; |
| 156 | + std::cout << " Operation: " << ((arp.operation == 1) ? "Request (1)" : "Reply (2)") << "\n"; |
| 157 | + std::cout << " Sender MAC: "; |
| 158 | + for (const auto& byte : arp.sender_mac) |
| 159 | + std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << ":"; |
| 160 | + std::cout << "\b \n"; // Remove last colon |
| 161 | + |
| 162 | + std::cout << " Sender IP: " << arp.sender_ip << "\n"; |
| 163 | + |
| 164 | + std::cout << " Target MAC: "; |
| 165 | + for (const auto& byte : arp.target_mac) |
| 166 | + std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << ":"; |
| 167 | + std::cout << "\b \n"; |
| 168 | + |
| 169 | + std::cout << " Target IP: " << arp.target_ip << "\n"; |
| 170 | + } |
| 171 | + |
| 172 | + |
| 173 | + } |
| 174 | + |
| 175 | + close(sock); |
| 176 | + return 0; |
| 177 | +} |
0 commit comments