Changer son adresse IP (sans redémarrer et sous XP/Seven)

ledaziarn Messages postés 3 Date d'inscription jeudi 10 décembre 2009 Statut Membre Dernière intervention 9 février 2010 - 4 févr. 2010 à 10:21
Zestyr Messages postés 466 Date d'inscription mercredi 12 août 2009 Statut Membre Dernière intervention 17 octobre 2011 - 9 févr. 2010 à 13:55
Bonjour a tous,


Mon problème parait simple mais je n'aie pas trouvé de réponse, en tout cas pas qui répondent a ma problématique


Pour simplifier les choses, je souhaite avoir une fonction, que j'appelle avec comme paramètres l'interface réseaux(ou l'ancienne IP) et une nouvelle IP Masque de sous réseaux et Gateway. Cette fonction doit m?affecter immédiatement cette IP a cette carte réseaux. Je veux être bloqué durant cette affectation.
Et les points qui me posent problème :
- Je veux changer d'IP et non pas en affecter une supplémentaire
- Je ne veux pas redémarrer
- Cela doit marcher sous XP, Vista et Seven


Pour le langage j'ai posté en C, mais si c'est du C++ je m?arrangerais sans problème .


Je possède sous XP une solution qui me convient :


APP_DWORD ChangeIpAddress(APP_DWORD dwOldIpAddr,APP_DWORD dwNewdIpAddr,APP_DWORD dwSubnetMask,APP_DWORD dwGatway)
{
   APP_DWORD            Error;
   HINSTANCE            HndLib;
   PSETADAPTERIPADDRESS SetAdapterIpAddress;
   APP_CHAR             AdapterGUID[50];


   /*First : find IP AdapterGUID*/
   OS_MEMSET(AdapterGUID,0 , 50);
   GetGuuiInterfaceName(AdapterGUID, dwOldIpAddr);

   Error = ERROR_NOT_SUPPORTED;

   /* Chargement de la DLL */
   HndLib = (HINSTANCE)LoadLibrary(TEXT("iphlpapi.dll"));
   if(HndLib != NULL)
   {
      /* Récupération de l'adresse de la procédure */
      SetAdapterIpAddress = (PSETADAPTERIPADDRESS)GetProcAddress(HndLib,"SetAdapterIpAddress");
      if(SetAdapterIpAddress != NULL)
      {
            /* Appel de la procédure */
            Error = SetAdapterIpAddress(AdapterGUID,0,dwNewdIpAddr,dwSubnetMask,dwGatway);
      }
   }

   return Error;
}




Cette solution a deux problème : elle utilise une fonction non documentée de Windows (ce qui n'est pas beau !) et sous Seven (je n'ai pas essayé sous Vista) elle ajoute une IP au lieu de me la changer, de plus elle n'est pas bloquante .

Les solutions que j'ai commencé à trouver sur le Net :
- La registry : problème cela demande un reboot à priori
- WMI mais ca a l'air un peux compliquer a mettre en place juste pour cela. De plus je voudrais éviter d'avoir à installer un SDK supplémentaire. Et je n'ai trouver aucun exemple simple (tuto tres basique du style: tu click la )
- Appeler netsh : crée un process est attendre qu'il ait finit. Le problème c'est que la je dois devenir administrateur. Or sous Seven cela signifie une boite de dialogue se que je ne veux pas ! (ou alors elle doit n'apparaitre qu'une seul foi pour toute l'application, même âpres des reboot PC).


Juste pour rassurer : non ce n'est pas un virus si je souhaite empêcher la fenêtre de dialogue a chaque démarrage de mon application c'est que celle-ci peut être placée dans le menu démarrer et se trouver sur des pc sans écran.

Désolé ce message st un peut long mais je voulais faire gagner du temps en montrant les piste déjà abordées .


Merci d'avance

5 réponses

Zestyr Messages postés 466 Date d'inscription mercredi 12 août 2009 Statut Membre Dernière intervention 17 octobre 2011
8 févr. 2010 à 22:39
Salut, comme toi je recherche aussi le moyen de pouvoir changer son ip aisément. J'ai regardé ton code et je voudrais savoir à quoi correspondent les types APP_DWORD, APP_CHAR et PSETADAPTERIPADDRESS. Tu pourrais évoquer les include et expliquer à quoi correspondent les arguments ?

Merci et bonne chance
0
ledaziarn Messages postés 3 Date d'inscription jeudi 10 décembre 2009 Statut Membre Dernière intervention 9 février 2010
9 févr. 2010 à 09:46
Salut, avant la solution ci dessus ne marche comme je souhaite que sous xp !

APP_DWORD est un unsigned long
APP_CHAR est un char
PSETADAPTERIPADDRESS est un type windows

popur que cela marche il faut ajouter l'include
#include


SetAdapterIpAddress:

DWORD SetAdapterIpAddress( char *pszAdapGUID,
DWORD dwDHCP,
DWORD dwIP,
DWORD dwMask,
DWORD dwGateway );

A noté que le parametre pszAdapGUID correspond a l'interface de ta carte reseaux


La fonction GetGuuiInterfaceName est une fonction a moi pour retrouver cette interface en focntion d'une IP. (j'utilse GetAdaptersInfo)


Sinon la reponse que j'ai trouvé pour xp et seven est netsh, je ne suis pas super content mais j'ai rien trouvait d'autre


APP_DWORD ChangeIpAddress(APP_LPCHAR lpsInterfaceName,APP_DWORD dwNewdIpAddr,APP_DWORD dwSubnetMask,APP_DWORD dwGatway)
{

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    APP_CHAR szCmdline[2048] = {0};
    APP_CHAR szWindowsCardName[2048] = {0};

    APP_DWORD dwResult = 0;

    struct in_addr ip;
    struct in_addr mask;
    struct in_addr gateway;
    int nbWrite = 0;
    ip.S_un.S_addr = dwNewdIpAddr;
    mask.S_un.S_addr = dwSubnetMask;
    gateway.S_un.S_addr = dwGatway;


    /* 
    Find the adapter name: the one from windows (eg "LOCAL NETOWRK 1") 
    this one can be find from the registry, on XP, VISTA and SEVEN : 
    SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\
    */

    if(1 != getWindowsAdapterName(lpsInterfaceName, szWindowsCardName)){
    
      return OS_NOT_OK;      
    }

    
    nbWrite  = sprintf(szCmdline, "netsh interface ip set address name="%s" static ", szWindowsCardName);
    nbWrite  += sprintf(szCmdline + nbWrite, " %s", inet_ntoa( ip));
    nbWrite  += sprintf(szCmdline + nbWrite, " %s", inet_ntoa( mask));

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW ;
    si.wShowWindow = SW_HIDE;

    ZeroMemory( &pi, sizeof(pi) );

    
    CreateProcess( NULL, 
                  szCmdline, 
                  NULL, 
                  NULL,
                  FALSE, 
                  REALTIME_PRIORITY_CLASS , 
                  NULL, 
                  NULL, 
                  &si, 
                  &pi);


   dwWaitIpChange = (APP_DWORD)(pi.hProcess);

   if(dwWaitIpChange != 0){

     WaitForSingleObject( (HANDLE)dwWaitIpChange, INFINITE );
     GetExitCodeProcess((HANDLE)dwWaitIpChange, &dwResult);

     CloseHandle( (HANDLE)dwWaitIpChange );
     CloseHandle( pi.hThread );

     dwWaitIpChange= 0;

     if(dwResult != 0){

       return OS_NOT_OK;
     }else{
       return OS_OK;
     }
  }
   return OS_NOT_OK;
}



Voila j'espere t'avoir aidé
0
Zestyr Messages postés 466 Date d'inscription mercredi 12 août 2009 Statut Membre Dernière intervention 17 octobre 2011
9 févr. 2010 à 12:17
Tu compile avec quoi ? J'ai tester sous code::blocks en incluant windows.h et les types restent non-déclarés. Merci encore


La conerie est humaine
0
ledaziarn Messages postés 3 Date d'inscription jeudi 10 décembre 2009 Statut Membre Dernière intervention 9 février 2010
9 févr. 2010 à 13:31
Je compile sous visual c++ 6

tu a ajouter :

#include

APP_DWORD et APP_CHAR son des types interne a mon projet, remplace les par "unsigned long" et "char"
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Zestyr Messages postés 466 Date d'inscription mercredi 12 août 2009 Statut Membre Dernière intervention 17 octobre 2011
9 févr. 2010 à 13:55
J'en été sur
Merci, je vais tester ça

La conerie est humaine
0
Rejoignez-nous