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
987 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Don't miss ATEN at NAB Show April 24-27!

Visit ATEN at NAB Show to learn how our "Seamlessly Entertaining" solutions deliver fast, precise video streaming without delays for the broadcasting and media environment. ATEN will showcase its 16x16 Modular Matrix Switch (VM1600) and KVM Over IP Solution (KE6900 series).

Question has a verified solution.

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

Suggested Solutions

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Note: for this to work properly you need to use a Cross-Over network cable. 1. Connect both servers S1 and S2 on the second network slots respectively. Note that you can use the 1st slots but usually these would be occupied by the Service Provide…
The goal of this video is to provide viewers with basic examples to understand opening and reading files 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.

735 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