/*
 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Send Management Frame
 *
 * Userspace helper which sends management frames via nl80211.  This
 * can be used to inject frames used for regulatory testing, for example
 * spectrum management frames.
 */

#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <linux/if_ether.h>
#include <net/if.h>
#include <pcap.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>

#include "ieee80211_header.h"

/*
 * Minimal ieee80211 radiotap header.  The bitmap must remain zero
 * for this header to be valid.
 */
struct radiotap_header {
  __u16 version;
  __u16 header_length;
  __u32 bitmap;
} __attribute__((packed));

struct radiotap_packet {
  struct radiotap_header radiotap_header;
  struct ieee80211_mgmt ieee80211_mgmt_frame;
  /* Depending on frame type, some IEs may fit above; the rest go below. */
  unsigned char overflow[1024];
} __attribute__((packed));

struct radiotap_packet_buf {
  struct radiotap_packet packet;
  size_t len;  /* Length of populated data */
};

#define PACKET_TIMEOUT_MS 1000
#define SSID_LENGTH 32

static const char * type_beacon = "beacon";
static const char * type_channel_switch = "channel_switch";
static const char * type_probe_response = "probe_response";
static const char * usage =
    "Usage:\n"
    "  send_management_frame -i interface -t channel_switch\n"
    "                             [-a dest-addr] [-b num-bss] [-c channel]\n"
    "                             [-d delay] [-n pkt-count] [-f footer-file]\n"
    "\n"
    "  send_management_frame -i interface -t <beacon|probe_response>\n"
    "                             [-a dest-addr] [-b num-bss] [-c channel]\n"
    "                             [-d delay] [-n pkt-count] [-s ssid-prefix]\n"
    "                             [-f footer-file]\n"
    "\n"
    "Common options:\n"
    "       interface:    interface to inject frames.\n"
    "       dest-addr:    destination address (DA) for the frame.\n"
    "                     default to broadcast.\n"
    "       num-bss:      number of synthetic bss for sending frames.\n"
    "                     default to 0 (use interface MAC).\n"
    "       channel:      channel to inject frames, default to 1.\n"
    "       delay:        milliseconds delay in between frames,\n"
    "                     default to 0 (no delay).\n"
    "       pkt-count:    total number of frames to send, 0 means infinite\n"
    "                     default to 1.\n"
    "       footer-file:  non-empty file containing data to append to frames.\n"
    "\n"
    "beacon, probe_response options:\n"
    "       ssid-prefix:  prefix for the SSIDs, default to FakeSSID\n";

enum message_type {
  /* No external meaning, so sort alphabetically */
  BEACON,
  CHANNEL_SWITCH,
  PROBE_RESPONSE,
};

uint8_t message_type_to_80211_frame_subtype[] = {
  /* Ordered to match |enum message_type| */
  WLAN_FC_STYPE_BEACON,
  WLAN_FC_STYPE_ACTION,
  WLAN_FC_STYPE_PROBE_RESP,
};

int get_interface_info(char *interface,
                       int *interface_index,
                       unsigned char *mac_address) {
  struct ifreq ifr;
  int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  if (sock < 0) {
    return -1;
  }

  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
  if (ioctl(sock, SIOCGIFINDEX, &ifr) != 0) {
    fprintf(stderr, "Can't get interface index for %s.\n", interface);
    return -1;
  }
  *interface_index = ifr.ifr_ifindex;

  if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
    fprintf(stderr, "Can't get hardware address for %s.\n", interface);
    return -1;
  }
  memcpy(mac_address, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
  printf("Found interface %s at index %d, "
         "address %02x:%02x:%02x:%02x:%02x:%02x.\n",
         interface, *interface_index,
         mac_address[0], mac_address[1], mac_address[2],
         mac_address[3], mac_address[4], mac_address[5]);
  return 0;
}

/*
 * SSID prefix should be under 24 characters.
 */
int create_ssid(char *ssid_prefix, int bss_number, char **ssid_out) {
  *ssid_out = calloc(1, SSID_LENGTH + 1);
  if (!ssid_prefix)
    sprintf(*ssid_out, "FakeSSID%08x", bss_number);
  else {
    if (strlen(ssid_prefix) > 24) {
      fprintf(stderr, "SSID prefix too long, must be less than 24 "
              "characters.\n");
      return -EINVAL;
    }
    sprintf(*ssid_out, "%s%08X", ssid_prefix, bss_number);
  }
  return 0;
}

