< Chap 13: Index | Winsock 2 Main | Netstat: Retrieve TCP, UDP Tables & Protocol Statistics >


 

 

IP Helper Functions 13 Part 1

 

 

What do we have in this chapter 13 part 1?

  1. Ipconfig

  2. Releasing and Renewing IPv4 Addresses

  3. Changing IPv4 Addresses

 

This chapter will introduce you to API functions that allow you to query and manage IP characteristics on your computer. The functions are designed to help you programmatically achieve the functionality that is available in the following standard IP utilities:

 

  1. IPCONFIG.EXE (or WINIPCFG.EXE in Microsoft Windows 95, Windows 98, and Windows Me): Displays IPv4 configuration information and permits you to release and renew DHCP-assigned IPv4 addresses.
  2. IPV6.EXE: A new API has been introduced that enumerates IPv6 addresses similar to the IPV6.EXE or NETSH.EXE commands: This utility will simply be entitled IPCONFIGV6.EXE.
  3. NETSTAT.EXE: Displays the TCP connection table, the UDP listener table, and the IPv4 protocol statistics.
  4. ROUTE.EXE: Displays and manipulates IPv4 routing tables.
  5. ARP.EXE: Displays and modifies the IPv4-to-physical address translation tables that ARP uses.

 

The functions described in this chapter are available mainly in Windows 98, Windows Me, Windows 2000, Windows XP and so on. Several are also available in Windows NT 4.0 Service Pack 4 or later; however, none are available in Windows 95. We will point out platform specifics as we discuss each function. The prototypes for all of the functions described in this chapter are defined in IPHLPAPI.H. In addition, many of the data structures are defined in IPTYPES.H. When you are building your application, you must link it to the library file IPHLPAPI.LIB.

Note that the IP Helper APIs were developed before the availability of IPv6 on the Windows platforms. Therefore, all of the APIs return information about IPv4 only except for a single new IP Helper API GetAdaptersAddresses(), which is discussed in the next section.

 

Ipconfig

 

The IPCONFIG.EXE utility presents two pieces of information: IPv4 configuration information and IPv4 configuration parameters specific to each network adapter installed on your machine.

 

IP Helper Functions: IPConfig utility options

 

To retrieve IP configuration information, use the GetNetworkParams() function, which is defined as:

DWORD GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);

The pFixedInfo parameter receives a pointer to a buffer that receives a FIXED_INFO data structure your application must provide to retrieve the IPv4 configuration information. The pOutBufLen parameter is a pointer to a variable that specifies the size of the buffer you passed in the pFixedInfo parameter. If your buffer is not large enough, GetNetworkParams() returns ERROR_BUFFER_ OVERFLOW and sets the pOutBufLen parameter to the required buffer size. The FIXED_INFO structure used in GetNetworkParams() is defined as:

 

typedef struct

{

    char            HostName[MAX_HOSTNAME_LEN + 4] ;

    char            DomainName[MAX_DOMAIN_NAME_LEN + 4];

    PIP_ADDR_STRING CurrentDnsServer;

    IP_ADDR_STRING  DnsServerList;

    UINT            NodeType;

    char            ScopeId[MAX_SCOPE_ID_LEN + 4];

    UINT            EnableRouting;

    UINT            EnableProxy;

    UINT            EnableDns;

} FIXED_INFO, *PFIXED_INFO;

 

The fields are defined as follows:

 

  1. HostName: Represents your computer's name as recognized by DNS.
  2. DomainName: Specifies the DNS domain your computer belongs to.
  3. CurrentDnsServer: Contains the current DNS server's IPv4 address.
  4. DnsServerList: Is a linked list containing the DNS servers that your machine uses.
  5. NodeType: Specifies how the system resolves NetBIOS names over an IPv4 network. Table 16-1 contains the possible values.
  6. ScopeId: Identifies a string value that is appended to a NetBIOS name to logically group two or more computers for NetBIOS communication over TCP/IP.
  7. EnableRouting: Specifies whether the system will route IPv4 packets between the networks it is connected to.
  8. EnableProxy: Specifies whether the system will act as a WINS proxy agent on a network. A WINS proxy agent answers broadcast queries for names that it has resolved through WINS and allows a network of b-node computers to connect to servers on other subnets registered with WINS.
  9. EnableDns: Specifies whether NetBIOS will query DNS for names that cannot be resolved by WINS, broadcast, or the LMHOSTS file.

 

Table 16-1 Possible Node Type Values

 

Value

Description

BROADCAST_NODETYPE

Known as b-node NetBIOS name resolution, in which the system uses IP broadcasting to perform NetBIOS name registration and name resolution.

PEER_TO_PEER_NODETYPE

Known as p-node NetBIOS name resolution, in which the system uses point-to-point communication with a NetBIOS name server (such as WINS) to register and resolve computer names to IP addresses.

MIXED_NODETYPE

Known as m-node (mixed node) NetBIOS name resolution, in which the system uses both the b-node and p-node techniques. The b-node method is used first; if it fails, the p-node method is used.

HYBRID_NODETYPE

Known as h-node (hybrid node) NetBIOS name resolution, in which the system uses both the b-node and p-node techniques. The p-node method is used first; if it fails, the b-node method is used next.

 

The DnsServerList field of a FIXED_INFO structure is an IP_ADDR_STRING structure that represents the beginning of a linked list of IPv4 addresses. This field is defined as:

 

typedef struct _IP_ADDR_STRING

{

    struct _IP_ADDR_STRING* Next;

    IP_ADDRESS_STRING       IpAddress;

    IP_MASK_STRING          IpMask;

    DWORD                   Context;

} IP_ADDR_STRING, *PIP_ADDR_STRING;

 

The Next field identifies the next DNS server IPv4 address in the list. If Next is set to NULL, it indicates the end of the list. The IpAddress field is a string of characters that represents an IPv4 address as a dotted decimal string. The IpMask field is a string of characters that represents the subnet mask associated with the IPv4 address listed in IpAddress. The final field, Context, identifies the IPv4 address with a unique value on the system.

The IPCONFIG.EXE utility is also capable of retrieving IP configuration information specific to a network interface. A network interface can be a hardware Ethernet adapter or even a RAS dial-up adapter. You can retrieve adapter information by calling GetAdaptersInfo(), which is defined as:

DWORD GetAdaptersInfo (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);

Use the pAdapterInfo parameter to pass a pointer to an application-provided buffer that receives an ADAPTER_INFO data structure with the adapter configuration information. The pOutBufLen parameter is a pointer to a variable that specifies the size of the buffer you passed in the pAdapterInfo parameter. If your buffer is not large enough, GetAdaptersInfo() returns ERROR_BUFFER_ OVERFLOW and sets the pOutBufLen parameter to the required buffer size.

The IP_ADAPTER_INFO structure is actually a list of structures containing IPv4 configuration information specific to every network adapter available on your machine. IP_ADAPTER_INFO is defined as:

 

typedef struct _IP_ADAPTER_INFO

{

    struct _IP_ADAPTER_INFO* Next;

    DWORD           ComboIndex;

    char            AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];

    char            Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];

    UINT            AddressLength;

    BYTE            Address[MAX_ADAPTER_ADDRESS_LENGTH];

    DWORD           Index;

    UINT            Type;

    UINT            DhcpEnabled;

    PIP_ADDR_STRING CurrentIpAddress;

    IP_ADDR_STRING  IpAddressList;

    IP_ADDR_STRING  GatewayList;

    IP_ADDR_STRING  DhcpServer;

    BOOL            HaveWins;

    IP_ADDR_STRING  PrimaryWinsServer;

    IP_ADDR_STRING  SecondaryWinsServer;

    time_t          LeaseObtained;

    time_t          LeaseExpires;

} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;

 

The fields of the structure are defined as follows:

 

  1. Next: Identifies the next adapter in the buffer. A NULL value indicates the end of the list.
  2. ComboIndex: Is not used and will be set to 0.
  3. AdapterName: Identifies the name of the adapter.
  4. Description: Is a simple description of the adapter.
  5. AddressLength: Identifies how many bytes make up the physical address of the adapter in the Address field.
  6. Address: Identifies the physical address of the adapter.
  7. Index: Identifies a unique internal index number of the network interface that this adapter is assigned to.
  8. Type: Specifies the type of the adapter as a numeric value. Table 16-2 defines the most common adapter types. A full listing of the supported adapter types can be found in IPIFCONS.H.

 

Table 16-2 Adapter Types

 

Adapter Type Value

Description

MIB_IF_TYPE_ETHERNET

Ethernet adapter

MIB_IF_TYPE_FDDI

Fiber Distributed Data Interface (FDDI) adapter

MIB_IF_TYPE_LOOPBACK

Loopback adapter

MIB_IF_TYPE_OTHER

Other type of adapter

MIB_IF_TYPE_PPP

PPP adapter

MIB_IF_TYPE_SLIP

Slip adapter

MIB_IF_TYPE_TOKENRING

Token Ring adapter

 

  1. DhcpEnabled: Specifies whether DHCP is enabled on this adapter.
  2. CurrentIpAddress: Is not used and will be set to a NULL value.
  3. IpAddressList: Specifies a list of IPv4 addresses assigned to the adapter.
  4. GatewayList: Specifies a list of IPv4 addresses representing the default gateway.
  5. DhcpServer: Specifies a list with only one element representing the IPv4 address of the DHCP server used.
  6. HaveWins: Specifies whether the adapter uses a WINS server.
  7. PrimaryWinsServer: Specifies a list with only one element representing the IPv4 address of the primary WINS server used.
  8. SecondaryWinsServer: Specifies a list with only one element representing the IPv4 address of the secondary WINS server used.
  9. LeaseObtained: Identifies when the lease for the IPv4 address was obtained from a DHCP server.
  10. LeaseExpires: Identifies when the lease on the IPv4 address obtained from DHCP expires.

 

The GetAdaptersInfo() returns a great deal of information about the physical adapter and the IPv4 addresses assigned to it, but it does not return any IPv6 information. Instead, a new API GetAdaptersAddresses() has been introduced to fill this gap as it returns address information for both IPv4 and IPv6. The API is declared as:

 

DWORD WINAPI GetAdaptersAddresses(

                        ULONG Family,

                        DWORD Flags,

                        PVOID Reserved,

                        PIP_ADAPTER_ADDRESSES pAdapterAddresses,

                        PULONG pOutBufLen

);

 

The Family parameter indicates which address family should be enumerated. The valid values are: AF_INET, AF_INET6, or AF_UNSPEC, depending on whether you want IPv4, IPv6, or all IP information. The Flags parameter controls the type of addresses returned. Table 16-3 lists the possible values and their meaning. Note that more than one flag can be specified by ORing multiple flags together. By default, all addresses are returned. The last two parameters are the buffer that the IP information is returned in and the length of the buffer.

 

-----------------------------------------------------------

Table 16-3 GetAdaptersAddresses() Flag

 

Flag

Description

GAA_FLAG_SKIP_UNICAST

Exclude unicast addresses.

GAA_FLAG_SKIP_ANYCAST

Exclude anycast addresses.

GAA_FLAG_SKIP_MULTICAST

Exclude multicast addresses.

GAA_FLAG_SKIP_DNS_SERVER

Exclude DNS server addresses.

 

The IP information is returned in the form of an IP_ADAPTER_ADDRESSES structure. This structure is defined as:

 

typedef struct _IP_ADAPTER_ADDRESSES {

        union {

               ULONGLONG Alignment;

               struct {

                      ULONG Length;

                      DWORD IfIndex;

             }

         }

         struct _IP_ADAPTER_ADDRESSES *Next;

         PCHAR AdapterName;

         PIP_ADAPTER_UNICAST_ADDRESS     FirstUnicastAddress;

         PIP_ADAPTER_ANYCAST_ADDRESS     FirstAnycastAddress;

         PIP_ADAPTER_MULTICAST_ADDRESS   FirstMulticastAddress;

         PIP_ADAPTER_DNS_SERVER_ADDRESS  FirstDnsServerAddress;

         PWCHAR   DnsSuffix;

         PWCHAR   Description;

         PWCHAR   FriendlyName;

         BYTE     PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];

         DWORD    PhysicalAddressLength;

         DWORD                Flags;

         DWORD                Mtu;

         DWORD                IfType;

         IF_OPER_STATUS       OperStatus;

         DWORD                Ipv6IfIndex;

         DWORD                ZoneIndices[16];

         PIP_ADAPTER_PREFIX   FirstPrefix;

} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;

 

  1. Length: Specifies the length of the structure.
  2. IfIndex: Specifies the interface index that can be cross-referenced with the interface indices that GetAdaptersInfo returns.
  3. Next Specifies: the next IP_ADAPTER_ADDRESSES structure returned.
  4. AdapterName: Specifies the adapter name these addresses are assigned to.
  5. FirstUnicastAddress: Pointer to a list of IP_ADAPER_UNICAST_ ADDRESS structures that contain information about each unicast address assigned to this adapter.
  6. FirstAnycastAddress: Pointer to a list of IP_ADAPTER_ANYCAST_ ADDRESS structures that contain information about each anycast address assigned to this adapter.
  7. FirstMulticastAddress: Pointer to a list of IP_ADAPTER_MULTICAST_ ADDRESS structures that contain information about each multicast address assigned to this adapter. This is extremely useful because it lists each multicast address joined on each physical interface.
  8. FirstDnsServerAddress: Pointer to a list of IP_ADAPTER_DNS_ SERVER_ADDRESS structures that contain information about each DNS server assigned to this adapter.
  9. DnsSuffix: Specifies the Unicode DNS suffix string associated with this adapter.
  10. Description Contains a Unicode string description of the adapter.
  11. FriendlyName: Contains a Unicode string description of the adapter that is usually more easily human readable than the Description field.
  12. PhysicalAddress: Specifies the physical address of the adapter in an array of bytes. For an Ethernet adapter, this would specify the MAC address.
  13. PhysicalAddressLength: Specifies the number of bytes that comprise the physical address contained in the PhysicalAddress field.
  14. Flags: Indicates the state of the adapter with respect to DDNS, DNS, and DHCP. Table 16-4 lists the possible flags.

 

