I need to change the IP address and submask of a specific network interface from a C/C program. In Windows documentation, I have found that I should use
Caution: The DeleteIPAddress() function deletes an IP address previously added using AddIPAddress(). If you just only use AddIPAddress() to add an IP address, after that you need to delete it manually.
This picture shows the IP added, and you can delete the added IP by “edit” on the left side.
Here is the code:
#pragma comment (lib, "Ws2_32.lib")
// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#include<IPHlpApi.h>
using namespace std;
#pragma warning(disable:4996)
int main()
{
PIP_ADAPTER_ADDRESSES pAddresses = nullptr;
IP_ADAPTER_DNS_SERVER_ADDRESS* pDnServer = nullptr;
ULONG outBufLen = 0;
DWORD dwRetVal = 10;
char buff[128];
DWORD bufflen = 128;
int i;
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize =128;
UINT iaIPAddress;
UINT imIPMask;
ULONG NTEContext = 0;
ULONG NTEInstance = 0;
LPVOID lpMsgBuf;
pIPAddrTable = (MIB_IPADDRTABLE*)VirtualAlloc(&dwSize, sizeof(PMIB_IPADDRTABLE), MEM_RESERVE, NULL);
pIPAddrTable = (MIB_IPADDRTABLE*)malloc(150 * sizeof(MIB_IPADDRTABLE));
GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if ((dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST, NULL, pAddresses, &outBufLen)) == NO_ERROR) {
while (pAddresses) {
printf("%S, %.2x-%.2x-%.2x-%.2x-%.2x-%.2x: \n",
pAddresses->FriendlyName,
pAddresses->PhysicalAddress[0], pAddresses->PhysicalAddress[1],
pAddresses->PhysicalAddress[2], pAddresses->PhysicalAddress[3],
pAddresses->PhysicalAddress[4], pAddresses->PhysicalAddress[5]);
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress;
pDnServer = pAddresses->FirstDnsServerAddress;
if (pDnServer)
{
sockaddr_in* sa_in = (sockaddr_in*)pDnServer->Address.lpSockaddr;
printf("DNS:%s\n", inet_ntop(AF_INET, &(sa_in->sin_addr), buff, bufflen));
}
if (pAddresses->OperStatus == IfOperStatusUp)
{
printf("Status: active\n");
}
else
{
printf("Status: deactive\n");
}
for (i = 0; pUnicast != NULL; i )
{
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in* sa_in = (sockaddr_in*)pUnicast->Address.lpSockaddr;
printf("IPV4 Unicast Address:%s\n", inet_ntop(AF_INET, &(sa_in->sin_addr), buff, bufflen));
}
else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6)
{
sockaddr_in6* sa_in6 = (sockaddr_in6*)pUnicast->Address.lpSockaddr;
printf("IPV6:%s\n", inet_ntop(AF_INET6, &(sa_in6->sin6_addr), buff, bufflen));
}
else
{
printf("\tUNSPEC");
}
pUnicast = pUnicast->Next;
}
printf("Number of Unicast Addresses: %d\n", i);
pAddresses = pAddresses->Next;
}
}
else {
LPVOID lpMsgBuf;
printf("Call to GetAdaptersAddresses failed.\n");
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL)) {
printf("\tError: %s", lpMsgBuf);
}
}
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
{
GlobalFree(pIPAddrTable);
}
// Make a second call to GetIpAddrTable to get the
// actual data we want
if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) == NO_ERROR) {
printf("\t Address: %d\n", pIPAddrTable->table[0].dwAddr);
printf("\t Mask: %d\n", pIPAddrTable->table[0].dwMask);
printf("\t Index: %d\n", pIPAddrTable->table[0].dwIndex);
printf("\t BCast: %d\n", pIPAddrTable->table[0].dwBCastAddr);
printf("\t Reasm: %d\n", pIPAddrTable->table[0].dwReasmSize);
}
else {
printf("Call to GetIpAddrTable failed.\n");
}
// IP and mask we will be adding
iaIPAddress = inet_addr("192.168.0.27");
imIPMask = inet_addr("255.255.255.0");
if ((dwRetVal = AddIPAddress(iaIPAddress,
imIPMask,
pIPAddrTable->table[0].dwIndex,
&NTEContext, &NTEInstance)) == NO_ERROR)
{
printf("\tIP address added.\n");
}
else {
printf("Error adding IP address.\n");
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL))
{
printf(" Error: %d");
}
LocalFree(lpMsgBuf);
}
if ((dwRetVal = DeleteIPAddress(NTEContext)) == NO_ERROR)
{
printf("\t IP Address Deleted.\n");
}
else {
printf("\t Call to DeleteIPAddress failed.\n");
}
free(pAddresses);
VirtualFree(&dwSize, 0, MEM_RELEASE);
return 0;
}