struct radiotap_packet_buf* packet_buf_alloc(uint16_t ieee80211_frame_subtype,
                                             const unsigned char* bssid,
                                             const unsigned char* source,
                                             const unsigned char* destination) {
  struct radiotap_packet_buf *packet_buf;
  struct ieee80211_mgmt *mgm_packet_ptr;
  packet_buf = calloc(1, sizeof(struct radiotap_packet_buf));
  packet_buf->len = 0;

  struct radiotap_packet* packet = &packet_buf->packet;
  packet->radiotap_header.version = 0;
  packet->radiotap_header.header_length = sizeof(packet->radiotap_header);
  packet->radiotap_header.bitmap = 0;
  packet_buf->len += sizeof(packet->radiotap_header);

  mgm_packet_ptr = &packet->ieee80211_mgmt_frame;
  mgm_packet_ptr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                               ieee80211_frame_subtype);
  memcpy(&mgm_packet_ptr->da, destination, sizeof(mgm_packet_ptr->da));
  memcpy(&mgm_packet_ptr->sa, source, sizeof(mgm_packet_ptr->sa));
  memcpy(&mgm_packet_ptr->bssid, bssid, sizeof(mgm_packet_ptr->bssid));
  packet_buf->len += (unsigned char *) &(mgm_packet_ptr->u) -
      (unsigned char *) mgm_packet_ptr;

  return packet_buf;
}

bool packet_buf_can_accept_bytes(size_t length,
                                 struct radiotap_packet_buf *packet_buf) {
  if (length > sizeof(packet_buf->packet) - packet_buf->len)
    return false;

  unsigned char *dest = (unsigned char *) packet_buf + packet_buf->len;
  struct ieee80211_mgmt *mgm_packet_ptr =
      &packet_buf->packet.ieee80211_mgmt_frame;

  switch (WLAN_FC_GET_STYPE(mgm_packet_ptr->frame_control)) {
    case WLAN_FC_STYPE_BEACON:
      return dest >= mgm_packet_ptr->u.beacon.variable;
    case WLAN_FC_STYPE_ACTION:
      if (mgm_packet_ptr->u.action.category == WLAN_ACTION_SPECTRUM_MGMT)
        return dest > &mgm_packet_ptr->u.action.u.chan_switch.switch_count;
      else
        assert(false);
      break;
    case WLAN_FC_STYPE_PROBE_RESP:
      return dest >= mgm_packet_ptr->u.probe_resp.variable;
      break;
    default:
      assert(false);
      break;
  }
}

int packet_buf_add_info_element(unsigned char element_id,
                                unsigned char element_data_length,
                                const unsigned char *element_data,
                                struct radiotap_packet_buf *packet_buf) {
  size_t info_element_len =
      sizeof(element_id) + sizeof(element_data_length) + element_data_length;
  if (!packet_buf_can_accept_bytes(info_element_len, packet_buf))
    return -1;

  unsigned char *dest = (unsigned char *) packet_buf + packet_buf->len;
  *dest++ = element_id;
  *dest++ = element_data_length;
  memcpy(dest, element_data, element_data_length);
  packet_buf->len += info_element_len;
  return 0;
}

int packet_buf_add_raw_data(size_t data_length,
                            const unsigned char *data,
                            struct radiotap_packet_buf *packet_buf) {
  if (!packet_buf_can_accept_bytes(data_length, packet_buf))
      return -1;

  unsigned char *dest = (unsigned char *) packet_buf + packet_buf->len;
  memcpy(dest, data, data_length);
  packet_buf->len += data_length;
  return 0;
}

