IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

wake on lan & paquet magic


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Par défaut wake on lan & paquet magic
    Bonjour,
    N'ayant pas touché au C depuis mon bts (qui a déjà quelque années maintenant ) je me remet dans le bain pour tenter de faire un prog de wol.
    Après quelques galères, les réflexes reviennent petit a petit et le script en soi est relativement simple.
    Je me suis inspiré de différents bouts de code trouvés a droite, a gauche sur le net mais je bloque sur la création du paquet magic.

    voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <winsock2.h>
     
    int main(int argc, char *argv[])
    {
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
            fprintf(stderr, "La fonction WSAStartup a echoue.\n");
        else
        {
            /* ... initialisation de la socket ... */
            SOCKET s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     
            if (s == INVALID_SOCKET)
                fprintf(stderr, "La fonction socket a echoue.\n");
            else
            {
                char mac[20];
                char data[102];
                int i, tampon, a, b;
                int errmac = 0;
     
                /* ... récupération de l'adresse mac ... */
                printf("entrer l'adresse mac du pc a demarrer :\n");
                fgets(mac, sizeof mac, stdin);
                char *p = strchr(mac, '\n');
                if(p)
                   *p = 0;
     
                /* ... vérification de l'adresse mac ... */
                if (strlen(mac)!=12) 
                   errmac=1; 
                else 
                {
                     for (i=0;i<(int)strlen(mac);i++) // Boucle parcourrant les caracteres saisis
                     {
                         if ((int)(mac[i])>=97&&(int)(mac[i])<=102) // Convertion des minuscules en majuscules
                         mac[i]=mac[i]-32;
                         if ( ((int)(mac[i])>=48&&(int)(mac[i])<=57)==FALSE ){ // Si ce n'est pas un nombre
                            if ( ((int)(mac[i])>=65&&(int)(mac[i])<=70)==FALSE ) // Si ce n'est pas l'une des 6 premières lettres
                               errmac = 1;
                         }
                     }
                }
     
                if(errmac)
                          fprintf(stderr, "adresse mac non valide.\n");
                else
                {
                    /* ... création du paquet magic ... */
                    for (i=0;i<6;i++)
                         data[i] = 0xff;
     
                    for (i=0;i<12;i=i+2)
                    {
                        a = (int) strtol(&mac[i], NULL, 16);
                        b = (int) strtol(&mac[i+1], NULL, 16);
                        tampon = a*0x10 + b;
                        memcpy(&data[i+6],&tampon,1);
                    }
     
                    for (i=0;i<15;i++) 
                        memcpy(&data[(i+2)*6],&data[6],6);
     
                    /* ... définition du destinataire ... */
                    SOCKADDR_IN dest;
     
                    dest.sin_family       = AF_INET;
                    dest.sin_addr.s_addr  = inet_addr("255.255.255.255"); // adresse de broadcast 
                    dest.sin_port         = htons(7);
                    memset(&dest.sin_zero, '\0', sizeof(dest.sin_zero));
     
                    /* ... envoi du paquet ... */
                    if(sendto(s, data, 102, 0, (SOCKADDR *)&dest, sizeof(dest)) <= 0);
                                 fprintf(stderr, "erreur a l'envoi du paquet.\n");                    
     
                    closesocket(s);
                }
            }
     
            /* ... libération de la dll winsock ... */
            WSACleanup();
        }	
        return 0;
    }
    j'ai l'impression que le problème vient plus précisément de mon appel a strol car quand je debug, les valeurs retourné dans a et b ne correspondent a rien d'identifiable et surtout pas a l'adresse mac rentré a la base.
    Donc si quelqu'un a des expliquation a me donner (voir une solution ), je suis preneur.

    2e chose :
    Je ne suis peut-être pas dans la bonne section mais sa m'évitera un 2e post.
    Existe-t-il un moyen de récupérer l'adresse mac d'un pc du réseau a partir du nom netbios (via wins ou dhcp ou autre) sans que celui-ci soit allumé bien entendu?

    PS: comme précisé plus haut, cela fait longtemps que je n'ai pas codé en c même si l'analogie avec le php (que je connais mieux) est facile, donc n'hésitez pas à me conseiller sur ma façon de coder si je sort des ineptie de codeur amateur dans mon prog.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par kennylafougere Voir le message
    j'ai l'impression que le problème vient plus précisément de mon appel a strol car quand je debug, les valeurs retourné dans a et b ne correspondent a rien d'identifiable et surtout pas a l'adresse mac rentré a la base.
    J'ai l'impression aussi.

    strtol() est une fonction qui transforme une chaine de caractères en nombre. Toi, ce que tu veux faire, c'est transformer un caractère en nombre et ce n'est pas la même chose.

    Il te faut créer une fonction (très simple) et utiliser cette fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int char2int(const char Val)
    {
       if( (Val >= '0') && (Val <= '9') )
          return Val - '0';
     
       if( (Val >= 'a') && (Val <= 'f') )
          return Val - 'a' + 10;
     
       if( (Val >= 'A') && (Val <= 'F') )
          return Val - 'A' + 10;
     
       /* mauvais caractère */
       return -1;
    }
    Autre chose, les valeurs magiques comme 97 ou 102, vaut mieux éviter et mettre 'a' ou 'f', c'est plus facile à lire.

    Citation Envoyé par kennylafougere Voir le message
    Existe-t-il un moyen de récupérer l'adresse mac d'un pc du réseau a partir du nom netbios (via wins ou dhcp ou autre) sans que celui-ci soit allumé bien entendu?
    Pas à ma connaissance
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Par défaut
    effectivement sa a l'air déjà plus cohérent comme sa même si je ne pourrais en être vraiment sûr qu'apres capture de la trame envoyé sur le réseau par contre je me retrouve avec une erreur sur le sendto() et un errno=0

    ps : j'ai pensé a inclure errno.h

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Un point virgule à la fin de la clause if et cela fout en l'air pas mal de choses

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(...) ;
    printf(...)
    Le printf est toujours exécuté car si le test est vrai, c'est le ";" qui est exécuté (c'est à dire rien)


    Au fait, pourquoi un buffer de 102 octets.

    Ton sendto contient une autre valeur magique (102). Ce serait mieux comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(sendto(s, data, sizeof(data), 0, (SOCKADDR *)&dest, sizeof(dest)) <= 0)/* ; pas de ; ici */
    {
       fprintf(stderr, "erreur a l'envoi du paquet (%d).\n", errno);
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Un point virgule à la fin de la clause if et cela fout en l'air pas mal de choses
    effectivement l'erreur de base

    Citation Envoyé par ram-0000 Voir le message
    Au fait, pourquoi un buffer de 102 octets.
    parce que c'est pile la taille de la trame a envoyer (au moins je suis sur de pas envoyer d'octets en trop)

    par contre, correction faite le sendto() est toujours en erreur avec errno = 0

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Par défaut
    bon la je commence vraiment a sécher, perror ne m'affiche pas d'erreur non plus.

    voici un condensé du code qui pause pb :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    /* ... initialisation de la dll winsock ... */
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
            fprintf(stderr, "La fonction WSAStartup a echoue.\n");
        else
        {
            /* ... initialisation de la socket ... */
            SOCKET s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     
            if (s == INVALID_SOCKET)
                fprintf(stderr, "La fonction socket a echoue.\n");
     
             /* ... définition du destinataire ... */
             SOCKADDR_IN dest;
     
             dest.sin_family       = AF_INET;
             dest.sin_addr.s_addr  = inet_addr("255.255.255.255"); 
             dest.sin_port         = htons(7);
             memset(&dest.sin_zero, '\0', sizeof(dest.sin_zero));
     
              /* ... envoi du paquet ... */
              int ret = sendto(s, data, sizeof(data), 0, (SOCKADDR *)&dest, sizeof(dest));
              if(ret < 0)
              {
                    fprintf(stderr,"Error %d in sendto: %s\n",errno,sys_errlist[errno]);
                    perror("sendto");
               }
     
               closesocket(s);
         }
    sortie => Error 0 in sendto: No error
    sendto: No error

    je me dis que ce qui a le plus de chance de générer une erreur est dest mais tout me semble correct.
    De plus le contrôle d'erreur qui ne detect rien est très bizarre

    WTF

Discussions similaires

  1. Wake on Lan avec carte réseau intel pro 1000 PL
    Par christophe_s46 dans le forum Composants
    Réponses: 1
    Dernier message: 31/08/2009, 19h22
  2. Wake On Lan :/
    Par Mikaz dans le forum Apple
    Réponses: 2
    Dernier message: 10/08/2009, 09h54
  3. wake on lan sur du wifi
    Par Mut dans le forum Hardware
    Réponses: 11
    Dernier message: 11/01/2009, 17h49
  4. Fichier BATCH pour exécuter une commande (Wake on LAN)
    Par snoopy69 dans le forum Windows XP
    Réponses: 0
    Dernier message: 23/04/2008, 07h14
  5. Filtrer un Wake-On-LAN
    Par Nixar dans le forum Protocoles
    Réponses: 2
    Dernier message: 24/04/2006, 12h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo