Advertisement
Guest User

Untitled

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