Table 16-4 IP_ADAPTERS_ADDRESSES Flags

 

Flag

Description

IP_ADAPTER_DDNS_ENABLED

Dynamic DNS is enabled on this adapter.

IP_ADAPTER_REGISTER_ADAPTER_SUFFIX

The DNS suffix for this adapter is registered.

IP_ADAPTER_DHCP_ENABLED

DHCP is enabled on this adapter.

IP_ADAPTER_RECEIVE_ONLY

The interface is capable of receiving data only.

IP_ADAPTER_NO_MULTICAST

The interface is not capable of receiving multicast data.

IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG

Indicates the “O” bit in the most recently received IPv6 router advertisement was set. This indicates the presence of stateful configuration information such as DHCPv6.

 

  1. Mtu: Specifies the maximum transmission unit support on this adapter.
  2. IfType: Specifies the type of adapter; see Table 16-2 for the possible values.
  3. OperStatus: Specifies the operational status of the adapter. For more information about this field, see RFC 2863.
  4. Ipv6IfIndex: Specifies the interface index of the adapter for the IPv6 addresses assigned to this interface. Note that this field should be used with IPv6 addresses and not the IfIndex field.
  5. ZoneIndices: Specifies the scope-IDs for the 16 different scope levels. The most popular scope levels are defined in the enumerated type SCOPE_LEVEL. Consult RFC2373 for more information.
  6. FirstPrefix: A linked list of IP_ADAPTER_PREFIX structures which contain the subnet prefixes which are on-link for this interface.

 

The last piece of the IP_ADAPTERS_ADDRESSES structure is the adapter structures. These four structures are very similar and for the most part contain the same kind of information. We'll discuss only the unicast version of the structure because the remaining address structures can be inferred from this one. The unicast structure is defined as:

 

typedef struct _IP_ADAPTER_UNICAST_ADDRESS {

        union {

              ULONGLONG Alignment;

              struct {

                     ULONG Length;

                     DWORD Flags;

              };

         };

         struct _IP_ADAPTER_UNICAST_ADDRESS *Next;

         SOCKET_ADDRESS      Address;

         IP_PREFIX_ORIGIN    PrefixOrigin;

         IP_SUFFIX_ORIGIN    SuffixOrigin;

         IP_DAD_STATE        DadState;

         ULONG               ValidLifetime;

         ULONG               PreferredLifeTime;

         ULONG               LeaseLifeTime;

} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;

 

 

Table 16-5 Per Address Flags

 

Per Address Flags

Description

IP_ADAPTER_ADDRESS_DNS_ELIGIBLE

Address can be registered with DNS (such as DHCP or RA assigned).

IP_ADAPTER_ADDRESS_TRANSIENT

Address is not a permanent address (such as IPv6 privacy address).

 

 

Table 16-6 Prefix Origin Values

 

Prefix Origin Value

Description

IpPrefixOriginOther

Prefix obtained from source other than those listed in this table.

IpPrefixOriginManual

Prefix was manually configured - for example, assigning a static IPv4 address.

IpPrefixOriginWellKnown

Prefix is a well-known address - for example, the loopback address.

IpPrefixOriginDhcp

Prefix is assigned by DHCP.

IpPrefixOriginRouterAdvertisement

Prefix is assigned by a router advertisement - for example, an IPv6 site local or global address.

 

 

Table 16-7 Suffix Origin Values

 

Suffix Origin Value

Description

IpSuffixOriginOther

Suffix obtained from a source other than those listed in this table.

IpSuffixOriginManual

Suffix was configured manually - for example, a statically assigned IP address.

IpSuffixOriginWellKnown

Suffix is a well-known address - for example, the loopback adapter.

IpSuffixOriginDhcp

Suffix is assigned by DHCP.

IpSuffixOriginLinkLayerAddress

