/*
 * IS-IS Rout(e)ing protocol - isis_pfpacket.c
 *
 * Copyright (C) 2001,2002    Sampo Saaristo
 *                            Tampere University of Technology      
 *                            Institute of Communications Engineering
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public Licenseas published by the Free 
 * Software Foundation; either version 2 of the License, or (at your option) 
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
 * more details.

 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <zebra.h>
#if ISIS_METHOD == ISIS_METHOD_PFPACKET
#include <net/ethernet.h>	/* the L2 protocols */
#include <netpacket/packet.h>

#include "log.h"
#include "stream.h"
#include "if.h"

#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_network.h"

#include "privs.h"

extern struct zebra_privs_t isisd_privs;

/*
 * Table 9 - Architectural constants for use with ISO 8802 subnetworks
 * ISO 10589 - 8.4.8
 */

u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };

static char discard_buff[8192];
static char sock_buff[8192];

/*
 * if level is 0 we are joining p2p multicast
 * FIXME: and the p2p multicast being ???
 */
static int
isis_multicast_join (int fd, int registerto, int if_num)
{
  struct packet_mreq mreq;

  memset (&mreq, 0, sizeof (mreq));
  mreq.mr_ifindex = if_num;
  if (registerto)
    {
      mreq.mr_type = PACKET_MR_MULTICAST;
      mreq.mr_alen = ETH_ALEN;
      if (registerto == 1)
	memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
      else if (registerto == 2)
	memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
      else if (registerto == 3)
	memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
      else
	memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);

    }
  else
    {
      mreq.mr_type = PACKET_MR_ALLMULTI;
    }
#ifdef EXTREME_DEBUG
  zlog_debug ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, "
	      "address = %02x:%02x:%02x:%02x:%02x:%02x",
	      fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
	      mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4],
	      mreq.mr_address[5]);
#endif /* EXTREME_DEBUG */
  if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
		  sizeof (struct packet_mreq)))
    {
      zlog_warn ("isis_multicast_join(): setsockopt(): %s", safe_strerror (errno));
      return ISIS_WARNING;
    }

  return ISIS_OK;
}

static int
open_packet_socket (struct isis_circuit *circuit)
{
  struct sockaddr_ll s_addr;
  int fd, retval = ISIS_OK;

  fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
  if (fd < 0)
    {
      zlog_warn ("open_packet_socket(): socket() failed %s",
		 safe_strerror (errno));
      return ISIS_WARNING;
    }

  /*
   * Bind to the physical interface
   */
  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
  s_addr.sll_family = AF_PACKET;
  s_addr.sll_protocol = htons (ETH_P_ALL);
  s_addr.sll_ifindex = circuit->interface->ifindex;

  if (bind (fd, (struct sockaddr *) (&s_addr),
	    sizeof (struct sockaddr_ll)) < 0)
    {
      zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));
      return ISIS_WARNING;
    }

  circuit->fd = fd;

  if (if_is_broadcast (circuit->interface))
    {
      /*
       * Join to multicast groups
       * according to
       * 8.4.2 - Broadcast subnetwork IIH PDUs
       * FIXME: is there a case only one will fail??
       */
      if (circuit->is_type & IS_LEVEL_1)
        /* joining ALL_L1_ISS */
        retval = isis_multicast_join (circuit->fd, 1,
                                      circuit->interface->ifindex);
      if (circuit->is_type & IS_LEVEL_2)
        /* joining ALL_L2_ISS */
        retval = isis_multicast_join (circuit->fd, 2,
                                      circuit->interface->ifindex);
      /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */
      retval = isis_multicast_join (circuit->fd, 3,
                                    circuit->interface->ifindex);
    }
  else
    {
      retval =
        isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
    }

  return retval;
}

/*
 * Create the socket and set the tx/rx funcs
 */
int
isis_sock_init (struct isis_circuit *circuit)
{
  int retval = ISIS_OK;

  if (isisd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));

  retval = open_packet_socket (circuit);

  if (retval != ISIS_OK)
    {
      zlog_warn ("%s: could not initialize the socket", __func__);
      goto end;
    }

  /* Assign Rx and Tx callbacks are based on real if type */
  if (if_is_broadcast (circuit->interface))
    {
      circuit->tx = isis_send_pdu_bcast;
      circuit->rx = isis_recv_pdu_bcast;
    }
  else if (if_is_pointopoint (circuit->interface))
    {
      circuit->tx = isis_send_pdu_p2p;
      circuit->rx = isis_recv_pdu_p2p;
    }
  else
    {
      zlog_warn ("isis_sock_init(): unknown circuit type");
      retval = ISIS_WARNING;
      goto end;
    }

end:
  if (isisd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));

  return retval;
}

static inline int
llc_check (u_char * llc)
{
  if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3)
    return 0;

  return 1;
}

