/*
* IP Port Scanner Version 1.0
* This is a program which scans the ports of a computer to find out
* the listening TCP/IP ports.
*
* Copyright (C) 1999 Victor STANESCU
*/
/*
* This program is free software; You can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your opinion) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <bruno@lmn.pub.ro>, or by paper mail
* Victor STANESCU, Tineretului 27 Ave., Bl. 18, App. 36, Sect. 4,
* Bucharest, ROMANIA.
*
* For other details, please read the README which should be included in
* every distribution of this program. If you do not have this file, please
* contact me as specified.
*/
#include <arpa/inet.h rel='nofollow' onclick='return false;'>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int list_all=0,out_to_file=0;
void give_help(char *prgname)
{
printf("Use: %s hostname||ip_address [options]\n",prgname);
printf("Where options are:\n");
printf("\t-b port\t\tBegin scan at this port (default 0)\n");
printf("\t-e port\t\tEnd scan at this port (default 1023)\n");
printf("\t-M mask\t\tThe mask can be either a network mask or\n");
printf("\t\t\t a plain number, specifying the number of 1's at the\n");
printf("\t\t\t left side of the network mask. Thus, a mask of 24\n");
printf("\t\t\t is equivalent with 255.255.255.0. With this option\n");
printf("\t\t\t set, it will scan all the network to whom the\n");
printf("\t\t\t specified machine belongs.\n");
printf("\t-S port\t\tThe source port from which the packets are sent.\n");
printf("\t\t\t It works slower with this option set, as it needs to\n");
printf("\t\t\t wait for the source port to be closed after each\n");
printf("\t\t\t connection.\n");
printf("\t-a\t\tList all ports, as they are scanned, even if they are\n");
printf("\t\t\t closed.\n");
printf("\t-o\t\tOutput to files. For each machine scanned, saves a\n");
printf("\t\t\t file named ip_address.dump.\n");
printf("\n");
}
void put_header()
{
printf("-------------------------------------------\n");
printf(" IPPS 1.0 IP Port Scanner \n");
printf("(C) 1999 Victor STANESCU <bruno@lmn.pub.ro>\n");
printf("-------------------------------------------\n");
}
void scan(unsigned int bp, unsigned int ep, unsigned int sport, struct sockaddr_in source, struct sockaddr_in dest)
{
int sockfd,err,result;
unsigned int i;
char tmp[20],fname[25],out[50];
struct servent *portname;
FILE *ff;
if(sport==-1)
snprintf(tmp,18,"%s","(unspecified)");
else
snprintf(tmp,18,"%d",sport);
if(out_to_file)
{
snprintf(fname,24,"%s.dump",inet_ntoa(dest.sin_addr));
ff=fopen(fname,"wt");
if(!ff)
{
printf("**ERROR** Could not open file %s\n\n",fname);
printf("Seems that you are not allowed to write here.\n");
exit(4);
}
fprintf(ff,"Scan range: %d -> %d from port %s\n",bp,ep,tmp);
fprintf(ff,"Open ports:\n");
}
printf("Scanning %s, ports %d:%d, from source port %s.\n",inet_ntoa(dest.sin_addr),bp,ep,tmp);
for(i=bp;i<=ep;i++)
{
sockfd=socket(AF_INET,SOCK_STREAM,0);
dest.sin_port=htons(i);
if(sport!=-1)
{
do{
err=bind(sockfd,(struct sockaddr *)&source,sizeof(struct sockaddr));
}while(err);
}
result=connect(sockfd,(struct sockaddr *)&dest,sizeof(struct sockaddr));
if(result!=-1)
{
write(sockfd,"quit",4);
portname=getservbyport(htons(i),"tcp");
if(portname)
snprintf(out,49,"%d\t%s",i,portname->s_name);
else
snprintf(out,49,"%d",i);
printf("\t%s\n",out);
if(out_to_file)
fprintf(ff,"%s\n",out);
}
else if(list_all)
printf("\t%d\t%s\n",i,"not open");
shutdown(sockfd,2);
close(sockfd);
}
if(out_to_file)
fclose(ff);
}
int main(int argc, char *argv[])
{
unsigned int bp=0,ep=1023,noofbits=32,sport=-1;
int crt,x=0,netscan=0;
struct sockaddr_in source,dest;
unsigned long daddr,netmask=0,begip,endip,crtip;
struct hostent *dhost;
put_header();
if(argc<2)
{
give_help(argv[0]);
exit(0);
}
if(argc>2)
{
/* we have some options then */
crt=2;
while(crt<argc)
{
switch(argv[crt][1])
{
case 'b':
crt++;
bp=atoi(argv[crt]);
if(bp<0 || bp rel='nofollow' onclick='return false;'>65535)
{
printf("**ERROR** Not a valid begin port: %u\n",bp);
exit(3);
}
crt++;
break;
case 'e':
crt++;
ep=atoi(argv[crt]);
if(ep<0 || ep>65535)
{
printf("**ERROR** Not a valid end port: %u\n",ep);
exit(3);
}
crt++;
break;
case 'a':
list_all=1;
crt++;
break;
case 'o':
out_to_file=1;
crt++;
break;
case 'M':
crt++;
if(strchr(argv[crt],'.'))
{
netmask=inet_addr(argv[crt]);
for(crtip=ntohl(netmask)^0xFFFFFFFF,noofbits=0;crtip;crtip=(crtip>>1),noofbits++);
noofbits=32-noofbits;
}
else
{
/*we have a plain number*/
noofbits=atoi(argv[crt]);
if( noofbits<0 || noofbits>32 )
{
printf("**ERROR** Not a valid netmask\n");
exit(3);
}
if(!noofbits)
{
printf("SCANNING THE INTERNET !\n");
}
netmask=0;
for(x=1;x<=noofbits;x++) netmask+=(1<<(32-x));
netmask=htonl(netmask);
}
crt++;
netscan=1;
break;
case 'S':
crt++;
sport=atoi(argv[crt]);
if(sport<0 || sport>65535)
{
printf("**ERROR** Not a valid source port: %u\n",sport);
exit(3);
}
{
int uid,suid;
uid=getuid();
suid=geteuid();
if( (sport<1024)&&uid&&geteuid )
{
printf("Only root can bind to ports 0:1023.\n");
printf("You may use as source port only a number from 1024:65535 range.\n");
exit(2);
}
}
crt++;
break;
default:
printf("**ERROR** Could not understand option %s\n",argv[crt]);
give_help(argv[0]);
exit(3);
break;
}
}
}
/* getting destination addres */
daddr=inet_addr(argv[1]);
if(daddr==-1)
{
printf("Resolving hostname %s ...",argv[1]);
fflush(NULL); /* if it fails to resolve, print something right now */
dhost=gethostbyname(argv[1]);
if(dhost==NULL)
{
herror("gethostbyname");
exit(1);
}
printf("OK\n");
printf(" # %s -> %s\n",argv[1],inet_ntoa(*((struct in_addr *)dhost->h_addr)));
printf("------------------------\n");
daddr=((struct in_addr *)dhost->h_addr)->s_addr;
}
/* setting the dest structure */
dest.sin_family=AF_INET;
source.sin_family=AF_INET;
source.sin_addr.s_addr=htonl(INADDR_ANY);
if(sport!=-1)
source.sin_port=htons(sport);
else
source.sin_port=htons(0);
bzero( &(dest.sin_zero),8);
bzero( &(source.sin_zero),8);
/*scanning*/
if(netscan)
{
begip=ntohl(netmask&daddr)+1;
endip=begip;
for(x=0;x<32-noofbits;x++) endip+=(1<<x);
for(crtip=begip;crtip<=endip;crtip++)
{
dest.sin_addr.s_addr=htonl(crtip);
scan(bp,ep,sport,source,dest);
}
}
else
{
dest.sin_addr.s_addr=daddr;
scan(bp,ep,sport,source,dest);
}
return 0;
}