Problem in GetHostByName & inet_ntoa in MFC(VC++ ) - visual-c++

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.

Related

How to read DNS Servers/ DNS Domain details using C sd-bus apis

I want to read the data available in Link 2; mainly DNS Servers and DNS Domains. I am not able to figure out how to read those data using c sd bus api.
test#ubuntu:~/Desktop/$systemd-resolve --status
Global
DNSSEC NTA: 10.in-addr.arpa
16.172.in-addr.arpa
....bla bla.
Link 2 (ens33)
Current Scopes: DNS
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
DNS Servers: 49.205.72.130
183.82.243.66
DNS Domain: ~.
If I had to use GetLink method, how could I get the DNS Servers and Domain information?
Needed something similar as below
#define DESTINATION "org.freedesktop.resolve1"
#define PATH "/org/freedesktop/resolve1"
#define INTERFACE "org.freedesktop.resolve1.Manager"
#define MEMBER "GetLink"
static int log_error(int error, const char *message) {
errno = -error;
fprintf(stderr, "%s: %m\n", message);
return error;
}
static int print_unit_path(sd_bus *bus) {
sd_bus_message *m = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *reply = NULL;
int r;
r = sd_bus_message_new_method_call(bus, &m,
DESTINATION, PATH, INTERFACE, MEMBER);
if (r < 0)
return log_error(r, "Failed to create bus message");
r = sd_bus_message_append(m, "i", 2);
if (r < 0)
return log_error(r, "Failed to append to bus message");
r = sd_bus_call(bus, m, -1, &error, &reply);
if (r < 0)
return log_error(r, "Call failed");
const char *ans;
r = sd_bus_message_read(reply, "o", &ans);
if (r < 0)
return log_error(r, "Failed to read reply");
printf("Link is \"%s\".\n", ans);
}
int main(int argc, char **argv) {
sd_bus *bus = NULL;
int r;
r = sd_bus_open_system(&bus);
if (r < 0)
return log_error(r, "Failed to acquire bus");
print_unit_path(bus);
}
Output: "/org/freedesktop/resolve1/link/_32"
How do I read the DNS using this link?
Thanks

Packet sniffer for link layer protocols

I am trying to convert a program called Responder which is written in Python to a C version. One of the spots I am stuck on is the listeners that listen on different ports. Responder listens for SMB on port 445 and 139. I created a small snippet that will listen on those ports as well. But when I run my program, I get no data.
void sniff(int PORT) {
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
if ((server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == 0) {
return;
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
return;
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
return;
}
if (listen(server_fd, 3) < 0) {
return;
}
printf("listen done.\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
return;
}
valread = read( server_fd , buffer, 1024);
printf("%s\n",buffer );
return;
}
If I do the above, I don't get anything.

How to get ipv4 address of an interface using libnl3 (netlink version 3) on linux?

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);
}

ftp client on linux '500 '': command not understood. '

i try to make simple ftp client to get list of files on bsd sockets. Here it is:
connectTo(int client_socket,
struct sockaddr_in* addr,
char* ipv4Address,
char* user,
char* password,
char* response) // buffer wchich store responses
{
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if(socket < 0)
{
printf("Can not create socket");
return 2;
}
addr->sin_family = AF_INET; // address family - internet socket
addr->sin_port = htons(PORT_NUMBER);
addr->sin_addr.s_addr = inet_addr(ipv4Address);
if(connect(client_socket,(struct sockaddr*)addr,sizeof(*addr)) < 0)
{
printf("Can not connect!\n");
return 3;
}
int size_read = recv(client_socket, response, BUF_SIZE, 0);
printf("size_read = %d\n",size_read);
response[size_read] = '\0'; // for not printing rubbish
printf("%s\n",response);
printf("sending username\n");
char *username = strdup("USER trenkinan\r\n");
send(client_socket,username,strlen(username)+1,0);
size_read = recv(client_socket, response, BUF_SIZE, 0);
// printf("size_read = %d\n",size_read);
response[size_read] = '\0'; // for not printing rubbish
printf("%s",response);
if(strstr(response,"331"))
{
//printf("sending password\n");
char *passwd = strdup("PASS test\r\n");
// printf("passwd string: %s",passwd);
int sent = send(client_socket,passwd,strlen(passwd)+1,0);
size_read = recv(client_socket, response, BUF_SIZE, 0);
response[size_read] = '\0'; // for not printing rubbish
printf("%s",response);
//printf("sent bytes: %d\n", sent);
}
return 0;
}
I use ftp server from debian repository(ftpd) on my work station. I try to execute this code and when i send password server answer that 500 '': command not understood.
I use wireshark to see what happens and all packages from my program looks fine, i use ftp command(lightweight ftp client on linux) to connect and it works but packages from that client looks the same as from my own client. Any ideas?
So, i found a bug: strlen(username) instead of strlen(username)+1. I hope it will help to someone.

API used to know IP of the Interface in VC++?

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

Resources