int
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
{
  int bytesread, addr_len;
  struct sockaddr_ll s_addr;
  u_char llc[LLC_LEN];

  addr_len = sizeof (s_addr);

  memset (&s_addr, 0, sizeof (struct sockaddr_ll));

  bytesread = recvfrom (circuit->fd, (void *) &llc,
			LLC_LEN, MSG_PEEK,
			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);

  if (bytesread < 0)
    {
      zlog_warn ("isis_recv_packet_bcast(): ifname %s, fd %d, bytesread %d, "
                 "recvfrom(): %s",
                 circuit->interface->name, circuit->fd, bytesread,
                 safe_strerror (errno));
      /* get rid of the packet */
      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                            MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                            (socklen_t *) &addr_len);
      return ISIS_WARNING;
    }
  /*
   * Filtering by llc field, discard packets sent by this host (other circuit)
   */
  if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
    {
      /*  Read the packet into discard buff */
      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                            MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                            (socklen_t *) &addr_len);
      if (bytesread < 0)
	zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
      return ISIS_WARNING;
    }

  /* on lan we have to read to the static buff first */
  bytesread = recvfrom (circuit->fd, sock_buff, sizeof (sock_buff), MSG_DONTWAIT,
			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
  if (bytesread < 0)
    {
      zlog_warn ("isis_recv_pdu_bcast(): recvfrom() failed");
      return ISIS_WARNING;
    }

  /* then we lose the LLC */
  stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);

  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);

  return ISIS_OK;
}

int
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
{
  int bytesread, addr_len;
  struct sockaddr_ll s_addr;

  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
  addr_len = sizeof (s_addr);

  /* we can read directly to the stream */
  bytesread = stream_recvfrom (circuit->rcv_stream, circuit->fd,
                               circuit->interface->mtu, 0,
                               (struct sockaddr *) &s_addr, 
                               (socklen_t *) &addr_len);

  if (s_addr.sll_pkttype == PACKET_OUTGOING)
    {
      /*  Read the packet into discard buff */
      bytesread = recvfrom (circuit->fd, discard_buff, sizeof (discard_buff),
                            MSG_DONTWAIT, (struct sockaddr *) &s_addr,
                            (socklen_t *) &addr_len);
      if (bytesread < 0)
	zlog_warn ("isis_recv_pdu_p2p(): recvfrom() failed");
      return ISIS_WARNING;
    }

  /* If we don't have protocol type 0x00FE which is
   * ISO over GRE we exit with pain :)
   */
  if (ntohs (s_addr.sll_protocol) != 0x00FE)
    {
      zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
		 ntohs (s_addr.sll_protocol));
      return ISIS_WARNING;
    }

  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);

  return ISIS_OK;
}

int
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
{
  struct msghdr msg;
  struct iovec iov[2];

  /* we need to do the LLC in here because of P2P circuits, which will
   * not need it
   */
  int written = 1;
  struct sockaddr_ll sa;

  stream_set_getp (circuit->snd_stream, 0);
  memset (&sa, 0, sizeof (struct sockaddr_ll));
  sa.sll_family = AF_PACKET;
  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
  sa.sll_ifindex = circuit->interface->ifindex;
  sa.sll_halen = ETH_ALEN;
  /* RFC5309 section 4.1 recommends ALL_ISS */
  if (circuit->circ_type == CIRCUIT_T_P2P)
    memcpy (&sa.sll_addr, ALL_ISS, ETH_ALEN);
  else if (level == 1)
    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
  else
    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);

  /* on a broadcast circuit */
  /* first we put the LLC in */
  sock_buff[0] = 0xFE;
  sock_buff[1] = 0xFE;
  sock_buff[2] = 0x03;

  memset (&msg, 0, sizeof (msg));
  msg.msg_name = &sa;
  msg.msg_namelen = sizeof (struct sockaddr_ll);
  msg.msg_iov = iov;
  msg.msg_iovlen = 2;
  iov[0].iov_base = sock_buff;
  iov[0].iov_len = LLC_LEN;
  iov[1].iov_base = circuit->snd_stream->data;
  iov[1].iov_len = stream_get_endp (circuit->snd_stream);

  written = sendmsg (circuit->fd, &msg, 0);

  return ISIS_OK;
}

int
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
{
  int written = 1;
  struct sockaddr_ll sa;

  stream_set_getp (circuit->snd_stream, 0);
  memset (&sa, 0, sizeof (struct sockaddr_ll));
  sa.sll_family = AF_PACKET;
  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
  sa.sll_ifindex = circuit->interface->ifindex;
  sa.sll_halen = ETH_ALEN;
  if (level == 1)
    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
  else
    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);


  /* lets try correcting the protocol */
  sa.sll_protocol = htons (0x00FE);
  written = sendto (circuit->fd, circuit->snd_stream->data,
		    stream_get_endp (circuit->snd_stream), 0, 
		    (struct sockaddr *) &sa,
		    sizeof (struct sockaddr_ll));

  return ISIS_OK;
}

#endif /* ISIS_METHOD == ISIS_METHOD_PFPACKET */
