Thread: Port scanner under Linux now giving me troubles

  1. #1
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266

    Port scanner under Linux now giving me troubles

    I posted a thread about a port scanner that I had written for both windows and linux. The issue in that thread was that it was running really fast under Linux, whereas under Windows, it was dog slow.

    I have revised my program to now scan an entire subnet up to the broadcast address (exclusive) and it scans the first just fine but when it gets to the second IP, it starts going at a snails pace just like under windows. This is verified through checking netstat... I can see the sessions in the SYN_SENT state and the port number incrementing, just very slowly... What gives?

    regardless of if you provide a subnet or ip, it'll do a bitwise AND and get the subnet and scan the whole thing.

    Usage is: ./portscan [subnet or ip] [subnet mask]
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    #define NET_MASK 0XFFFFFFFF
    #define PORT_LIMIT 65535
    #define BASE_PORT 0
    
    void get_addr_space(unsigned long int *, unsigned long int *, struct in_addr, struct in_addr);
    void scan_addr(unsigned long int, struct sockaddr_in *, unsigned short);
    int test_port(int, unsigned short, struct sockaddr_in *, char *);
    void port_info(unsigned short, char *);
    
    
    int main(int argc, char ** argv){
    
      unsigned short port = BASE_PORT;
      unsigned long int curr_addr = 0, max_addr = 0;
      struct sockaddr_in target;
      struct in_addr mask;
      
      inet_pton(AF_INET, argv[1], &target.sin_addr);
      inet_pton(AF_INET, argv[2], &mask);
      
      get_addr_space(&curr_addr, &max_addr, target.sin_addr, mask);
      
      target.sin_family = AF_INET;
      
      curr_addr = ntohl(curr_addr);
      max_addr = ntohl(max_addr);
      
      while(curr_addr < max_addr - 1)
        scan_addr(curr_addr++, &target, port);
      
      return 0;
    }
    
    void get_addr_space(unsigned long int * min, unsigned long int * max, struct in_addr subnet, struct in_addr mask){
      
      unsigned long int subnet_bits = subnet.s_addr & mask.s_addr;
      
      *min = subnet_bits;
      *max = subnet_bits;
      
      //*max = ((~*max + subnet_bits) & ~mask.s_addr) + *max;
      *max = NET_MASK & ~mask.s_addr + *max;
    }
    
    void scan_addr(unsigned long int dec_addr, struct sockaddr_in * target, unsigned short port){
      
      int client_socket = 0;
      char ipv4[INET_ADDRSTRLEN];
      
      target->sin_addr.s_addr = htonl(dec_addr);
      target->sin_port = port;
      printf("\nTrying IP %s\n", inet_ntop(AF_INET, &target->sin_addr, ipv4, INET_ADDRSTRLEN)); 
      
      while(port < PORT_LIMIT)
        if(!test_port(client_socket, port++, target, "tcp"))
          port_info(port - 1, "tcp");
      
    }
    
    int test_port(int client_socket, unsigned short port, struct sockaddr_in * target, char * svc_proto){
      
      printf("\t - Trying %s port %u\r", svc_proto, port); 
      
      target->sin_family = AF_INET;
      target->sin_port = htons(port);
      
      if((client_socket = socket(AF_INET, (svc_proto == "tcp" ? SOCK_STREAM : SOCK_DGRAM), 0)) > 0){
        if(connect(client_socket, (struct sockaddr *)target, sizeof(*target))){
          close();
          return 1;
        }
        else
          return 0;
      }else
        perror("");
      
    }
    
    void port_info(unsigned short port, char * svc_proto){
      
      struct servent * service;
      
      if((service = getservbyport(htons(port), svc_proto)))
        printf("\t - %s port %u (%s) is open\n", svc_proto, port, service->s_name);
      else
        printf("\t - %s port %u is open\n", svc_proto, port);
      
      
    }

  2. #2
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    I think I know why... there is no host at that IP or any of the lower ips for that matter. Need to now find a way to check if IP has a host reachable first (ping or something)

  3. #3
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    In case anyone is wondering... I now check errno for EHOSTUNREACH. Final code (for now) below.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <errno.h>
    
    #define NET_MASK 0XFFFFFFFF
    #define PORT_LIMIT 0XFFFF
    #define BASE_PORT 0X0000
    
    void get_addr_space(unsigned long int *, unsigned long int *, struct in_addr, struct in_addr);
    void scan_addr(unsigned long int, struct sockaddr_in *, unsigned short);
    int test_port(int, unsigned short, struct sockaddr_in *, char *);
    void port_info(unsigned short, char *);
    
    
    int main(int argc, char ** argv){
      
      unsigned short port = BASE_PORT;
      unsigned long int curr_addr = 0, max_addr = 0;
      struct sockaddr_in target;
      struct in_addr mask;
      
      inet_pton(AF_INET, argv[1], &target.sin_addr);
      inet_pton(AF_INET, argv[2], &mask);
      
      get_addr_space(&curr_addr, &max_addr, target.sin_addr, mask);
      
      target.sin_family = AF_INET;
      
      curr_addr = ntohl(curr_addr);
      max_addr = ntohl(max_addr);
      
      //printf("Min: %u, Max: %u\n", curr_addr, max_addr + 1);
      
      
      while(curr_addr < max_addr - 1)
        scan_addr(++curr_addr, &target, port);
      
      return 0;
    }
    
    void get_addr_space(unsigned long int * min, unsigned long int * max, struct in_addr subnet, struct in_addr mask){
      
      unsigned long int subnet_bits = subnet.s_addr & mask.s_addr;
      
      *min = subnet_bits;
      *max = subnet_bits;
      
      //*max = ((~*max + subnet_bits) & ~mask.s_addr) + *max;
      *max = NET_MASK & ~mask.s_addr + *max;
    }
    
    void scan_addr(unsigned long int dec_addr, struct sockaddr_in * target, unsigned short port){
      
      int client_socket = 0;
      char ipv4[INET_ADDRSTRLEN];
      
      target->sin_addr.s_addr = htonl(dec_addr);
      
      target->sin_port = htons(port);
      
      printf("Trying IP %s\n\n", inet_ntop(AF_INET, &target->sin_addr, ipv4, INET_ADDRSTRLEN)); 
      
      
      while(port < PORT_LIMIT){
        if(test_port(client_socket, port++, target, "tcp"))
          port_info(port - 1, "tcp");
        
        else if(errno == EHOSTUNREACH)
          break;
        else
          continue;
      }
      
    }
    
    int test_port(int client_socket, unsigned short port, struct sockaddr_in * target, char * svc_proto){
      
      printf("Trying %s port %u\r", svc_proto, port); 
      
      target->sin_family = AF_INET;
      target->sin_port = htons(port);
      
      if((client_socket = socket(AF_INET, (svc_proto == "tcp" ? SOCK_STREAM : SOCK_DGRAM), 0)) > 0){
        if(!connect(client_socket, (struct sockaddr *)target, sizeof(*target))){
          close(client_socket);
          return 1;
        }
        else
          close(client_socket);
        return 0;
      }else
        perror("");
      
    }
    
    void port_info(unsigned short port, char * svc_proto){
      
      struct servent * service;
      
      if((service = getservbyport(htons(port), svc_proto)))
        printf("%s port %u (%s) is open\n", svc_proto, port, service->s_name);
      else
        printf("%s port %u is open\n", svc_proto, port);
      
      
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C port scanner
    By xchg in forum Linux Programming
    Replies: 5
    Last Post: 02-18-2009, 04:34 PM
  2. My TCP Port Scanner in C
    By billy786 in forum Networking/Device Communication
    Replies: 5
    Last Post: 06-28-2008, 07:12 PM
  3. Port Scanner
    By Stabbsy in forum Networking/Device Communication
    Replies: 11
    Last Post: 11-28-2006, 09:45 AM
  4. Port Scanner
    By w4ck0z in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-22-2004, 04:08 PM
  5. g++ giving me BIG troubles!!!
    By MrPink in forum C++ Programming
    Replies: 5
    Last Post: 05-15-2004, 02:23 PM