How to get domain ip address using domain name in C++? - c++

i am using visual c++,
I want to get a domain ip address from domain name..
how do i get it..
i already tried gethostbyname function...
here my code...
HOSTENT* remoteHost;
IN_ADDR addr;
hostName = "domainname.com";
printf("Calling gethostbyname with %s\n", hostName);
remoteHost =gethostbyname(hostName);
memcpy(&addr.S_un.S_addr, remoteHost->h_addr, remoteHost->h_length);
printf("The IP address is: %s\n", inet_ntoa(addr));
But i get a wrong ip address.

Here's complete source code to a little utility I find handy at times (I've named it "resolve"). All it does is resolve a domain name to a numeric IP (v4) address, and print it out. As-is, it's for Windows -- for Linux (or similar) you'd just need to get rid of the use_WSA class (and object thereof).
#include <windows.h>
#include <winsock.h>
#include <iostream>
#include <iterator>
#include <exception>
#include <algorithm>
#include <iomanip>
#include "infix_iterator.h"
class use_WSA {
WSADATA d;
WORD ver;
public:
use_WSA() : ver(MAKEWORD(1,1)) {
if ((WSAStartup(ver, &d)!=0) || (ver != d.wVersion))
throw(std::runtime_error("Error starting Winsock"));
}
~use_WSA() { WSACleanup(); }
};
int main(int argc, char **argv) {
if ( argc < 2 ) {
std::cerr << "Usage: resolve <host-name>";
return EXIT_FAILURE;
}
try {
use_WSA x;
hostent *h = gethostbyname(argv[1]);
unsigned char *addr = reinterpret_cast<unsigned char *>(h->h_addr_list[0]);
std::copy(addr, addr+4, infix_ostream_iterator<unsigned int>(std::cout, "."));
}
catch (std::exception const &exc) {
std::cerr << exc.what() << "\n";
return EXIT_FAILURE;
}
return 0;
}
This also uses the infix_ostream_iterator I've posted previously.

Related

How to create or manage Libuv TCP server in a c++ fuction?