Suffix is obtained from the lower network layer. For example, IPv6 link local addresses.

IpSuffixOriginRandom

Suffix is a randomly assigned value. For example, IPv6 privacy addresses.

 

 

Table 16-8 Address States

 

Address State

Description

IpDadStateInvalid

Address is in the process of being deleted.

IpDadStateTentative

Duplicate address detection is in progress.

IpDadStateDuplicate

A duplicate address has been detected.

IpDadStateDeprecated

Address is no longer preferred for new connections.

IpDatStatePreferred

Address is the preferred address.

 

 

Releasing and Renewing IPv4 Addresses

 

The IPCONFIG.EXE utility also features the ability to release and renew IPv4 addresses obtained from the DHCP server by specifying the /release and /renew command line parameters. If you want to programmatically release an IPv4 address, you can call the IPReleaseAddress() function, which is defined as:

DWORD IpReleaseAddress (PIP_ADAPTER_INDEX_MAP AdapterInfo);

If you want to renew an IP address, you can call the IPRenewAddress() function, which is defined as:

DWORD IpRenewAddress (PIP_ADAPTER_INDEX_MAP AdapterInfo);

Each of these two functions features an AdapterInfo parameter that is an IP_ADAPTER_INDEX_MAP structure, which identifies the adapter to release or renew the address for. The IP_ADAPTER_INDEX_MAP structure is defined as:

 

typedef struct _IP_ADAPTER_INDEX_MAP

{

    ULONG Index;

    WCHAR Name[MAX_ADAPTER_NAME];

}IP_ADAPTER_INDEX_MAP, *PIP_ADAPTER_INDEX_MAP;

 

The fields of this structure are defined as follows:

 

 

You can retrieve the IP_ADAPTER_INDEX_MAP structure for a particular adapter by calling the GetInterfaceInfo() function, which is defined as:

DWORD GetInterfaceInfo (IN PIP_INTERFACE_INFO pIfTable, OUT PULONG dwOutBufLen);

The pIfTable parameter is a pointer to an IP_INTERFACE_INFO application buffer that will receive interface information. The dwOutBufLen parameter is a pointer to a variable that specifies the size of the buffer you passed in the pIfTable parameter. If the buffer is not large enough to hold the interface information, GetInterfaceInfo() returns the error ERROR_INSUFFICIENT_BUFFER and sets the dwOutBufLen parameter to the required buffer size. The IP_INTERFACE_INFO structure is defined as:

 

typedef struct _IP_INTERFACE_INFO

{

    LONG                 NumAdapters;

    IP_ADAPTER_INDEX_MAP Adapter[1];

} IP_INTERFACE_INFO,*PIP_INTERFACE_INFO;

 

Its fields are defined as follows:

 

 

Once you have obtained the IP_ADAPTER_INDEX_MAP structure for a particular adapter, you can release or renew the DHCP-assigned IPv4 address using the IPReleaseAddress() and IPRenewAddress() functions we just described.

 

Changing IPv4 Addresses

 

The IPCONFIG.EXE utility does not allow you to change an IP address for a network adapter (except in the case of DHCP). However, two functions will allow you to add or delete an IP address for a particular adapter: the AddIpAddress() and DeleteIpAddress() IP Helper functions. These require you to understand adapter index numbers and IP context numbers. In Windows, every network adapter has a unique index ID (which we described earlier), and every IP address has a unique context ID. Adapter index IDs and IP context numbers can be retrieved using GetAdaptersInfo(). The AddIpAddress() function is defined as:

 

DWORD AddIPAddress (

    IPAddr Address,

    IPMask IpMask,

    DWORD IfIndex,

    PULONG NTEContext,

    PULONG NTEInstance

);

 

The Address parameter specifies the IPv4 address to add as an unsigned long value. The IpMask parameter specifies the subnet mask for the IPv4 address as an unsigned long value. The IfIndex parameter specifies the adapter index to add the address to. The NTEContext parameter receives the context value associated with the IPv4 address added. The NTEInstance parameter receives an instance value associated with an IPv4 address.

If you want to programmatically delete an IPv4 address for an adapter, you can call DeleteIpAddress(), which is defined as:

DWORD DeleteIPAddress (ULONG NTEContext);

The NTEContext parameter identifies a context value associated with an IPv4 address. This value can be obtained from GetAdaptersInfo(), which we described earlier in the chapter.

Note that IPv4 addresses added via the AddIpAddress function are persistent only until reboot.

 

 

 


< Chap 13: Index | Winsock 2 Main | Netstat: Retrieve TCP, UDP Tables & Protocol Statistics >