The thing is char currentPort[10] does not reset it self to empty, so it can take another value of 10 chars. I do not how to make currentPort[10] empty at the end of every loop. In other words, relating to my trial-and-error tries, i noticed the new value in every loop append beside the old value, untill hits array size limit. I treid what you have said, but i get completely unrelated error! I can't illustrate until you see my code.
The following program scans range of port of the local machine that program is running on. Hence, this is my first program so i do not really know if the algorithm is right or now...I only care how to solve this loop thing for now. First of all, prints the name of the host name.
#include<iostream>
#include<string>
#include<sstream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.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 *pcName = new char[40]; //holds your pc name
string tempPort; //holds ports temporarly
int startingPort; //stores the starting range of port number
int status; //receives the status of your pc address
char currentPort[10]; //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;
}
//call host (local machine) name
void callHostName()
{
/**get your computer's name**/
//char *pcName = new char[40]; //holds your pc name - i made it static
size_t pcNameSize; //holds size of the name
int hostNameStatus; //holds status of the function whether it succeeded or failed
hostNameStatus = gethostname(pcName, pcNameSize); //gethostname grabs your pc name & pass it to pcName
//make sure function host name returned successfully
if(hostNameStatus == -1 )
{
cout<<"Error: could not locate your host name\n";
exit(1);
}
//print machine name
cout<<"Your Machine Name: ";
cout<<pcName<<endl;
cout<<endl;
//deallocate memory
//delete[] pcName; - i put it inside main()
}
//getaddrinfe locates your machine, more specific
//details of your host address is returned to results.
void getAddrIn()
{
/***first parameter of getaddrinfo() is the host name to connect to, or an IP address to
connect to. If you put a host name in the first parameter, you can get its ip address from
results, but if you put an IP address as the first parameter, getaddrinfo() will not be able
to obtain the hostname, so getaddrinfo can lookup an IP address for a hostname, but can not
give you a host name for a given IP address as far as i know. To get a host name for an
IP Address, you need to use gethostname() or getnameinfo(). You could simply put NULL in the
first parameter if you want to listen on your host's IP address, port "currentPort". Note that
this doesn't actually do any listening or network setup; it merely sets up structures we'll
use later . See "hints.ai_flags = AI_PASSIVE;" at the top; this tells getaddrinfo() to assign
the address of my local host to the socket structures. - you can put a specific address in as
the first parameter to getaddrinfo() where I currently have NULL. If you put NULL in the first
parameter, this will assign the address of your local host to the socket structure. Putting NULL
as the first parameter will not print your local IP address to the screen when you request it
from results - you will just see an artibetry result like - IPv6 ::. Go ahead & change pcName to
NULL to see this in action! pcName here carries the name of the local machine....***/
status = getaddrinfo(pcName, currentPort, &hints, &results);
if(status != 0)
{
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
}
//get local IP which is usually version 4
void grabLocalIP()
{
//carries your local IP
char ipString[INET6_ADDRSTRLEN];
struct addrinfo *p;
cout<<"IP Address for "<<pcName<<" is of type ";
//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;
}
}
//convert a port from int to *char, so it can be passed into getaddrinfo()
//call this function before the loop starts
void convertPortsToString()
{
//convert startingPort to string. After that, convert the string into *char...
//string tempPort; make it static
stringstream out;
out<<startingPort;
tempPort = out.str(); //tempPort carries startingPort in string format
//convert tempPort to *char - currentPort going to be passed into getaddrinfo()
//char currentPort[10]; - i made it static
strcpy(currentPort, tempPort.c_str());
}
//convert a port from int to *char, so it can be passed into getaddrinfo()
//call this function at the bottom of the loop
void convertIncrementedPortsToString()
{
//you have to declare out in every loop, otherwise the
//incremented ports will concatenated with the previous ports.
stringstream out;
out<<startingPort;
tempPort = out.str(); //tempPort carries startingPort in string format
strcpy(currentPort, tempPort.c_str()); //convert the string to *char
}
//Run the program
int main()
{
//struct addrinfo hints; //fill your host info - hints is input - i made it static
//struct addrinfo *results; //gets your host info - results is output - i made it static
//int status; //receives the status of your pc address - i made it static
//int startingPort; //stores the starting range of port number - i made it static
int endingPort; //stores the ending rage of port number
system("clear");
//tell user what program does
progDesc();
//grab the name of the local machine (host)
callHostName();
//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;
//call getaddrinfo() to output to "results"
//so you can grab the local IP from results
getAddrIn();
//grab your machine local IP
grabLocalIP();
//ask port range from user
cout<<"Enter Starting Port: ";
cin>>startingPort;
cout<<"Enter Ending Port: ";
cin>>endingPort;
cout<<endl;
cout<<"Start Checking: "<<endl;
//convert a port from int to *char, so it can be passed into getaddrinfo()
convertPortsToString();
//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;
}
//connect to your own IP address in every loop with
//a new port, connect() will associate your socket
//with the "current port number & your local IP address".
int connectStatus;
connectStatus = connect(socketfd, results->ai_addr, results->ai_addrlen);
if(connectStatus == -1 )
{
cout<<"Port "<<currentPort<<" is Closed or Blocked.\n";
}else{
cout<<"Port "<<currentPort<<" is OPEN.\n";
}
//close the created socket, because
//a new one should be created in every
//loop because connect will fail if the
//socket is already connected. You'd
//need to disconnect or close the socket
//at the end of the loop. I choose to
//close & create one in the next loop.
close(socketfd);
//move to the next port in the specified range
startingPort++;
/***convert the incremented port to *char***/
convertIncrementedPortsToString();
}
//deallocate memory
delete[] pcName;
//free linkedlist of struct addrinfo *results
freeaddrinfo(results);
return 0;
}
If i take this out, my program return hostNameStatus as failed! Completely unrelated. Same problem happens if i take off "string tempPort & stringstream out", Weird! Isn't it!