diff options
author | Aaditya Dhruv <[email protected]> | 2025-08-03 23:39:50 -0500 |
---|---|---|
committer | Aaditya Dhruv <[email protected]> | 2025-08-03 23:39:50 -0500 |
commit | 11550c66c0002a86d8c899812989325f191ef797 (patch) | |
tree | 18620712ab82db5940767b400450d735d9501575 | |
parent | 59feca8a49bd5fbe6d6331c518ab24d1addb6cb3 (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.txt | 1 | ||||
-rw-r--r-- | src/arpee.c | 92 |
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); + } + } } |