//	ARP CONTROL 1.03
//	Krystian Buszkowski 2008
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define rekordow 1024
#define wersja "ARP CONTROL 1.06"

char ip[rekordow][20];
char nazwa[rekordow][160];
char mac[rekordow][20];

void usun_wpis_arpa(char adres[]) //ten adres bedzie dzialal z kazdym mac adresem
{
    char komenda[50];
    if(adres[0]=='#') return;
    sprintf(komenda,"arp -d %s",adres);
    printf("ARP CONTROL: Znaleziono hash \"#\": Adres %s jest teraz poza kontrolą mac-adresow\n",adres);
    system(komenda);
    return;
}


char kontrola_mac(char *rekord,int wielkosc,int wywolanie)
{
    if(*rekord=='#') 
	{
	    usun_wpis_arpa(rekord);
	    return 0;
	}
    rekord+=2;
    for(int i=2; i<wielkosc;i+=3)
	{
	    if(*rekord!=':') 
		{
		    printf("ARP CONTROL: Błąd w mac adresie, linia:%i znak: %i\n",wywolanie+1,i);	
		    return 1;
		}
	    if((*rekord==':')&&(*(rekord+1)==0)) 
		{
		    printf("ARP CONTROL: Błąd w mac adresie, linia:%i znak: %i\n",wywolanie+1,i);	
		    return 1;
		}
	    
	    rekord+=3;
	}
    //printf("%i",*rekord);
    return 0;
}

char kontrola_nazwy(char *rekord,int wielkosc,int wywolanie)
{
    if(wielkosc>15) 
		{
		    //printf("ARP CONTROL: Skróciłem nazwę-> %s \tlinia:%i\n",rekord,wywolanie+1);	
		    rekord+=15;
		    *rekord=0;
		    rekord-=15;
		    printf("ARP CONTROL: Skróciłem nazwę-> %s \tlinia:%i\n",rekord,wywolanie+1);	
		    return 1;
		}
    return 0;
}



void stworz_arp(int wywolanie) //robienie tablicy arpa
{
    FILE *plik;
    plik=fopen("/etc/maskarada/arp_table","w");
    for(int i=0;i<wywolanie;i++)  
	{
	    if(mac[i][0]=='#') 
		{
		    usun_wpis_arpa(ip[i]);    
		    continue;
		}
	    if((mac[i][0]!=0)&&(ip[i][0]!=0)) fprintf(plik,"%s %s\n",mac[i],ip[i]);
	}
    fclose(plik);
    return;
}

void stworz_host(int wywolanie)  //robienie pliku hosts
{
    FILE *plik;
    plik=fopen("/etc/maskarada/hosts","w");
    fprintf(plik,"# /etc/hosts\n\n# Nie usuwaj następnej linii. Wiele programów\n# wymaga takiego wpisu do poprawnej pracy.\n\n127.0.0.1       localhost.localdomain   localhost\n");
    for(int i=0;i<wywolanie-1;i++)
	{
	    if(mac[i][0]=='#') continue;
	    if(strlen(nazwa[i])==0) sprintf(nazwa[i],"nieznany%i",i+2);
	    fprintf(plik,"%s %s\n",ip[i],nazwa[i]);
	}
    fclose(plik);
    return;
}

void przydzial(char *buf,int *wywolanie,int *nr)
{
    if(*nr==1) 
	{
		strcpy(ip[*wywolanie],buf);
	}
    if(*nr==0) 
        {
		if(kontrola_mac(buf,strlen(buf),*wywolanie)!=1) strcpy(mac[*wywolanie],buf);
        }
    if(*nr==2) 
        {
		strcpy(nazwa[*wywolanie],buf);
		kontrola_nazwy(nazwa[*wywolanie],strlen(nazwa[*wywolanie]),*wywolanie);
        
        }
    if(*nr>2) 
        {
		strcat(nazwa[*wywolanie],"_");
		strcat(nazwa[*wywolanie],buf);
		kontrola_nazwy(nazwa[*wywolanie],strlen(nazwa[*wywolanie]),*wywolanie);
        }
}

void rozdziel(char *rekord,int *wielkosc_rekordu,int *wywolanie) //rozdzielamy rekord do odpowiednich tablic
{
	char buf[300];
	int i=0,j=0,nr=0;
	while(1)
	    {
		if((*rekord==32)||(*rekord==9))
		    {
			buf[i]=0;
			przydzial(buf,wywolanie,&nr);    
			nr++; //po kolei 1 to ip, 2 to mac, 3 to nazwa
			rekord++;
			i=0;
		    }
		buf[i]=*rekord;
		rekord++;
		i++;
		j++;
		if(j==*wielkosc_rekordu) break;
	    }
	    buf[i-1]=0;
	    przydzial(buf,wywolanie,&nr);						
	    return;
}

void ip_mac_nazwa(char *bufor,long *wielkosc_pliku) //pobieramy rekord do rozdzielenia
{	
	char buf[300];
	int i=0,j=0,wywolanie=0;
	while(1)
	    {
		if(*bufor==10)
		    {
			buf[i]=0;
			if(buf[0]!=0) rozdziel(buf,&i,&wywolanie);
			wywolanie++;
			bufor++;
			i=0;
		    }
		buf[i]=*bufor;
		bufor++;
		i++;
		j++;
		if(j==*wielkosc_pliku) break;
	    }
	    buf[i-1]=0;
	    if(buf[0]!=0) rozdziel(buf,&i,&wywolanie);
	    wywolanie++;
	    stworz_arp(wywolanie);
	    stworz_host(wywolanie);
	    return;		
}

int przetwarzaj_plik(void)  //ladujemy plik do pamieci, zeby nie meczyc dysku
{
	FILE *plik;
	char *bufor;
	long wielkosc_pliku;
	size_t wynik_czytania;
	
	plik=fopen("/etc/maskarada/staticarp","r");
	if(plik==NULL) 
	{
	printf("brak pliku staticarp w katalogu /etc/maskarada/\n");
	return 1;
	}
	
	//lookamy na wielkosc pliku
	fseek(plik,0,SEEK_END);
	wielkosc_pliku=ftell(plik);
	//printf("Zaalokowalim %i bajtów\n",wielkosc_pliku);
	rewind(plik);
	
	bufor=(char*)malloc(sizeof(char)*wielkosc_pliku);
	if(bufor==NULL)
	    {
		 printf("Mamy za mało pamięci :(\n");
		 free(bufor);
		 fclose(plik);
		 return 1;
	    }
	
	wynik_czytania=fread(bufor,1,wielkosc_pliku,plik);
	if(wynik_czytania!=wielkosc_pliku) 
	    {
		printf("problemy z czytaniem\n");
	        free(bufor);
		fclose(plik);
		return 1;
	    }
	
	ip_mac_nazwa(bufor,&wielkosc_pliku);
	
	free(bufor);
	fclose(plik);
	return 0;
}

int main()
{
	puts(wersja);
	if(przetwarzaj_plik()==1) 
	    {
		puts("Program zakończony błędem... nic nie zrobiono");
		return 1;
	    }	
	system("arp -f /etc/maskarada/arp_table");
	system("cp /etc/maskarada/hosts /etc/");
	puts("ARP CONTROL: Tablica ARP zaktualizowana");
	puts("ARP CONTROL: Plik hosts zastąpiony");
	return 0;
}


