aboutsummaryrefslogtreecommitdiff
path: root/src/arpee.c
blob: 69a8366249a698f0137ae58ec6e4232a2f35c0d6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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>
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_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]);

      // 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);
    }
  }
}