< Change IP & IPConfig Examples | IP Helper Functions Main | DHCP Renew & Release >
What do we have in this chapter 13 part 6?
|
IPConfig for IPv6 Example
Create a new empty Win32 console mode application and add the project/solution name.
Add the following source code. |
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1996 - 2001 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*
Module Name: Ipconfigv6examplesrc.cpp
Abstract:
This module illustrates how to programmatically retrieve IPv6 configuration
information similar to the IPV6.EXE or NETSH.EXE commands. It demonstrates
how to use the IP Helper APIs GetNetworkParams() and GetAdaptersAddresses().
Original author: Anthony Jones
Revision History:
*/
// Link to ws2_32.lib
#include <winsock2.h>
// Link to Iphlpapi.lib
#include <iphlpapi.h>
#include <iptypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
// String constants for IP_PREFIX_ORIGIN enumerated type
const char *PrefixOriginStr[] =
{
"Other",
"Manual",
"Well Known",
"DHCP",
"Router Advertisement",
"6to4"
};
// String constants for IP_SUFFIX_ORIGIN enumerated type
const char *SuffixOriginStr[] =
{
"Other",
"Manual",
"Well Known",
"DHCP",
"Link Layer Address",
"Random"
};
// String constants for IP_DAD_STATE enumerated type
const char *DadStateStr[] =
{
"Invalid",
"Tentative",
"Duplicate",
"Deprecated",
"Preferred"
};
// String constants for IF_OPER_STATUS enumerated type
const char *OperStatusStr[] =
{
"Invalid",
"Up", // IfOperStatusUp
"Down", // IfOperStatusDown
"Testing", // IfOperStatusTesting
"Unknown", // IfOperStatusUnknown
"Dormant", // IfOperStatusDormant
"Not Present", // IfOperStatusNotPresent
"Lower Layer Down" // IfOperStatusLowerLayerDown
};
// Function: usage
// Description: Prints usage information and exits.
int usage(char *progname)
{
fprintf(stderr, "Usage: %s [-4] [-6]\n", progname);
fprintf(stderr, " -4 Query AF_INET only\n"
" -6 Query AF_INET6 only\n"
" -su Skip unicast addresses\n"
" -sa Skip anycast addresses\n"
" -sm Skip multicast addresses\n"
);
return 0;
}
// Function: FormatPhysicalAddress
// Description:
// Takes a BYTE array and converts each byte into two hexadecimal
// digits followed by a dash (-). The converted data is placed
// into the supplied string buffer.
void FormatPhysicalAddress(BYTE *addr, int addrlen, char *buf, int buflen)
{
char *ptr=NULL;
int i, idx=0;
ptr = buf;
if (addrlen == 0)
{
strcpy_s(ptr, 6, "NONE");
}
else
{
for(i=0; i < addrlen ;i++)
{
// Take each byte and convert to a hex digit
_itoa_s( addr[i] >> 4, ptr, sizeof(ptr), 16);
ptr++;
_itoa_s( addr[i] & 0x0F, ptr, sizeof(ptr), 16);
ptr++;
// Add the dash if we're not at the end
if (i+1 < addrlen)
{
*ptr = '-';
ptr++;
}
}
*ptr = '\0';
}
}
// Function: FormatAdapterType
// Description:
// This function takes the adapter type which is a simple integer
// and returns the string representation for that type. Since there
// are many adapter types we just worry about the most common ones.
// The whole list of adapter types is defined in IPIfCons.h.
void FormatAdapterType(int type, char *buf, int buflen)
{
switch (type)
{
// Make sure the destination buffer is big enough!
// alternatively, we just _TRUNCATE the source
// ...or it is a bug?
case MIB_IF_TYPE_OTHER:
strncpy_s(buf, _countof(buf), "Other", buflen);
break;
case MIB_IF_TYPE_ETHERNET:
strncpy_s(buf, _countof(buf), "Ethernet", _TRUNCATE);
break;
case MIB_IF_TYPE_TOKENRING:
strncpy_s(buf, _countof(buf), "Token Ring", buflen);
break;
case MIB_IF_TYPE_FDDI:
strncpy_s(buf, _countof(buf), "FDDI", buflen);
break;
case MIB_IF_TYPE_PPP:
strncpy_s(buf, _countof(buf), "PPP", buflen);
break;
case MIB_IF_TYPE_LOOPBACK:
strncpy_s(buf, _countof(buf), "Loopback", _TRUNCATE);
break;
case MIB_IF_TYPE_SLIP:
strncpy_s(buf, _countof(buf), "SLIP", buflen);
break;
default:
// + 64 is weird here...*^^$(^%)...arghhhhhhh!!!
sprintf_s(buf+64, _countof(buf)+64, "Other Type %d", type);
break;
}
}
// Function: main
// Description:
// Parse the command line parameters and then obtain the adapter
// information via the GetAdaptersAddresses function. Print the
// returned structures to stdout.
int main(int argc, char **argv)
{
PFIXED_INFO pFixedInfo;
DWORD FixedInfoSize = 0;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
DWORD AdapterAddrsSize;
PIP_ADDR_STRING pAddrStr;
PIP_ADAPTER_UNICAST_ADDRESS pUnicastAddress;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycastAddress;
PIP_ADAPTER_MULTICAST_ADDRESS pMulticastAddress;
WSADATA wsd;
DWORD Err, Flags=0;
int af, i;
char szAddress[128];
DWORD dwAddressLen=128;
char buf[3000];
int buflen=3000;
BOOL bIndent;
if(argc < 2)
{
usage(argv[0]);
exit(1);
}
// Load Winsock for the string conversion utilities
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("Unable to load winsock!\n");
return -1;
}
else
printf("WSAStartup() is OK!\n");
// Initialize the variables
af = AF_UNSPEC;
Flags = 0;
// Parse the command line
for(i=1; i < argc ;i++)
{
if (strlen(argv[i]) < 2)
usage(argv[0]);
if (argv[i][0] == '-' || argv[i][0] == '/')
{
switch (tolower(argv[i][1]))
{
case '4':
af = AF_INET;
break;
case '6':
af = AF_INET6;
break;
case 's':
switch (tolower(argv[i][2]))
{
case 'u':
Flags |= GAA_FLAG_SKIP_UNICAST;
break;
case 'a':
Flags |= GAA_FLAG_SKIP_ANYCAST;
break;
case 'm':
Flags |= GAA_FLAG_SKIP_MULTICAST;
break;
default:
usage(argv[0]);
break;
}
break;
default:
usage(argv[0]);
break;
}
}
}
// Get the main IP configuration information for this machine using a FIXED_INFO structure
if ((Err = GetNetworkParams(NULL, &FixedInfoSize)) != 0)
{
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER))
{
printf("GetNetworkParams() sizing failed with error %d\n", Err);
return -1;
}
}
else
printf("GetNetworkParams() should be fine!\n");
// Allocate memory from sizing information
if ((pFixedInfo = (PFIXED_INFO) GlobalAlloc(GPTR, FixedInfoSize)) == NULL)
{
printf("Memory allocation error!\n");
return -1;
}
else
printf("GlobalAlloc() looks fine!\n");
// Print the fixed network parameters
if ((Err = GetNetworkParams(pFixedInfo, &FixedInfoSize)) == 0)
{
printf("GetNetworkParams() is OK!\n");
printf("\tHost Name . . . . . . . . . : %s\n", pFixedInfo->HostName);
printf("\tDomain Name . . . . . . . . : %s\n", pFixedInfo->DomainName);
printf("\tDNS Servers . . . . . . . . : %s\n", pFixedInfo->DnsServerList.IpAddress.String);
pAddrStr = pFixedInfo->DnsServerList.Next;
while(pAddrStr)
{
printf(" %-15s\n", pAddrStr->IpAddress.String);
pAddrStr = pAddrStr->Next;
}
printf("\tNode Type . . . . . . . . . : ");
switch (pFixedInfo->NodeType)
{
case 1:
printf("%s\n", "Broadcast");
break;
case 2:
printf("%s\n", "Peer to peer");
break;
case 4:
printf("%s\n", "Mixed");
break;
case 8:
printf("%s\n", "Hybrid");
break;
default:
printf("\n");
}
printf("\tNetBIOS Scope ID. . . . . . : %s\n", pFixedInfo->ScopeId);
printf("\tIP Routing Enabled. . . . . : %s\n", (pFixedInfo->EnableRouting ? "yes" : "no"));
printf("\tWINS Proxy Enabled. . . . . : %s\n", (pFixedInfo->EnableProxy ? "yes" : "no"));
printf("\tNetBIOS Resolution Uses DNS : %s\n", (pFixedInfo->EnableDns ? "yes" : "no"));
}
else
{
printf("GetNetworkParams() failed with error code %d\n", Err);
return -1;
}
// Enumerate all of the adapter specific information using the
// IP_ADAPTER_ADDRESSES structure.
// Note: IP_ADAPTER_INFO contains a linked list of adapter entries.
AdapterAddrsSize = 0;
if ((Err = GetAdaptersAddresses(af, Flags, NULL, NULL, &AdapterAddrsSize)) != 0)
{
if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER))
{
printf("GetAdaptersAddresses() sizing failed with error code %d\n", Err);
printf("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
return -1;
}
}
else
printf("GetAdaptersAddresses() should be OK!\n");
// Allocate memory from sizing information
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL)
{
printf("Memory allocation error!\n");
return -1;
}
else
printf("GlobalAlloc() for PIP_ADAPTER_ADDRESSES is OK!\n");
// Get actual adapter information
if ((Err = GetAdaptersAddresses(af, Flags, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS)
{
printf("GetAdaptersAddresses() failed with error code %d\n", Err);
return -1;
}
else
printf("GetAdaptersAddresses() is OK!\n");
// Enumerate through each returned adapter and print its information
pAdapt = pAdapterAddrs;
while (pAdapt)
{
printf("\n");
printf("\tDescription : %S\n", pAdapt->Description);
printf("\t Adapter Name : %s\n", pAdapt->AdapterName);
printf("\t DNS Suffix : %S\n", pAdapt->DnsSuffix);
printf("\t Friendly Name: %S\n", pAdapt->FriendlyName);
FormatPhysicalAddress(pAdapt->PhysicalAddress, pAdapt->PhysicalAddressLength, buf, buflen);
printf("\t Physical Addr: %s\n", buf);
printf("\t MTU . . . . . . . . . . : %d\n", pAdapt->Mtu);
FormatAdapterType(pAdapt->IfType, buf, buflen);
printf("\t Interface Type . . . . : %s\n", buf);
printf("\t Interface Index: . . . : %d\n", pAdapt->IfIndex);
printf("\t Flags: . . . . . . . . : ");
bIndent = FALSE;
if (pAdapt->Flags & IP_ADAPTER_DDNS_ENABLED)
{
printf("DDNS Enabled...\n");
bIndent = TRUE;
}
if (pAdapt->Flags & IP_ADAPTER_REGISTER_ADAPTER_SUFFIX)
{
if (bIndent == TRUE)
printf("\t ");
printf("Register DNS Adapter Suffix...\n");
bIndent = TRUE;
}
if (pAdapt->Flags & IP_ADAPTER_DHCP_ENABLED)
{
if (bIndent == TRUE)
printf("\t ");
printf("DHCP Enabled...\n");
bIndent = TRUE;
}
pUnicastAddress = pAdapt->FirstUnicastAddress;
if (pUnicastAddress)
printf("\n\t UNICAST ADDRESS(ES):\n");
while (pUnicastAddress)
{
printf("\t Flags: . . . . . . . . : ");
if (pUnicastAddress->Flags == 0)
printf("None");
if ((pUnicastAddress->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE) == IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)
printf("DNS_ELIGIBLE ");
if ((pUnicastAddress->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) == IP_ADAPTER_ADDRESS_TRANSIENT)
printf("TRANSIENT");
printf("\n");
dwAddressLen = 128;
memset(szAddress, 0, 128);
if (WSAAddressToStringA(
pUnicastAddress->Address.lpSockaddr,
pUnicastAddress->Address.iSockaddrLength,
NULL,
szAddress,
&dwAddressLen) == SOCKET_ERROR)
{
printf("WSAAddressToString() failed with error code %d\n", WSAGetLastError());
}
else
printf("WSAAddressToString() should be OK!\n");
printf("\t Address: . . . . . . . : %s\n", szAddress);
printf("\t Valid Lifetime . . . . : %lu\n", pUnicastAddress->ValidLifetime);
printf("\t Preferred Lifetime: . . : %lu\n", pUnicastAddress->PreferredLifetime);
printf("\t Lease Lifetime: . . . . : %lu\n", pUnicastAddress->LeaseLifetime);
printf("\t Prefix Origin: . . . . : %s\n", PrefixOriginStr[pUnicastAddress->PrefixOrigin]);
printf("\t Suffix Origin: . . . . : %s\n", SuffixOriginStr[pUnicastAddress->SuffixOrigin]);
printf("\t Dad State: . . . . . . : %s\n", DadStateStr[pUnicastAddress->DadState]);
pUnicastAddress = pUnicastAddress->Next;
printf("\n");
}
// Print anycast addresses
pAnycastAddress = pAdapt->FirstAnycastAddress;
if (pAnycastAddress)
printf("\t ANYCAST ADDRESS(ES):\n");
while (pAnycastAddress)
{
dwAddressLen = 128;
memset(szAddress, 0, 128);
if (WSAAddressToStringA(
pAnycastAddress->Address.lpSockaddr,
pAnycastAddress->Address.iSockaddrLength,
NULL,
szAddress,
&dwAddressLen) == SOCKET_ERROR)
{
printf("WSAAddressToString() failed with error code %d\n", WSAGetLastError());
}
else
printf("WSAAddressToString() should be fine!\n");
printf("\t Address: . . . . . . . : %s\n", szAddress);
printf("\t Flags: . . . . . . . . : "); //lu\n", pAnycastAddress->Flags);
if (pAnycastAddress->Flags == 0)
printf("None");
else if ((pAnycastAddress->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE) == IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)
printf("DNS_ELIGIBLE ");
else if ((pAnycastAddress->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) == IP_ADAPTER_ADDRESS_TRANSIENT)
printf("TRANSIENT");
printf("\n");
pAnycastAddress = pAnycastAddress->Next;
}
// Print multicast addresses
pMulticastAddress = pAdapt->FirstMulticastAddress;
if (pMulticastAddress)
printf("\t MULTICAST ADDRESS(ES):\n", pAdapt->FirstMulticastAddress);
while (pMulticastAddress)
{
dwAddressLen = 128;
memset(szAddress, 0, 128);
if (WSAAddressToStringA(
pMulticastAddress->Address.lpSockaddr,
pMulticastAddress->Address.iSockaddrLength,
NULL,
szAddress,
&dwAddressLen) == SOCKET_ERROR)
{
printf("WSAAddressToString() failed with error code %d\n", WSAGetLastError());
}
else
printf("WSAAddressToString() should be OK!\n");
printf("\t Address: . . . . . . . : %s\n", szAddress);
printf("\t Flags: . . . . . . . . : ");
if (pMulticastAddress->Flags == 0)
printf("None");
else if ((pMulticastAddress->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE) == IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)
printf("DNS_ELIGIBLE ");
else if ((pMulticastAddress->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) == IP_ADAPTER_ADDRESS_TRANSIENT)
printf("TRANSIENT");
printf("\n");
pMulticastAddress = pMulticastAddress->Next;
}
pAdapt = pAdapt->Next;
}
if(WSACleanup() == 0)
printf("WSACleanup() is OK!\n");
else
printf("WSACleanup() failed with error code %d\n", WSAGetLastError());
return 0;
}
Build and run the project.
-------------------------------------------------
The following screenshot shows the Windows Ipv6 utility.
< Change IP & IPConfig Examples | IP Helper Functions Main | DHCP Renew & Release >