www.pudn.com > halfscan.zip > halfscan.c


 
/* http://www.cotse.com  Fear the swimming Elephant! */ 
 
/********************************************************************** 
** This is a real simple half opened connection scanner I 
** put together. It scans ports 0 to 1024 for listening 
** processes, and writes to stdout the ports that are  
** listening. 
** 
** halflife@saturn.net 
** 
** NOTE: You have to define MY_IP as your ip. If you have 
** a dynamic ip, this is gonna bite :-). 
*********************************************************************/ 
 
/* define the following as your ip address */ 
#define MY_IP		"193.62.1.250" 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
int syn_timeout = 0; 
 
unsigned short in_cksum(unsigned short *, int); 
int scan_port(unsigned short, unsigned int, unsigned int); 
void alarm_handler(int); 
 
void alarm_handler(int s) 
{ 
   alarm(0); 
   syn_timeout = 1; 
} 
 
int scan_port(unsigned short port, unsigned int src_addr, unsigned int dst_addr) 
{ 
   struct tcphdr send_tcp; 
   struct recv_tcp 
   { 
      struct iphdr ip; 
      struct tcphdr tcp; 
      unsigned char blah[65535]; 
   }recv_tcp; 
   struct pseudo_header 
   { 
      unsigned int source_address; 
      unsigned int dest_address; 
      unsigned char placeholder; 
      unsigned char protocol; 
      unsigned short tcp_length; 
      struct tcphdr tcp; 
   }pseudo_header; 
   int tcp_socket; 
   struct sockaddr_in sin; 
   int sinlen; 
   static int blah = 0; 
    
   blah++; 
   send_tcp.source = getpid() + blah; 
   send_tcp.dest = htons(port); 
   send_tcp.seq = getpid() + blah; 
   send_tcp.ack_seq = 0; 
   send_tcp.res1 = 0; 
   send_tcp.doff = 5; 
   send_tcp.res2 = 0; 
   send_tcp.fin = 0; 
   send_tcp.syn = 1; 
   send_tcp.rst = 0; 
   send_tcp.psh = 0; 
   send_tcp.ack = 0; 
   send_tcp.urg = 0; 
   send_tcp.window = htons(512); 
   send_tcp.check = 0; 
   send_tcp.urg_ptr = 0;                
   pseudo_header.source_address = src_addr; 
   pseudo_header.dest_address = dst_addr; 
   pseudo_header.placeholder = 0; 
   pseudo_header.protocol = IPPROTO_TCP; 
   pseudo_header.tcp_length = htons(20); 
   bcopy(&send_tcp, &pseudo_header.tcp, 20); 
   send_tcp.check = in_cksum((unsigned short *)&pseudo_header, 32); 
   sin.sin_family = AF_INET; 
   sin.sin_port = htons(port); 
   sin.sin_addr.s_addr = dst_addr; 
   sinlen=sizeof(sin); 
   signal(SIGALRM, alarm_handler); 
   tcp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 
   if(tcp_socket < 0) 
   { 
      fprintf(stderr, "couldnt open raw socket\n"); 
      exit(1); 
   } 
   sendto(tcp_socket, &send_tcp, 20, 0, (struct sockaddr *)&sin, sinlen); 
   syn_timeout = 0; 
   alarm(10); 
   while(1) 
   { 
      read(tcp_socket, (struct recv_tcp *)&recv_tcp, 65535); 
      if(syn_timeout == 1) {close(tcp_socket);syn_timeout=0;return -1;} 
      if(recv_tcp.tcp.dest == (getpid() + blah)) 
      { 
         alarm(0); 
         close(tcp_socket); 
         if(recv_tcp.tcp.rst == 1) return 0; 
         else return 1; 
      } 
   } 
} 
 
unsigned short in_cksum(unsigned short *ptr, int nbytes) 
{ 
	register long		sum;		/* assumes long == 32 bits */ 
	u_short			oddbyte; 
	register u_short	answer;		/* assumes u_short == 16 bits */ 
 
	/* 
	 * Our algorithm is simple, using a 32-bit accumulator (sum), 
	 * we add sequential 16-bit words to it, and at the end, fold back 
	 * all the carry bits from the top 16 bits into the lower 16 bits. 
	 */ 
 
	sum = 0; 
	while (nbytes > 1)  { 
		sum += *ptr++; 
		nbytes -= 2; 
	} 
 
				/* mop up an odd byte, if necessary */ 
	if (nbytes == 1) { 
		oddbyte = 0;		/* make sure top half is zero */ 
		*((u_char *) &oddbyte) = *(u_char *)ptr;   /* one byte only */ 
		sum += oddbyte; 
	} 
 
	/* 
	 * Add back carry outs from top 16 bits to low 16 bits. 
	 */ 
 
	sum  = (sum >> 16) + (sum & 0xffff);	/* add high-16 to low-16 */ 
	sum += (sum >> 16);			/* add carry */ 
	answer = ~sum;		/* ones-complement, then truncate to 16 bits */ 
	return(answer); 
} 
 
main(int argc, char **argv) 
{    
   unsigned short i; 
   if(argc < 2) 
   { 
      fprintf(stderr, "%s target_ip\n", argv[0]); 
      exit(0); 
   } 
   if(geteuid() != 0) 
   { 
      fprintf(stderr, "this program requires root\n"); 
      exit(0); 
   } 
   printf("Scanning %s\n", argv[1]); 
   for(i=0;i < 1025;i++) 
   { 
      if(scan_port(i, inet_addr(MY_IP), inet_addr(argv[1]))==1) 
         printf("Port %d active\n", i); 
   } 
}