/*
 * simple port scanner. it scans a range of ports.
 *
 * "THE BEER-WARE LICENSE" (by Poul-Henning Kamp, Revision 42)
 * emdel wrote this file. As long as you retain this notice
 * you can do whatever you want with this stuff. If we meet some day, and you
 * think this stuff is worth it, you can buy me a beer in return.
 * 
 * emdel
 *
 */

#include <stdio.h>
#include <sys/socket.h> /* for socket(), connect() etc.. */
#include <arpa/inet.h> /* for sockaddr_in etc.. */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */


#define INFO "Copyright (c) 2008 emdel <emdel@playhack.net> "
#define WHAT "useless but fast portscanner "

#define MAX 65535

void help( void );
void version( void );
void normal( int vport1, int vport2, char *vip );
void saveFile( char *fname, int vport1, int vport2, char *vip );
void allPorts( char *fname, int ports, char *vip );

int main( int argc, char *argv[] )
{
    int s, i, test, ports;
    struct sockaddr_in vaddr; /* victim address */
    unsigned short vport1, vport2; /* first and the last port to scan */
    char *vip; /* victim ip in dotted quad notation */
    char *fname;
    FILE *ptr;

    fprintf( stdout, "\n\n\t\t\t# yes another simple port scanner coded by emdel #\n\n" );

    
    if( argc != 5 )
    {
        if( argc == 1 )
        {
            help( );
            exit( 25 );
        }
        else if( strcmp( argv[1], "-h" ) == 0 )
        {
            help( );
            exit( 25 );
        }
        else if( strcmp( argv[1], "-v" ) == 0 )
        {
            version( );
            exit( 25 );
        }
        else if( strcmp( argv[2], "-a" ) == 0 )
        {
            fprintf( stdout, ">please, insert the name of the file:  " );
	    fname = ( char * )malloc( 100 );
            scanf( "%s" , fname );
            fname = realloc( fname, strlen( fname ) + 1 );
            ports = MAX;
            vip = argv[1];
            allPorts( fname, ports, vip );
            exit( 25 );
        }
        else
        {
	    fprintf( stderr, "Usage: %s <Victim IP> <First Port> <Last Port> <flags>\n\n" , argv[0] );
            exit( 25 );
        }
    }


    for( i = 1; i <= argc; i++ )
    {
        if( strcmp( argv[i] , "-f" ) == 0 )
        {
	    vip = argv[1];
	    vport1 = atoi( argv[2] );
            vport2 = atoi( argv[3] );
            fprintf( stdout, ">please, insert the name of the file:  " );
            fname = ( char * )malloc( 100 );
	    scanf( "%s" , fname );
            fname = realloc( fname, strlen( fname ) + 1 );
            saveFile( fname, vport1, vport2, vip );
            exit( 25 );
        }
	if( strcmp( argv[i] , "-n" ) == 0 )
	{
	    vip = argv[1];
            vport1 = atoi( argv[2] );
            vport2 = atoi( argv[3] );
	    normal( vport1, vport2, vip );
            exit( 25 );
	}
    }

return 0;

}

void help( void )
{
    fprintf( stderr, "\t\t\t\t %s \n" , WHAT );
    fprintf( stderr, "\t\t\t %s \n\n" , INFO );
    fprintf( stdout, "\n\n FLAGS: \n\n" );
    fprintf( stdout, "-v => version of this program\n");
    fprintf( stdout, "-h => this window\n" );
    fprintf( stdout, "-n => normal shell based scan\n");
    fprintf( stdout, "-f => save all in a file\n" );
    fprintf( stdout, "-a => scan all ports ( save the output in a file ) [ usage : <ip> <-a> ]\n\n" );
    fprintf( stdout, "\t\t # report bugs to %s \n\n" , INFO );
}

void version( void )
{
    fprintf( stdout, "version 0.0.1 - report bugs to %s \n" , INFO );
}

void saveFile( char *fname, int vport1, int vport2, char *vip )
{
    
    int i, s, test;
    FILE *ptr;
    struct  sockaddr_in vaddr;

	ptr = fopen( fname , "w" );
        if( ptr == NULL )
        {
            fprintf( stderr, "error, i can't open the file!\n" );
            exit( 25 );
        }

         fprintf( ptr, "\t\t# output of the scan using yaeps v 0.0.1 \n\n" );
	
	 for( i = vport1; i <= vport2; i++ )
         {
            s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
            if( s < 0 )
            {
                fprintf( ptr, "there are some problems in socket()\n" );
                exit( 25 );
            }
            memset( &vaddr, 0, sizeof( vaddr ) );
            vaddr.sin_family = AF_INET;
            vaddr.sin_addr.s_addr = inet_addr( vip );
            vaddr.sin_port = htons( i );
            test = connect( s, ( struct sockaddr * )&vaddr, sizeof( vaddr ) );
            if( test >= 0 )
                fprintf( ptr, "[ %s ] -> port %d is open! ^_^\n" , vip, i );
            else
                fprintf( ptr, "[ %s ] -> port %d is closed :(\n" , vip, i );
            close( s );
         }
         fprintf( ptr, "\n\n\t\t -- END -- \n\n" );
         fclose( ptr );
}

void normal( int vport1, int vport2, char *vip )
{
        int i, s, test;
    	struct  sockaddr_in vaddr;

        fprintf( stdout, "\n\n\t\t -- BEGIN -- \n\n" );
        for( i = vport1; i <= vport2; i++ )
        {
            s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
            if( s < 0 )
            {
                fprintf( stderr, "there are some problems in socket()\n" );
                exit( 25 );
            }
            memset( &vaddr, 0, sizeof( vaddr ) );
            vaddr.sin_family = AF_INET;
            vaddr.sin_addr.s_addr = inet_addr( vip );
            vaddr.sin_port = htons( i );
            test = connect( s, ( struct sockaddr * )&vaddr, sizeof( vaddr ) );
            if( test >= 0 )
                fprintf( stdout, "[ %s ] -> port %d is open! ^_^\n" , vip, i );
            else
                fprintf( stdout, "[ %s ] -> port %d is closed :(\n" , vip, i );
            close( s );
        }
        fprintf( stdout, "\n\n\t\t -- END -- \n\n" );
}

void allPorts( char *fname, int ports, char *vip )
{

	int i, s, test;
    	struct  sockaddr_in vaddr;
        FILE *ptr;

        ptr = fopen( fname , "w" );
        if( ptr == NULL )
        {
           fprintf( stderr, "error, i can't open the file!\n" );
           exit( 25 );
        }
	
	fprintf( ptr, "i'm scanning all ports using yaeps v 0.0.1... \n\n" );
        fprintf( ptr, "\n\n\t\t -- BEGIN -- \n\n" );
        for( i = 0; i <= ports; i++ )
        {
            s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
            if( s < 0 )
            {
                fprintf( stderr, "there are some problems in socket()\n" );
                exit( 25 );
            }
            memset( &vaddr, 0, sizeof( vaddr ) );
            vaddr.sin_family = AF_INET;
            vaddr.sin_addr.s_addr = inet_addr( vip );
            vaddr.sin_port = htons( i );
            test = connect( s, ( struct sockaddr * )&vaddr, sizeof( vaddr ) );
            if( test >= 0 )
                fprintf( ptr, "[ %s ] -> port %d is open! ^_^\n" , vip, i );
            else
                fprintf( ptr, "[ %s ] -> port %d is closed :(\n" , vip, i );
            close( s );
        }
        fprintf( ptr, "\n\n\t\t -- END -- \n\n" );
        fclose( ptr ); 
}