I am trying to create a TCP server in a function int create_server(int port_number, char ip_addr_string[IPV4_ADDR_SIZE]) which is called in main.
When I run the c++ code given below: Assertion failed: (w->fd >= 0), function uv__io_poll, file kqueue.c, line 149.
#include <iostream>
#include <vector>
#include <algorithm>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <future>
#include <sys/types.h>
#include <uv.h>
#define IPV4_ADDR_SIZE 15
uv_loop_t* loop;
struct sockaddr_in addr;
std::map <int, uv_tcp_t * > pool;
int create_tunnel(int port_number, char ip_addr_string[IPV4_ADDR_SIZE]){
uv_tcp_t global_server;
uv_tcp_init(loop, &global_server);
uv_ip4_addr("0.0.0.0", port_number, &addr);
uv_tcp_bind(&global_server, (const struct sockaddr *)&addr, 0);
int r = uv_listen((uv_stream_t *)&global_server, 128, NULL);
if(r){
fprintf(stderr, "Listen error: %s \n", uv_strerror(r));
}
else{
fprintf(stdout, "Listening on: %d \n", port_number);
}
pool[rand()] = &global_server;
return r;
}
int main(int argc, const char *argv[]){
int status = 1;
loop = uv_default_loop();
uv_loop_init(loop);
loop->data = &pool;
status = create_tunnel(7011, (char*)"0.0.0.0");
std::cout<< "status: " << status << std::endl;
uv_run(loop, UV_RUN_DEFAULT);
return 0;
I think this error is because the servers created are not tracked by the event_loop when the create_server function ends, but I am not sure.
Any help, please?

ServerSocket throws InvalidArgumentException, but docs don't specify why. Why?

I'm using Poco to create a webserver. I ran into an error with the ServerSocket library. Here's the minimum code to reproduce the error.
#include <iostream>
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"
#define PORT (unsigned short) 3000
int main()
{
Poco::Net::ServerSocket x;
x.bind(PORT);
Poco::Net::StreamSocket conn;
Poco::Net::SocketAddress clientAddr;
try {
conn = x.acceptConnection(clientAddr);
}
catch (Poco::InvalidArgumentException e) {
printf("Oh no! %s\n", e.displayText().c_str());
return 1;
}
printf("Huzzah!");
return 0;
}
I tried to look at [the docs] (https://pocoproject.org/docs/Poco.Net.ServerSocket.html#25093) to understand the error, but it doesn't even list this function as throwing this error. I've also tried the parameterless version of the function, and it still throws this exception, (which indicates to me it's not the function but a sub function throwing the error). Why? and how can I fix it, or work around it?
As WhozCraig said, the problem was not putting it in listening state. The code should be
#include <iostream>
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"
#define PORT (unsigned short) 3000
int main()
{
Poco::Net::ServerSocket x;
x.bind(PORT);
x.listen(1); // or number of acceptable connections
Poco::Net::StreamSocket conn;
Poco::Net::SocketAddress clientAddr;
try {
conn = x.acceptConnection(clientAddr);
}
catch (const Poco::InvalidArgumentException& e) {
printf("Oh no! %s\n", e.displayText().c_str());
return 1;
}
printf("Huzzah!");
return 0;
}

How to use libssh's SCP with ssh::Session

I am using libssh's C++ wrapper (libsshpp.hpp) and I'm trying to call ssh_scp_new for an SCP routine by giving it my ssh::Session variable but I get the following error:
cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’ for argument ‘1’ to ‘ssh_scp_struct* ssh_scp_new(ssh_session, int, const char*)’
I am able to get SCP working by completely not using the C++ ssh::Session class and going with the C example but obviously this is not my preferred workaround. Looking at libsshpp.hpp I was able to find a getCSession() function but it is only privately accessible and I'm not sure how to use it (or if it's even what I think it is).
Here is my sample code:
#include <iostream>
#include <fstream>
#include <libssh/libsshpp.hpp>
int main()
{
int port = 22;
int verbosity = SSH_LOG_PROTOCOL;
ssh::Session session;
try
{
session.setOption(SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
session.setOption(SSH_OPTIONS_PORT, &port);
session.setOption(SSH_OPTIONS_USER, "user");
session.setOption(SSH_OPTIONS_HOST, "host");
session.connect();
if (session.isServerKnown() != SSH_SERVER_KNOWN_OK)
{
if (session.writeKnownhost() != SSH_OK)
{
std::cout << "writeKnownHost failed" << std::endl;
}
else
{
session.connect();
}
}
if (session.userauthPassword("password") !=
SSH_AUTH_SUCCESS)
{
std::cout << "Authentication Error" << std::endl;
}
ssh_scp scp;
int rc;
// error cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’
scp = ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
}
catch (ssh::SshException e)
{
std::cout << "Error during connection : ";
std::cout << e.getError() << std::endl;
}
return 0;
}
How do I SCP send or receive a file with libssh using C++ methods?
Thanks!
As you can see the error. You have to decide to weather use ssh::Session class or ssh_session structure. The libssh library is a C library, and it has just a C++ wrapper (that may not contain all functionalities like in the original language)
Here is how to send connect and send files using libssh library (current stable version 0.7.3) according to official documentation.
Using ssh_session: (in C)
-use ssh_new() to create a ssh_session pointer.
-use int ssh_connect(ssh_session session) to connect.
-use *int ssh_options_set ( ssh_session session, enum ssh_options_e type,const void * value )* Take a look on this documentation http://api.libssh.org/stable/group__libssh__session.html#ga7a801b85800baa3f4e16f5b47db0a73d
-add your controls
-send file using ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
-free the connection using ssh_free(ssh_session session)
//You can try this simple program (from official libssh tutorials)
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int scp_write(ssh_session session)
{
ssh_scp scp;
int rc;
scp = ssh_scp_new
(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
if (scp == NULL)
{
fprintf(stderr, "Error allocating scp session: %s\n", ssh_get_error(session));
return SSH_ERROR;
}
rc = ssh_scp_init(scp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
ssh_scp_free(scp);
return rc;
}
ssh_scp_close(scp);
ssh_scp_free(scp);
return SSH_OK;
}
int main(int argc, char* argv[])
ssh_session my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
return 1;
scp_write(my_ssh_session );
ssh_free(my_ssh_session);
return 0;
}
Using ssh::Session (in C++) well, no wrapper allows this currently :( .
Here is some useful examples for the use of libssh library. Hope it helps !
http://api.libssh.org/master/libssh_tutorial.html

libnids didn't capture xmpp packet

this program can detect http flow and etc....
but it ignores XMPP flow ; i don't know why ?
(I guess this is a port problem , but i don't know where i should fix it )
Below are the relevant sections from main.cpp :
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include "nids.h"
#include <cstdlib>
#include <unistd.h>
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
// struct tuple4 contains addresses and port numbers of the TCP connections
// the following auxiliary function produces a string looking like
// 10.0.0.1,1024,10.0.0.2,23
char *
adres (struct tuple4 addr)
{
static char buf[256];
strcpy (buf, int_ntoa (addr.saddr));
sprintf (buf + strlen (buf), ",%i,", addr.source);
strcat (buf, int_ntoa (addr.daddr));
sprintf (buf + strlen (buf), ",%i", addr.dest);
return buf;
}
void
tcp_callback (struct tcp_stream *a_tcp, void ** this_time_not_needed)
{
printf("packet captured !\n");
}
int
main ()
{
// here we can alter libnids params, for instance:
// nids_params.n_hosts=256;
struct nids_chksum_ctl nochksumchk;
nochksumchk.netaddr = 0;
nochksumchk.mask = 0;
nochksumchk.action = NIDS_DONT_CHKSUM;
//char fileName[] = "/home/test.pcap";
//nids_params.filename =fileName;
nids_register_chksum_ctl(&nochksumchk, 1);
char myDevice [] = "eth0";
nids_params.device =myDevice;
if (!nids_init ())
{
fprintf(stderr,"%s\n",nids_errbuf);
exit(1);
}
nids_register_tcp ( (void*)tcp_callback);
nids_run ();
return 0;
}
My pcap file has some problem about syncing in tcp connection .
So above snippet code of libnids is correct !

Using select without listen()ing, possible?

I am building a client that:
Should be able to recieve information from both the server and the standart input
Should be able to recieve information from the server without asking, for example when another client sends a message.
To do so I tried using select to monitor both possible inputs.
What happens is that when a keyboard input is monitored I send a message to the client and I expect one back, so there's no problem. But when the server sends an unexpected message nothing happens, and I don't know why. Is using select() the proper way to do so? Is it even possible to use select() without listen()ing?
Here's my code (compileable):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
#include <fstream>
#define MAX_CLIENT_NAME 30
#define MAX_TWIT_SIZE 140
#define NUM_OF_ARG 4
#define ERROR -1
#define GREAT_SUCCESS 0
#define OK "OK"
#define EXIT "EXIT"
using std::string;
using std::cerr;
using std::endl;
using std::cout;
string clientName;
int srverfd, numbytes, status, maxSock ;
fd_set inputFdSet; /* Socket file descriptors we want to wake
up for, using select() */
int establishConnection(char * serverAddress,char * port){
if ((srverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return ERROR;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
inet_aton(serverAddress, &server.sin_addr);
server.sin_port = htons(atoi(port));
memset(&(server.sin_zero), '\0', 8);
if (connect(srverfd,(const struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {
perror("connect");
close(srverfd);
return ERROR;
}
maxSock = srverfd;
return GREAT_SUCCESS;
}
const char * getUserTweet(){
string temp;
getline(std::cin,temp);
return temp.c_str();
}
void sendMessage(string message){
if ((numbytes = send(srverfd, message.c_str(), message.length(), 0)) == -1) {
perror("sendMessage");
close(srverfd);
}
cout<<"Message sent: "<< message << endl;
return;
}
const char * getMessage(){
char buf[MAX_TWIT_SIZE];
memset(buf,'\0',MAX_TWIT_SIZE);
if ((numbytes = recv(srverfd, buf, 140, 0)) == -1) {
perror("getMessage");
close(srverfd);
}
string temp = buf;
return temp.c_str();
}
void build_select_list() {
FD_ZERO(&inputFdSet);
FD_SET(srverfd,&inputFdSet);
FD_SET(STDIN_FILENO,&inputFdSet);
if (STDIN_FILENO > maxSock)
maxSock = STDIN_FILENO;
return;
}
void readSocket(fd_set tempfd) {
const char * tweet, * inMessage;
if (FD_ISSET(srverfd,&tempfd)) {
inMessage = getMessage();
cout << inMessage << endl;
}
if (FD_ISSET(STDIN_FILENO,&tempfd)) {
tweet = getUserTweet();
sendMessage(tweet);
inMessage = getMessage();
if (strcmp(inMessage,OK) != 0) {
cout << inMessage << endl;
}
if (strcmp(inMessage,EXIT) == 0) {
return;
}
}
return;
}
int main (int argc, char *argv[] ){
int value;
bool clientON = false;
if(establishConnection(argv[2],argv[3])){
cerr << "usage: failed to make connection" << endl << "exiting..." << endl;
exit(EXIT_FAILURE);
}
cout << "Connected successfully" << endl;
sendMessage("CONNECT "+clientName); //Connect
if(strcmp(getMessage(),OK) == 0){
clientON = true;
}
while(clientON){
build_select_list();
value = select(maxSock, &inputFdSet, NULL, NULL, NULL);
if (value < 0) {
perror("select");
exit(EXIT_FAILURE);
}
if (value == 0) {
continue;
}
else {
readSocket(inputFdSet);
}
}
sendMessage("DISCONNECT");
if(strcmp(getMessage(),OK) == 0){
// do nothing
}
close(srverfd);
return 0;
}
Your select call is invalid. The first parameter must be the highest file descriptor in any of the sets, plus one.
As you have it, an event on srverfd will not "wake up" the select call (unless STDIN_FILENO was somehow less than srverfd, in which case stdin events wouldn't unlock select - but that won't happen in practice).
There are quite a few other problems with your code. (It doesn't really look like C++.)
getUserTweet is unreliable (undefined behavior - temp is destroyed as soon as the function returns, so the char* you return has disappeared by the time its caller will try to use it). Same for getMessage. To remedy that, use std::string everywhere, and only extract the char* when you call into C library functions).
readSocket needlessly copies the FD set (can be expensive).
You should really get rid of all those globals - build one or two classes to encapsulate that state and the networking functions, or something like that.