/*
 * 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 <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <linux/if.h>
#include <linux/if_packet.h>

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

int ring_create(struct tun_data *tunnel) {
  int packetsock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
  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));
	close(packetsock);
    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));
	close(packetsock);
    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));
	close(packetsock);
    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);
  }
}
