aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaditya Dhruv <[email protected]>2025-08-03 23:39:50 -0500
committerAaditya Dhruv <[email protected]>2025-08-03 23:39:50 -0500
commit11550c66c0002a86d8c899812989325f191ef797 (patch)
tree18620712ab82db5940767b400450d735d9501575
parent59feca8a49bd5fbe6d6331c518ab24d1addb6cb3 (diff)
Add support for sending ARP REPLY packets
Input includes the MAC Address and the spoofed IP address. For any broadcast REQUEST packet, the target protocol address (ipv4) is checked against the spoofed address, and if they are equal, an appropriate ARP REPLY is sent
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/arpee.c92
2 files changed, 83 insertions, 10 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 48a00de..5718117 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,2 +1,3 @@
add_executable(arpee arpee.h arpee.c)
target_link_libraries(arpee PRIVATE junk)
+install(CODE "execute_process(COMMAND sudo setcap 'CAP_NET_RAW+eip' ./build/src/arpee)")
diff --git a/src/arpee.c b/src/arpee.c
index fd9715f..69a8366 100644
--- a/src/arpee.c
+++ b/src/arpee.c
@@ -1,18 +1,90 @@
+#include <arpa/inet.h>
#include <junk/network.h>
+#include <linux/if_ether.h>
+#include <netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
-int main(int argc, char** argv) {
- if (argc != 2) {
+void print_usage() {
+ char *usage = "\
+arpee: Respond to ARP REQUESTS for spoofed IPs\n\
+USAGE:\n\
+arpee MACADDRESS IPADDRESS\n\
+MACADDRESS is the physical address on which the ARP REQUESTS will be responded to\n\
+IPADDRESS is the spoofed IPv4 address\n";
+ fprintf(stdout, "%s", usage);
+}
+int main(int argc, char **argv) {
+ if (argc != 3) {
+ print_usage();
return -1;
}
- int sock = eth_bind(argv[1]);
- printf("Got socket: %d\n", sock);
- char tmp_packet[sizeof(arp_packet)];
- memset(tmp_packet, 0, sizeof(arp_packet));
- arp_packet* packet = (arp_packet*) tmp_packet;
- eth_recv(sock, packet);
- fprintf(stderr, "%02X", packet->sender_hardware_address[0]);
+ int sock = eth_arp_bind(argv[1]);
+ // Keep listening for packets, and respond if appropriate
+ while (1) {
+ char recv_buffer[sizeof(arp_packet)];
+ memset(recv_buffer, 0, sizeof(arp_packet));
+ // Recieve a packet
+ arp_packet *recv_packet = (arp_packet *)recv_buffer;
+ eth_arp_recv(sock, recv_packet);
+
+ // Convert recieved binary IPv4 address to octet notation
+ char recv_ipv4_address[16];
+ sprintf(recv_ipv4_address, "%d.%d.%d.%d",
+ (unsigned char)recv_packet->target_protocol_address[0],
+ (unsigned char)recv_packet->target_protocol_address[1],
+ (unsigned char)recv_packet->target_protocol_address[2],
+ (unsigned char)recv_packet->target_protocol_address[3]);
+
+ // Only spoof arp packet if the REQUEST is asking for spoofed IP
+ // AND the recieved packet was a REQUEST (NOT REPLY)
+ printf("OP: %d", recv_packet->operation);
+ if (htons(recv_packet->operation) == 1 &&
+ strcmp(recv_ipv4_address, argv[2]) == 0)
+
+ {
+ fprintf(stderr,
+ "REQUEST for spoofed IP address %s, sending response...\n",
+ argv[2]);
+ char *send_buffer[sizeof(arp_packet)];
+ memset(send_buffer, 0, sizeof(send_buffer));
+ arp_packet *send_packet = (arp_packet *)send_buffer;
+ // Set sender hardware address (MAC) to host's macaddr
+ sscanf((char *)argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ &send_packet->sender_hardware_address[0],
+ &send_packet->sender_hardware_address[1],
+ &send_packet->sender_hardware_address[2],
+ &send_packet->sender_hardware_address[3],
+ &send_packet->sender_hardware_address[4],
+ &send_packet->sender_hardware_address[5]);
+ // Set sender IPv4 address to spoofed address
+ sscanf((char *)argv[2], "%d.%d.%d.%d",
+ &send_packet->sender_protocol_address[0],
+ &send_packet->sender_protocol_address[1],
+ &send_packet->sender_protocol_address[2],
+ &send_packet->sender_protocol_address[3]);
- return 0;
+ // Set target hardware address (MAC) to Request (recv) address
+ memcpy(send_packet->target_hardware_address,
+ recv_packet->sender_hardware_address,
+ sizeof(send_packet->target_hardware_address));
+ // Set target IPv4 address to requesting host's IPv4
+ memcpy(send_packet->target_protocol_address,
+ recv_packet->sender_protocol_address,
+ sizeof(send_packet->target_protocol_address));
+
+ // Type = Ethernet
+ send_packet->hardware_type = htons(0x01);
+ // Protocol is IPv4
+ send_packet->protocol_type = htons(ETH_P_IP);
+ // MAC address length
+ send_packet->hardware_length = (6);
+ // IPV4 Length
+ send_packet->protocol_length = (4);
+ // 0x02 = REPLY
+ send_packet->operation = htons(0x02);
+
+ eth_arp_send(sock, send_packet);
+ }
+ }
}