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
976 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 6

Expert Comment

by:Werrock
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:F-J-K
Comment Utility
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
Comment Utility
>> 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
Comment Utility
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
Comment Utility
Worked i had to do

g++ fileName -lsocket -lnsl
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
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…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
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.

763 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now