void packet_buf_add_fixed_params(int frame_num,
                                 struct radiotap_packet_buf *packet_buf) {
  struct ieee80211_mgmt *mgm_packet_ptr =
      &packet_buf->packet.ieee80211_mgmt_frame;

  uint16_t stype = WLAN_FC_GET_STYPE(mgm_packet_ptr->frame_control);
  if (stype == WLAN_FC_STYPE_PROBE_RESP) {
    mgm_packet_ptr->u.probe_resp.timestamp[0] = frame_num;
    mgm_packet_ptr->u.probe_resp.timestamp[1] = frame_num >> 8;
    mgm_packet_ptr->u.probe_resp.timestamp[2] = frame_num >> 16;
    mgm_packet_ptr->u.probe_resp.timestamp[3] = frame_num >> 24;
    mgm_packet_ptr->u.probe_resp.beacon_int = 0x64;  // 0.1024 seconds.  A lie.
    mgm_packet_ptr->u.probe_resp.capab_info = 0x1;  // We are an AP.
    packet_buf->len += sizeof(mgm_packet_ptr->u.probe_resp);
  } else if (stype == WLAN_FC_STYPE_BEACON) {
    mgm_packet_ptr->u.beacon.timestamp[0] = frame_num;
    mgm_packet_ptr->u.beacon.timestamp[1] = frame_num >> 8;
    mgm_packet_ptr->u.beacon.timestamp[2] = frame_num >> 16;
    mgm_packet_ptr->u.beacon.timestamp[3] = frame_num >> 24;
    mgm_packet_ptr->u.beacon.beacon_int = 0x64;  // 0.1024 seconds.  A lie.
    mgm_packet_ptr->u.beacon.capab_info = 0x1;  // We are an AP.
    packet_buf->len += sizeof(mgm_packet_ptr->u.beacon);
  }
}


int packet_buf_add_bss_info(char *ssid_prefix,
                            int bss_number,
                            uint8_t channel,
                            struct radiotap_packet_buf *packet_buf) {
  char *ssid;
  if (create_ssid(ssid_prefix, bss_number, &ssid) != 0) {
    goto err_exit;
  }

  unsigned char supported_rates[] = { 0x82, 0x84, 0x8b, 0x96,
                                      0x0c, 0x12, 0x18, 0x24 };

  if (packet_buf_add_info_element(WLAN_EID_SSID, strlen(ssid),
                                  (unsigned char *) ssid, packet_buf) != 0 ||
      packet_buf_add_info_element(WLAN_EID_SUPP_RATES, sizeof(supported_rates),
                                  supported_rates, packet_buf) != 0 ||
      packet_buf_add_info_element(WLAN_EID_DS_PARAMS, sizeof(channel),
                                  &channel, packet_buf) != 0 ) {
    goto err_exit;
  }
  free(ssid);
  return 0;

err_exit:
  free(ssid);
  return -1;
}

int fill_chanswitch_message_frame(uint8_t channel,
                                  struct radiotap_packet_buf *packet_buf) {
  struct radiotap_packet *packet = &packet_buf->packet;
  struct ieee80211_mgmt *chanswitch_packet_ptr = &packet->ieee80211_mgmt_frame;

  chanswitch_packet_ptr->u.action.category = WLAN_ACTION_SPECTRUM_MGMT;
  packet_buf->len += sizeof(chanswitch_packet_ptr->u.action.category);

  chanswitch_packet_ptr->u.action.u.chan_switch.action_code =
      WLAN_ACTION_SPCT_CHL_SWITCH;
  chanswitch_packet_ptr->u.action.u.chan_switch.element_id =
      WLAN_EID_CHANNEL_SWITCH;
  chanswitch_packet_ptr->u.action.u.chan_switch.length =
      WLAN_EID_LENGTH_CHANNEL_SWITCH;
  chanswitch_packet_ptr->u.action.u.chan_switch.switch_mode =
      WLAN_CHANNEL_SWITCH_MODE_XMIT_FORBIDDEN;
  chanswitch_packet_ptr->u.action.u.chan_switch.new_chan = channel;
  chanswitch_packet_ptr->u.action.u.chan_switch.switch_count = 5;
  packet_buf->len += sizeof(chanswitch_packet_ptr->u.action.u.chan_switch);

  return 0;
}

int fill_beacon_proberesp_message_frame(char *ssid_prefix,
                                        uint8_t channel,
                                        int bss_number,
                                        int frame_num,
                                        struct radiotap_packet_buf *packet_buf)
{
  packet_buf_add_fixed_params(frame_num, packet_buf);
  if (packet_buf_add_bss_info(ssid_prefix, bss_number, channel, packet_buf) !=
      0) {
    fprintf(stderr, "BSS info didn't fit in output buffer!?\n");
    return -EINVAL;
  }

  return 0;
}

