/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ring.c - packet ring buffer functions
 */

#include <arpa/inet.h>
#include <errno.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>

#include "config.h"
#include "logging.h"
#include "ring.h"
#include "translate.h"

int ring_create(struct tun_data *tunnel) {
  // Will eventually be bound to htons(ETH_P_IPV6) protocol,
  // but only after appropriate bpf filter is attached.
  int packetsock = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  if (packetsock < 0) {
    logmsg(ANDROID_LOG_FATAL, "packet socket failed: %s", strerror(errno));
    return -1;
  }

  int ver = TPACKET_V2;
  if (setsockopt(packetsock, SOL_PACKET, PACKET_VERSION, (void *)&ver, sizeof(ver))) {
    logmsg(ANDROID_LOG_FATAL, "setsockopt(PACKET_VERSION, %d) failed: %s", ver, strerror(errno));
    return -1;
  }

  int on = 1;
  if (setsockopt(packetsock, SOL_PACKET, PACKET_LOSS, (void *)&on, sizeof(on))) {
    logmsg(ANDROID_LOG_WARN, "PACKET_LOSS failed: %s", strerror(errno));
  }

  struct packet_ring *ring = &tunnel->ring;
  ring->numblocks          = TP_NUM_BLOCKS;

  int total_frames = TP_FRAMES * ring->numblocks;

  struct tpacket_req req = {
    .tp_frame_size = TP_FRAME_SIZE,    // Frame size.
    .tp_block_size = TP_BLOCK_SIZE,    // Frames per block.
    .tp_block_nr   = ring->numblocks,  // Number of blocks.
    .tp_frame_nr   = total_frames,     // Total frames.
  };

  if (setsockopt(packetsock, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)) < 0) {
    logmsg(ANDROID_LOG_FATAL, "PACKET_RX_RING failed: %s", strerror(errno));
    return -1;
  }

  size_t buflen = TP_BLOCK_SIZE * ring->numblocks;
  ring->base    = mmap(NULL, buflen, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED | MAP_POPULATE,
                    packetsock, 0);
  if (ring->base == MAP_FAILED) {
    logmsg(ANDROID_LOG_FATAL, "mmap %lu failed: %s", buflen, strerror(errno));
    return -1;
  }

  ring->block    = 0;
  ring->slot     = 0;
  ring->numslots = TP_BLOCK_SIZE / TP_FRAME_SIZE;
  ring->next     = (struct tpacket2_hdr *)ring->base;

  logmsg(ANDROID_LOG_INFO, "Using ring buffer with %d frames (%d bytes) at %p", total_frames,
         buflen, ring->base);

  return packetsock;
}

/* function: ring_advance
 * advances to the next position in the packet ring
 * ring - packet ring buffer
 */
static struct tpacket2_hdr *ring_advance(struct packet_ring *ring) {
  uint8_t *next = (uint8_t *)ring->next;

  ring->slot++;
  next += TP_FRAME_SIZE;

  if (ring->slot == ring->numslots) {
    ring->slot = 0;
    ring->block++;

    if (ring->block < ring->numblocks) {
      next += TP_FRAME_GAP;
    } else {
      ring->block = 0;
      next        = (uint8_t *)ring->base;
    }
  }

  ring->next = (struct tpacket2_hdr *)next;
  return ring->next;
}

/* function: ring_read
 * reads a packet from the ring buffer and translates it
 * read_fd  - file descriptor to read original packet from
 * write_fd - file descriptor to write translated packet to
 * to_ipv6  - whether the packet is to be translated to ipv6 or ipv4
 */
void ring_read(struct packet_ring *ring, int write_fd, int to_ipv6) {
  struct tpacket2_hdr *tp = ring->next;
  if (tp->tp_status & TP_STATUS_USER) {
    uint8_t *packet = ((uint8_t *)tp) + tp->tp_net;
    translate_packet(write_fd, to_ipv6, packet, tp->tp_len);
    tp->tp_status = TP_STATUS_KERNEL;
    tp            = ring_advance(ring);
  }
}
