Benvenuti nel sito Fortech Embedded Labs

Modificare l'indirizzo IP di un device

Un problema che si presenta spesso lavorando con dispositivi connessi in rete è quello di impostare l'indirizzo IP del nostro device.
Alcune reti utilizzano indirizzi IP statici, altre assegnano gli indirizzi tramite un server DHCP.
L'indirizzo IP può essere configurato inserendo nel registry alcune chiavi.
Questa soluzione può essere pratica per dispositivi che verranno sempre usati in reti con DHCP oppure per dispositivi che gestiranno connessioni punto a punto con un cavo di rete e possono usare sempre lo stesso indirizzo IP.
Per dispositivi che devono poter funzionare all'interno di reti differenti è indispensabile poter modificare la configurazione TCP/IP dinamicamente.
Windows CE mette a disposizione componenti del pannello di controllo pensati per questo scopo. Non sempre, però, il pannello di controllo è accessibile.
Per modificare le impostazioni relative all'indirizzo IP è necessario configurare le chiavi di registro e poi chiedere al driver del dispositivo di rete per cui si è effettuata la modifica di ricaricare la configurazione. Una volta completata l'operazione, il nostro device utilizzerà le nuove impostazioni, senza bisogno di resettarlo o fermare i servizi.
Il programma di esempio qui riportato consente, da linea di comando, di modificare le impostazioni TCP/IP di uno dei device di rete.
Richiamandolo con '*' come unico parametro sulla command-line imposterà il funzionamento tramite DHCP. Passando invece un indirizzo IP nella notazione XXX.XXX.XXX.XXX e, opzionalmente, un gateway e un DNS nello stesso formato, configurerà staticamente i parametri TCP/IP del device.
Ovviamente le funzioni di questo semplice esempio possono essere incorporate nella vostra applicazione senza bisogno di richiamare un tool esterno.
Se il vostro dispositivo non memorizza il registry in modo permanente, sarà necessario ripetere l'inizializzazione dei parametri TCP/IP ad ogni restart del device.
Per compilare il codice è necessario che il vostro SDK includa il supporto per TCP/IP, ndis e Windows Sockets e aggiungere la libreria ws2.lib tra quelle referenziate dai parametri del linker.

Scarica il sorgente dell'esempio

ciao a tutti, sulla falsa

ciao a tutti,

sulla falsa riga di ciò che stato pubblicato vi lascio questa DLL:

Utilizzo i metodi via PInvoke per rinominare le macchine CE e/o cambiare indirizzo e subnet mask. Invece di salvare i dati nel registro di configurazione essi sono a livello di parametrizzazione applicazione, caricati ad ogni avviamento, salvati ad ogni variazione.
Perchè le modifiche abbiano effetto bisogna riavviare il dispositivo (parlo della mia applicazione)

ciao
//header DLL
#ifdef CBETHUTLS_EXPORTS
#define CBETHUTLS_API __declspec(dllexport)
#else
#define CBETHUTLS_API __declspec(dllimport)
#endif

extern "C"
{
CBETHUTLS_API UINT getConvIpAddress(char *);
CBETHUTLS_API DWORD getNetInf(char *, char *, char *);
CBETHUTLS_API DWORD RenewHostName (char *);
CBETHUTLS_API DWORD RenewIpAddress00 (char *, char *);
}

//cpp DLL

#include "stdafx.h"
#include "CBETHUTLS.h"
#include
#include
#include "iprtrmib.h"
#include "iphlpapi.h"
#include "winsock2.h"

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2.lib")

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

CBETHUTLS_API UINT getConvIpAddress(char * value)
{
return inet_addr(value);
}

CBETHUTLS_API DWORD getNetInf(char *retHostName,
char *retIpAddress,
char *retIpMask)
{
int i;
ULONG ulOutBufLen;
DWORD dwRetVal;

FIXED_INFO *pFixedInfo;
IP_ADAPTER_INFO *pAdapterInfo;
IP_ADAPTER_INFO *pAdapter;

//Make a fake call to get the length of the buffer
ulOutBufLen = 0;
GetNetworkParams( NULL, &ulOutBufLen );

//Now that we have the necessary size, allocate the memory
pFixedInfo = (FIXED_INFO *) malloc( ulOutBufLen );

dwRetVal = GetNetworkParams( pFixedInfo, &ulOutBufLen );
if (dwRetVal != NO_ERROR )
{
return dwRetVal;
}

for(i = 0; i HostName[i];
free(pFixedInfo);

//Make a fake call to GetAdaptersInfo to get the size of the buffer
ulOutBufLen = 0;
GetAdaptersInfo( NULL, &ulOutBufLen) ;

//Now that we know the necessary buffer size, allocate the memory
pAdapterInfo = (IP_ADAPTER_INFO *) malloc( ulOutBufLen );

dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen);
if (dwRetVal != ERROR_SUCCESS)
{
free (pAdapterInfo);
return dwRetVal;
}

//Loop through the adapters and print info on each one.
pAdapter = pAdapterInfo;

for(i = 0; i IpAddressList.IpAddress.String[i];
*(retIpMask+i) = pAdapter->IpAddressList.IpMask.String[i];
}

//Free the memory we used.
if (pAdapterInfo)
free(pAdapterInfo);

return 0;
}