struct radiotap_packet_buf *get_message_frame(
    enum message_type message_type,
    const unsigned char *interface_address,
    const unsigned char *destination_address,
    char *ssid_prefix,
    uint8_t channel,
    int bss_count,
    int frame_num,
    unsigned char *footer_data,
    size_t footer_len) {
  int bss_number = 0;
  unsigned char bss_address[ETH_ALEN];
  memcpy(bss_address, interface_address, sizeof(bss_address));
  if (bss_count) {
    bss_number = frame_num % bss_count;
    bss_address[0] = 0x2;  // Make this an administratively scoped address.
    bss_address[5] += bss_number;  // Make the BSSIDs unique.
    bss_address[4] += bss_number / 256;
  }

  struct radiotap_packet_buf *packet_buf =
      packet_buf_alloc(message_type_to_80211_frame_subtype[message_type],
                       bss_address, interface_address, destination_address);

  /* Generate frame based on the message type */
  int ret;
  switch (message_type) {
    case BEACON:
    case PROBE_RESPONSE:
      ret = fill_beacon_proberesp_message_frame(ssid_prefix, channel,
                                                bss_number, frame_num,
                                                packet_buf);
      break;
    case CHANNEL_SWITCH:
      ret = fill_chanswitch_message_frame(channel, packet_buf);
      break;
  }

  if (ret != 0) {
    fprintf(stderr, "Message frame generation failed with %d.\n", ret);
    ret = -EINVAL;
    goto err_exit;
  }

  if (footer_data) {
    ret = packet_buf_add_raw_data(footer_len, footer_data, packet_buf);
    if (ret != 0) {
      fprintf(stderr, "Footer append failed with %d.\n", ret);
      goto err_exit;
    }
  }

  return packet_buf;

err_exit:
  free(packet_buf);
  return NULL;
}

static int g_do_exit = 0;

void set_do_exit(int signum) {
  g_do_exit = 1;
}

int get_footer_bytes(char *footer_file, unsigned char **footer) {
  struct stat st;
  if (stat(footer_file, &st) != 0) {
    fprintf(stderr, "Error getting footer file size.\n");
    goto cleanup_footer;
  }

  if (!st.st_size) {
    fprintf(stderr, "Footer file must be non-empty.\n");
    goto cleanup_footer;
  }

  *footer = (unsigned char *) malloc(st.st_size);

  int fd = open(footer_file, O_RDONLY);
  if (fd == -1) {
    fprintf(stderr, "Error opening footer file.\n");
    goto cleanup_mem;
  }
  if (read(fd, *footer, st.st_size) != st.st_size) {
    fprintf(stderr, "Error reading footer file.\n");
    goto cleanup_fd;
  }
  close(fd);
  return st.st_size;

cleanup_fd:
  close(fd);
cleanup_mem:
  free(*footer);
cleanup_footer:
  *footer = NULL;
  return -1;
}

