EDN Admin
Well-known member
Im developing a PC application at work that must talk ethernet to an embedded system that has static IP 192.168.0.214. This embedded system expects my host PC to have static IP 192.168.0.215. My PC application must:<br/> <br/> 1. Change from DHCP to static IP 192.168.0.215 when the program first starts up.<br/> 2. Communicate via ethernet to the embedded system (send and receive miscellaneous messages).<br/> 3. Change back to DHCP when the program ends.<br/> <br/> I have some closely related code that I borrowed from another project. This code has functions to get the PC IP address, add another IP address to the network adapters IP list, and send/receive ethernet messages. And these functions work very well. So, I guess the only thing I need is to develop a function that will change the PC back and forth between DHCP and static IP.<br/> <br/> I do not want to use netsh, or any other such utility. I want to do this programatically.<br/> <br/> Im using Microsoft Visual Studio 2005 Professional Edition. My host PC is running Windows XP (with Service Pack 2). It has a single network adapter named "Local Area Connection".<br/> <br/> At the expense of being very verbose, Ive included the source code Ive borrowed from another project (it appears below), in case this will help you help me. There are 3 functions:<br/> <br/> 1. ethernetIfGetMyIPAddress (gets the IP address of the current PC).<br/> 2. ethernetIfAddIpToPC (adds an IP address to the network adapters IP list).<br/> 3. ethernetIfCleanUp (deletes the IP address that was added).<br/> <br/> Thanks in advance.<br/> <br/> <br/> DCA_API int ethernetIfGetMyIPAddress(int hostIndex, char *theAddr)<br/> {<br/> static hostent *pHostEnt = NULL;<br/> static char szHostName[128] = {NULL};<br/> char tempNo[4];<br/> int j;<br/> unsigned int anOctet;<br/> int rtnStatus = EI_SUCCESS;<br/> <br/> /*<br/> * Initialize the returned IP address to a NULL string.<br/> */<br/> *theAddr = NULL;<br/> <br/> if (WSAStartup (MAKEWORD(2,2), &WSAData) != 0)<br/> rtnStatus = EI_WSAStartup_FAIL;<br/> <br/> /*<br/> * Always update the host entry table. This is required for the simple fact<br/> * that the host computer will be connected/disconnected from the Eternet in<br/> * a dynamic environment. If the host entry table will reflect the current<br/> * state of the IP address. An address of 127.0.0.1 indicates that the host<br/> * PC is not attached and the default loopback IP address is returned.<br/> */<br/> else if (gethostname(szHostName, 128) != 0)<br/> {<br/> rtnStatus = EI_HOSTNAME_UNAVAIL;<br/> }<br/> <br/> else if ((pHostEnt = gethostbyname(szHostName)) == NULL)<br/> {<br/> rtnStatus = EI_HOSTENTRY_UNAVAIL;<br/> }<br/> <br/> /*<br/> * Assuming that only one adapter is attached... the last<br/> * adapter in the list "pHostEnt->h_addr_list" is assumed to be the<br/> * desired adapter utilized for reprogramming.<br/> */<br/> else if ((pHostEnt != NULL) &&<br/> (pHostEnt->h_addr_list[hostIndex] != NULL))<br/> {<br/> for (j=0; j<pHostEnt->h_length; j++)<br/> {<br/> /*<br/> * Build the string defining the IP address of the first<br/> * adapter.<br/> */<br/> if (j>0)<br/> strcat(theAddr,".");<br/> <br/> anOctet = (unsigned int)(unsigned char)<br/> (pHostEnt->h_addr_list[hostIndex][j]);<br/> sprintf(tempNo,<br/> "%i",<br/> anOctet);<br/> strcat(theAddr, tempNo);<br/> }<br/> <br/> if (debugMode)<br/> printf("ethernetIfGetMyIPAddress reported IP of %srn",<br/> theAddr);<br/> }<br/> <br/> /*<br/> * Return a string with nothing in it to indicate the selected adapter<br/> * index does not exist.<br/> */<br/> else<br/> {<br/> rtnStatus = EI_HOSTENTRY_NOT_FOUND;<br/> }<br/> <br/> reportStatus("ethernetIfGetMyIPAddress",rtnStatus);<br/> <br/> return rtnStatus;<br/> <br/> } /* ethernetIfGetMyIPAddress */<br/> <br/> DCA_API int ethernetIfAddIpToPC(char *szPCIP)<br/> {<br/> // IP and mask we will be adding<br/> UINT iaIPAddress;<br/> UINT imIPMask;<br/> <br/> int rtnStatus = EI_SUCCESS;<br/> DWORD index;<br/> DWORD dwRetVal;<br/> DWORD dwSize = 0;<br/> <br/> // if (initComplete != TRUE)<br/> //{<br/> // rtnStatus = EI_INITERROR;<br/> // reportStatus("ethernetIfAddIpToPC",rtnStatus);<br/> // return rtnStatus;<br/> //}<br/> <br/> // Before calling AddIPAddress we use GetIpAddrTable to get<br/> // an adapter to which we can add the IP.<br/> PMIB_IPADDRTABLE pIPAddrTable;<br/> <br/> // Format the IP address from a character string to an IP address value.<br/> iaIPAddress = inet_addr(szPCIP);<br/> imIPMask = inet_addr("255.255.255.0"); // Always<br/> <br/> pIPAddrTable = (MIB_IPADDRTABLE*) malloc(sizeof(MIB_IPADDRTABLE));<br/> <br/> // Make an initial call to GetIpAddrTable to get the<br/> // necessary size into the dwSize variable<br/> if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)<br/> {<br/> free( pIPAddrTable );<br/> pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize );<br/> }<br/> <br/> // Make a second call to GetIpAddrTable to get the<br/> // actual data we want and check for a duplicate IP address.<br/> if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) == NO_ERROR )<br/> {<br/> for (index=0;index<pIPAddrTable->dwNumEntries;index++)<br/> {<br/> if (pIPAddrTable->table[index].dwAddr == iaIPAddress)<br/> rtnStatus = EI_DUPIP;<br/> }<br/> }<br/> <br/> else if (dwRetVal == ERROR_INVALID_PARAMETER)<br/> rtnStatus = EI_INVALIDPARAMETER;<br/> <br/> else if (dwRetVal == ERROR_NOT_SUPPORTED)<br/> rtnStatus = EI_UNSUPPRTEDOS;<br/> <br/> else<br/> {<br/> LPVOID lpMsgBuf;<br/> <br/> if (debugMode)<br/> printf("Error getting IP address, error = %d (0x%08X).n",<br/> dwRetVal,dwRetVal);<br/> <br/> if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |<br/> FORMAT_MESSAGE_FROM_SYSTEM |<br/> FORMAT_MESSAGE_IGNORE_INSERTS,<br/> NULL,<br/> dwRetVal,<br/> MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language<br/> (LPTSTR) &lpMsgBuf,<br/> 0,<br/> NULL ))<br/> {<br/> if (debugMode)<br/> printf("tError: %s", lpMsgBuf);<br/> }<br/> <br/> else<br/> {<br/> if (debugMode)<br/> printf("FormatMessage1 returned an error of %drn",<br/> GetLastError());<br/> }<br/> <br/> rtnStatus = EI_FAIL;<br/> }<br/> <br/> // Check for an unhadled error<br/> if (rtnStatus != EI_SUCCESS)<br/> {<br/> free(pIPAddrTable);<br/> reportStatus("ethernetIfAddIpToPC",rtnStatus);<br/> return rtnStatus;<br/> }<br/> <br/> if ( (dwRetVal = AddIPAddress(iaIPAddress,<br/> imIPMask,<br/> pIPAddrTable->table[0].dwIndex,<br/> &NTEContext,<br/> &NTEInstance) ) == NO_ERROR)<br/> {<br/> if (debugMode)<br/> printf("IP address added.n");<br/> }<br/> <br/> // Not sure what this error code is but appears to work fine.<br/> // Thought it might be that the IP address already exists, no harm done.<br/> else if (dwRetVal == 0xC000022A)<br/> {<br/> if (debugMode)<br/> printf("*** IP address already exists at %s, continuing ***n",<br/> szPCIP);<br/> }<br/> <br/> // Check for known errors as defined by the the documentation.<br/> else if (dwRetVal == ERROR_DEV_NOT_EXIST)<br/> rtnStatus = EI_INVALIDADAPTER;<br/> <br/> else if (dwRetVal == ERROR_DUP_DOMAINNAME)<br/> rtnStatus = EI_DUPDOMAIN;<br/> <br/> else if (dwRetVal == ERROR_INVALID_HANDLE)<br/> rtnStatus = EI_NOADMINPRIV;<br/> <br/> else if (dwRetVal == ERROR_INVALID_PARAMETER)<br/> rtnStatus = EI_INVALIDPARAMETER;<br/> <br/> else if (dwRetVal == ERROR_NOT_SUPPORTED)<br/> rtnStatus = EI_UNSUPPRTEDOS;<br/> <br/> // If any other error occurs, then attempt to print a string defining the<br/> // error.<br/> else<br/> {<br/> LPVOID lpMsgBuf;<br/> <br/> if (debugMode)<br/> printf("Error adding IP address, error = %d (0x%08X).n",<br/> dwRetVal,dwRetVal);<br/> <br/> if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |<br/> FORMAT_MESSAGE_FROM_SYSTEM |<br/> FORMAT_MESSAGE_IGNORE_INSERTS,<br/> NULL,<br/> dwRetVal,<br/> 0, //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language<br/> (LPTSTR) &lpMsgBuf,<br/> 0,<br/> NULL ))<br/> {<br/> if (debugMode)<br/> printf("tError: %s", lpMsgBuf);<br/> }<br/> <br/> else<br/> {<br/> if (debugMode)<br/> printf("FormatMessage2 returned an error of %drn",<br/> GetLastError());<br/> }<br/> <br/> rtnStatus = EI_FAIL;<br/> }<br/> <br/> free(pIPAddrTable);<br/> <br/> reportStatus("ethernetIfAddIpToPC",rtnStatus);<br/> <br/> return rtnStatus;<br/> <br/> } /* ethernetIfAddIpToPC */<br/> <br/> DCA_API void ethernetIfCleanUp(void)<br/> {<br/> DWORD dwRetVal;<br/> <br/> // Reset flag denoting that the DCA has not be found. A new search<br/> // is required to "re-acquire" the DCA.<br/> LocalDCAFound = FALSE;<br/> <br/> // Delete the IP we just added using the NTEContext<br/> // variable where the handle was returned<br/> if ((dwRetVal = DeleteIPAddress(NTEContext)) != NO_ERROR)<br/> {<br/> if (debugMode)<br/> printf("tCall to DeleteIPAddress failed with error %d.n",<br/> dwRetVal);<br/> }<br/> <br/> } /* ethernetIfCleanUp */<br/>
View the full article
View the full article