CBETHUTLS_API DWORD RenewIpAddress00 (char * newIpVal, char * newIpMaskVal)
{
ULONG ulOutBufLen;
DWORD dwRetVal;
UINT iaIPAddress;
UINT imIPMask;
ULONG NTEContext = 0;
ULONG NTEInstance = 0;
MIB_IPADDRTABLE *pIPAddrTable;
IP_INTERFACE_INFO* pInfo;

//Make a fake call to GetInterfaceInfo to get the size of the buffer
ulOutBufLen = 0;
GetInterfaceInfo(NULL, &ulOutBufLen);

//Now that we have the necessary size, allocate the memory and make a real call.
pInfo = (IP_INTERFACE_INFO *) malloc(ulOutBufLen);
dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen);

if ( dwRetVal == ERROR_SUCCESS )
{
/* THIS WORKS BUT IT TAKES A LONG TIME AND INTERRUPTS NET CONNECTIONS*/
if ((dwRetVal = IpReleaseAddress(&pInfo->Adapter[0])) == NO_ERROR)
{

//Make a fake call to GetAdaptersInfo to get the size of the buffer
ulOutBufLen = 0;
GetIpAddrTable(NULL, &ulOutBufLen, FALSE);

//Now that we have the necessary size, allocate the memory and make a real call.
pIPAddrTable = (MIB_IPADDRTABLE *) malloc(ulOutBufLen);
dwRetVal = GetIpAddrTable(pIPAddrTable, &ulOutBufLen, FALSE);

if ( dwRetVal != NO_ERROR )
{
free ( pIPAddrTable );
free ( pInfo);
return dwRetVal;
}

//Utilizziamo per default l'indice di tabella 0 che fa riferimento al solo disp. di rete installato
if((iaIPAddress = inet_addr(newIpVal)) == INADDR_NONE)
return (DWORD) INADDR_NONE;

if((imIPMask = inet_addr(newIpMaskVal)) == INADDR_NONE)
return (DWORD) INADDR_NONE;

dwRetVal = AddIPAddress (
iaIPAddress,
imIPMask,
pIPAddrTable->table[0].
dwIndex,
&NTEContext,
&NTEInstance
);

if ( dwRetVal != NO_ERROR)
{
free ( pIPAddrTable );
free ( pInfo);
return dwRetVal;
}
free ( pIPAddrTable );
free ( pInfo);
return 0;
}
}
}

CBETHUTLS_API DWORD RenewIpAddress01 (UINT ipAddress, UINT ipMask)
{
ULONG ulOutBufLen;
DWORD dwRetVal;
ULONG NTEContext = 0;
ULONG NTEInstance = 0;
MIB_IPADDRTABLE *pIPAddrTable;
IP_INTERFACE_INFO* pInfo;

//Make a fake call to GetInterfaceInfo to get the size of the buffer
ulOutBufLen = 0;
GetInterfaceInfo(NULL, &ulOutBufLen);

//Now that we have the necessary size, allocate the memory and make a real call.
pInfo = (IP_INTERFACE_INFO *) malloc(ulOutBufLen);
dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen);

if ( dwRetVal != NO_ERROR )
{
/* THIS WORKS BUT IT TAKES A LONG TIME AND INTERRUPTS NET CONNECTIONS*/
if ((dwRetVal = IpReleaseAddress(&pInfo->Adapter[0])) == NO_ERROR)
{
//Make a fake call to GetAdaptersInfo to get the size of the buffer
ulOutBufLen = 0;
GetIpAddrTable(NULL, &ulOutBufLen, FALSE);

//Now that we have the necessary size, allocate the memory and make a real call.
pIPAddrTable = (MIB_IPADDRTABLE *) malloc(ulOutBufLen);
dwRetVal = GetIpAddrTable(pIPAddrTable, &ulOutBufLen, FALSE);

if ( dwRetVal != NO_ERROR )
{
//Utilizziamo per default l'indice di tabella 0 che fa riferimento al solo disp. di rete installato
dwRetVal = AddIPAddress (
ipAddress,
ipMask,
pIPAddrTable->table[0].
dwIndex,
&NTEContext,
&NTEInstance
);

if ( dwRetVal != NO_ERROR)
{
return dwRetVal;
}
}
free (pInfo);
free ( pIPAddrTable );
return dwRetVal;
}
}
free(pInfo);
return 0;
}
// Rinomina dell'hostname
CBETHUTLS_API DWORD RenewHostName (char * newVal)
{
int size = 0;

while(true)
{
if(*(newVal+size)== '\0')
break;
size++;
}
if(sethostname(newVal, size+1)!= 0)
{
return WSAGetLastError();
}
return 0;
}

Grazie mille fabbrit. Hai

Grazie mille fabbrit. Hai colto perfettamente lo spirito di queste pagine, chiunque voglia contribuire con idee e suggerimenti è bene accetto.
Ovviamente sono benvenute le critiche e i suggerimenti utili a migliorare gli esempi che mano a mano pubblicheremo in questo spazio.

News

12/03/2010
Corso "Building Solutions with Windows Embedded CE 6.0 R3" dal 12 al 16 Aprile
Building Solutions with Windows® Embedded CE 6.0 Corso Microsoft MSDN-2542 con materiale ...
09/11/2009
Corso "Building Solutions with Windows® Embedded CE 6.0" dal 30 Novembre al 4 Dicembre
Building Solutions with Windows® Embedded CE 6.0 Corso Microsoft MSDN-2542 Il corso si ...
18/02/2009
Fortech Embedded Labs diventa Windows Embedded Silver Partner
L'impegno nel settore embedded e la competenza di Fortech Embedded Labs relativamente ...
12/02/2009
Corso "Building Solutions Using Windows Embedded CE 6.0 R2" (MSDN-2542)
Descrizione Dal 4 all'8 Maggio 2008 si svolgerà, presso la sede Fortech ...
12/02/2009
Windows Embedded Seminars
Fortech Embedded Labs partecipa al seminario Windows Embedded che si terrà ...