Skip to content

Commit f856d1c

Browse files
committed
Merge http-entry-fix-AliNoor into http-parsing-update, cleaned build artifacts
2 parents 48769c1 + 7b5fa44 commit f856d1c

11 files changed

Lines changed: 526 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ configure_file("${CMAKE_SOURCE_DIR}/config/interface.cfg"
1414
set(SOURCES
1515
src/main.cpp
1616
src/entry.cpp
17+
src/parsers/http.cpp
1718
src/parsers/ethernet.cpp
1819
src/parsers/ipv4.cpp
1920
src/parsers/http.cpp
@@ -24,6 +25,7 @@ set(SOURCES
2425
src/utils/decIPv4.cpp
2526
src/parsers/arp.cpp
2627
src/parsers/tcp.cpp
28+
src/parsers/ftp.cpp
2729
)
2830

2931
# Compiler warnings

include/parsers/ftp.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef PARSERS_FTP_H
2+
#define PARSERS_FTP_H
3+
4+
#include <cstdint>
5+
#include <string>
6+
#include <vector>
7+
8+
namespace parsers {
9+
// Full FTP Command Structure
10+
struct FTPCommand {
11+
std::string command; // FTP command, e.g., "USER", "PASS", "LIST"
12+
std::vector<std::string> arguments; // Command arguments
13+
std::vector<std::string> responses; // Server responses (multi-line support)
14+
15+
bool is_response; // True if this is a server response
16+
bool is_response_complete; // Whether full response is captured
17+
int response_code; // Numeric response code (e.g., 220, 331), -1 if not applicable
18+
19+
std::string to_string() const;
20+
};
21+
22+
23+
// Function to parse FTP command from a buffer
24+
FTPCommand parse_ftp_command(const uint8_t* buffer, std::size_t length, bool from_server);
25+
}
26+
#endif // PARSERS_FTP_H

index.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Example Domain</title>
5+
6+
<meta charset="utf-8" />
7+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
8+
<meta name="viewport" content="width=device-width, initial-scale=1" />
9+
<style type="text/css">
10+
body {
11+
background-color: #f0f0f2;
12+
margin: 0;
13+
padding: 0;
14+
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
15+
16+
}
17+
div {
18+
width: 600px;
19+
margin: 5em auto;
20+
padding: 2em;
21+
background-color: #fdfdff;
22+
border-radius: 0.5em;
23+
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
24+
}
25+
a:link, a:visited {
26+
color: #38488f;
27+
text-decoration: none;
28+
}
29+
@media (max-width: 700px) {
30+
div {
31+
margin: 0 auto;
32+
width: auto;
33+
}
34+
}
35+
</style>
36+
</head>
37+
38+
<body>
39+
<div>
40+
<h1>Example Domain</h1>
41+
<p>This domain is for use in illustrative examples in documents. You may use this
42+
domain in literature without prior coordination or asking for permission.</p>
43+
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
44+
</div>
45+
</body>
46+
</html>

screenshots/ss1.png

127 KB
Loading

screenshots/ss2.png

110 KB
Loading

screenshots/ss3.png

126 KB
Loading

src/entry.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int run_entry() {
4747
if (len < 0) {
4848
perror("[-] Packet receive failed");
4949
break;
50+
5051
}
5152

5253
packet_number++;
@@ -116,6 +117,13 @@ int run_entry() {
116117
std::cout << " Checksum: " << decoders::checksum_to_string(tcp.checksum) << "\n";
117118
std::cout << " Urgent Pointer: " << tcp.urgent_pointer << "\n";
118119
std::cout << " Options Length: " << static_cast<int>(tcp.options_length) << "\n";
120+
121+
// --- HTTP Parsing ---
122+
parsers::HTTPHeader http = parsers::parse_http_header(tcp.payload, tcp.payload_length);
123+
if (http.is_http) {
124+
std::cout << "[HTTP] Parsed Request/Response:\n"
125+
<< http.to_string() << std::endl;
126+
}
119127

120128
if (tcp.options_length > 0) {
121129
std::cout << " Options (hex): ";

src/entry.cpp.backup

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
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

Comments
 (0)