Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.29 KB | None | 0 0
  1. #include <netinet/ip.h>
  2. #include <netinet/tcp.h>
  3. #include <netinet/udp.h>
  4. #include <netinet/ip_icmp.h>
  5. #include <netinet/if_ether.h>
  6. #include <arpa/inet.h>
  7. #include <netinet/in.h>
  8. #include <pcap/pcap.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <ifaddrs.h>
  12. #include <netdb.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdbool.h>
  16. #include <stdlib.h>
  17. #include <unistd.h>
  18. #include <sys/ioctl.h>
  19. #include <net/if.h>
  20. #include <ctype.h>
  21. #include <errno.h>
  22. #include <signal.h>
  23.  
  24. //the packet length
  25. #define PCKT_LEN 8192
  26. #define HOSTNAME_LEN 253 //domain name/IP addr can be max 253 characters long
  27. #define PORTS_LEN 128 //size for array with ports to scan
  28. pcap_t *pcap;
  29.  
  30. /* ethernet headers are always exactly 14 bytes [1] */
  31. #define SIZE_ETHERNET 14
  32.  
  33. /* Ethernet header */
  34. struct sniff_ethernet {
  35.         u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
  36.         u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
  37.         u_short ether_type;                     /* IP? ARP? RARP? etc */
  38. };
  39.  
  40. #define IP_HL(ip)               (((ip)->ip_hl) & 0x0f)
  41.  
  42. /*******************************************************************
  43.  * Title: rawudp.c
  44.  * Date: 20.4.2019
  45.  * Code version:
  46.  * Availability: https://www.tenouk.com/Module43a.html
  47. ********************************************************************/
  48.  
  49. // UDP header's structure
  50. struct udpheader {
  51.     unsigned short int udph_srcport;
  52.     unsigned short int udph_destport;
  53.     unsigned short int udph_len;
  54.     unsigned short int udph_chksum;
  55. };
  56.  
  57. /* Structure of a TCP header */
  58.  
  59. struct tcpheader {
  60.     unsigned short int tcph_srcport;
  61.     unsigned short int tcph_destport;
  62.     unsigned int       tcph_seqnum;
  63.     unsigned int       tcph_acknum;
  64.     unsigned char      tcph_reserved:4;//, tcph_offset:4;
  65.     unsigned char  th_offx2;               /* data offset, rsvd */
  66. #define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
  67.      unsigned char tcph_flags;
  68.     unsigned int
  69.         tcp_res1:4,      /*little-endian*/
  70.         tcph_hlen:4,     /*length of tcp header in 32-bit words*/
  71.         tcph_fin:1,      /*Finish flag "fin"*/
  72.         tcph_syn:1,       /*Synchronize sequence numbers to start a connection*/
  73.         tcph_rst:1,      /*Reset flag */
  74.     tcph_psh:1,      /*Push, sends data to the application*/
  75.     tcph_ack:1,      /*acknowledge*/
  76.     tcph_urg:1,      /*urgent pointer*/
  77.     tcph_res2:2;
  78.     unsigned short int tcph_win;
  79.     unsigned short int tcph_chksum;
  80.     unsigned short int tcph_urgptr;
  81. };
  82.  
  83. // Function for checksum calculation. From the RFC,
  84. // the checksum algorithm is:
  85. //  "The checksum field is the 16 bit one's complement of the one's
  86. //  complement sum of all 16 bit words in the header.  For purposes of
  87. //  computing the checksum, the value of the checksum field is zero."
  88. unsigned short csum(unsigned short *buf, int nwords)
  89. {
  90.     unsigned long sum;
  91.     for (sum = 0; nwords > 0; nwords--)
  92.     {
  93.         sum += *buf++;
  94.     }
  95.     sum = (sum >> 16) + (sum &0xffff);
  96.     sum += (sum >> 16);
  97.     return (unsigned short)(~sum);
  98. }
  99.  
  100. /*
  101.  * END OF REUSED CODE
  102.  */
  103.  
  104. //from linux man page: a pcap_handler routine to be called with three arguments: a  u_char  pointer
  105. //which  is  passed  in  the  user  argument  to  pcap_loop()  or pcap_dispatch(), a const struct
  106. //pcap_pkthdr pointer pointing to the packet time stamp and lengths, and a const  u_char  pointer
  107. //to  the  first  caplen  (as given in the struct pcap_pkthdr a pointer to which is passed to the
  108. //callback routine) bytes of data from the packet.  The struct pcap_pkthdr and  the  packet  data
  109. //are not to be freed by the callback routine, and are not guaranteed to be valid after the call‐
  110. //back routine returns; if the code needs them to be valid after the callback,  it  must  make  a
  111. //copy of them.
  112. //args = arguments to the packet handler
  113. //pkthdr = the pcap format packet header
  114. //ptr_caplen = the packet libcap has extracted from the network interface
  115. void udp_pcap_handler(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *ptr_caplen)
  116. {
  117. }
  118.  
  119. void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
  120. {
  121.     printf("       From: Janinka with love");
  122.  
  123.     static int count = 1;                   /* packet counter */
  124.    
  125.     /* declare pointers to packet headers */
  126.     const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
  127.     const struct ip *ip;              /* The IP header */
  128.     const struct tcpheader *tcp;            /* The TCP header */
  129.     const char *payload;                    /* Packet payload */
  130.  
  131.     int size_ip;
  132.     int size_tcp;
  133.     int size_payload;
  134.    
  135.     printf("\nPacket number %d:\n", count);
  136.     count++;
  137.    
  138.     /* define ethernet header */
  139.     ethernet = (struct sniff_ethernet*)(packet);
  140.    
  141.     /* define/compute ip header offset */
  142.     ip = (struct ip*)(packet + SIZE_ETHERNET);
  143.         //size_ip =
  144.     //size_ip = IP_HL(ip)*4;
  145.     if (size_ip < 20) {
  146.         printf("   * Invalid IP header length: %u bytes\n", size_ip);
  147.     //  return;
  148.     }
  149.  
  150.     /* print source and destination IP addresses */
  151.     printf("       From: %s\n", inet_ntoa(ip->ip_src));
  152.     printf("         To: %s\n", inet_ntoa(ip->ip_dst));
  153.    
  154.     /* determine protocol */   
  155.     switch(ip->ip_p) {
  156.         case IPPROTO_TCP:
  157.             printf("   Protocol: TCP\n");
  158.                         tcp = (struct tcpheader *)(packet + SIZE_ETHERNET + size_ip);
  159.                         if( tcp->tcph_flags == 0x14 )
  160.                             printf(" closed");
  161.                         else
  162.                             printf(" open");
  163.             break;
  164.         case IPPROTO_UDP:
  165.             printf("   Protocol: UDP\n");
  166.             return;
  167.         case IPPROTO_ICMP:
  168.             printf("   Protocol: ICMP\n");
  169.             return;
  170.         case IPPROTO_IP:
  171.             printf("   Protocol: IP\n");
  172.             return;
  173.         default:
  174.             printf("   Protocol: unknown\n");
  175.             return;
  176.     }
  177.    
  178.     /*
  179.      *  OK, this packet is TCP.
  180.      */
  181.    
  182.     /* define/compute tcp header offset */
  183.     tcp = (struct tcpheader*)(packet + SIZE_ETHERNET + size_ip);
  184.     size_tcp = TH_OFF(tcp)*4;
  185.     if (size_tcp < 20) {
  186.         printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
  187.         //return;
  188.     }
  189.    
  190.     printf("   Src port: %d\n", ntohs(tcp->tcph_srcport));
  191.     printf("   Dst port: %d\n", ntohs(tcp->tcph_destport));
  192.    
  193.     /* define/compute tcp payload (segment) offset */
  194.     payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
  195.    
  196.     /* compute tcp payload (segment) size */
  197.     size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp);
  198.    
  199.     /*
  200.      * Print payload data; it might be binary, so don't just
  201.      * treat it as a string.
  202.      */
  203.     if (size_payload > 0) {
  204.         printf("   Payload (%d bytes):\n", size_payload);
  205.         //print_payload(payload, size_payload);
  206.     }
  207.  
  208. return;
  209. }
  210.  
  211. void alarm_handler(int sig)
  212. {
  213.     pcap_breakloop(pcap);
  214. }
  215.  
  216. int main(int argc, char *argv[])
  217. {
  218.     char interface[PORTS_LEN] = "";
  219.     char tcp_ports[PORTS_LEN] = "";
  220.     char udp_ports[PORTS_LEN] = "";
  221.     char scanned_computer[HOSTNAME_LEN];//will contain domain name or IP adderss of the scanned machine
  222.     struct addrinfo hints, *info, *res;
  223.     struct ifreq *my_ifreq;
  224.     char errbuf[PCAP_ERRBUF_SIZE];
  225.     int sd, sendfd, recvfd;
  226.     bool udp_range = false, tcp_range = false;
  227.     char *udp_parse, *tcp_parse;
  228.     struct servent *srvport;
  229.     struct ifaddrs *ifaddr, *ifa;
  230.     int family;
  231.     struct sockaddr_in *sa;
  232.     char *addr;
  233.     char buffer[PCKT_LEN];
  234.     struct ip *iph = (struct ip *) buffer;
  235.     struct udpheader *udp = (struct udpheader *) (buffer + sizeof(struct ip));
  236.     struct tcpheader *tcp = (struct tcpheader *)(buffer + sizeof(struct ip));
  237.     struct sockaddr_in sin, din;
  238.     int one = 1;
  239.     const int *val = &one;
  240.  
  241.     memset(buffer, 0, PCKT_LEN);
  242.  
  243.     //parse arguments
  244.     if (argc < 3 || argc > 8)
  245.     {
  246.         fprintf(stderr, "Wrong combination of arguments\n");
  247.     }
  248.     for (int i = 1; i <= argc - 1 ; i += 2)
  249.     {
  250.     if (strcmp(argv[i], "-i") == 0)
  251.     {
  252.         strcpy(interface, argv[i + 1]);
  253.     }
  254.     else if ((strcmp(argv[i], "-pu") == 0) && (argv[i + 1] != NULL))
  255.     {
  256.         strcpy(udp_ports, argv[i + 1]);
  257.             printf("UDP: %s\n", udp_ports);
  258.     }
  259.     else if (strcmp(argv[i], "-pt") == 0)
  260.     {
  261.         strcpy(tcp_ports, argv[i + 1]);
  262.             printf("%s\n", tcp_ports);
  263.     }
  264.     else
  265.     {
  266.         strcpy(scanned_computer, argv[i]);
  267.         i -= 1;
  268.     }
  269.     }
  270.     if (scanned_computer == NULL)
  271.     {
  272.         fprintf(stderr, "IP address or domain name not specified\n");
  273.     return -1;
  274.     }
  275.     else
  276.     {
  277.         //getting IP address of the scanned machine:
  278.     struct hostent *he;
  279.         he = gethostbyname(scanned_computer);
  280.     if(he == NULL)
  281.     {
  282.         fprintf(stderr, "gethostbyname() error\n");
  283.         return -1;
  284.     }
  285.     char *tmp_scanned_computer = inet_ntoa(*((struct in_addr*) he->h_addr_list[0]));
  286.     strcpy(scanned_computer, tmp_scanned_computer);
  287.     }
  288.  
  289.     int my_beautiful_port = 32769; //I do realise the user can meet the port, so setting a fix number
  290.                         //like this is not ideal, but I'm running out of time
  291.  
  292.     //getting target IP address
  293.     /*******************************************************************
  294.     * Title: "Server program"
  295.     * Date: 20.4.2019
  296.     * Code version:
  297.     * Availability: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html
  298.     ********************************************************************/
  299.     memset(&hints, 0, sizeof(struct addrinfo));
  300.     hints.ai_family = AF_UNSPEC; // allow IPv4 or IPv6
  301.     hints.ai_socktype = SOCK_DGRAM; /* Datagram socket .. (or SOCK_STREAM?) */
  302.     hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address (or AI_CANONNAME?)*/
  303.     hints.ai_protocol = 0;          /* Any protocol */
  304.     hints.ai_canonname = NULL;
  305.     hints.ai_addr = NULL;
  306.     hints.ai_next = NULL;
  307.  
  308.     /*
  309.     * END OF REUSED CODE
  310.     */
  311.  
  312.     //get dst IP/domain name from args
  313.     if (isdigit(scanned_computer[1]) == 0)
  314.     {
  315.         struct hostent *dst_host = gethostbyname(scanned_computer);
  316.     if (dst_host == NULL)
  317.     {
  318.         fprintf(stderr, "Wrong domain name\n");
  319.         return -1;
  320.         strcpy(scanned_computer, dst_host->h_addr_list[0]);
  321.     }
  322.     }
  323.     else
  324.     {
  325.         ;
  326.     }
  327.  
  328.     //get source IP address
  329.     if (getifaddrs(&ifaddr) == -1)
  330.     {
  331.         perror;
  332.     return -1;
  333.     }
  334.     if (interface[0] == 0)
  335.     {
  336.         for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
  337.     {
  338.             if (ifa->ifa_addr == NULL)
  339.             {
  340.             continue;
  341.         }
  342.         if (0 == (ifa->ifa_flags & (IFF_LOOPBACK)) && (ifa->ifa_flags & (IFF_RUNNING))
  343.                         && (ifa->ifa_addr->sa_family == AF_INET))
  344.         {
  345.         family = ifa->ifa_addr->sa_family;//IPv4 or IPv6 asi AF_INET
  346.         sa = (struct sockaddr_in *) ifa->ifa_addr;
  347.         strcpy(interface, ifa->ifa_name);
  348.         addr = inet_ntoa(sa->sin_addr);//source address
  349.         break;
  350.         }
  351.         if (ifa->ifa_next == NULL)
  352.         {
  353.             fprintf(stderr, "couldn't resolve IP address\n");
  354.         return -1;
  355.         }
  356.     }
  357.     }
  358.     else
  359.     {
  360.         for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
  361.     {
  362.         if ((strcmp(interface, ifa->ifa_name) == 0) && (ifa->ifa_addr->sa_family == AF_INET))
  363.         {
  364.             sa = (struct sockaddr_in *) ifa->ifa_addr;
  365.         strcpy(interface, ifa->ifa_name);
  366.         addr = inet_ntoa(sa->sin_addr);//source address
  367.         break;
  368.         }
  369.         else
  370.         {
  371.             if (ifa->ifa_next == NULL)
  372.         {
  373.             fprintf(stderr, "couldn't resolve IP address\n");
  374.             return -1;
  375.         }
  376.         continue;
  377.         }
  378.     }
  379.     }
  380.  
  381.     //parse udp ports
  382.     int scanned_udp_ports[PORTS_LEN];
  383.     if(strstr(udp_ports, "-") != NULL)
  384.     {
  385.         //range of udp ports is given
  386.     //int scanned_udp_ports[2];
  387.     udp_range = true;
  388.     int i = 0;
  389.     while ((udp_parse = strtok( i ? NULL : udp_ports, "-")) != NULL)
  390.     {
  391.         if (i == 2)
  392.         {
  393.             fprintf(stderr, "wrong range format given for UDP ports\n");
  394.         return 1;
  395.         }
  396.         scanned_udp_ports[i++] = atoi(udp_parse);
  397.     }
  398.     if (scanned_udp_ports[0] > scanned_udp_ports[1])
  399.     {
  400.         //if the user inserted range parameter in descending order, swap
  401.         int tmp = scanned_udp_ports[0];
  402.         scanned_udp_ports[0] = scanned_udp_ports[1];
  403.         scanned_udp_ports[1] = tmp;
  404.     }
  405.     //check port numbers given: ????
  406.     if ((scanned_udp_ports[2] - scanned_udp_ports[1]) > 65536)
  407.     {
  408.         fprintf(stderr, "Wrong port number given\n");
  409.         return 1;
  410.     }
  411.     }
  412.     else
  413.     {
  414.         int i = 0;
  415.     while ((udp_parse = strtok( i ? NULL : udp_ports, ",")) != NULL)
  416.     {
  417.         //strcpy(scanned_udp_ports[i++], (udp_parse));
  418.             scanned_udp_ports[i++] = atoi(udp_parse);
  419.     }
  420.     scanned_udp_ports[i] = 0;
  421.     }
  422.  
  423.     //parse tcp ports
  424.     int scanned_tcp_ports[PORTS_LEN];
  425.     if (tcp_ports[0] != 0)
  426.     {
  427.         if (strstr(tcp_ports, "-") != NULL)
  428.     {
  429.         //range of tcp ports is given
  430.         tcp_range = true;
  431.         int i = 0;
  432.         while ((tcp_parse = strtok( i ? NULL : tcp_ports, "-")) != NULL)
  433.         {
  434.             if (i == 2)
  435.         {
  436.             fprintf(stderr, "wrong range format given for TCP ports\n");
  437.             return 1;
  438.         }
  439.         scanned_tcp_ports[i++] = atoi(tcp_parse);
  440.         }
  441.         if (scanned_tcp_ports[0] > scanned_tcp_ports[1])
  442.         {
  443.             //if the user inserted range parameter in descending order, swap
  444.         int tmp = scanned_tcp_ports[0];
  445.         scanned_tcp_ports[0] = scanned_tcp_ports[1];
  446.         scanned_tcp_ports[1] = tmp;
  447.         }
  448.         //check port numbers given: ????
  449.         if ((scanned_tcp_ports[1] - scanned_tcp_ports[0]) > 65536)
  450.         {
  451.             fprintf(stderr, "Wrong port number given\n");
  452.         return 1;
  453.         }
  454.     }
  455.     else
  456.     {
  457.         int i = 0;
  458.         while ((tcp_parse = strtok( i ? NULL : tcp_ports, ",")) != NULL)
  459.         {
  460.             scanned_tcp_ports[i++] = atoi(tcp_parse);
  461.         }
  462.         scanned_tcp_ports[i] = '\0';
  463.     }
  464.     }
  465.  
  466.     //create socket for sending packets
  467. //    sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
  468. //    if (sd < 0)
  469. //    {
  470. //        perror("Socket() error");
  471. //  return -1;
  472. //    }
  473.  
  474.     //start scan
  475.     printf("PORT\tSTATE\n");
  476.     //UDP scan
  477.     if (udp_ports != NULL)
  478.     {
  479.     /*******************************************************************
  480.      * Title: rawudp.c
  481.      * Date: 20.4.2019
  482.      * Code version:
  483.      * Availability: https://www.tenouk.com/Module43a.html
  484.     ********************************************************************/
  485.         sin.sin_family = AF_INET;
  486.     din.sin_family = AF_INET;
  487.     // Port numbers
  488.     sin.sin_port = htons(my_beautiful_port);
  489.     // IP addresses
  490.     sin.sin_addr.s_addr = inet_addr(addr);//my hostname/ip
  491.     din.sin_addr.s_addr = inet_addr(scanned_computer);
  492.        
  493.     // Fabricate the IP header or we can use the
  494.     // standard header structures but assign our own values.
  495.     iph->ip_hl = 5;
  496.     iph->ip_v = 4;
  497.     iph->ip_tos = 16; // Low delay
  498.     iph->ip_len = sizeof(struct ip) + sizeof(struct udpheader);
  499.     iph->ip_id = htonl(54321);
  500.     iph->ip_ttl = 255; //64; // hops
  501.     iph->ip_p = 17; // UDP
  502.     iph->ip_off = 0;
  503.     // Source IP address, can use spoofed address here!!!
  504.     iph->ip_src.s_addr = inet_addr(addr);
  505.     //h The destination IP address
  506.     iph->ip_dst.s_addr = inet_addr(scanned_computer);
  507.    
  508.     // Fabricate the UDP header. Source port number, redundant
  509.     udp->udph_srcport = htons(my_beautiful_port);
  510.     // Destination port number
  511.     udp->udph_len = htons(sizeof(struct udpheader));
  512.    
  513.     // Calculate the checksum for integrity
  514.     iph->ip_sum = csum((unsigned short *)buffer, sizeof(struct ip) +
  515.             sizeof(struct udpheader));
  516.     iph->ip_len = sizeof(struct ip) + sizeof(struct udpheader);
  517.     //create a raw socket with UDP protocol, IPv4
  518.     //to receive ICMP response packets
  519.     recvfd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
  520.     if (recvfd < 0)
  521.     {
  522.         perror("UDP socket() error\n");
  523.         return 1;
  524.     }
  525.  
  526.     if (setsockopt(recvfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
  527.     {
  528.         fprintf(stderr, "setsockopt() error\n");
  529.         return -1;
  530.     }
  531.     /*
  532.         *  END OF REUSED CODE    
  533.         */
  534.  
  535.     if (udp_range)
  536.     {
  537.         for (int i = scanned_udp_ports[0]; i <= scanned_udp_ports[1]; i++)
  538.         {
  539.             udp->udph_destport = htons(i);
  540.         din.sin_port = htons(i);
  541.         iph->ip_sum = csum((unsigned short *)buffer,
  542.                 (sizeof(struct ip) + sizeof(struct udpheader)));
  543.        
  544.         //packet capture
  545.         if ((pcap = pcap_open_live(interface, PCKT_LEN, 1, 500, errbuf)) == NULL)
  546.         {
  547.             fprintf(stderr, "pcap_open_live() error: %s\n", strerror(errno));
  548.             pcap_freealldevs((pcap_if_t *)pcap);
  549.             return -1;
  550.         }
  551.  
  552.         struct bpf_program fp;
  553.                
  554.         if (pcap_compile(pcap, &fp, "icmp and icmp[icmptype] == icmp-unreach"
  555.                             , 0, PCAP_NETMASK_UNKNOWN) == -1)
  556.         {
  557.             fprintf(stderr, "pcap_compile() error\n");
  558.             return -1;
  559.         }
  560.         if (pcap_setfilter(pcap, &fp) == -1)
  561.         {
  562.             fprintf(stderr, "pcap_setfilter() error\n");
  563.             return -1;
  564.         }
  565.  
  566.         //a UDP/ICMP packet could get lost on the way, therefore trying to repeat it a few times
  567.         //unless I get a response
  568.         int pcap_dispatch_ret_val;
  569.         for(int j = 0; j <= 2; j++)
  570.         {
  571.                     if (sendto(recvfd, buffer, iph->ip_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)
  572.             {
  573.                 fprintf(stderr, "sending UDP packet failed %s\n", strerror(errno));
  574.             return -1;
  575.             }
  576.                 alarm(2);
  577.                     signal(SIGALRM, alarm_handler);
  578.             pcap_dispatch_ret_val = pcap_dispatch(pcap, 1, udp_pcap_handler, NULL);
  579.             if (pcap_dispatch_ret_val == 0)
  580.             {
  581.                     if (j < 2)
  582.             {
  583.                 continue;
  584.             }
  585.             else
  586.             {
  587.                 printf("%d/udp\topen\n", i);
  588.             }
  589.             }
  590.             else if (pcap_dispatch_ret_val == -1)
  591.             {
  592.                 fprintf(stderr, "pcap_dispatch() error: %s\n", strerror(errno));
  593.             return -1;
  594.             }
  595.             else if (pcap_dispatch_ret_val == -2)
  596.             {
  597.                     if (j < 2)
  598.             {
  599.                 continue;
  600.             }
  601.             else
  602.             {
  603.                 printf("%d/udp\topen\n", i);
  604.             }
  605.             }
  606.             else
  607.             {
  608.                 printf("%d/udp\tclosed\n", i);
  609.             }
  610.         }
  611.         pcap_close(pcap);
  612.         }
  613.     }
  614.     else
  615.     {
  616.         for (int i = 0; scanned_udp_ports[i] != 0; i++)
  617.         {
  618.             udp->udph_destport = htons(i);
  619.         din.sin_port = htons(i);
  620.         iph->ip_sum = csum((unsigned short *)buffer, (sizeof(struct ip) + sizeof(struct udpheader)));
  621.                 //packet capture
  622.         if ((pcap = pcap_open_live(interface, PCKT_LEN, 1, 500, errbuf)) == NULL)
  623.         {
  624.             fprintf(stderr, "pcap_open_live() error: %s\n", strerror(errno));
  625.             pcap_freealldevs((pcap_if_t *)pcap);
  626.             return -1;
  627.         }
  628.            
  629.             struct bpf_program fp;
  630.         if (pcap_compile(pcap, &fp, "icmp and icmp[icmptype] == icmp-unreach"
  631.                             , 0, PCAP_NETMASK_UNKNOWN) == -1)
  632.         {
  633.             fprintf(stderr, "pcap_compile() error\n");
  634.             return -1;
  635.         }
  636.         if (pcap_setfilter(pcap, &fp) == -1)
  637.         {
  638.             fprintf(stderr, "pcap_setfilter() error\n");
  639.             return -1;
  640.         }
  641.  
  642.         //a UDP/ICMP packet could get lost on the way, therefore trying to test it a few times
  643.         int pcap_dispatch_ret_val;
  644.         for(int j = 0; j <= 2; j++)
  645.         {
  646.             if (sendto(recvfd, buffer, iph->ip_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0)
  647.             {
  648.                 fprintf(stderr, "sending UDP packet failed %s\n", strerror(errno));
  649.             return -1;
  650.             }
  651.             alarm(2);
  652.             signal(SIGALRM, alarm_handler);
  653.             pcap_dispatch_ret_val = pcap_dispatch(pcap, 1, udp_pcap_handler, NULL);
  654.             if (pcap_dispatch_ret_val == 0)
  655.             {
  656.                 if (j < 2)
  657.             {
  658.                 continue;
  659.             }
  660.             else
  661.             {
  662.                 printf("%d/udp\topen\n", scanned_udp_ports[i]);
  663.             }
  664.             }
  665.             else if (pcap_dispatch_ret_val == -1)
  666.             {
  667.                 //not using pcap_breakloop, no need to check explicitly for -2
  668.             //TODO: NOW I'm using breakloop
  669.             fprintf(stderr, "pcap_dispatch() error: %s\n", strerror(errno));
  670.             return -1;
  671.             }
  672.             else if (pcap_dispatch_ret_val == -2)
  673.             {
  674.                 if (j < 2)
  675.             {
  676.                 continue;
  677.             }
  678.             else
  679.             {
  680.                 printf("%d/udp\topen\n", scanned_udp_ports[i]);
  681.             }
  682.             }
  683.             else
  684.             {
  685.                 printf("%d/udp\tclosed\n", scanned_udp_ports[i]);
  686.             break;
  687.             }
  688.         }
  689.             pcap_close(pcap);
  690.         }
  691.     }
  692.     }
  693.  
  694.     //TCP scan
  695.     if (tcp_ports != NULL)
  696.     {
  697.         // IP structure
  698.         iph->ip_hl = 5;
  699.         iph->ip_v = 4;
  700.         iph->ip_tos = 16;
  701.         iph->ip_len = sizeof(struct ip) + sizeof(struct tcpheader);
  702.         iph->ip_id = htonl(54321);
  703.         iph->ip_off = 0;
  704.         iph->ip_ttl = 64;
  705.         iph->ip_p = 6; // TCP
  706.         iph->ip_sum = 0; // Done by kernel
  707.         // Source IP, modify as needed, spoofed, we accept through command line argument
  708.         iph->ip_src.s_addr = inet_addr(addr);
  709.         // Destination IP, modify as needed, but here we accept through command line argument
  710.         iph->ip_dst.s_addr = inet_addr(scanned_computer);
  711.  
  712.         sin.sin_addr.s_addr = inet_addr(addr);
  713.         din.sin_addr.s_addr = inet_addr(scanned_computer);
  714.         sin.sin_family = AF_INET;
  715.         din.sin_family = AF_INET;
  716.         // Source port, can be any, modify as needed
  717.         sin.sin_port = htons(my_beautiful_port);
  718.  
  719.         ///
  720.         sendfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
  721.         if (sendfd < 0)
  722.         {
  723.             perror("socket() error");
  724.             return -1;
  725.         }
  726.     if (tcp_range)
  727.     {
  728.         for (int i = scanned_tcp_ports[0]; i <= scanned_tcp_ports[1]; i++)
  729.             {
  730.             /*******************************************************************
  731.              * Title: rawtcp.c
  732.              * Date: 20.4.2019
  733.              * Code version:
  734.              * Availability: https://www.tenouk.com/Module43a.html
  735.             ********************************************************************/
  736.                 tcp->tcph_srcport = htons(my_beautiful_port);
  737.             tcp->tcph_destport = htons(i);
  738.                 tcp->tcph_seqnum = htonl(1);
  739.                 tcp->tcph_acknum = 0;
  740.                 tcp->th_offx2 = 5;
  741.                 tcp->tcph_syn = 1;
  742.                 tcp->tcph_ack = 0;
  743.                 tcp->tcph_win = htons(32767);
  744.                 tcp->tcph_chksum = 0; // Done by kernel
  745.                 tcp->tcph_urgptr = 0;
  746.  
  747.         din.sin_port = htons(i);
  748.  
  749.         iph->ip_sum = csum((unsigned short *)buffer,
  750.                 (sizeof(struct ip) + sizeof(struct tcpheader)));
  751.     iph->ip_len = sizeof(struct ip) + sizeof(struct tcpheader);
  752.  
  753.                 // Inform the kernel do not fill up the headers' structure, we fabricated our own
  754.                 if(setsockopt(sendfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0)
  755.                 {
  756.                     perror("setsockopt() error");
  757.                     exit(-1);
  758.                 }
  759.  
  760.                 /*
  761.                  * END OF REUSED CODE
  762.                  */
  763.     char filter_exp[] = "port 32769 && port 23";        /* filter expression [3] */
  764.     struct bpf_program fp;          /* compiled filter program (expression) */
  765.     bpf_u_int32 mask;           /* subnet mask */
  766.     bpf_u_int32 net;            /* ip */
  767.         int num_packets = 10;
  768.     /* open capture device */
  769.     pcap = pcap_open_live(interface, PCKT_LEN, 1, 1000, errbuf);
  770.     if (pcap == NULL) {
  771.         fprintf(stderr, "Couldn't open device %s: %s\n", interface, errbuf);
  772.         exit(EXIT_FAILURE);
  773.     }
  774.  
  775.     /* make sure we're capturing on an Ethernet device [2] */
  776. //  if (pcap_datalink(pcap) != DLT_EN10MB) {
  777. //      fprintf(stderr, "%s is not an Ethernet\n", interface);
  778. //      exit(EXIT_FAILURE);
  779. //  }
  780.  
  781.     /* compile the filter expression */
  782.     if (pcap_compile(pcap, &fp, filter_exp, 0, net) == -1) {
  783.         fprintf(stderr, "Couldn't parse filter %s: %s\n",
  784.             filter_exp, pcap_geterr(pcap));
  785.         exit(EXIT_FAILURE);
  786.     }
  787.  
  788.     /* apply the compiled filter */
  789.     if (pcap_setfilter(pcap, &fp) == -1) {
  790.         fprintf(stderr, "Couldn't install filter %s: %s\n",
  791.             filter_exp, pcap_geterr(pcap));
  792.         exit(EXIT_FAILURE);
  793.     }
  794.                 if(sendto(sendfd, buffer, iph->ip_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  795.                 // Verify
  796.                 {
  797.                    perror("sendto() error");
  798.                    exit(-1);
  799.                 }
  800.                 printf("%d\n", i);
  801.     /* now we can set our callback function */
  802. //  pcap_loop(pcap, num_packets, got_packet, NULL);
  803.             alarm(2);
  804.             signal(SIGALRM, alarm_handler);
  805.         int pcap_dispatch_ret_val;
  806.             pcap_dispatch_ret_val = pcap_dispatch(pcap, 1, got_packet, NULL);
  807.                     if (pcap_dispatch_ret_val == -1)
  808.                     {
  809.                         fprintf(stderr, "pcap_dispatch() error\n");
  810.                         return -1;
  811.                     }
  812.             else if (pcap_dispatch_ret_val <= 0)
  813.             {
  814.                 printf("%d/tcp\topen\n", i);
  815.                     }
  816.                     else
  817.                     {
  818.                 printf("%d/tcp\tclosed\n",i);
  819.                     }
  820.                
  821.             }
  822.         }
  823.     }
  824. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement