// (c) Copyright 2004 Stichting Wireless Leiden, all
//    rights reserved. More information can be found on
//    http://wwww.wirelessleiden.nl and the license is at:
//    http://wleiden.webweaving.org:8080/svn/node-config/LICENSE
//
// Nodechck - Programma om wleiden.conf files te lezen
//            en te vergelijken met actuele informatie uit de nodes
//
// Rev.0.5 23/11/2004 RO
// Fout verbeterd: 172.1.1.223 en 172.1.1.22 werden gelijk geacht, zodat lijsten niet klopten
// Uitvoer uit nodes aan alle lijsten gekoppeld
// Lijst toegevoegd: outputs1.csv, uitgaande van nodeuitvoer, waaraan genesis data toegevoegd is.
//
// Rev.0.4 22/11/2004 RO
// compatibility:
// io.h verwijderd
// memicmp() voor unix toegevoegd
// getest op unix
//
// Rev.0.3 22/11/2004 RO
// niet-ANSI functies eruit gegooid, voorbereid met #ifdef voor linux padnamen (niet getest)
// input ./nnames: tekstfile, lijst van nodenamen
// input ./confs: tekstfile, actuele output van nodes, gegenereerd door extern script
// input ./location: tekstfile: pad naar nodemappen in bv. svn
// code en structures toegevoegd om node output in te lezen
// in configip1 kolommen toegevoegd met actuele node-info. o.a. macadres
// ip-adres in interfaceconfig van wleiden.conf is bepalend voor koppeling met actuele data
//
// Rev.0.2 14/11/2004 RO
// $master_ip bij interface ingevuld
// komma's vervangen door ; in plaats van weglaten
// structures IPADDRESS en IPRANGE toegevoegd voor eenvoudiger vergelijken
// rekening houden met ontbrekende sprintf bij sommige $config-regels
// uitvoer naar configs1.csv, configs2.csv(gesorteerd op ip)
// configip1.csv(ipstart en ipend toegevoegd,overbodige kolommen verwijderd, comment in .csv toegevoegd
//
// Rev.0.1 12/11/2004 RO
// dimensies van desc, point_to_point, ospfneighbors verhoogd
// gegevens van hoofd interface in aliassen overgenomen
// komma's uit velden geskipt ivm csv-lijst (3e regel node-som heeft ',' in desc-veld)
//
// Rev.0.0 10/11/2004 initial revision Rudolf Oosterhuis

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#define BOOL unsigned int
#define FALSE (0==1)
#define TRUE (0==0)

typedef struct
{
   unsigned char ip0;
   unsigned char ip1;
   unsigned char ip2;
   unsigned char ip3;
} IPADDRESS;

typedef struct
{
   IPADDRESS      ip;
   unsigned char mask;
} IPRANGE;

typedef struct
{
   char volgnr[4];
   char name[20];
   char present[2];
} CNODEOUTPUT;

typedef struct
{
   char volgnr[4];
   char nodenr[4];
   char configname[10];
   char ether[20];
   char status[20];
   char ssid[40];
   char stationname[40];
   char channel[4];
} CARDOUTPUT;

typedef struct
{
   char cardnr[4];
   char ip[18];
   char netmask[12];
   char broadcast[18];
} IFOUTPUT;

typedef struct
{
   char volgnr[4];
   char name[20];
   char location[100]; 
   char master_ip[20];
   char gw_open[10];
   char nodetype[10];
   char nodename[30];
   char status[10];
   char OS[20];
   char labelpos[30];
   char X[10];
   char Y[10];
   char N[10];
   char E[10];
   char ESSID[34];
} CNODE;

typedef struct
{
   char volgnr[4];
   char nodenr[4];
   char configname[10];
   char sprintfname[10];
   char type[10]; 
   char ip[20];
   char desc[46];
   char sdesc[20];
   char speed[20];

   char pointtopoint[35];

   char ospfbroadcast[6];
   char ospfneighbors[35];

   char mode[10];
   char essid[34];
   char channel[3];

   char polar[6];
   char antenna[10];
   char gain[10];
   char direction[6];
   char beamwidth[6];
   char cable[3];
   char heigth[4];

   char dhcp[8];
   IPRANGE ipr;
   IPADDRESS ipstart;
   IPADDRESS ipend;
   IPADDRESS ptp1;
   IPADDRESS ptp2;
   IPADDRESS on1;
   IPADDRESS on2;
} CARD;


void LeesNode(void);
void LeesNodeOutput(void);
void BehandelRegel(void);
void BehandelOutputRegel(void);
void FormatRegel(void);
void MaakCSV(int code);
void MaakCSV2(int code);
void MaakCSV3(int code);
void MaakIpOverzicht(void);
void AddKomma(void);
void AddTekst(void);
void VulIpAdressen(void);
void SwapCards(int i);
int CompareIp(IPADDRESS *ad1,IPADDRESS *ad2);

char nnamesbuf[2000];
char location[64];
char fn[64];
char buf[50];
#define BUFLEN 1000
char Tekstbuf[BUFLEN];
char Regelbuf[BUFLEN];
char Formatbuf[BUFLEN];
FILE *hConf;
size_t numread,toread;
CNODEOUTPUT CNodeOutput[100];
CNODE CNode[100];
IFOUTPUT IfOutput[600];
CARDOUTPUT CardOutput[400];
CARD Card[600];
int NodeTeller;
int CardTeller;
int NodeOutputTeller;
int CardOutputTeller;
int IfOutputTeller;
BOOL bNodeBezig;
BOOL bCardBezig;

#ifndef WIN32
#define memicmp strncasecmp
#endif

main()
{
   FILE *hFile;
   NodeTeller=0;
   CardTeller=0;

   if (hFile=fopen("location","r"))
   {
      fread(location,sizeof(char),64,hFile);
      fclose(hFile);
      {
         char *pos=&location[strlen(location)-1];
         while (*pos=='\n'||*pos=='\r'||*pos=='\t'||*pos==' ')
	 {
	    *pos='\0';
	    pos--;
	 }
      }
      if (hFile=fopen("nnames","r"))
      {
         char *pos;
         numread=fread(nnamesbuf,sizeof(char),2000,hFile);
         fclose(hFile);
         pos=strtok(nnamesbuf,"\n\r");
         while(pos)
         {
            memset((char*)&(CNode[NodeTeller]),'\0',sizeof(CNode[NodeTeller]));
            strcpy(CNode[NodeTeller++].name,pos);
            pos=strtok(NULL,"\n\r");
         }
         NodeTeller=0;
         while (*(CNode[NodeTeller].name))
         {
#ifdef WIN32
            sprintf(fn,"%s%s\\wleiden.conf",location,CNode[NodeTeller].name);
#else
            sprintf(fn,"%s%s/wleiden.conf",location,CNode[NodeTeller].name);
#endif
            printf(fn);
            printf("\n");

            if (hConf=fopen(fn,"r"))
            {
               LeesNode();
               fclose(hConf);
            }
            NodeTeller++;
         }
      }
   }
   sprintf(buf,"\naantal nodes: %i\n\r",NodeTeller);
   printf(buf);

   if (hConf=fopen("confs","r"))
   {
      LeesNodeOutput();
      fclose(hConf);
   }
   MaakCSV(1);
   MaakIpOverzicht();
   MaakCSV3(1);

   return 0;
}

void LeesNodeOutput(void)
{
   char *pos;
   int regels=0;
   int rest;
   memset((char*)&(CNodeOutput),'\0',sizeof(CNodeOutput));
   NodeOutputTeller=-1;
   CardOutputTeller=-1;
   IfOutputTeller=-1;

   toread=BUFLEN;
   numread=fread(Tekstbuf,sizeof(char),toread,hConf);

   pos=strtok(Tekstbuf,"\n\r" );
   while (pos)
   {
      unsigned j;
      strcpy(Regelbuf,Tekstbuf);
      rest=strlen(Regelbuf);
      for (j=0;j<numread-rest-1;j++)
      {
         Tekstbuf[j]=Tekstbuf[j+rest+1]; //tekst naar links schuiven
      }
      if (numread==BUFLEN)
      {
         numread-=(rest+1);
         numread+=fread(Tekstbuf+numread,sizeof(char),rest+1,hConf);
         if (numread<BUFLEN) Tekstbuf[numread]='\0';
      }
      else
      {
         numread-=(rest+1);
         Tekstbuf[numread]='\0';
      }

      BehandelOutputRegel();
      strcat(Regelbuf,"\n");
      printf("%s",Regelbuf);
      regels++;
      pos=strtok(Tekstbuf,"\n\r" );
   }
   sprintf(buf,"\naantal regels: %i\n\r",regels);
   printf(buf);
}

void BehandelOutputRegel(void)
{
   char *pos=Regelbuf;
   CNODEOUTPUT *pCNO;
   CARDOUTPUT *pCDO;
   IFOUTPUT *pIO;
   while (*pos=='\n'||*pos=='\r') pos++;
   if (!memicmp(pos,"CONFIG FOR ",11))
   {
      pCNO=&CNodeOutput[++NodeOutputTeller];
      strncpy(pCNO->name,pos+11,sizeof(pCNO->name));
      sprintf(pCNO->volgnr,"%3d",NodeOutputTeller);
      strcpy(pCNO->present,"0");
   }
   else if (*pos!=' '&&*pos!='\t')
   {
      //interface naam
      unsigned int len;
      char *pos1=pos;
      pCDO=&CardOutput[++CardOutputTeller];
      pCNO=&CNodeOutput[NodeOutputTeller];
      strcpy(pCNO->present,"1");
      while(*pos1++!=':');
      len=pos1-pos-1;
      if (len>9) len=9;
      memcpy(pCDO->configname,pos,len);
      pCDO->configname[len]='\0';
      sprintf(pCDO->volgnr,"%3d",CardOutputTeller);
      sprintf(pCDO->nodenr,"%3d",NodeOutputTeller);
   }
   else
   {
      pCDO=&CardOutput[CardOutputTeller];
      while (*pos==' '||*pos=='\t'||*pos=='\n'||*pos=='\r') pos++;//skip leading spaces
      if (!memicmp(pos,"inet ",5))
      {
         unsigned int len;
         char *pos1=pos+5;
         pIO=&IfOutput[++IfOutputTeller];
         while(*pos1++!=' ');
         len=pos1-pos-6;
         if (len>17) len=17;
         memcpy(pIO->ip,pos+5,len);
         pIO->ip[len]='\0';
         memcpy(pIO->netmask,pos1+8,10);
         pIO->netmask[10]='\0';
         if (*(pos1+19)=='b') //broadcast
         {
            strcpy(pIO->broadcast,pos1+29);
         }
         sprintf(pIO->cardnr,"%3d",CardOutputTeller);
      }
      else if (!memicmp(pos,"ether ",6)) strcpy(pCDO->ether,pos+6);
      else if (!memicmp(pos,"status: ",8)) strcpy(pCDO->status,pos+8);
      else if (!memicmp(pos,"ssid ",5))
      {
         unsigned int len;
         char *pos1=pos+5;
         while(*pos1++!=' ');
         len=pos1-pos-6;
         if (len>38) len=38;
         memcpy(pCDO->ssid,pos+5,len);
         pCDO->ssid[len]='\0';
      }
      else if (!memicmp(pos,"channel ",8))
      {
         unsigned int len;
         char *pos1=pos+8;
         while(*pos1++!=' ');
         len=pos1-pos-9;
         if (len>3) len=3;
         memcpy(pCDO->channel,pos+8,len);
         pCDO->channel[len]='\0';
      }
      else if (!memicmp(pos,"stationname ",12)) strcpy(pCDO->stationname,pos+12);
   }
}

void LeesNode(void)
{
   char *pos;
   int regels=0;
   int rest;
   bCardBezig=FALSE;

   toread=BUFLEN;
   numread=fread(Tekstbuf,sizeof(char),toread,hConf);

   pos=strtok(Tekstbuf,"\n\r" );
   while (pos)
   {
      unsigned j;
      strcpy(Regelbuf,Tekstbuf);
      rest=strlen(Regelbuf);
      for (j=0;j<numread-rest-1;j++)
      {
         Tekstbuf[j]=Tekstbuf[j+rest+1]; //tekst naar links schuiven
      }
      if (numread==BUFLEN)
      {
         numread-=(rest+1);
         numread+=fread(Tekstbuf+numread,sizeof(char),rest+1,hConf);
         if (numread<BUFLEN) Tekstbuf[numread]='\0';
      }
      else
      {
         numread-=(rest+1);
         Tekstbuf[numread]='\0';
      }

      BehandelRegel();
      strcat(Formatbuf,"\n");
      printf(Formatbuf);
      regels++;
      pos=strtok(Tekstbuf,"\n\r" );
   }
   sprintf(buf,"\naantal regels: %i\n\r",regels);
   printf(buf);
}

void FormatRegel(void)
{
   char *pos=Regelbuf;
   char *pose=Formatbuf;
   BOOL bDescFlag;
   BOOL bDubbelIpFlag;
   {
      //vervang # door \0
      char *posd=pos;
      while (*posd!='#'&&*posd!='\0') posd++;
      *posd='\0';
   }
   {
      //vervang /" door /'
      char *posd=pos;
      while (*posd!='\0') 
      {
         if (*posd=='\"') *posd='\'';
         posd++;
      }
   }
   while (pos[strlen(pos)-1]==' ') //skip trailing spaces
   {
      pos[strlen(pos)-1]='\0';
   }
   if (pos[strlen(pos)-1]==';') //skip trailing ;
   {
      pos[strlen(pos)-1]='\0';
   }
   if (pos[strlen(pos)-1]=='\'') //skip trailing '
   {
      pos[strlen(pos)-1]='\0';
   }
   while (pos[strlen(pos)-1]==' ') //skip trailing spaces
   {
      pos[strlen(pos)-1]='\0';
   }
   while (*pos==' '||*pos=='\t'||*pos=='\n'||*pos=='\r') pos++;//skip leading spaces

   bDescFlag=(!memicmp(pos,"DESC",4)); //bij DESC spaties laten
   bDubbelIpFlag=(!memicmp(pos,"POINT_TO_POINT=",15)||!memicmp(pos,"OSPF_NEIGHBORS=",15)); //spaties vervangen door ;
   for (;*pos!='\0';pos++)
   {
      if (bDubbelIpFlag&&(*pos==' '||*pos=='\t'))
      {
         while (*pos==' '||*pos=='\t') pos++;//skip overige spaces
         *(--pos)=';';
      }
      while (!bDescFlag&&(*pos==' '||*pos=='\t')) pos++;//skip spaces
      if (*pos=='\'') //neem tekst tussen quotes letterlijk over
      {               //tot volgende quote of eind
         *pose++=*pos++;
         while (*pos!='\''&&*pos!='\0')
         {
            if (*pos==',') *pos=';'; //geen komma's ivm csv-list
            *pose++=*pos++;
         }
      }
      if (*pos==',') *pos=';'; //geen komma's ivm csv-list
      *pose++=*pos;
   }
   *pose='\0';
   strcpy(Regelbuf,Formatbuf);
}

void BehandelRegel(void)
{
   char *pos=Regelbuf;
   CNODE *pCN=&CNode[NodeTeller];
   CARD *pCd=&Card[CardTeller];
   FormatRegel();
   
   if (!bCardBezig)
   {
      if (!memicmp(pos,"$location='",11)) strncpy(pCN->location,pos+11,sizeof(pCN->location));
      else if (!memicmp(pos,"$master_ip='",12))
      {
         sprintf(pCN->volgnr,"%3d",NodeTeller); //hier want t hoeft maar 1 keer
         strncpy(pCN->master_ip,pos+12,sizeof(pCN->master_ip));
      }
      else if (!memicmp(pos,"$gw_open='",10)) strncpy(pCN->gw_open,pos+10,sizeof(pCN->gw_open));
      else if (!memicmp(pos,"$nodetype='",11)) strncpy(pCN->nodetype,pos+11,sizeof(pCN->nodetype));
      else if (!memicmp(pos,"$nodename='",11)) strncpy(pCN->nodename,pos+11,sizeof(pCN->nodename));
      else if (!memicmp(pos,"$status='",9)) strncpy(pCN->status,pos+9,sizeof(pCN->status));
      else if (!memicmp(pos,"$OS='",5)) strncpy(pCN->OS,pos+5,sizeof(pCN->OS));
      else if (!memicmp(pos,"$labelpos='",11)) strncpy(pCN->labelpos,pos+11,sizeof(pCN->labelpos));
      else if (!memicmp(pos,"$X='",4)) strncpy(pCN->X,pos+4,sizeof(pCN->X));
      else if (!memicmp(pos,"$Y='",4)) strncpy(pCN->Y,pos+4,sizeof(pCN->Y));
      else if (!memicmp(pos,"$N='",4)) strncpy(pCN->N,pos+4,sizeof(pCN->N));
      else if (!memicmp(pos,"$E='",4)) strncpy(pCN->E,pos+4,sizeof(pCN->E));
      else if (!memicmp(pos,"$ESSID='",8)) strncpy(pCN->ESSID,pos+8,sizeof(pCN->ESSID));
      
      else if (!memicmp(pos,"$config{'",9))
      {
         unsigned int len;
         char *pos1=pos+9;
         while(*pos1++!='\'');
         len=pos1-pos-10;
         if (len>9) len=9;
         memcpy(pCd->configname,pos+9,len);
         pCd->configname[len]='\0';
         sprintf(pCd->volgnr,"%3d",CardTeller); //hier want t hoeft maar 1 keer
         sprintf(pCd->nodenr,"%3d",NodeTeller); //hier want t hoeft maar 1 keer
         //opvang voor ontbreken van 'sprintf' bij sommige configs
         if (*(pos+12+len)=='<')
         {
            strncpy(pCd->sprintfname,pos+len+14,sizeof(pCd->sprintfname));
         }
         else strncpy(pCd->sprintfname,pos+len+21,sizeof(pCd->sprintfname));
         bCardBezig=TRUE;
         if (*(pCd->configname+strlen(pCd->configname)-2)==':')
         { //alias, dan hoofdgegevens overnemen, ga ervan uit dat hoofd-interface altijd direct aan aliassen voorafgaat
            int j=0;
            while (*((pCd-j)->configname+strlen((pCd-j)->configname)-2)==':'&&(j<=CardTeller)) j++;
            if (j<=CardTeller)
            {
               strncpy(pCd->mode,(pCd-j)->mode,sizeof(pCd->mode));
               strncpy(pCd->essid,(pCd-j)->essid,sizeof(pCd->essid));
               strncpy(pCd->channel,(pCd-j)->channel,sizeof(pCd->channel));
               strncpy(pCd->polar,(pCd-j)->polar,sizeof(pCd->polar));
               strncpy(pCd->antenna,(pCd-j)->antenna,sizeof(pCd->antenna));
               strncpy(pCd->gain,(pCd-j)->gain,sizeof(pCd->gain));
               strncpy(pCd->direction,(pCd-j)->direction,sizeof(pCd->direction));
               strncpy(pCd->beamwidth,(pCd-j)->beamwidth,sizeof(pCd->beamwidth));
               strncpy(pCd->cable,(pCd-j)->cable,sizeof(pCd->cable));
               strncpy(pCd->heigth,(pCd-j)->heigth,sizeof(pCd->heigth));
            }
         }
      }
   }
   else /*if (bCardBezig)*/
   {
      if (!memicmp(pos,pCd->sprintfname,strlen(pCd->sprintfname)))
      {
         VulIpAdressen();
         CardTeller++;
         bCardBezig=FALSE;
      }
      else if (!memicmp(pos,"TYPE=",5)) strncpy(pCd->type,pos+5,sizeof(pCd->type));
      else if (!memicmp(pos,"IP=",3))
      {
         if (!memicmp(pos+3,"$master_ip",10))
         {
            strcpy(pCd->ip,pCN->master_ip);
            strcat(pCd->ip,pos+13);
         }
         else strncpy(pCd->ip,pos+3,sizeof(pCd->ip));
      }
      else if (!memcmp(pos,"DESC=",5)) strncpy(pCd->desc,pos+5,sizeof(pCd->desc));
      else if (!memicmp(pos,"SDESC=",6)) strncpy(pCd->sdesc,pos+6,sizeof(pCd->sdesc));
      else if (!memicmp(pos,"SPEED=",6)) strncpy(pCd->speed,pos+6,sizeof(pCd->speed));
      else if (!memicmp(pos,"POINT_TO_POINT=",15)) strncpy(pCd->pointtopoint,pos+15,sizeof(pCd->pointtopoint));
      else if (!memicmp(pos,"OSPF_BROADCAST=",15)) strncpy(pCd->ospfbroadcast,pos+15,sizeof(pCd->ospfbroadcast));
      else if (!memicmp(pos,"OSPF_NEIGHBORS=",15)) strncpy(pCd->ospfneighbors,pos+15,sizeof(pCd->ospfneighbors));
      else if (!memicmp(pos,"DHCP=",5)) strncpy(pCd->dhcp,pos+5,sizeof(pCd->dhcp));
      else if (!memicmp(pos,"MODE=",5)) strncpy(pCd->mode,pos+5,sizeof(pCd->mode));
      else if (!memicmp(pos,"ESSID=",6)) strncpy(pCd->essid,pos+6,sizeof(pCd->essid));
      else if (!memicmp(pos,"CHANNEL=",8)) strncpy(pCd->channel,pos+8,sizeof(pCd->channel));
      else if (!memicmp(pos,"POLAR=",6)) strncpy(pCd->polar,pos+6,sizeof(pCd->polar));
      else if (!memicmp(pos,"ANTENNA=",8)) strncpy(pCd->antenna,pos+8,sizeof(pCd->antenna));
      else if (!memicmp(pos,"GAIN=",5)) strncpy(pCd->gain,pos+5,sizeof(pCd->gain));
      else if (!memicmp(pos,"DIRECTION=",10)) strncpy(pCd->direction,pos+10,sizeof(pCd->direction));
      else if (!memicmp(pos,"BEAMWIDTH=",10)) strncpy(pCd->beamwidth,pos+10,sizeof(pCd->beamwidth));
      else if (!memicmp(pos,"CABLE=",6)) strncpy(pCd->cable,pos+6,sizeof(pCd->cable));
      else if (!memicmp(pos,"HEIGTH=",7)) strncpy(pCd->heigth,pos+7,sizeof(pCd->heigth));
   }
}

void VulIpAdressen(void)
{
   CARD *pCd=&Card[CardTeller];
   char buf[36];
   char *t;
   strcpy(buf,pCd->ip);//111.111.111.111/30
   t=strtok(buf,".");
   if (t)
   {
      pCd->ipr.ip.ip0=(unsigned char)atoi(t);
      t=strtok(NULL,".");
      if (t)
      {
         pCd->ipr.ip.ip1=(unsigned char)atoi(t);
         t=strtok(NULL,".");
         if (t)
         {
            pCd->ipr.ip.ip2=(unsigned char)atoi(t);
            t=strtok(NULL,"/");// let op /
            if (t)
            {
               pCd->ipr.ip.ip3=(unsigned char)atoi(t);
               t=strtok(NULL,".");
               if (t) pCd->ipr.mask=(unsigned char)atoi(t);
            }
         }
      }
   }
   strcpy(buf,pCd->pointtopoint);//111.111.111.111;111.111.111.111
   t=strtok(buf,".");
   if (t)
   {
      pCd->ptp1.ip0=(unsigned char)atoi(t);
      t=strtok(NULL,".");
      if (t)
      {
         pCd->ptp1.ip1=(unsigned char)atoi(t);
         t=strtok(NULL,".");
         if (t)
         {
            pCd->ptp1.ip2=(unsigned char)atoi(t);
            t=strtok(NULL,";");// let op ;
            if (t)
            {
               pCd->ptp1.ip3=(unsigned char)atoi(t);
               t=strtok(NULL,".");
               if (t)
               {
                  pCd->ptp2.ip0=(unsigned char)atoi(t);
                  t=strtok(NULL,".");
                  if (t)
                  {
                     pCd->ptp2.ip1=(unsigned char)atoi(t);
                     t=strtok(NULL,".");
                     if (t)
                     {
                        pCd->ptp2.ip2=(unsigned char)atoi(t);
                        t=strtok(NULL,";");
                        if (t) pCd->ptp2.ip3=(unsigned char)atoi(t);
                     }
                  }
               }
            }
         }
      }
   }
   strcpy(buf,pCd->ospfneighbors);//111.111.111.111;111.111.111.111
   t=strtok(buf,".");
   if (t)
   {
      pCd->on1.ip0=(unsigned char)atoi(t);
      t=strtok(NULL,".");
      if (t)
      {
         pCd->on1.ip1=(unsigned char)atoi(t);
         t=strtok(NULL,".");
         if (t)
         {
            pCd->on1.ip2=(unsigned char)atoi(t);
            t=strtok(NULL,";");// let op ;
            if (t)
            {
               pCd->on1.ip3=(unsigned char)atoi(t);
               t=strtok(NULL,".");
               if (t)
               {
                  pCd->on2.ip0=(unsigned char)atoi(t);
                  t=strtok(NULL,".");
                  if (t)
                  {
                     pCd->on2.ip1=(unsigned char)atoi(t);
                     t=strtok(NULL,".");
                     if (t)
                     {
                        pCd->on2.ip2=(unsigned char)atoi(t);
                        t=strtok(NULL,";");
                        if (t) pCd->on2.ip3=(unsigned char)atoi(t);
                     }
                  }
               }
            }
         }
      }
   }
   {
      IPADDRESS ips=pCd->ipr.ip;
      int mask3=pCd->ipr.mask;
      if (mask3<24)//komt nu niet voor, maar vang af met 0,0,0,0
      {
         ips.ip0=ips.ip1=ips.ip2=ips.ip3=0;
         pCd->ipstart=pCd->ipend=ips;
      }
      else
      {
         int mask3p,mask3pxor;
         mask3-=24;
         mask3p=255;
         mask3p>>=mask3; //shift right
         mask3pxor=255^mask3p;
         ips.ip3=ips.ip3&mask3pxor;
         pCd->ipstart=ips;
         ips.ip3=ips.ip3|mask3p;
         pCd->ipend=ips;
      }
   }
}

void MaakIpOverzicht(void)
{
   //bubble sort card records op oplopend ip
   CARD *pCd1,*pCd2;
   IPADDRESS *pAd1, *pAd2;
   int i,j;
   BOOL swapped;
   do
   {
      swapped=FALSE;
      for (i=0,j=1;i<CardTeller-1;i++,j++)
      {
         BOOL swappen=FALSE;
         pCd1=&Card[i];pCd2=&Card[j];
         pAd1=&(pCd1->ipr.ip);pAd2=&(pCd2->ipr.ip);
         if (pAd1->ip0>pAd2->ip0) swappen=TRUE;
         else if (pAd1->ip0<pAd2->ip0) continue;
         else if (pAd1->ip1>pAd2->ip1) swappen=TRUE;
         else if (pAd1->ip1<pAd2->ip1) continue;
         else if (pAd1->ip2>pAd2->ip2) swappen=TRUE;
         else if (pAd1->ip2<pAd2->ip2) continue;
         else if (pAd1->ip3>pAd2->ip3) swappen=TRUE;
         else if (pAd1->ip3<pAd2->ip3) continue;
         else if (pCd1->ipr.mask<pCd2->ipr.mask) swappen=TRUE;
         if (swappen)
         {
            SwapCards(i);
            swapped=TRUE;
         }
      }
   }
   while (swapped);
   MaakCSV(2);
   MaakCSV2(1);
}

void SwapCards(int i)
{
   CARD tempCd=Card[i+1];
   Card[i+1]=Card[i];
   Card[i]=tempCd;
}

void MaakCSV2(int code)
{
   int i;
   CNODE *pCN;
   CARD *pCd;
   if (code==1) hConf=fopen("configip1.csv","w");
   if (code==2) hConf=fopen("configip2.csv","w");
   if (hConf)
   {
      strcpy(buf,"status");AddTekst();AddKomma();
      strcpy(buf,"nodename");AddTekst();AddKomma();
      strcpy(buf,"configname");AddTekst();AddKomma();
      strcpy(buf,"essid");AddTekst();AddKomma();
      strcpy(buf,"sdesc");AddTekst();AddKomma();
      strcpy(buf,"master_ip");AddTekst();AddKomma();
      strcpy(buf,"IP-range");AddTekst();AddKomma();
      strcpy(buf,"IP-start");AddTekst();AddKomma();
      strcpy(buf,"IP-end");AddTekst();AddKomma();
      strcpy(buf,"point_to_point");AddTekst();AddKomma();
      strcpy(buf,"ospf_neighbors");AddTekst();AddKomma();
      strcpy(buf,"mode");AddTekst();AddKomma();
      strcpy(buf,"channel");AddTekst();AddKomma();
      strcpy(buf,"Current data from nodes");AddTekst();AddKomma();
      fwrite( "\n", sizeof( char ), 1, hConf );
      
      for (i=0;i<CardTeller;i++)
      {
         pCd=&Card[i];
         pCN=&CNode[atoi(pCd->nodenr)];
         if (i>0)
         { //extra lege regel
            if (CompareIp(&(pCd->ipstart),&((pCd-1)->ipstart))||CompareIp(&(pCd->ipend),&((pCd-1)->ipend)))
               fwrite( "\n", sizeof( char ), 1, hConf );
         }
         fwrite( pCN->status, sizeof( char ), strlen(pCN->status), hConf );AddKomma();
         fwrite( pCN->nodename, sizeof( char ), strlen(pCN->nodename), hConf );AddKomma();
         fwrite( pCd->configname, sizeof( char ), strlen(pCd->configname), hConf );AddKomma();
         fwrite( pCd->essid, sizeof( char ), strlen(pCd->essid), hConf );AddKomma();
         fwrite( pCd->sdesc, sizeof( char ), strlen(pCd->sdesc), hConf );AddKomma();
         fwrite( pCN->master_ip, sizeof( char ), strlen(pCN->master_ip), hConf );AddKomma();
         fwrite( pCd->ip, sizeof( char ), strlen(pCd->ip), hConf );AddKomma();
         {
            char buf[20];
            sprintf(buf,"%i.%i.%i.%i",pCd->ipstart.ip0,pCd->ipstart.ip1,pCd->ipstart.ip2,pCd->ipstart.ip3);
            fwrite( buf, sizeof( char ),strlen(buf), hConf );AddKomma();
            sprintf(buf,"%i.%i.%i.%i",pCd->ipend.ip0,pCd->ipend.ip1,pCd->ipend.ip2,pCd->ipend.ip3);
            fwrite( buf, sizeof( char ),strlen(buf), hConf );AddKomma();
         }
         fwrite( pCd->pointtopoint, sizeof( char ), strlen(pCd->pointtopoint), hConf );AddKomma();
         fwrite( pCd->ospfneighbors, sizeof( char ), strlen(pCd->ospfneighbors), hConf );AddKomma();
         fwrite( pCd->mode, sizeof( char ), strlen(pCd->mode), hConf );AddKomma();
         fwrite( pCd->channel, sizeof( char ), strlen(pCd->channel), hConf );AddKomma();
         {
            int j;
            IFOUTPUT *pIO;
            char tbuf[30];
            strcpy(tbuf,pCd->ip);
            for (j=0;j<strlen(pCd->ip);j++)
            {
               if (tbuf[j]=='/') tbuf[j]='\0';
            }
            for (j=0;j<IfOutputTeller;j++)
            {
               pIO=&IfOutput[j];//lengtes moeten ook gelijk zijn anders: 172.1.1.227==172.1.1.22
               if ((strlen(pIO->ip)==strlen(tbuf))&&(!memcmp(pIO->ip,tbuf,strlen(pIO->ip)))) break;
            }
            if (j<IfOutputTeller)
            {
               CARDOUTPUT *pCDO=&CardOutput[atoi(pIO->cardnr)];
               fwrite( pIO->ip, sizeof( char ), strlen(pIO->ip), hConf );AddKomma();
               fwrite( pCDO->configname, sizeof( char ), strlen(pCDO->configname), hConf );AddKomma();
               fwrite( pCDO->ether, sizeof( char ), strlen(pCDO->ether), hConf );AddKomma();
               fwrite( pCDO->status, sizeof( char ), strlen(pCDO->status), hConf );AddKomma();
               fwrite( pCDO->ssid, sizeof( char ), strlen(pCDO->ssid), hConf );AddKomma();
               fwrite( pCDO->stationname, sizeof( char ), strlen(pCDO->stationname), hConf );AddKomma();
               fwrite( pCDO->channel, sizeof( char ), strlen(pCDO->channel), hConf );AddKomma();
            }
         }
         
#ifdef xyz //even er uit
         {
            BOOL even;
            int test=pCd->ipr.ip.ip3;
            even=(test==((int)(test/2))*2);
            if (!memicmp(pCd->mode,"managed",7)&&!even)
            {
               fwrite("oneven ip-adres en managed mode",sizeof( char ),31,hConf);
               AddKomma();
            }
            if (!memicmp(pCd->mode,"master",6)&&even)
            {
               fwrite("even ip-adres en master mode",sizeof( char ),28,hConf);
               AddKomma();
            }
         }
         
         if (CompareIp(&pCd->ptp1,&pCd->ipstart)<0||CompareIp(&pCd->ptp1,&pCd->ipend)>0)
         {
            fwrite("point-to-point adres buiten range",sizeof( char ),33,hConf);
            AddKomma();
         }
         if (CompareIp(&pCd->on1,&pCd->ipstart)<0||CompareIp(&pCd->on1,&pCd->ipend)>0)
         {
            fwrite("ospf-neighbors adres buiten range",sizeof( char ),33,hConf);
            AddKomma();
         }
#endif
         fwrite( "\n", sizeof( char ), 1, hConf );
      }
      fclose(hConf);
   }
}

void MaakCSV(int code)
{
   int i;
   CNODE *pCN;
   CARD *pCd;
   if (code==1) hConf=fopen("configs1.csv","w");
   if (code==2) hConf=fopen("configs2.csv","w");
   if (hConf)
   {
      strcpy(buf,"location");AddTekst();AddKomma();
      strcpy(buf,"master_ip");AddTekst();AddKomma();
      strcpy(buf,"gw_open");AddTekst();AddKomma();
      strcpy(buf,"nodetype");AddTekst();AddKomma();
      strcpy(buf,"nodename");AddTekst();AddKomma();
      strcpy(buf,"status");AddTekst();AddKomma();
      strcpy(buf,"OS");AddTekst();AddKomma();
      strcpy(buf,"labelpos");AddTekst();AddKomma();
      strcpy(buf,"X");AddTekst();AddKomma();
      strcpy(buf,"Y");AddTekst();AddKomma();
      strcpy(buf,"N");AddTekst();AddKomma();
      strcpy(buf,"E");AddTekst();AddKomma();
      strcpy(buf,"ESSID");AddTekst();AddKomma();
      strcpy(buf,"configname");AddTekst();AddKomma();
      strcpy(buf,"sprintfname");AddTekst();AddKomma();
      strcpy(buf,"type");AddTekst();AddKomma();
      strcpy(buf,"ip");AddTekst();AddKomma();
      strcpy(buf,"desc");AddTekst();AddKomma();
      strcpy(buf,"sdesc");AddTekst();AddKomma();
      strcpy(buf,"speed");AddTekst();AddKomma();
      strcpy(buf,"point_to_point");AddTekst();AddKomma();
      strcpy(buf,"ospf_broadcast");AddTekst();AddKomma();
      strcpy(buf,"ospf_neighbors");AddTekst();AddKomma();
      strcpy(buf,"dhcp");AddTekst();AddKomma();
      strcpy(buf,"mode");AddTekst();AddKomma();
      strcpy(buf,"essid");AddTekst();AddKomma();
      strcpy(buf,"channel");AddTekst();AddKomma();
      strcpy(buf,"polar");AddTekst();AddKomma();
      strcpy(buf,"antenna");AddTekst();AddKomma();
      strcpy(buf,"gain");AddTekst();AddKomma();
      strcpy(buf,"direction");AddTekst();AddKomma();
      strcpy(buf,"beamwidth");AddTekst();AddKomma();
      strcpy(buf,"cable");AddTekst();AddKomma();
      strcpy(buf,"heigth");AddTekst();AddKomma();
      
      fwrite( "\n", sizeof( char ), 1, hConf );
      
      for (i=0;i<CardTeller;i++)
      {
         pCd=&Card[i];
         pCN=&CNode[atoi(pCd->nodenr)];
         fwrite( pCN->location, sizeof( char ), strlen(pCN->location), hConf );AddKomma();
         fwrite( pCN->master_ip, sizeof( char ), strlen(pCN->master_ip), hConf );AddKomma();
         fwrite( pCN->gw_open, sizeof( char ), strlen(pCN->gw_open), hConf );AddKomma();
         fwrite( pCN->nodetype, sizeof( char ), strlen(pCN->nodetype), hConf );AddKomma();
         fwrite( pCN->nodename, sizeof( char ), strlen(pCN->nodename), hConf );AddKomma();
         fwrite( pCN->status, sizeof( char ), strlen(pCN->status), hConf );AddKomma();
         fwrite( pCN->OS, sizeof( char ), strlen(pCN->OS), hConf );AddKomma();
         fwrite( pCN->labelpos, sizeof( char ), strlen(pCN->labelpos), hConf );AddKomma();
         fwrite( pCN->X, sizeof( char ), strlen(pCN->X), hConf );AddKomma();
         fwrite( pCN->Y, sizeof( char ), strlen(pCN->Y), hConf );AddKomma();
         fwrite( pCN->N, sizeof( char ), strlen(pCN->N), hConf );AddKomma();
         fwrite( pCN->E, sizeof( char ), strlen(pCN->E), hConf );AddKomma();
         fwrite( pCN->ESSID, sizeof( char ), strlen(pCN->ESSID), hConf );AddKomma();
         fwrite( pCd->configname, sizeof( char ), strlen(pCd->configname), hConf );AddKomma();
         fwrite( pCd->sprintfname, sizeof( char ), strlen(pCd->sprintfname), hConf );AddKomma();
         fwrite( pCd->type, sizeof( char ), strlen(pCd->type), hConf );AddKomma();
         fwrite( pCd->ip, sizeof( char ), strlen(pCd->ip), hConf );AddKomma();
         fwrite( pCd->desc, sizeof( char ), strlen(pCd->desc), hConf );AddKomma();
         fwrite( pCd->sdesc, sizeof( char ), strlen(pCd->sdesc), hConf );AddKomma();
         fwrite( pCd->speed, sizeof( char ), strlen(pCd->speed), hConf );AddKomma();
         fwrite( pCd->pointtopoint, sizeof( char ), strlen(pCd->pointtopoint), hConf );AddKomma();
         fwrite( pCd->ospfbroadcast, sizeof( char ), strlen(pCd->ospfbroadcast), hConf );AddKomma();
         fwrite( pCd->ospfneighbors, sizeof( char ), strlen(pCd->ospfneighbors), hConf );AddKomma();
         fwrite( pCd->dhcp, sizeof( char ), strlen(pCd->dhcp), hConf );AddKomma();
         fwrite( pCd->mode, sizeof( char ), strlen(pCd->mode), hConf );AddKomma();
         fwrite( pCd->essid, sizeof( char ), strlen(pCd->essid), hConf );AddKomma();
         fwrite( pCd->channel, sizeof( char ), strlen(pCd->channel), hConf );AddKomma();
         fwrite( pCd->polar, sizeof( char ), strlen(pCd->polar), hConf );AddKomma();
         fwrite( pCd->antenna, sizeof( char ), strlen(pCd->antenna), hConf );AddKomma();
         fwrite( pCd->gain, sizeof( char ), strlen(pCd->gain), hConf );AddKomma();
         fwrite( pCd->direction, sizeof( char ), strlen(pCd->direction), hConf );AddKomma();
         fwrite( pCd->beamwidth, sizeof( char ), strlen(pCd->beamwidth), hConf );AddKomma();
         fwrite( pCd->cable, sizeof( char ), strlen(pCd->cable), hConf );AddKomma();
         fwrite( pCd->heigth, sizeof( char ), strlen(pCd->heigth), hConf );AddKomma();
         {
            int j;
            IFOUTPUT *pIO;
            char tbuf[30];
            strcpy(tbuf,pCd->ip);
            for (j=0;j<strlen(pCd->ip);j++)
            {
               if (tbuf[j]=='/') tbuf[j]='\0';
            }
            for (j=0;j<IfOutputTeller;j++)
            {
               pIO=&IfOutput[j];//lengtes moeten ook gelijk zijn anders: 172.1.1.227==172.1.1.22
               if ((strlen(pIO->ip)==strlen(tbuf))&&(!memcmp(pIO->ip,tbuf,strlen(pIO->ip)))) break;
            }
            if (j<IfOutputTeller)
            {
               CARDOUTPUT *pCDO=&CardOutput[atoi(pIO->cardnr)];
               fwrite( pIO->ip, sizeof( char ), strlen(pIO->ip), hConf );AddKomma();
               fwrite( pCDO->configname, sizeof( char ), strlen(pCDO->configname), hConf );AddKomma();
               fwrite( pCDO->ether, sizeof( char ), strlen(pCDO->ether), hConf );AddKomma();
               fwrite( pCDO->status, sizeof( char ), strlen(pCDO->status), hConf );AddKomma();
               fwrite( pCDO->ssid, sizeof( char ), strlen(pCDO->ssid), hConf );AddKomma();
               fwrite( pCDO->stationname, sizeof( char ), strlen(pCDO->stationname), hConf );AddKomma();
               fwrite( pCDO->channel, sizeof( char ), strlen(pCDO->channel), hConf );AddKomma();
            }
         }
         fwrite( "\n", sizeof( char ), 1, hConf );
      }
      fclose(hConf);
   }
}

void MaakCSV3(int code)
{
   int i;
   CNODE *pCN;
   CARD *pCd;
   IFOUTPUT *pIO;
   CARDOUTPUT *pCDO;
   CNODEOUTPUT *pCNO;
   if (code==1) hConf=fopen("outputs1.csv","w");
   if (code==2) hConf=fopen("outputs2.csv","w");
   if (hConf)
   {
      strcpy(buf,"name");AddTekst();AddKomma();
      strcpy(buf,"stationname");AddTekst();AddKomma();
      strcpy(buf,"ssid");AddTekst();AddKomma();
      strcpy(buf,"configname");AddTekst();AddKomma();
      strcpy(buf,"status");AddTekst();AddKomma();
      strcpy(buf,"ether");AddTekst();AddKomma();
      strcpy(buf,"channel");AddTekst();AddKomma();
      strcpy(buf,"ip");AddTekst();AddKomma();
      strcpy(buf,"netmask");AddTekst();AddKomma();
      strcpy(buf,"broadcast");AddTekst();AddKomma();
      strcpy(buf,"wleiden.conf");AddTekst();AddKomma();
      fwrite( "\n", sizeof( char ), 1, hConf );
      
      for (i=0;i<IfOutputTeller;i++)
      {
         pIO=&IfOutput[i];
         pCDO=&CardOutput[atoi(pIO->cardnr)];
         pCNO=&CNodeOutput[atoi(pCDO->nodenr)];
         fwrite( pCNO->name, sizeof( char ), strlen(pCNO->name), hConf );AddKomma();
         fwrite( pCDO->stationname, sizeof( char ), strlen(pCDO->stationname), hConf );AddKomma();
         fwrite( pCDO->ssid, sizeof( char ), strlen(pCDO->ssid), hConf );AddKomma();
         fwrite( pCDO->configname, sizeof( char ), strlen(pCDO->configname), hConf );AddKomma();
         fwrite( pCDO->status, sizeof( char ), strlen(pCDO->status), hConf );AddKomma();
         fwrite( pCDO->ether, sizeof( char ), strlen(pCDO->ether), hConf );AddKomma();
         fwrite( pCDO->channel, sizeof( char ), strlen(pCDO->channel), hConf );AddKomma();
         fwrite( pIO->ip, sizeof( char ), strlen(pIO->ip), hConf );AddKomma();
         fwrite( pIO->netmask, sizeof( char ), strlen(pIO->netmask), hConf );AddKomma();
         fwrite( pIO->broadcast, sizeof( char ), strlen(pIO->broadcast), hConf );AddKomma();
         {
            int j;
            char tbuf[30];
            for (j=0;j<CardTeller;j++)
            {
               int k;
               pCd=&Card[j];
               strcpy(tbuf,pCd->ip);
               for (k=0;k<strlen(pCd->ip);k++)
               {
                  if (tbuf[k]=='/') tbuf[k]='\0';
               }
               if ((strlen(pIO->ip)==strlen(tbuf))&&(!memcmp(pIO->ip,tbuf,strlen(pIO->ip)))) break;
            }
            if (j<CardTeller)
            {
               pCN=&CNode[atoi(pCd->nodenr)];
               fwrite( pCN->master_ip, sizeof( char ), strlen(pCN->master_ip), hConf );AddKomma();
               fwrite( pCN->nodename, sizeof( char ), strlen(pCN->nodename), hConf );AddKomma();
               fwrite( pCN->status, sizeof( char ), strlen(pCN->status), hConf );AddKomma();
               fwrite( pCN->ESSID, sizeof( char ), strlen(pCN->ESSID), hConf );AddKomma();
               fwrite( pCd->configname, sizeof( char ), strlen(pCd->configname), hConf );AddKomma();
               fwrite( pCd->sprintfname, sizeof( char ), strlen(pCd->sprintfname), hConf );AddKomma();
               fwrite( pCd->type, sizeof( char ), strlen(pCd->type), hConf );AddKomma();
               fwrite( pCd->ip, sizeof( char ), strlen(pCd->ip), hConf );AddKomma();
               fwrite( pCd->desc, sizeof( char ), strlen(pCd->desc), hConf );AddKomma();
               fwrite( pCd->sdesc, sizeof( char ), strlen(pCd->sdesc), hConf );AddKomma();
               fwrite( pCd->pointtopoint, sizeof( char ), strlen(pCd->pointtopoint), hConf );AddKomma();
               fwrite( pCd->ospfbroadcast, sizeof( char ), strlen(pCd->ospfbroadcast), hConf );AddKomma();
               fwrite( pCd->ospfneighbors, sizeof( char ), strlen(pCd->ospfneighbors), hConf );AddKomma();
               fwrite( pCd->dhcp, sizeof( char ), strlen(pCd->dhcp), hConf );AddKomma();
               fwrite( pCd->mode, sizeof( char ), strlen(pCd->mode), hConf );AddKomma();
               fwrite( pCd->essid, sizeof( char ), strlen(pCd->essid), hConf );AddKomma();
               fwrite( pCd->channel, sizeof( char ), strlen(pCd->channel), hConf );AddKomma();
            }
         }
         fwrite( "\n", sizeof( char ), 1, hConf );
      }
      fclose(hConf);
   }
}

void AddKomma(void)
{
   fwrite( ",", sizeof( char ), 1, hConf );
}

void AddTekst(void)
{
   fwrite( buf, sizeof( char ), strlen(buf), hConf );
}

int CompareIp(IPADDRESS *ad1,IPADDRESS *ad2)
{//ad1>ad2->1;ad1==ad2->0;ad1<ad2->-1
   if(ad1->ip0>ad2->ip0) return 1;
   if(ad1->ip0<ad2->ip0) return -1;
   if(ad1->ip1>ad2->ip1) return 1;
   if(ad1->ip1<ad2->ip1) return -1;
   if(ad1->ip2>ad2->ip2) return 1;
   if(ad1->ip2<ad2->ip2) return -1;
   if(ad1->ip3>ad2->ip3) return 1;
   if(ad1->ip3<ad2->ip3) return -1;
   return 0;
}

