#include <machine/param.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static const char rcsid[] = "@(#)$Id: ipfwdpr.c,v 1.1 2006/05/12 06:44:48 eugen Exp $";

void usage(char *name, char* s)
{
  if(s) fprintf(stderr,"unparsed: %s\n",s);
  fprintf(stderr,"usage: %s [-i] [-q] first1-last1 [first2-last2 [...]]\n", name);
  exit(1);
}

int main(int argc, char* argv[])
{
  int fd, incl = 0, mode = -1, verbose = 1;
  u_short j, i, f, l;
  struct dn_pipe8 p;
  char *title;

  char *name[] = { "ipfwdpr", "ipfwdqr" };
  char *label[] = { "Pipe", "Queue" };

  title = strrchr(argv[0], '/');
  if (title == NULL) title = argv[0];
  else title++;

  if (!strcmp(title, name[0])) mode = 0;
  else if (!strcmp(title, name[1])) mode = 1;
  
  if (mode < 0) {
    fprintf(stderr, "%s must be called as %s or %s only\n",
      title, name[0], name[1]);
    exit(1);
  }
  
  while ((fd=getopt(argc,argv,"iq")) != -1)
  switch (fd) {
  case 'i': incl = 1; break;
  case 'q': verbose = 0; break;
    default : usage(argv[0], NULL);
  }

  argc -= optind;
  argv += optind;
  if(!argc) usage(title, NULL);
  
  memset(&p, 0, sizeof(p));
  fd = -1;
  
  for(j = 0; j < argc; j++) {
    if (sscanf(argv[j],"%hu-%hu", &f, &l) != 2) 
      usage(title, argv[j]);
    if(incl) l++;
     
    if (fd < 0 && ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)) {
      perror("cannot open socket to IP_FIREWALL");
      exit(1);
    }
 
    for (i = f; i < l; i++) {
      if(mode) {
        p.pipe_nr = 0;
        p.fs.fs_nr = i;
      }
      else {
        p.pipe_nr = i;
	p.fs.fs_nr = 0;
      }
      if(!setsockopt(fd, IPPROTO_IP, IP_DUMMYNET_DEL, &p, sizeof(p))
          && verbose)
        printf("%s %hu deleted\n", label[mode], i);
    }
  }
  close(fd);
  return 0;
}