I want to know the name of API which used to know current IP of the Interface.
I have two interface ethernet and WLAN.Both Interface are UP and i want to know IP of specific interface then Is there any API in VC++ that will give me interface IP ?
Thanks,
Neel
GetAdaptersInfo or GetAdaptersAddresses.
Use DnsQuery
/************************************************************\
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright © 2000 Microsoft Corporation. All Rights Reserved.
/***************************************************************/
/*
FILE: Dnsquery.cpp
DESCRIPTION: This sample illustrates the use of DnsQuery() function to send query to
a DNS server to resolve the host name to an IP address and vice-versa.
PLATFORM: Windows 2000
WRITTEN BY: Rashmi Anoop
DATE: 3/22/2000
*/
/*
includes
*/
#include <windows.h> //windows
#include <windns.h> //DNS api's
#include <stdio.h> //standard i/o
#include <winsock.h> //winsock
#define BUFFER_LEN 255
//Usage of the program
void Usage(char *progname) {
fprintf(stderr,"Usage\n%s -n [OwnerName] -t [Type] -s [DnsServerIp]\n",
progname);
fprintf(stderr,"Where:\n\t\"OwnerName\" is name of the owner of the record set being queried\n");
fprintf(stderr,"\t\"Type\" is the type of record set to be queried A or PTR\n");
fprintf(stderr,"\t\"DnsServerIp\"is the IP address of DNS server (in dotted decimal notation)");
fprintf(stderr,"to which the query should be sent\n");
exit(1);
}
// the main function
void __cdecl main(int argc, char *argv[])
{
DNS_STATUS status; // return value of DnsQuery_A() function.
PDNS_RECORD pDnsRecord; //pointer to DNS_RECORD structure
PIP4_ARRAY pSrvList = NULL; //pinter to IP4_ARRAY structure
LPTSTR pOwnerName = NULL; //owner name to be queried
WORD wType; //Type of the record to be queried
char DnsServIp[BUFFER_LEN]; //DNS server ip address
DNS_FREE_TYPE freetype ;
freetype = DnsFreeRecordListDeep;
IN_ADDR ipaddr;
if (argc > 4) {
for (int i = 1; i < argc ; i++) {
if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {
switch (tolower(argv[i][1])) {
case 'n':
pOwnerName = argv[++i];
break;
case 't':
if (!_stricmp(argv[i+1], "A") )
wType = DNS_TYPE_A; //Query host records to resolve a name
else if (!_stricmp(argv[i+1], "PTR") )
wType = DNS_TYPE_PTR; //Query PTR records to resovle an IP address
else
Usage(argv[0]);
i++;
break;
case 's':
// Allocate memory for IP4_ARRAY structure
pSrvList = (PIP4_ARRAY) LocalAlloc(LPTR,sizeof(IP4_ARRAY));
if (!pSrvList) {
printf("Memory allocation failed \n");
exit(1);
}
if (argv[++i]) {
strncpy(DnsServIp, argv[i], sizeof(DnsServIp)-1 );
DnsServIp[sizeof(DnsServIp)-1] = '\0';
pSrvList->AddrCount = 1;
pSrvList->AddrArray[0] = inet_addr(DnsServIp); //DNS server IP address
if ( pSrvList->AddrArray[0] == INADDR_NONE ) {
printf("Invalid DNS server IP address \n");
Usage( argv[0] );
}
break;
}
default:
Usage(argv[0]);
break;
}
}
else
Usage(argv[0]);
}
}
else
Usage(argv[0]);
// Calling function DnsQuery_A() to query Host or PTR records
status = DnsQuery_A(pOwnerName, //pointer to OwnerName
wType, //Type of the record to be queried
DNS_QUERY_BYPASS_CACHE, // Bypasses the resolver cache on the lookup.
pSrvList, //contains DNS server IP address
&pDnsRecord, //Resource record comprising the response
NULL); //reserved for future use
if (status) {
if (wType == DNS_TYPE_A)
printf("Failed to query the host record for %s and the error is %d \n", pOwnerName, status);
else
printf("Failed to query the PTR record and the error is %d \n", status);
}
else {
if (wType == DNS_TYPE_A) {
//convert the Internet network address into a string
//in Internet standard dotted format.
ipaddr.S_un.S_addr = (pDnsRecord->Data.A.IpAddress);
printf("The IP address of the host %s is %s \n", pOwnerName,inet_ntoa(ipaddr));
// Free memory allocated for DNS records
DnsRecordListFree(pDnsRecord, freetype);
}
else {
printf("The host name is %s \n",(pDnsRecord->Data.PTR.pNameHost));
// Free memory allocated for DNS records
DnsRecordListFree(pDnsRecord, freetype);
}
}
LocalFree(pSrvList);
}
Output :
DNSQuery.exe -n localhost -t A
The IP address of the host localhost is 127.0.0.1
Related
I'm learning the netlink library version 3 and I want to know how to get the ipv4 address of a specified network interface. I can get the mac address and even requery the interface name from a link data structure, but I can not figure out how to get the ip address using the libnl and libnl-route libs. I did find some code to get the ip address using the libnl-cli lib but that is for dumping the results to a file descriptor (think stdout). I have sent mail to the mailing list for this library but I have not gotten a response.
Here is my code:
https://gist.github.com/netskink/4f554ed6657954b17ab255ad5bc6d1f0
Here are my results:
./stats
Returned link name is enp6s0
Returned link addr is a0:36:9f:66:93:13
Ive seen the mechanism to retrieve the ip address using ioctls, but since netlink lib can return the ip address using the cli sublibrary I figure it can be done but I can not figure out a way.
Interface can have multiple addresses (ipv4 and ipv6 addresses - code sample gave me one ipv4 and one ipv6), so there is no such function that returns one address for interface. If only you had specific local address, you could have called rtnl_addr_get. Instead you can iterate addresses.
#include <libnl3/netlink/cache.h>
void addr_cb(struct nl_object *o, void *data)
{
int ifindex = (int)(intptr_t)data;
struct rtnl_addr *addr = (rtnl_addr *)o;
if (NULL == addr) {
/* error */
printf("addr is NULL %d\n", errno);
return;
}
int cur_ifindex = rtnl_addr_get_ifindex(addr);
if(cur_ifindex != ifindex)
return;
const struct nl_addr *local = rtnl_addr_get_local(addr);
if (NULL == local) {
/* error */
printf("rtnl_addr_get failed\n");
return;
}
char addr_str[ADDR_STR_BUF_SIZE];
const char *addr_s = nl_addr2str(local, addr_str, sizeof(addr_str));
if (NULL == addr_s) {
/* error */
printf("nl_addr2str failed\n");
return;
}
fprintf(stdout, "\naddr is: %s\n", addr_s);
}
You can iterate addresses from cache and see if they contain needed address (looking at ifindex). Please take a look at https://www.infradead.org/~tgr/libnl/doc/api/cache_8c_source.html for useful functions (there is some filter function).
int ifindex = rtnl_link_get_ifindex(p_rtnl_link);
printf("ifindex: %d\n", ifindex);
bool empty = nl_cache_is_empty(addr_cache);
printf("empty: %d\n", empty);
nl_cache_foreach(addr_cache,
addr_cb, (void*)(intptr_t)ifindex);
And to check ip version use rtnl_addr_get_family.
Building upon user2518959's answer.
The rtnl_addr_alloc_cache and rtnl_link_alloc_cache both return a nl_cache object/structure. Even those these two results are of the same type, they have different routines which can be used on each.
The nl_cache returned from rtnl_addr_alloc_cache can be used to get rtnl_addr object/structures. Which are in turn can be used to call rtnl_addr_get_local to get the ipv4 or ipv6 address.
In contrast, the nl_cache returned from rtnl_link_alloc_cache can be used to get the interface name (eth0, enp6s0, ...) and the mac address. The routines are rtnl_link_get_by_name and rtnl_link_get_addr respectively.
In either case, the common link between the two is routine rtnl_addr_get_index and rtnl_link_get_index which return an interface index which can be used to relate either entry from each cache. ie. interface 1 from the addr version of nl_cache and interface 1 from the link nl_cache are the same interface. One gives the ip address and the other gives the mac address and name.
Lastly, a tunnel will have an ip address but no mac so it will not have a link name or mac address.
Here is some code which shows user25185959 approach and an alternate method which shows the relationship explictly. User2518959 passed the interface number into the callback to filter out interfaces.
#include <libnl3/netlink/netlink.h>
#include <libnl3/netlink/route/link.h>
#include <libnl3/netlink/route/addr.h>
#include <libnl3/netlink/cache.h>
#include <libnl3/netlink/route/addr.h>
#include <errno.h>
/*
gcc ipchange.c -o ipchange $(pkg-config --cflags --libs libnl-3.0 libnl-route-3.0 libnl-cli-3.0)
*/
#include <stdbool.h>
#define ADDR_STR_BUF_SIZE 80
void addr_cb(struct nl_object *p_nl_object, void *data) {
int ifindex = (int) (intptr_t) data; // this is the link index passed as a parm
struct rtnl_addr *p_rtnl_addr;
p_rtnl_addr = (struct rtnl_addr *) p_nl_object;
int result;
if (NULL == p_rtnl_addr) {
/* error */
printf("addr is NULL %d\n", errno);
return;
}
// This routine is not mentioned in the doxygen help.
// It is listed under Attributes, but no descriptive text.
// this routine just returns p_rtnl_addr->a_ifindex
int cur_ifindex = rtnl_addr_get_ifindex(p_rtnl_addr);
if(cur_ifindex != ifindex) {
// skip interaces where the index differs.
return;
}
// Adding this to see if I can filter on ipv4 addr
// this routine just returns p_rtnl_addr->a_family
// this is not the one to use
// ./linux/netfilter.h: NFPROTO_IPV6 = 10,
// ./linux/netfilter.h: NFPROTO_IPV4 = 2,
// this is the one to use
// x86_64-linux-gnu/bits/socket.h
// defines AF_INET6 = PF_INET6 = 10
// defines AF_INET = PF_INET = 2
result = rtnl_addr_get_family(p_rtnl_addr);
// printf( "family is %d\n",result);
if (AF_INET6 == result) {
// early exit, I don't care about IPV6
return;
}
// This routine just returns p_rtnl_addr->a_local
const struct nl_addr *p_nl_addr_local = rtnl_addr_get_local(p_rtnl_addr);
if (NULL == p_nl_addr_local) {
/* error */
printf("rtnl_addr_get failed\n");
return;
}
char addr_str[ADDR_STR_BUF_SIZE];
const char *addr_s = nl_addr2str(p_nl_addr_local, addr_str, sizeof(addr_str));
if (NULL == addr_s) {
/* error */
printf("nl_addr2str failed\n");
return;
}
fprintf(stdout, "\naddr is: %s\n", addr_s);
}
int main(int argc, char **argv, char **envp) {
int err;
struct nl_sock *p_nl_sock;
struct nl_cache *link_cache;
struct nl_cache *addr_cache;
struct rtnl_addr *p_rtnl_addr;
struct nl_addr *p_nl_addr;
struct nl_link *p_nl_link;
struct rtnl_link *p_rtnl_link;
char addr_str[ADDR_STR_BUF_SIZE];
char *pchLinkName;
char *pchLinkAddr;
char *pchIPAddr;
char *interface;
interface = "enp6s0";
pchLinkAddr = malloc(40);
pchIPAddr = malloc(40);
strcpy(pchLinkAddr,"11:22:33:44:55:66");
strcpy(pchIPAddr,"123.456.789.abc");
p_nl_sock = nl_socket_alloc();
if (!p_nl_sock) {
fprintf(stderr, "Could not allocate netlink socket.\n");
exit(ENOMEM);
}
// Connect to socket
if(err = nl_connect(p_nl_sock, NETLINK_ROUTE)) {
fprintf(stderr, "netlink error: %s\n", nl_geterror(err));
p_nl_sock = NULL;
exit(err);
}
// Either choice, the result below is a mac address
err = rtnl_link_alloc_cache(p_nl_sock, AF_UNSPEC, &link_cache);
//err = rtnl_link_alloc_cache(p_nl_sock, AF_INET, &link_cache);
//err = rtnl_link_alloc_cache(p_nl_sock, IFA_LOCAL, &link_cache);
if (0 != err) {
/* error */
printf("rtnl_link_alloc_cache failed: %s\n", nl_geterror(err));
return(EXIT_FAILURE);
}
err = rtnl_addr_alloc_cache(p_nl_sock, &addr_cache);
if (0 != err) {
/* error */
printf("rtnl_addr_alloc_cache failed: %s\n", nl_geterror(err));
return(EXIT_FAILURE);
}
p_rtnl_link = rtnl_link_get_by_name(link_cache, "enp6s0");
if (NULL == p_rtnl_link) {
/* error */
printf("rtnl_link_get_by_name failed\n");
return(EXIT_FAILURE);
}
pchLinkName = rtnl_link_get_name(p_rtnl_link);
if (NULL == pchLinkName) {
/* error */
printf("rtnl_link_get_name failed\n");
return(EXIT_FAILURE);
}
printf("Returned link name is %s\n",pchLinkName);
////////////////////////////////// mac address
p_nl_addr = rtnl_link_get_addr(p_rtnl_link);
if (NULL == p_nl_addr) {
/* error */
printf("rtnl_link_get_addr failed\n");
return(EXIT_FAILURE);
}
pchLinkAddr = nl_addr2str(p_nl_addr, pchLinkAddr, 40);
if (NULL == pchLinkAddr) {
/* error */
printf("rtnl_link_get_name failed\n");
return(EXIT_FAILURE);
}
printf("Returned link addr is %s\n",pchLinkAddr);
////////////////////////////////// ip address
// How to get ip address for a specified interface?
//
// The way she showed me.
//
// Return interface index of link object
int ifindex = rtnl_link_get_ifindex(p_rtnl_link);
printf("ifindex: %d\n", ifindex);
// She gave me this but its not necessary
// Returns true if the cache is empty. True if the cache is empty.
// bool empty = nl_cache_is_empty(addr_cache);
// printf("empty: %d\n", empty);
// Call a callback on each element of the cache. The
// arg is passed on the callback function.
// addr_cache is the cache to iterate on
// addr_cb is the callback function
// ifindex is the argument passed to the callback function
//
nl_cache_foreach(addr_cache, addr_cb, (void*)(intptr_t)ifindex);
// This shows that the link index returned from rtnl_addr_get_index
// and rtnl_link_get_index are equivalent when using the rtnl_addr
// and rtnl_link from the two respective caches.
// Another way...
// This will iterate through the cache of ip's
printf("Getting the list of interfaces by ip addr cache\n");
int count = nl_cache_nitems(addr_cache);
printf("addr_cache has %d items\n",count);
struct nl_object *p_nl_object;
p_nl_object = nl_cache_get_first(addr_cache);
p_rtnl_addr = (struct rtnl_addr *) p_nl_object;
for (int i=0; i<count; i++) {
// This routine just returns p_rtnl_addr->a_local
const struct nl_addr *p_nl_addr_local = rtnl_addr_get_local(p_rtnl_addr);
if (NULL == p_nl_addr_local) {
/* error */
printf("rtnl_addr_get failed\n");
return(EXIT_FAILURE);
}
int cur_ifindex = rtnl_addr_get_ifindex(p_rtnl_addr);
printf("This is index %d\n",cur_ifindex);
const char *addr_s = nl_addr2str(p_nl_addr_local, addr_str, sizeof(addr_str));
if (NULL == addr_s) {
/* error */
printf("nl_addr2str failed\n");
return(EXIT_FAILURE);
}
fprintf(stdout, "\naddr is: %s\n", addr_s);
//
printf("%d\n",i);
p_nl_object = nl_cache_get_next(p_nl_object);
p_rtnl_addr = (struct rtnl_addr *) p_nl_object;
// Just for grins
}
// Another way...
// This will iterate through the cache of LLC
printf("Getting the list of interfaces by mac cache\n");
count = nl_cache_nitems(link_cache);
printf("addr_cache has %d items\n",count);
p_nl_object = nl_cache_get_first(link_cache);
p_rtnl_link = (struct rtnl_link *) p_nl_object;
for (int i=0; i<count; i++) {
// This routine just returns p_rtnl_addr->a_local
const struct nl_addr *p_nl_addr_mac = rtnl_link_get_addr(p_rtnl_link);
if (NULL == p_nl_addr_mac) {
/* error */
printf("rtnl_addr_get failed\n");
return(EXIT_FAILURE);
}
int cur_ifindex = rtnl_link_get_ifindex(p_rtnl_link);
printf("This is index %d\n",cur_ifindex);
const char *addr_s = nl_addr2str(p_nl_addr_mac, addr_str, sizeof(addr_str));
if (NULL == addr_s) {
/* error */
printf("nl_addr2str failed\n");
return(EXIT_FAILURE);
}
fprintf(stdout, "\naddr is: %s\n", addr_s);
//
printf("%d\n",i);
p_nl_object = nl_cache_get_next(p_nl_object);
p_rtnl_link = (struct rtnl_link *) p_nl_object;
}
return(EXIT_SUCCESS);
}
I am using the following code to find out the address of the entry point for a file called linked list.exe, but it outputs a big number of the kind 699907 whereas the size of the file itself is only 29Kb, so what does this number mean and how can I find the address of the entry point?
#include<iostream>
#include<fstream>
#include<iomanip>
#include<strstream>
#include<Windows.h>
#include<stdio.h>
#include<WinNT.h>
int main()
{
FILE *fp;
if((fp = fopen("linked list.exe","rb"))==NULL)
std::cout<<"unable to open";
int i ;
char s[2];
IMAGE_DOS_HEADER imdh;
fread(&imdh,sizeof(imdh),1,fp);
fseek(fp,imdh.e_lfanew,0);
IMAGE_NT_HEADERS imnth;
fread(&imnth,sizeof(imnth),1,fp);
printf("%d",imnth.OptionalHeader.AddressOfEntryPoint);
}
The AddressOfEntryPoint is the relative virtual address of the entry point, not the raw offset in the file. It holds the address of the first instruction that will be executed when the program starts.
Usually this is not the same as the beginning of the code section. If you want to get the beginning of the code section, you should see the BaseOfCode field.
The file is getting opened in memory that's why the address of entry point number is very big. The system provides available memory to file hence, base address always changes when file is opened in memory.
If you want to access actual disk offset of AEP i.e. address of entry point please find below snippet of code.
LPCSTR fileName="exe_file_to_parse";
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS peHeader;
PIMAGE_SECTION_HEADER sectionHeader;
hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\n CreateFile failed in read mode \n");
return 1;
}
hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hFileMapping==0)
{
printf("\n CreateFileMapping failed \n");
CloseHandle(hFile);
return 1;
}
lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
if(lpFileBase==0)
{
printf("\n MapViewOfFile failed \n");
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}
dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; //pointer to dos headers
if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE)
{
//if it is executable file print different fileds of structure
//dosHeader->e_lfanew : RVA for PE Header
printf("\n DOS Signature (MZ) Matched");
//pointer to PE/NT header
peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew);
if(peHeader->Signature==IMAGE_NT_SIGNATURE)
{
printf("\n PE Signature (PE) Matched \n");
// valid executable
//address of entry point
DWORD ptr = peHeader->OptionalHeader.AddressOfEntryPoint;
printf("\n RVA : %x \n",ptr); // this is in memory address
//suppose any one wants to know actual disk offset of "address of entry point" (AEP)
sectionHeader = IMAGE_FIRST_SECTION(peHeader);
UINT nSectionCount = peHeader->FileHeader.NumberOfSections;
UINT i=0;
for( i=0; i<=nSectionCount; ++i, ++sectionHeader )
{
if((sectionHeader->VirtualAddress) > ptr)
{
sectionHeader--;
break;
}
}
if(i>nSectionCount)
{
sectionHeader = IMAGE_FIRST_SECTION(peHeader);
UINT nSectionCount = peHeader->FileHeader.NumberOfSections;
for(i=0; i<nSectionCount-1; ++i,++sectionHeader);
}
DWORD retAddr = ptr - (sectionHeader->VirtualAddress) +
(sectionHeader->PointerToRawData);
printf("\n Disk Offset : %x \n",retAddr+(PBYTE)lpFileBase);
// retAddr+(PBYTE)lpFileBase contains the actual disk offset of address of entry point
}
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
//getchar();
return 0;
}
else
{
printf("\n DOS Signature (MZ) Not Matched \n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}
/* As usual, make the appropriate includes and declare the variables. */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *host, **names, **addrs;
struct hostent *hostinfo;
/* Set the host in question to the argument supplied with the getname call,
or default to the user's machine. */
if(argc == 1) {
char myname[256];
gethostname(myname, 255);
host = myname;
}
else
host = argv[1];
/* Make the call to gethostbyname and report an error if no information is found. */
hostinfo = gethostbyname(host);
if(!hostinfo) {
fprintf(stderr, "cannot get info for host: %s\n", host);
exit(1);
}
/* Display the hostname and any aliases it may have. */
printf("results for host %s:\n", host);
printf("Name: %s\n", hostinfo -> h_name);
printf("Aliases:");
names = hostinfo -> h_aliases;
while(*names) {
printf(" %s", *names);
names++;
}
printf("\n");
/* Warn and exit if the host in question isn't an IP host. */
if(hostinfo -> h_addrtype != AF_INET) {
fprintf(stderr, "not an IP host!\n");
exit(1);
}
/* Otherwise, display the IP address(es). */
addrs = hostinfo -> h_addr_list;
while(*addrs) {
char *ip_str = inet_ntoa(*(struct in_addr *)*addrs);
printf(" %s", ip_str);
/* <BEGIN> Get the host name by IP address */
struct in_addr addr = {0};
if (!inet_aton(ip_str, &addr)) {
printf("Cannot parse IP %s\n", ip_str);
exit(1);
}
struct hostent *remoteHost = gethostbyaddr((void*)&addr, sizeof(addr), AF_INET);
if (remoteHost == NULL) {
printf("\nInvalid remoteHost\n");
exit(1);
}
printf("\nOfficial name: %s\n", remoteHost->h_name);
char **pAlias;
for(pAlias=remoteHost->h_aliases; *pAlias != 0; pAlias++) {
printf("\tAlternate name: %s\n", *pAlias);
}
/* <End> */
addrs++;
}
printf("\n");
exit(0);
}
/* Test Run for www.yahoo */
user#ubuntu:~/Documents/C$ ./getname2way www.yahoo.com
results for host www.yahoo.com:
Name: any-fp.wa1.b.yahoo.com
Aliases: www.yahoo.com fp.wg1.b.yahoo.com
209.191.122.70
Official name: ir1.fp.vip.mud.yahoo.com
/* Test Run for www.google.com */
user#ubuntu:~/Documents/C$ ./getname2way www.google.com
results for host www.google.com:
Name: www.l.google.com
Aliases: www.google.com
74.125.225.83
Invalid remoteHost
Why the code doesn't work for www.google.com?
The IP address 74.125.225.83 does not have a reverse PTR record. You can always test on the command line with nslookup or dig.
can't find 74.125.225.83: Non-existent domain
http://en.wikipedia.org/wiki/Reverse_DNS_lookup
I am using below code for getting IP from passing domain name.
It is returning me proper IP but now when some network setting is changed Server Ip is also changed .
Now als0 it is returning me that Old IP not the new one.
Any help is highly appreciared.
CString CNDSClientDlg::GetIPFromDomain(char* cDomainName)
{
if(cDomainName == NULL)
{
MessageBox("Invalid Domain Name","Network Drive Solution", MB_ICONERROR | MB_OK);
return "";
}
char *cIPAddress = NULL;
WSADATA wsaData = {0};
int iResult = 0;
hostent *remoteHost = NULL;
struct in_addr addr;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
MessageBox("WSAStartup failed","Network Drive Solution", MB_ICONERROR | MB_OK);
return "";
}
remoteHost = gethostbyname(cDomainName);
addr.s_addr = *(u_long *) remoteHost->h_addr_list[0];
cIPAddress = inet_ntoa(addr);
return cIPAddress;
}
You probably get the address from your DNS cache.
Use ipconfig /flushdns to clear the cache.
On a Linux system with a wired and a wireless interface (e.g. 192.168.1.x and 192.168.2.x subnets) I want to send a UDP broadcast that goes out via ALL available interfaces (i.e. both through the wired and the wireless interface).
Currently I sendto() to INADDR_BROADCAST, however it seems that the broadcast only is sent through one of the interfaces (not always the same and subsequent broadcasts may use the other interface).
Is there a way that I can send a UDP broadcast that goes out through every single interface?
First of all, you should consider broadcast obsolete, specially INADDR_BROADCAST (255.255.255.255). Your question highlights exactly one of the reasons that broadcast is unsuitable. It should die along with IPv4 (hopefully). Note that IPv6 doesn't even have a concept of broadcast (multicast is used, instead).
INADDR_BROADCAST is limited to the local link. Nowadays, it's only visible use is for DHCP auto-configuration, since at such time, the client will not know yet in what network it is connected to.
With a single sendto(), only a single packet is generated, and the outgoing interface is determined by the operating system's routing table (ip route on linux). You can't have a single sendto() generate more than one packet, you would have to iterate over all interfaces, and either use raw sockets or bind the socket to a device using setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ethX") to send each packet bypassing the OS routing table (this requires root privileges). Not a good solution.
Instead, since INADDR_BROADCAST is not routed anyway, you can achieve almost the same thing by iterating over each interface, and sending the packet to its broadcast address. For example, assuming that your networks have 255.255.255.0 (/24) masks, the broadcast addresses are 192.168.1.255 and 192.168.2.255. Call sendto() once for each of these addresses and you will have accomplished your goal.
Edit: fixed information regarding to INADDR_BROADCAST, and complementing the answer with information about SO_BINDTODEVICE.
You can't have a single sendto() generate a packet on every interface - in general (fragmentation notwithstanding) it's one packet transmitted for each sendto().
You'll need to transmit the packet once for each interface and either:
use low-level (setsockopt()?) calls to select the outbound interface
send to the specific broadcast address for each known interface
the latter is however not suitable if you're trying to do some sort of discovery mechanism, such that the devices you're expecting to respond aren't actually correctly configured with an IP address in the same subnet as the interface they're connected to.
From Jeremy's solution on UNIX Socket FAQ:
#include <stdio.h>
#ifdef WIN32
# include <windows.h>
# include <winsock.h>
# include <iphlpapi.h>
#else
# include <unistd.h>
# include <stdlib.h>
# include <sys/socket.h>
# include <netdb.h>
# include <netinet/in.h>
# include <net/if.h>
# include <sys/ioctl.h>
#endif
#include <string.h>
#include <sys/stat.h>
typedef unsigned long uint32;
#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
# define USE_GETIFADDRS 1
# include <ifaddrs.h>
static uint32 SockAddrToUint32(struct sockaddr * a)
{
return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0;
}
#endif
// convert a numeric IP address into its string representation
static void Inet_NtoA(uint32 addr, char * ipbuf)
{
sprintf(ipbuf, "%li.%li.%li.%li", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
}
// convert a string represenation of an IP address into its numeric equivalent
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while((shift >= 0)&&(*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char) atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
static void PrintNetworkInterfaceInfos()
{
#if defined(USE_GETIFADDRS)
// BSD-style implementation
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while(p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i=0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it
ipTable = (MIB_IPADDRTABLE *) malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
// Try to get the Adapters-info table, so we can given useful names to the IP
// addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
// the potential race condition between the size-query call and the get-data call.
// I love a well-designed API :^P
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i=0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i=0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while((next)&&(name==NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while(ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
if (name == NULL)
{
sprintf(buf, "unnamed-%i", i);
name = buf;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
}
int main(int, char **)
{
PrintNetworkInterfaceInfos();
return 0;
}