Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How can i connect to a specific port in remote host by using connect()? C++ - Linux Socket Programming

Posted on 2008-10-24
8
986 Views
Last Modified: 2012-08-13
I'm trying to write a code that connects to scan range of ports of one of my hosts remotely ....
I submitted a rough code just to illustrate the point. Please look at the places where i commented with asteriks //*******.

I'm using connect(). connect function will not connect if a port is not specified.

getaddrinfo(remoteIP, NULL, &hints, &results); this piece of code, will take remoteIP user entered and put it into ai_addr. Second parameter represents local port number, i put NULL, because i'm after the remoteIP ports not my local ports. Can you help me how to connect to a specific port for a remote host?

Note: i'm using getaddrinfo() which supposes to do everything automatically, instead of filling things manually.

I hope my question is clear enough.
#include<iostream>
#include<string>
#include<sstream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<errno.h>
using namespace std;
 
int main()
{
	struct addrinfo hints;      	//fill your host info - hints is input
	struct addrinfo *results;	//gets your host info - results is output
	//remoteIP variable that holds th given IP
	int startingPort;               //stores the starting range of port number
	int endingPort;                 //stores the ending rage of port number
	int status;                     //receives the status of your pc address
	
	system("clear");
	
	//set size of hints to zero
	memset(&hints, 0, sizeof hints);
 
	//fill some of your host address info
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
 
	//ask user to enter remoteIP...
	
	//remoteIP variable carries the entered IP
 
	//ask port range from user
	cout<<"Enter Starting Port: ";
	cin>>startingPort;
 
	cout<<"Enter Ending Port: ";
	cin>>endingPort;
 
	cout<<endl;
 
	cout<<"Start Scanning Ports on: "<<remoteIP<<endl;
 
	//check the status
	while(startingPort <= endingPort)
	{
		//************I put NULL in the middle because there is no 
		//***********need to specify any port on our local machine
		//***********connect() will get specify any random local IP
		//***********for us**********************************
		status = getaddrinfo(remoteIP, NULL, &hints, &results);
 
		if(status != 0)
		{
			fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
			exit(1);
		}
 
		//create a socket.
		int socketfd;
		socketfd = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
 
		if(socketfd == -1 )
		{
			cout<<"Error: failed to create a socket.\n";
			return 2;
		}
 
 
		//***********************connect to remoteIP*************************************//
		//*********ai_addr holds the ip address & should hold the port too. However,//
		//*********how can i insert the starting port into ai_addr?********//
		int connectStatus;
		connectStatus = connect(socketfd, results->ai_addr, results->ai_addrlen);
	
		if(connectStatus == -1 )
		{		
			cout << "connect failed; reason = " << strerror(errno) <<endl; 
	
		}else{
			cout<<"Port "<<currentPort<<" is OPEN.\n";
		}
 
		close(socketfd);
	
		//move to the next port in the specified range
		startingPort++;
 
	}
 
	return 0;
}

Open in new window

0
Comment
Question by:F-J-K
  • 5
  • 2
8 Comments
 
LVL 6

Accepted Solution

by:
Werrock earned 250 total points
ID: 22797687
Set the port in results->ai_addr before calling connect.

results->ai_addr.sin_port = htons(PORTNUMBER);
0
 
LVL 1

Author Comment

by:F-J-K
ID: 22800018
Note: ai_addr is of type struct sockaddr .....
sin_port is in struct socksaddr_in

I should do this:

struct sockaddr *specifyPort = (struct sockaddr_in*)results->ai_addr;

specifyPort->sin_port = htons(currentPort);

BUT here we fill specifyPort, not "results" & we are going to connect using "results" like this

connectStatus = connect(socketfd, results->ai_addr, results->ai_addrlen);

Questions:

1. As far as i know, any changes i make in specifyPort will effect results because specifyPort points to the same place where results point, am i right?

2. I did the steps i just mentioned above, however i get compiler error:

RemotePortScanner.cpp: In function int main():
RemotePortScanner.cpp:160: error: invalid conversion from char* to uint16_t
RemotePortScanner.cpp:160: error:   initializing argument 1 of uint16_t htons(uint16_t)

Can you guide me please?!


struct addrinfo {
 
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
 
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC  .... main result will be given 		   // sa_family in ai_addr
 
int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
 
int ai_protocol; // use 0 for "any"
 
size_t ai_addrlen; // size of ai_addr in bytes
 
struct sockaddr *ai_addr; // struct sockaddr_in or _in6
 
char *ai_canonname; // full canonical hostname
 
struct addrinfo *ai_next; // linked list, next node
 
};
 
struct sockaddr {
 
unsigned short sa_family;
char sa_data[14]; // 14 bytes of protocol address
 
};
 
struct sockaddr_in {
 
short int sin_family; // Address family, AF_INET
 
unsigned short int sin_port; // Port number
 
struct in_addr sin_addr; // Internet address
 
unsigned char sin_zero[8]; // Same size as struct sockaddr
 
};

Open in new window

0
 
LVL 1

Author Comment

by:F-J-K
ID: 22800144
This one seems to work when i put the IP address as 127.0.1.1
It could catch the open ports and the closed ones.

I did not try to put any of my remote address yet, as i can not recall it.
I will try it when i get home.

Can you check my code below please...

Thats where i made the change

//******************************************************************
            struct sockaddr_in *specifyPort = (struct sockaddr_in *)results->ai_addr;

            specifyPort->sin_port = htons(startingPort);
