F-J-K
asked on
How can i connect to a specific port in remote host by using connect()? C++ - Linux Socket Programming
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.
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;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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);
//************************ ********** ********** ********** **********
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;
}
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);
NULL is the servname value. You can specify a port number here, for example:
char *port = "80";
status = getaddrinfo(remoteIP, port, &hints, &results);
ASKER
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...
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...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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.
ASKER
Worked i had to do
g++ fileName -lsocket -lnsl
g++ fileName -lsocket -lnsl
ASKER
sin_port is in struct socksaddr_in
I should do this:
struct sockaddr *specifyPort = (struct sockaddr_in*)results->ai_a
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:
RemotePortScanner.cpp:160:
Can you guide me please?!
Open in new window