/*  -*- Mode: C;  -*- */

/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe is free software; you can redistribute it and/or modify            *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
*   Nprobe 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 Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#ifdef __alpha__
#include <sys/mbuf.h>
#include <machine/endian.h>
#endif

#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#undef __STDC__
#include <netinet/ip.h>
#include <netinet/udp.h>
#ifdef __alpha__
#include <netinet/ip_var.h>
#endif
#ifdef __linux__
#define __FAVOR_BSD
#endif
#include <netinet/tcp.h>
#ifdef __alpha__
#include <net/if_llc.h>
#include <netinet/if_ether.h>
#endif
#include <netinet/if_fddi.h>

#ifdef __linux__
//#include <linux/if_ether.h>
#include <net/ethernet.h>
#include <netinet/ip_icmp.h>

#include "linux_tweaks.h"

#endif

#ifdef PRINT_OUT
#include "print_util.h"
#include "cprintf.h"
#endif

#include "basic_defs.h"

#ifdef FLOW_FILT

inline int 
is_net(unsigned int addr, char *netspec)
{
  char *ap = netspec;
  unsigned int net = 0x0, mask = 0x0;
  unsigned char *net8 = (unsigned char *)&net, *mask8 = (unsigned char *)&mask;
  int fi = 0;

  while (fi < 3)
    {
      if (*ap == '.')
        {
          ap++;
          continue;
        }
      else if (*ap == 'x')
        {
          mask8[fi++] = 0x00;
          ap++;
        }
      else 
        {
          mask8[fi] = 0xff;
          net8[fi++] = strtoul(ap, &ap, 0) & 0xff;
        }
    }
  
  if (fi != 3)
    {
      printf("bad net filter\n");
      exit (1);
    }
  else
    {
      mask8[3] = 0x00;
    }

  //printf("addr %x net %x mask %x\n", addr, net, mask);

  
  return ((addr & mask) == net);
}

inline int is_local_net(unsigned int addr)
{
  return (
	  /* local Class Bs */
	  is_net(addr, "128.232.x.x") /* cl.cam.ac.uk */
	  || is_net(addr, "129.169.x.x") /* eng.cam.uk */
	  || is_net(addr, "131.111.x.x") /* cam.ac.uk */
	  || is_net(addr, "158.124.x.x") /* orl2 */
	  || is_net(addr, "193.60.x.x")	/* c01camacuk a class B or several class Cs ? */
	  /* local Class Cs */
	  || is_net(addr, "192.5.239.x") /* orl */
	  || is_net(addr, "192.18.195.x") /* mrc apu */
	  || is_net(addr, "192.153.213")	/* gw */
	  || is_net(addr, "192.31.62.x") /* sri - out of use? */
	  || is_net(addr, "192.84.5.x") /* mrc bsu */
	  || is_net(addr, "193.60.80.x") /* C00 cam.ac.uk - spare? */
	  );
}

unsigned int 
_inet_addr(char *cp)
{
  struct in_addr addr;

  if (inet_aton(cp, &addr) == 0)
    {
      fprintf(stderr, "local_inet_addr: invalid address %s\n", cp);
      exit (1);
    }

  return *((unsigned int *)&addr);
}

inline int 
ffilt(struct ip *ipp)
{

  unsigned int srcaddr = *((unsigned int *)&ipp->ip_src);
  unsigned int dstaddr = *((unsigned int *)&ipp->ip_dst);

  if (is_net(srcaddr, "212.58.x.x")  /* bbc news */
      || is_net(dstaddr, "212.58.x.x")
      || is_net(srcaddr, "195.153.x.x") /* Guardian */
      || is_net(dstaddr, "195.153.x.x"))

    return 0;

  return 1;

}

#endif /* ifdef FLOW_FILT */ 