//****************************************************************
#include<iostream>
#include<string>
#include<sstream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<errno.h>
using namespace std;
 
 
struct addrinfo hints;      	//fill your host info - hints is input
struct addrinfo *results;	//gets your host info - results is output
char *remoteIP = new char[40];  //holds inserted remote IP
string tempPort;                //holds ports temporarly
int startingPort;               //stores the starting range of port number
int status;                     //receives the status of your pc address
int currentPort;           //holds current port
 
//program description
void progDesc()
{
     cout<<"This is a simple port scanner, scan range of\n";
     cout<<"ports on your local machine...\n"<<endl;
 
}
 
 
//getaddrinfe locates your machine, more specific
//details of your host address is returned to results. 
void getAddrIn()
{
	status = getaddrinfo(remoteIP, NULL , &hints, &results);
 
	if(status != 0)
	{
		fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
		exit(1);
	}
}
 
//get host name of the remote IP
void grabHostName()
{
	//carries your target's host name
	char hostName[100];
	struct addrinfo *p;
	
	cout<<"Host name for \""<<remoteIP<<"\" is:";
 
	//print all your local IP Addresses
	for(p = results; p != NULL; p = p->ai_next)
	{
		void *addr;
		string ipVer;
		if(p->ai_family == AF_INET)
		{
			struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
			addr = &(ipv4->sin_addr);
			ipVer = "IPv4";
 
		}else{
			struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
			addr = &(ipv6->sin6_addr);
			ipVer = "IPv6";
		}
 
		//inet_ntop(p->ai_family, addr, ipString, sizeof ipString);
		cout<<""<<ipVer<<": ";
		//printf("%s\n", ipString);
		cout<<endl;
	}	
}
 
 
//Run the program
int main()
{
	int endingPort;                 //stores the ending rage of port number
 
	system("clear");
 
	//tell user what program does
	progDesc();
	
	//set size of hints to zero
	memset(&hints, 0, sizeof hints);
 
	//fill some of your host address info
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
 
	//ask for remote IP
	cout<<"Please enter your target IP: ";
	cin>>remoteIP;
 
	getAddrIn();
 
	//ask port range from user
	cout<<"Enter Starting Port: ";
	cin>>startingPort;
 
	cout<<"Enter Ending Port: ";
	cin>>endingPort;
 
	cout<<endl;
 
	cout<<"Start Checking: "<<endl;
 
 
	//check the status
	while(startingPort <= endingPort)
	{
		//call getaddrinfo()
		getAddrIn();
 
		//create a socket.
		int socketfd;
		socketfd = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
 
		if(socketfd == -1 )
		{
			cout<<"Error: failed to create a socket.\n";
			return 2;
		}
 
//******************************************************************
		struct sockaddr_in *specifyPort = (struct sockaddr_in *)results->ai_addr;
 
		specifyPort->sin_port = htons(startingPort);
//****************************************************************
		int connectStatus;
		connectStatus = connect(socketfd, results->ai_addr, results->ai_addrlen);
	
		if(connectStatus == -1 )
		{		
			if(errno == ECONNREFUSED)
				cout<<"Port "<<startingPort<<" is Closed or Blocked.\n";
			//Alternatively, you can do:
			//cout << "connect failed; reason = " << strerror(errno) <<endl; 	
		}else{
			cout<<"Port "<<startingPort<<" is OPEN.\n";
		}
 
 
		close(socketfd);
	
		//move to the next port in the specified range
		startingPort++;
 
	}
 
	//deallocate memory
	delete[] remoteIP;
 
	//free linkedlist of struct addrinfo *results 
	freeaddrinfo(results);
 
	return 0;
}

Open in new window

0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
LVL 6

Expert Comment

by:Werrock
ID: 22800165
In status = getaddrinfo(remoteIP, NULL, &hints, &results);
NULL is the servname value. You can specify a port number here, for example:
char *port = "80";
status = getaddrinfo(remoteIP, port, &hints, &results);
0
 
LVL 1

Author Comment

by:F-J-K
ID: 22800288
Now thats confuses me, as what i have been reading in Beej's Guide to Network Programming, the place of NULL, carries a local port number. If i do not want to specify any local port number, i should put NULL.
Connect() will specify one for me automatically.
If i'm a server & want to listen on port e.g. 3460, i would do

status = getaddrinfo(localIP, 3460, &hints, &results);

I may understood it wrong! i will double check...
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 250 total points
ID: 22802109
>> 1. As far as i know, any changes i make in specifyPort will effect results because specifyPort points to the same place where results point, am i right?

Yes.


>> RemotePortScanner.cpp:160: error: invalid conversion from char* to uint16_t

htons takes a uint16_t, not a char*. You have to pass it a uint16_t.
0
 
LVL 1

Author Comment

by:F-J-K
ID: 22802259
Yes this seems to work, i just upload it to my remote host part of a UNIX server. I compiled the code by g++ under UNIX Solaris, i keep getting these extra unknown errors:

Undefined first referenced
symbol in file
__xnet_connect /var/tmp//ccidZvCu.o
__xnet_socket /var/tmp//ccidZvCu.o
getaddrinfo /var/tmp//ccidZvCu.o
freeaddrinfo /var/tmp//ccidZvCu.o
gai_strerror /var/tmp//ccidZvCu.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

I think the problem is about linking. Can you tell me how to link in command line, i have not done it before..

g++ myCode.cpp ....... how to link?
i will google it anyway.

I will run it in Unix & scan the ports of the current machine i'm in right now, to see if it works or not.
I passed 127.0.1.1 to remoteIP, it scanned well. I hope its going to work for remote hosts too.



0
 
LVL 1

Author Comment

by:F-J-K
ID: 22802666
Worked i had to do

g++ fileName -lsocket -lnsl
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question