#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "ip-mtbdd.h"

#define BUFSIZE 32

int main()
{
  FILE *fp;
  MTBDD *bdd=NULL;
  IPaddress from_adr, to_adr, address;
  int netmask;
  int counter=0;
#if 0
  int trigger=0;
#endif

  int from[4], to[4], country;
  fp = fopen("ipblocks.map", "rb");
  while (1)
  {
    from[0]=getc(fp);
    if (from[0]==EOF) break;
    from[1]=getc(fp); 
    if (from[1]==EOF) break;
    from[2]=getc(fp); 
    if (from[2]==EOF) break;
    from[3]=getc(fp);
    if (from[3]==EOF) break;

    to[0]=getc(fp); 
    if (to[0]==EOF) break;
    to[1]=getc(fp); 
    if (to[1]==EOF) break;
    to[2]=getc(fp); 
    if (to[2]==EOF) break;
    to[3]=getc(fp);
    if (to[3]==EOF) break;
    country=getc(fp);
    if (country==EOF) break;

    from_adr =
      (((IPaddress) from[0]) << 24) |
      (((IPaddress) from[1]) << 16) |
      (((IPaddress) from[2]) << 8) |
      ((IPaddress) from[3]);
    to_adr =
      (((IPaddress) to[0]) << 24) |
      (((IPaddress) to[1]) << 16) |
      (((IPaddress) to[2]) << 8) |
      ((IPaddress) to[3]);

#if 0
    if (from_adr == 0xD2F80000U && to_adr == 0xD2FFFFFFU)
    {
      printf("IP block for Japan ISP.\n");
    }
#endif

#if 0
      printf("%d.%d.%d.%d-%d.%d.%d.%d => %d\n",
        from[0], from[1], from[2], from[3],
        to[0], to[1], to[2], to[3], country);
      fflush(stdout);
#endif

    for(address=from_adr; address<=to_adr && address>0; address+= (1<<netmask))
    {
      for(netmask=0; netmask<32; netmask++)
      {
	if (address & ((1U<<netmask)-1)) break;
	if ((address | ((1U<<netmask)-1)) > to_adr) break;
      }
      netmask--;

#if 0
      printf("%lX/%d\n", address, netmask);
      fflush(stdout);
#endif
      bdd = mtbdd_add(bdd, address, 32-netmask, country);
    }

#if 0
    switch (mtbdd_find(bdd, 0xD2FD7165, 32))
    {
    case MTBDD_UNDEFINED_VALUE:
      break;

    case 5:
      trigger=1;
      break;

    default:
      if (!trigger) break;
#endif

    counter++;
    if (counter % 1000 == 0)
    {
      fprintf(stderr, "%d blocks registered, bdd size=%d, blocks=%d\n",
	      counter, mtbdd_size(bdd), mtbdd_malloced_blocks);
      fflush(stderr);
    }
  }
  fclose(fp);

  mtbdd_save("internet.ipmap", bdd);

  return 0;
}
