#include <stdio.h>
#include <stdlib.h>
#include <math.h>


#define MAC 13



/*********** Prototypes des fonctions ***************/
void extraction_MAC(char position, FILE *fichier);
void calcul_longueur(FILE *fichier);
void calcul_entete(FILE *fichier);
void version_IP(FILE *fichier);
void extraction_IP(char position, FILE *fichier);

/**************** Fonction d'extraction de l'adresse IP ******************/
void extraction_IP(char position, FILE *fichier)
{
    char lect [2]= "";
    int octet_IP = 0;
    char i = 0;
    char j = 0;

    for(i=0;i<4;i++)
    {
        fseek(fichier,position,SEEK_SET);   // Position longueur totale
        fgets(lect, 3, fichier);    // Lecture des 2 caractères
        position = position + 2;// Pointage deux caractères plus loin pour lecture suivante
        octet_IP = 0 ;              // Remise à zéro de la variable de calcul
        for(j=0; j<2;j++)
        {
            if (lect [j]<60) // Test si le caractère est un chiffre ou une lettre en ASCII
                octet_IP = octet_IP + ((lect[j]-48)*pow(16,(1-j)));
                else octet_IP = octet_IP + ((lect[j]-87)*pow(16,(1-j)));
        }
        if(i<3) printf("%d.",octet_IP);
        else printf("%d",octet_IP);
    }

}
/*************************************************************************/


/************** Fonction d'extraction de la version d'IP *****************/
void version_IP(FILE *fichier)
{
    char ver_IP = 0;
    fseek(fichier,28,SEEK_SET); // Position sur version IP
    ver_IP = fgetc(fichier) - 0x30;
    printf("%d", ver_IP);
}
/*************************************************************************/



/*********** Fonction de calcul de la longueur de l'entête ***************/
void calcul_entete(FILE *fichier)
{
    char longueur_entete=0;                 // Entier qui contiendra la longueur de la trame

        fseek(fichier,29,SEEK_SET);         // Position longueur totale
        longueur_entete=fgetc(fichier);     // Lecture du caractère correspondant
        longueur_entete = (longueur_entete - 0x30)*4; // Conversion ASCII vers décimal
        printf("%d",longueur_entete);       // Affichage en décimal de la longueur

}
/*************************************************************************/


/********************* Lecture d'une adresse MAC *************************/
void extraction_MAC(char position, FILE *fichier)
{
    char adress_MAC[MAC] = ""; // Chaîne vide de taille adresse MAC

    fseek(fichier,position,SEEK_SET);   // Positionnement dans le fichier

    fgets(adress_MAC, MAC, fichier);    // Lecture de la chaine de l'adresse

    printf("%s\n\n", adress_MAC);

}
/*************************************************************************/

/*********** Fonction de calcul de la longueur de la trame ***************/
void calcul_longueur(FILE *fichier)
{
    char i = 0;
    int longueur = 0;
    char longueur_totale[4]=""; // Déclaration d'un tableau pour contenir les 4 car de la long

        fseek(fichier,32,SEEK_SET); // Position longueur totale
        fgets(longueur_totale, 5, fichier); // Lecture de la chaine de longueur

        for(i=0;i<4;i++)    // Routine de conversion et de calcul
        {
            if (longueur_totale[i]<60) // Test si le caractère est un chiffre ou une lettre en ASCII
                longueur = longueur + ((longueur_totale[i]-48)*pow(16,(3-i)));
                else longueur = longueur + ((longueur_totale[i]-87)*pow(16,(3-i)));
                   }
        printf("%d",longueur);
}
/*************************************************************************/



/************************ Programme principal ****************************/
int main(int argc, char *argv[])
{
    FILE* fichier = NULL;
    char nom_de_fichier[20]="";     // Chaine vide qui contiendra le nom du fichier à traiter
    char car ;
    char sortie ;
    char octet = 0;

    printf("Application d'analyse d'une trame Ethernet 2\n\n");

do
    {
    printf("\nSaisissez le nom du fichier a analyser\n");   // Saisie du fichier à analyser
    scanf("%s", nom_de_fichier);

    fichier = fopen(nom_de_fichier, "r");       // Ouverture du fichier en lecture seule

    if (fichier != NULL)                        // test si le fichier existe
    {

        /* Extraction de la version de l'IP */
        printf("\nL'adresse IP est une version ");
        version_IP(fichier);
        printf("\n\n");

        /* Extraction de la longueur de l'entête */
        printf("\nLa longueur de l'entete est de ");
        calcul_entete(fichier);
        printf(" octets\n\n");

        /* Extraction des adresses MAC de source et de destination */
        printf("\nAdresse MAC de la destination: "); // On affiche la chaîne
        extraction_MAC(0,fichier);
        printf("\nAdresse MAC de la source: "); // On affiche la chaîne
        extraction_MAC(12,fichier);
        printf("\n");


        /* Extraction de la longueur totale */
        printf("La longueur totale de la trame est de "); // On affiche la chaîne
        calcul_longueur(fichier);
        printf(" octets\n\n");


        /* Extraction des adresses IP source et destination*/
        printf("\nL'adresse IP de la machine source est ");
        extraction_IP(52,fichier);
        printf("\n\n");
        printf("\nL'adresse IP de la machine destination est ");
        extraction_IP(60,fichier);
        printf("\n\n");

        fclose(fichier); // Fermeture du fichier
    }// si le fichier n'existe pas
    else printf("\nCe fichier de capture d'une trame n'existe pas !!\n\n");


    /* Test pour nouvelle analyse ou sortie */
    printf("\n\nTapez C pour analyser une nouvelle trame\n") ;
	/* On saisi un caractère*/
    car = getche();
	/* On compare le caractère pour savoir si nous devons faire une autre analyse*/
	sortie = ((car == 'c')||(car == 'C'));
	system("cls");

} while(sortie);

printf("\n\n");
printf("********************************************************************************\n");
printf("********************************************************************************\n");
printf("********************************************************************************\n");
printf("***************************      Fin du programme     **************************\n");
printf("********************************************************************************\n");
printf("********************************************************************************\n");
printf("********************************************************************************\n");
system("pause");
    return 0;
}
/*************************************************************************/
