#include <stdio.h>    // pour printf, scanf
#include <stdlib.h>   // pour atoi, exit, malloc (si besoin)
#include <string.h>   // pour strtok, strcmp (si tu découpes l’IP en chaîne)
#include <math.h>     // pour pow() (calcul du nombre d’adresses)
#include <stdint.h>   // pour uint32_t (manipuler l’IP en entier 32 bits proprement)


int main(void){
    while (1)
    {
       

    
        char ip_string[20];
        int mask_int;




        printf("Veuillez rentrer une adresse IP : ");
        scanf("%s", ip_string);

        printf("Veuillez rentrer un mask en notation CIDR (juste le nombre): ");
        scanf("%d", &mask_int);

        printf("IP : %s\n", ip_string);

        int ip[4];

        // traitement de l'IP string pour la transformer en tableau de int afin de pouvoir faire des operations dessus
        char *token = strtok(ip_string, ".");
        int i = 0;
        while (token != NULL && i < 4) {
            ip[i] = atoi(token);  // conversion chaîne → entier
            token = strtok(NULL, ".");
            i++;
        }

        uint32_t mask = 0;  // tous les bits à 0

        mask = (0xFFFFFFFF  << (32 - mask_int)); // le 0xFFFFFFFF permet de mettre tt les bits a 1 puis on fait le decalage mais comme taille limite, les 1 en trop sont supprimer car ils sont pousser par les 0 qui rentre


        /* permet d afficher le masque en decimale pointé
        printf("%d %d %d %d",
        (mask >> 24) & 0xFF,   // premier octet
        (mask >> 16) & 0xFF,   // deuxième octet
        (mask >> 8)  & 0xFF,   // troisième octet
        mask & 0xFF);          // quatrième octet

        */


        int nb_adresses = pow(2, (32 - mask_int));

        int nb_hotes = nb_adresses - 2;


        int ip_reseau[4];
        int broadcast[4];

        ip_reseau[0] = ip[0] & ((mask >> 24) & 0xFF);
        ip_reseau[1] = ip[1] & ((mask >> 16) & 0xFF);
        ip_reseau[2] = ip[2] & ((mask >> 8) & 0xFF);
        ip_reseau[3] = ip[3] & ((mask) & 0xFF);


        broadcast[0] = ip_reseau[0] | ((~mask >> 24) & 0xFF); // ~ c est le NON binaire
        broadcast[1] = ip_reseau[1] | ((~mask >> 16) & 0xFF); // | est le OU binaire
        broadcast[2] = ip_reseau[2] | ((~mask >> 8) & 0xFF);
        broadcast[3] = ip_reseau[3] | (~mask & 0xFF);



        printf("Masque : /%d\nMasque decimal : %d.%d.%d.%d\nNombre d'hotes : %d\nNombre d'adresses : %d\nIP reseau : %d.%d.%d.%d\nIP broadcast : %d.%d.%d.%d\n\n\n", mask_int, (mask >> 24) & 0xFF, (mask >> 16) & 0xFF, (mask >> 8) & 0xFF, mask & 0xFF, nb_hotes, nb_adresses, ip_reseau[0], ip_reseau[1], ip_reseau[2], ip_reseau[3], broadcast[0], broadcast[1], broadcast[2], broadcast[3]);

        /*
        // permet d'empecher la fermeture automatique de la fenetre quand on l ouvre depuis windows 
        // le while est obligatoire car un scanf laisse un \n et le getchar va le lire  
        int c;
        while ((c = getchar()) != '\n' && c != EOF);  // vide le buffer
        printf("Appuyez sur la touche Entree pour quitter...\n");
        getchar();  // attend que l'utilisateur appuie sur Entree
        */
        }

    return 0;
    

}