int main(int argc, char **argv) {
  char *interface = NULL;
  int interface_index;
  unsigned char mac_address[ETH_ALEN];
  char *message_name = NULL;
  unsigned char *frame = NULL;
  const int promiscuous = 1;
  pcap_t *pcap = NULL;
  char errbuf[PCAP_ERRBUF_SIZE];
  int inject_return;
  char buf[2048];
  int exit_value = 1;
  int pkt_count = 1;
  unsigned char channel = 1;
  int ms_delay = 0;
  int num_bss = 0;
  char *ssid_prefix = NULL;
  char *destination_address_string = NULL;
  char *footer_file = NULL;
  unsigned char *footer_data = NULL;
  int c;

  while ((c = getopt (argc, argv, "hb:c:d:i:n:t:s:a:f:")) != -1) {
    switch (c) {
      case 'b':
        num_bss = atoi(optarg);
        break;
      case 'c':
        channel = (unsigned char) atoi(optarg);
        break;
      case 'd':
        ms_delay = atoi(optarg);
        break;
      case 'i':
        interface = optarg;
        break;
      case 'n':
        pkt_count = atoi(optarg);
        break;
      case 't':
        message_name = optarg;
        break;
      case 's':
        ssid_prefix = optarg;
        break;
      case 'a':
        destination_address_string = optarg;
        break;
      case 'f':
        footer_file = optarg;
        break;
      case 'h':
      default:
        fprintf(stderr, "%s", usage);
        return 1;
    }
  }

  /* Validate arguments; ordering follows usage message */
  if (interface == NULL || message_name == NULL) {
    fprintf(stderr, "%s", usage);
    goto cleanup;
  }
  if (ms_delay < 0) {
    fprintf(stderr, "Invalid value for delay %d, must be >= 0.\n",
            ms_delay);
    goto cleanup;
  }

  enum message_type message_type;
  if (strcmp(message_name, type_beacon) == 0) {
    message_type = BEACON;
  } else if (strcmp(message_name, type_channel_switch) == 0) {
    message_type = CHANNEL_SWITCH;
  } else if (strcmp(message_name, type_probe_response) == 0) {
    message_type = PROBE_RESPONSE;
  } else {
    fprintf(stderr, "Invalid message type [%s].\n", message_name);
    goto cleanup;
  }

  if (ssid_prefix && message_type == CHANNEL_SWITCH) {
    fprintf(stderr, "-s is not valid for message type [%s].\n", message_name);
    goto cleanup;
  }

  unsigned char custom_dest[ETH_ALEN];
  const unsigned char broadcast_address[] = { 0xff, 0xff, 0xff,
                                              0xff, 0xff, 0xff };
  const unsigned char *destination_address_bytes;
  if (destination_address_string) {
    if (sscanf(destination_address_string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
               &custom_dest[0], &custom_dest[1], &custom_dest[2],
               &custom_dest[3], &custom_dest[4], &custom_dest[5]) !=
        ETH_ALEN) {
      fprintf(stderr, "Invalid destination address [%s].\n",
              destination_address_string);
      goto cleanup;
    }
    destination_address_bytes = custom_dest;
  } else {
    destination_address_bytes = broadcast_address;
  }

  size_t footer_len = 0;
  if (footer_file) {
    footer_len = get_footer_bytes(footer_file, &footer_data);
  }

  /* Get interface information */
  if (get_interface_info(interface, &interface_index, mac_address) != 0) {
    fprintf(stderr, "Can't get information on AP interface %s.\n", interface);
    goto cleanup;
  }

  pcap = pcap_open_live(interface,
                        sizeof(buf),
                        promiscuous,
                        PACKET_TIMEOUT_MS,
                        errbuf);
  if (pcap == NULL) {
    fprintf(stderr, "Could not open capture handle.\n");
    goto cleanup;
  }

  if (pcap_datalink(pcap) != DLT_IEEE802_11_RADIO) {
    fprintf(stderr, "Interface %s does not use RadioTap.\n", interface);
    goto cleanup;
  }

  struct sigaction exit_action;
  exit_action.sa_handler = set_do_exit;
  exit_action.sa_flags = 0;
  sigfillset(&exit_action.sa_mask);
  sigaction(SIGTERM, &exit_action, NULL);
  sigaction(SIGINT, &exit_action, NULL);

  /*
   * Generate and inject number of frames specified. Continuous sending
   * if number of frame specified is 0.
   */
  int i = 0;
  while ( (i < pkt_count) || (pkt_count == 0) ) {
    struct radiotap_packet_buf *packet_buf =
        get_message_frame(message_type, mac_address, destination_address_bytes,
                          ssid_prefix, channel, num_bss, i, footer_data,
                          footer_len);
    if (!packet_buf) {
      fprintf(stderr, "Can't generate a frame of type %s.\n", message_name);
      goto cleanup;
    }

    unsigned char *frame = (unsigned char *) &packet_buf->packet;
    size_t frame_length = packet_buf->len;
    size_t j = 0;
    if (i == 0) {
      printf("Frame (length %zu): ", frame_length);
      for (j = 0; j < frame_length; j++) {
        printf("%02x ", frame[j]);
      }
      printf("\n");
    }

    if (ms_delay > 0)
      usleep(ms_delay * 1000);

    inject_return = pcap_inject(pcap, frame, frame_length);
    if (i == 1) printf("Inject returned %d.\n", inject_return);
    i++;

    free(frame);
    frame=NULL;

    if (g_do_exit)
      break;
  }
  exit_value = 0;
  printf("Transmitted %d frames.\n", i);

cleanup:
  if (pcap) {
    pcap_close(pcap);
  }
  free(footer_data);
  free(frame);

  return exit_value;
}
