home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit 2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Texts / Improving-Security / security11.txt < prev    next >
Encoding:
Text File  |  1999-11-04  |  33.0 KB  |  1,928 lines

  1.  
  2.                               == Phrack 49 ==
  3.                       Volume Seven, Issue Forty-Nine
  4.                                File 15 of 16
  5.                    --------------------------------------
  6.                               by Uriel Maimon
  7.  
  8. Introduction
  9.  
  10. During the course of time, there has risen a demand to know the services a
  11. certain host offers. The field of portscanning rose to offer a solution to
  12. this need. At first, implementations such as SATAN, connected to each tcp
  13. port using the full three-way-handshake (opening a full tcp connection).
  14. The upside to this method is that the user who is scanning does not need to
  15. custom build the ip packet he is scanning with, because he uses standard
  16. system calls, and does not need root access (generally a uid of 0 is needed
  17. to use SOCK_RAW, /dev/bpf,/dev/nit and so forth) the major down side to
  18. this method is that it is easily detectable and also easily detered, using
  19. any number of methods, most notably the TCP Wrappers made by Wietse Venema.
  20.  
  21. The next step was of course SYN-scanning or 'half open scanning' which
  22. implies that a full tcp connection is never established. The process of
  23. establishing a tcp connection is three phased: the originating party first
  24. sends a TCP packet with the SYN flag on, then the target party sends a TCP
  25. packet with the flags SYN and ACK on if the port is open, or, if the port
  26. is closed, the target party resets the connection with the RST flag. The
  27. third phase of the negotiation is when the originating party sends a final
  28. TCP packet with the ACK flag on (all these packets, of course, have the
  29. corresponding sequence numbers, ack numbers, etc). The connection is now
  30. open. A SYN-scanner only sends the first packet in the three-way-handshake,
  31. the SYN packet, and waits for the SYN|ACK or a RST. When it receives one of
  32. the two it knows whether or not the port is listening. The major advantage
  33. to this method is that it is not detected by normal logs such as "SATAN
  34. detectors" or Wiestse's tcp_wrappers. The main disadvantages are:
  35.  
  36.   1. This method can still be detected by certian loggers that log SYN
  37.      connection attempts ('tcplog' for example), and can still be detected
  38.      by netstat(1).
  39.   2. The sender, under most operating systems, needs to custom build the
  40.      entire IP packet for this kind of scanning (I don't know of any
  41.      operating system under which this is not true, if you know of one,
  42.      please let me know). This requires access to SOCK_RAW
  43.      (getprotbyname('raw'); under most systems) or /dev/bpf (Berkeley
  44.      packet filter), /dev/nit (Sun 'Network Interface Tap') etc. This
  45.      usually requires root or privileged group access.
  46.   3. A great deal of firewalls who would filter out this scan, will not
  47.      filter out the StealthScan(TM) (all rights reserved to vicious little
  48.      red blow ficiouz deliciouz (kosher) chicken surpass INC PLC LTD).
  49.  
  50. A note about UDP portscanning
  51.  
  52. In this article I will ignore UDP portscanning for the simple reason that
  53. it lacks the complexity of tcp; it is not a connection oriented stream
  54. protocol but rather a connectionless datagram protocol. To scan a UDP port
  55. to see if it is listening, simply send any UDP packet to the port. You will
  56. receive an ICMP 'Destination Port Unreachable' packet if the port is not
  57. listening.
  58.  
  59. To the best of my knowledge this is the only way to scan UDP ports. I will
  60. be glad to be corrected -- if anyone knows of a different method please
  61. E-mail me.
  62.  
  63. The Stealth Scan
  64.  
  65. This method relies on bad net code in the BSD code. Since most of the
  66. networking code in most any operating system today is BSD netcode or a
  67. derivative thereof it works on most systems. (A most obvious exception to
  68. this is Cisco routers... Gosh! GOOD networking code ?!?@$! HERESY! Alan Cox
  69. will have a heart attack when he hears of this!)
  70.  
  71. Disadvantages of this technique:
  72.  
  73.   1. The IP packet must still be custom built. I see no solution for this
  74.      problem, unless some really insecure system calls will be put in. I
  75.      see no real need for this because SLIP/PPP services are so common
  76.      these days, getting super user access on a machine is not a problem
  77.      any more.
  78.   2. This method relies on bugs in net code. This can and probably will be
  79.      fixed in the near future. (Shhhhhh. Don't tell Alan Cox. He hates good
  80.      efficient networking code.) OpenBSD, for example, has already fixed
  81.      this bug.
  82.   3. The outcome of a scan is never known, and the outcome is not similar
  83.      over different architectures and operating systems. It is not
  84.      reliable.
  85.  
  86. Main advantages of this method over the other methods:
  87.  
  88.   1. Very difficult to log. Even once the method is known, devising a
  89.      logging method without fixing the actual bug itself is problematic.
  90.   2. Can circumvent some firewalls.
  91.   3. Will not show up on netstat(1).
  92.   4. Does not consist of any part of the standard TCP three-way-handshake.
  93.   5. Several different methods consisting of the same principle.
  94.  
  95. The actual algorithm:
  96.  
  97. I use TCP packets with the ACK, and FIN flags turned on. I use these simply
  98. because they are packets that should always return RST on an unopened
  99. connection sent to a port. From now on I refer to such packets as 'RST' ,
  100. 'FIN', or 'ACK' packets.
  101.  
  102. method #1:
  103.  
  104. Send a FIN packet. If the destination host returns a RST then the port is
  105. closed, if there is no return RST then the port is listening. The fact that
  106. this method works on so many hosts is a sad testimonial to the state of the
  107. networking code in most operating system kernels.
  108.  
  109. method #2
  110.  
  111. Send an ACK packet. If the returning packets ttl is lower than in the rest
  112. of the RST packets received, or if the window size is greater than zero,
  113. the port is probably listening.
  114.  
  115. (Note on the ttl: This bug is almost understandable. Every function in IP
  116. is a routing function. With every interface change, the packets ttl is
  117. subtracted by one. In the case of an open port, the ttl was decremented
  118. when it was received and examined, but when it was 'noticed' the flag was
  119. not a SYN, a RST was sent, with a ttl one lower then if the port had simply
  120. been closed. This might not be the case. I have not checked this theory
  121. against the BSD networking code. Feel free to correct me.
  122.  
  123. Uriel
  124.  
  125. /*
  126.  
  127.  * scantcp.c
  128.  
  129.  *
  130.  
  131.  * version 1.32
  132.  
  133.  *
  134.  
  135.  * Scans for listening TCP ports by sending packets to them and waiting for
  136.  
  137.  * replies. Relys upon the TCP specs and some TCP implementation bugs found
  138.  
  139.  * when viewing tcpdump logs.
  140.  
  141.  *
  142.  
  143.  * As always, portions recycled (eventually, with some stops) from n00k.c
  144.  
  145.  * (Wow, that little piece of code I wrote long ago still serves as the base
  146.  
  147.  *  interface for newer tools)
  148.  
  149.  *
  150.  
  151.  * Technique:
  152.  
  153.  * 1. Active scanning: not supported - why bother.
  154.  
  155.  *
  156.  
  157.  * 2. Half-open scanning:
  158.  
  159.  *      a. send SYN
  160.  
  161.  *      b. if reply is SYN|ACK send RST, port is listening
  162.  
  163.  *      c. if reply is RST, port is not listening
  164.  
  165.  *
  166.  
  167.  * 3. Stealth scanning: (works on nearly all systems tested)
  168.  
  169.  *      a. sends FIN
  170.  
  171.  *      b. if RST is returned, not listening.
  172.  
  173.  *      c. otherwise, port is probably listening.
  174.  
  175.  *
  176.  
  177.  * (This bug in many TCP implementations is not limited to FIN only; in fact
  178.  
  179.  *  many other flag combinations will have similar effects. FIN alone was
  180.  
  181.  *  selected because always returns a plain RST when not listening, and the
  182.  
  183.  *  code here was fit to handle RSTs already so it took me like 2 minutes
  184.  
  185.  *  to add this scanning method)
  186.  
  187.  *
  188.  
  189.  * 4. Stealth scanning: (may not work on all systems)
  190.  
  191.  *      a. sends ACK
  192.  
  193.  *      b. waits for RST
  194.  
  195.  *      c. if TTL is low or window is not 0, port is probably listening.
  196.  
  197.  *
  198.  
  199.  * (stealth scanning was created after I watched some tcpdump logs with
  200.  
  201.  *  these symptoms. The low-TTL implementation bug is currently believed
  202.  
  203.  *  to appear on Linux only, the non-zero window on ACK seems to exists on
  204.  
  205.  *  all BSDs.)
  206.  
  207.  *
  208.  
  209.  * CHANGES:
  210.  
  211.  * --------
  212.  
  213.  * 0. (v1.0)
  214.  
  215.  *    - First code, worked but was put aside since I didn't have time nor
  216.  
  217.  *      need to continue developing it.
  218.  
  219.  * 1. (v1.1)
  220.  
  221.  *    - BASE CODE MOSTLY REWRITTEN (the old code wasn't that maintainable)
  222.  
  223.  *    - Added code to actually enforce the usecond-delay without usleep()
  224.  
  225.  *      (replies might be lost if usleep()ing)
  226.  
  227.  * 2. (v1.2)
  228.  
  229.  *    - Added another stealth scanning method (FIN).
  230.  
  231.  *      Tested and passed on:
  232.  
  233.  *      AIX 3
  234.  
  235.  *      AIX 4
  236.  
  237.  *      IRIX 5.3
  238.  
  239.  *      SunOS 4.1.3
  240.  
  241.  *      System V 4.0
  242.  
  243.  *      Linux
  244.  
  245.  *      FreeBSD
  246.  
  247.  *      Solaris
  248.  
  249.  *
  250.  
  251.  *      Tested and failed on:
  252.  
  253.  *      Cisco router with services on ( IOS 11.0)
  254.  
  255.  *
  256.  
  257.  * 3. (v1.21)
  258.  
  259.  *    - Code commented since I intend on abandoning this for a while.
  260.  
  261.  *
  262.  
  263.  * 4. (v1.3)
  264.  
  265.  *    - Resending for ports that weren't replied for.
  266.  
  267.  *      (took some modifications in the internal structures. this also
  268.  
  269.  *       makes it possible to use non-linear port ranges
  270.  
  271.  *       (say 1-1024 and 6000))
  272.  
  273.  *
  274.  
  275.  * 5. (v1.31)
  276.  
  277.  *    - Flood detection - will slow up the sending rate if not replies are
  278.  
  279.  *      recieved for STCP_THRESHOLD consecutive sends. Saves alot of resends
  280.  
  281.  *      on easily-flooded networks.
  282.  
  283.  *
  284.  
  285.  * 6. (v1.32)
  286.  
  287.  *      - Multiple port ranges support.
  288.  
  289.  *        The format is: |[,|,...]
  290.  
  291.  *
  292.  
  293.  *        Examples: 20-26,113
  294.  
  295.  *                  20-100,113-150,6000,6660-6669
  296.  
  297.  *
  298.  
  299.  * PLANNED: (when I have time for this)
  300.  
  301.  * ------------------------------------
  302.  
  303.  * (v2.x) - Multiple flag combination selections, smart algorithm to point
  304.  
  305.  *          out uncommon replies and cross-check them with another flag
  306.  
  307.  *
  308.  
  309.  */
  310.  
  311. #define RESOLVE_QUIET
  312.  
  313. #include <stdio.h>
  314.  
  315. #include <netinet/in.h>
  316.  
  317. #include <netinet/ip.h>
  318.  
  319. #include <netinet/ip_tcp.h>
  320.  
  321. #include <sys/time.h>
  322.  
  323. #include <sys/types.h>
  324.  
  325. #include <sys/socket.h>
  326.  
  327. #include <unistd.h>
  328.  
  329. #include <stdlib.h>
  330.  
  331. #include <string.h>
  332.  
  333. #include <signal.h>
  334.  
  335. #include <errno.h>
  336.  
  337. #include "resolve.c"
  338.  
  339. #include "tcppkt03.c"
  340.  
  341. #define STCP_VERSION "1.32"
  342.  
  343. #define STCP_PORT  1234                /* Our local port. */
  344.  
  345. #define STCP_SENDS 3
  346.  
  347. #define STCP_THRESHOLD 8
  348.  
  349. #define STCP_SLOWFACTOR 10
  350.  
  351. /* GENERAL ROUTINES ------------------------------------------- */
  352.  
  353. void banner(void)
  354.  
  355.      {
  356.  
  357.         printf("\nscantcp\n");
  358.  
  359.         printf("version %s\n",STCP_VERSION);
  360.  
  361.      }
  362.  
  363.  
  364.  
  365. void usage(const char *progname)
  366.  
  367.      {
  368.  
  369.         printf("\nusage: \n");
  370.  
  371.         printf("%s <method> <source> <dest> <ports> <udelay> <delay> [sf]\n\n",progname);
  372.  
  373.         printf("\t : 0: half-open scanning (type 0, SYN)\n");
  374.  
  375.         printf("\t           1: stealth scanning (type 1, FIN)\n");
  376.  
  377.         printf("\t           2: stealth scanning (type 2, ACK)\n");
  378.  
  379.         printf("\t<source> : source address (this host)\n");
  380.  
  381.         printf("\t<dest>   : target to scan\n");
  382.  
  383.         printf("\t<ports>  : ports/and or ranges to scan - eg: 21-30,113,6000\n");
  384.  
  385.         printf("\t<udelay> : microseconds to wait between TCP sends\n");
  386.  
  387.         printf("\t<delay>  : seconds to wait for TCP replies\n");
  388.  
  389.         printf("\t[sf]     : slow-factor in case sends are dectected to be too fast\n\n");
  390.  
  391.      }
  392.  
  393. /* OPTION PARSING etc ---------------------------------------- */
  394.  
  395. unsigned char *dest_name;
  396.  
  397. unsigned char *spoof_name;
  398.  
  399. struct sockaddr_in destaddr;
  400.  
  401. unsigned long dest_addr;
  402.  
  403. unsigned long spoof_addr;
  404.  
  405. unsigned long usecdelay;
  406.  
  407. unsigned      waitdelay;
  408.  
  409. int slowfactor = STCP_SLOWFACTOR;
  410.  
  411. struct portrec                         /* the port-data structure */
  412.  
  413. {
  414.  
  415.    unsigned           n;
  416.  
  417.    int                state;
  418.  
  419.    unsigned char      ttl;
  420.  
  421.    unsigned short int window;
  422.  
  423.    unsigned long int  seq;
  424.  
  425.    char               sends;
  426.  
  427. } *ports;
  428.  
  429. char *portstr;
  430.  
  431. unsigned char scanflags;
  432.  
  433. int done;
  434.  
  435. int rawsock;                           /* socket descriptors */
  436.  
  437. int tcpsock;
  438.  
  439. int lastidx = 0;                       /* last sent index */
  440.  
  441. int maxports;                          /* total number of ports */
  442.  
  443. void timeout(int signum)               /* timeout handler           */
  444.  
  445.      {                                 /* this is actually the data */
  446.  
  447.         int someopen = 0;              /* analyzer function. werd.  */
  448.  
  449.         unsigned lastsent;
  450.  
  451.         int checklowttl = 0;
  452.  
  453.  
  454.  
  455.         struct portrec *p;
  456.  
  457.  
  458.  
  459.         printf("* SCANNING IS OVER\n\n");
  460.  
  461.         fflush(stdout);
  462.  
  463.  
  464.  
  465.         done = 1;
  466.  
  467.  
  468.  
  469.         for (lastsent = 0;lastsentstate == -1)
  470.  
  471.                if (p->ttl > 64)
  472.  
  473.                {
  474.  
  475.                   checklowttl = 1;
  476.  
  477.                   break;
  478.  
  479.                }
  480.  
  481.           }
  482.  
  483.  
  484.  
  485. /* the above loop checks whether there's need to report low-ttl packets */
  486.  
  487.  
  488.  
  489.         for (lastsent = 0;lastsentn);
  490.  
  491.  
  492.  
  493.              tcpip_send(rawsock,&destaddr,
  494.  
  495.                         spoof_addr,destaddr.sin_addr.s_addr,
  496.  
  497.                         STCP_PORT,ntohs(destaddr.sin_port),
  498.  
  499.                         TH_RST,
  500.  
  501.                         p->seq++, 0,
  502.  
  503.                         512,
  504.  
  505.                         NULL,
  506.  
  507.                         0);
  508.  
  509.           }                            /* just RST -everything- sent   */
  510.  
  511.                                        /* this inclued packets a reply */
  512.  
  513.                                        /* (even RST) was recieved for  */
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.         for (lastsent = 0;lastsentstate)
  524.  
  525.                     {
  526.  
  527.                      case -1: break;
  528.  
  529.                      case 1 : printf("# port %d is listening.\n",p->n);
  530.  
  531.                        someopen++;
  532.  
  533.                        break;
  534.  
  535.                      case 2 : printf("# port %d maybe listening (unknown response).\n",
  536.  
  537.                                      p->n);
  538.  
  539.                        someopen++;
  540.  
  541.                        break;
  542.  
  543.                      default: printf("# port %d needs to be rescanned.\n",p->n);
  544.  
  545.                     }
  546.  
  547.                   break;
  548.  
  549.                 case TH_ACK:
  550.  
  551.                   switch (p->state)
  552.  
  553.                     {
  554.  
  555.                      case -1:
  556.  
  557.                        if (((p->ttl < 65) && checklowttl) || (p->window >0))
  558.  
  559.                          {
  560.  
  561.                             printf("# port %d maybe listening",p->n);
  562.  
  563.                             if (p->ttl < 65) printf(" (low ttl)");
  564.  
  565.                             if (p->window >0) printf(" (big window)");
  566.  
  567.                             printf(".\n");
  568.  
  569.                             someopen++;
  570.  
  571.                          }
  572.  
  573.                        break;
  574.  
  575.                      case 1:
  576.  
  577.                      case 2:
  578.  
  579.                        printf("# port %d has an unexpected response.\n",
  580.  
  581.                               p->n);
  582.  
  583.                        break;
  584.  
  585.                      default:
  586.  
  587.                        printf("# port %d needs to be rescanned.\n",p->n);
  588.  
  589.                     }
  590.  
  591.                   break;
  592.  
  593.                 case TH_FIN:
  594.  
  595.                   switch (p->state)
  596.  
  597.                     {
  598.  
  599.                      case -1:
  600.  
  601.                        break;
  602.  
  603.                      case 0 :
  604.  
  605.                        printf("# port %d maybe open.\n",p->n);
  606.  
  607.                        someopen++;
  608.  
  609.                        break;
  610.  
  611.                      default:
  612.  
  613.                        printf("# port %d has an unexpected response.\n",p->n);
  614.  
  615.                     }
  616.  
  617.                }
  618.  
  619.           }
  620.  
  621.  
  622.  
  623.         printf("-----------------------------------------------\n");
  624.  
  625.         printf("# total ports open or maybe open: %d\n\n",someopen);
  626.  
  627.         free(ports);
  628.  
  629.  
  630.  
  631.         exit(0);                       /* heh. */
  632.  
  633.  
  634.  
  635.      }
  636.  
  637. int resolve_one(const char *name, unsigned long *addr, const char *desc)
  638.  
  639.      {
  640.  
  641.         struct sockaddr_in tempaddr;
  642.  
  643.         if (resolve(name, &tempaddr,0) == -1) {
  644.  
  645.            printf("error: can't resolve the %s.\n",desc);
  646.  
  647.            return -1;
  648.  
  649.         }
  650.  
  651.  
  652.  
  653.         *addr = tempaddr.sin_addr.s_addr;
  654.  
  655.         return 0;
  656.  
  657.      }
  658.  
  659. void give_info(void)
  660.  
  661.      {
  662.  
  663.         printf("# response address           : %s (%s)\n",spoof_name,inet_ntoa(spoof_addr));
  664.  
  665.         printf("# target address             : %s (%s)\n",dest_name,inet_ntoa(dest_addr));
  666.  
  667.         printf("# ports                      : %s\n",portstr);
  668.  
  669.         printf("# (total number of ports)    : %d\n",maxports);
  670.  
  671.         printf("# delay between sends        : %lu microseconds\n",usecdelay);
  672.  
  673.         printf("# delay                      : %u seconds\n",waitdelay);
  674.  
  675.         printf("# flood dectection threshold : %d unanswered sends\n",STCP_THRESHOLD);
  676.  
  677.         printf("# slow factor                : %d\n",slowfactor);
  678.  
  679.         printf("# max sends per port         : %d\n\n",STCP_SENDS);
  680.  
  681.      }
  682.  
  683. int parse_args(int argc, char *argv[])
  684.  
  685. {
  686.  
  687.  
  688.  
  689.    if (strrchr(argv[0],'/') != NULL)
  690.  
  691.      argv[0] = strrchr(argv[0],'/') + 1;
  692.  
  693.  
  694.  
  695.    if (argc < 7)  {
  696.  
  697.       printf("%s: not enough arguments\n",argv[0]);
  698.  
  699.       return -1;
  700.  
  701.    }
  702.  
  703.  
  704.  
  705.    switch (atoi(argv[1]))
  706.  
  707.      {
  708.  
  709.       case 0  : scanflags = TH_SYN;
  710.  
  711.                 break;
  712.  
  713.       case 1  : scanflags = TH_FIN;
  714.  
  715.                 break;
  716.  
  717.       case 2  : scanflags = TH_ACK;
  718.  
  719.                 break;
  720.  
  721.       default : printf("%s: unknown scanning method\n",argv[0]);
  722.  
  723.                 return -1;
  724.  
  725.      }
  726.  
  727.  
  728.  
  729.    spoof_name = argv[2];
  730.  
  731.    dest_name = argv[3];
  732.  
  733.  
  734.  
  735.    portstr = argv[4];
  736.  
  737.  
  738.  
  739.    usecdelay = atol(argv[5]);
  740.  
  741.    waitdelay = atoi(argv[6]);
  742.  
  743.    if (argc > 7) slowfactor = atoi(argv[7]);
  744.  
  745.  
  746.  
  747.    if ((usecdelay == 0) && (slowfactor > 0))
  748.  
  749.      {
  750.  
  751.         printf("%s: adjusting microsecond-delay to 1usec.\n");
  752.  
  753.         usecdelay++;
  754.  
  755.      }
  756.  
  757.    return 0;
  758.  
  759. }
  760.  
  761. /* MAIN ------------------------------------------------------ */
  762.  
  763. int build_ports(char *str)       /* build the initial port-database */
  764.  
  765. {
  766.  
  767.    int i;
  768.  
  769.    int n;
  770.  
  771.    struct portrec *p;
  772.  
  773.    int sport;
  774.  
  775.  
  776.  
  777.    char *s;
  778.  
  779.  
  780.  
  781.  
  782.  
  783.    s        = str;
  784.  
  785.    maxports = 0;
  786.  
  787.    n        = 0;
  788.  
  789.  
  790.  
  791.    while (*s != '\0')
  792.  
  793.      {
  794.  
  795.         switch (*s)
  796.  
  797.           {
  798.  
  799.            case '0':
  800.  
  801.            case '1':
  802.  
  803.            case '2':
  804.  
  805.            case '3':
  806.  
  807.            case '4':
  808.  
  809.            case '5':
  810.  
  811.            case '6':
  812.  
  813.            case '7':
  814.  
  815.            case '8':
  816.  
  817.            case '9':
  818.  
  819.              n *= 10;
  820.  
  821.              n += (*s - '0');
  822.  
  823.              break;
  824.  
  825.            case '-':
  826.  
  827.              if (n == 0) return -1;
  828.  
  829.              sport = n;
  830.  
  831.              n = 0;
  832.  
  833.              break;
  834.  
  835.            case ',':
  836.  
  837.              if (n == 0) return -1;
  838.  
  839.              if (sport != 0)
  840.  
  841.                {
  842.  
  843.                   if (sport >= n) return -1;
  844.  
  845.                   maxports += n-sport;
  846.  
  847.                   sport = 0;
  848.  
  849.                } else
  850.  
  851.                maxports++;
  852.  
  853.              n = 0;
  854.  
  855.              break;
  856.  
  857.           }
  858.  
  859.         s++;
  860.  
  861.      }
  862.  
  863.    if (n == 0) return -1;
  864.  
  865.    if (sport != 0)
  866.  
  867.      {
  868.  
  869.         if (sport >= n) return -1;
  870.  
  871.         maxports += n-sport;
  872.  
  873.         sport = 0;
  874.  
  875.      }
  876.  
  877.    else
  878.  
  879.      maxports++;
  880.  
  881.  
  882.  
  883.    maxports+=2;
  884.  
  885.  
  886.  
  887.    if ((ports = (struct portrec *)malloc((maxports)*sizeof(struct portrec))) == NULL)
  888.  
  889.      {
  890.  
  891.         fprintf(stderr,"\nerror: not enough memory for port database\n\n");
  892.  
  893.         exit(1);
  894.  
  895.      }
  896.  
  897.    s        = str;
  898.  
  899.    maxports = 0;
  900.  
  901.    n        = 0;
  902.  
  903.  
  904.  
  905.    while (*s != '\0')
  906.  
  907.      {
  908.  
  909.         switch (*s)
  910.  
  911.           {
  912.  
  913.            case '0':
  914.  
  915.            case '1':
  916.  
  917.            case '2':
  918.  
  919.            case '3':
  920.  
  921.            case '4':
  922.  
  923.            case '5':
  924.  
  925.            case '6':
  926.  
  927.            case '7':
  928.  
  929.            case '8':
  930.  
  931.            case '9':
  932.  
  933.              n *= 10;
  934.  
  935.              n += (*s - '0');
  936.  
  937.              break;
  938.  
  939.            case '-':
  940.  
  941.              if (n == 0) return -1;
  942.  
  943.              sport = n;
  944.  
  945.              n = 0;
  946.  
  947.              break;
  948.  
  949.            case ',':
  950.  
  951.              if (n == 0) return -1;
  952.  
  953.              if (sport != 0)
  954.  
  955.                {
  956.  
  957.                   if (sport >= n) return -1;
  958.  
  959.                   while (sport <= n)
  960.  
  961.                     {
  962.  
  963.                        for (i=0;in == sport) break;
  964.  
  965.  
  966.  
  967.                        if (i < maxports-1 )
  968.  
  969.                          printf("notice: duplicate port - %d\n",sport);
  970.  
  971.                        else
  972.  
  973.                          {
  974.  
  975.                             (ports+maxports)->n = sport;
  976.  
  977.                             maxports++;
  978.  
  979.                          }
  980.  
  981.                        sport++;
  982.  
  983.                     }
  984.  
  985.                   sport = 0;
  986.  
  987.                } else
  988.  
  989.                {
  990.  
  991.                   for (i=0;in == n) break;
  992.  
  993.  
  994.  
  995.                   if (i < maxports-1 )
  996.  
  997.                     printf("notice: duplicate port - %d\n",n);
  998.  
  999.                   else
  1000.  
  1001.                     {
  1002.  
  1003.                        (ports+maxports)->n = n;
  1004.  
  1005.                        maxports++;
  1006.  
  1007.                     }
  1008.  
  1009.                }
  1010.  
  1011.              n = 0;
  1012.  
  1013.              break;
  1014.  
  1015.           }
  1016.  
  1017.         s++;
  1018.  
  1019.      }
  1020.  
  1021.    if (n == 0) return -1;
  1022.  
  1023.    if (sport != 0)
  1024.  
  1025.      {
  1026.  
  1027.         if (sport >= n) return -1;
  1028.  
  1029.         while (sport <= n)
  1030.  
  1031.           {
  1032.  
  1033.              for (i=0;in == sport) break;
  1034.  
  1035.  
  1036.  
  1037.              if (i < maxports-1 )
  1038.  
  1039.                printf("notice: duplicate port - %d\n",sport);
  1040.  
  1041.              else
  1042.  
  1043.                {
  1044.  
  1045.                   (ports+maxports)->n = sport;
  1046.  
  1047.                   maxports++;
  1048.  
  1049.                }
  1050.  
  1051.              sport++;
  1052.  
  1053.           }
  1054.  
  1055.         sport = 0;
  1056.  
  1057.      } else
  1058.  
  1059.      {
  1060.  
  1061.         for (i=0;in == n) break;
  1062.  
  1063.  
  1064.  
  1065.         if (i < maxports-1 )
  1066.  
  1067.           printf("notice: duplicate port - %d\n",n);
  1068.  
  1069.         else
  1070.  
  1071.           {
  1072.  
  1073.              (ports+maxports)->n = n;
  1074.  
  1075.              maxports++;
  1076.  
  1077.           }
  1078.  
  1079.      }
  1080.  
  1081.  
  1082.  
  1083.    printf("\n");
  1084.  
  1085.  
  1086.  
  1087.    for (i=0;istate = 0;
  1088.  
  1089.         p->sends = 0;
  1090.  
  1091.      }
  1092.  
  1093.  
  1094.  
  1095.    return 0;
  1096.  
  1097.  
  1098.  
  1099. }
  1100.  
  1101.  
  1102.  
  1103. struct portrec *portbynum(int num)
  1104.  
  1105. {
  1106.  
  1107.    int i = 0;
  1108.  
  1109.  
  1110.  
  1111.    while ( ((ports+i)->n != num) && (istate != 0) || (p->sends == STCP_SENDS))
  1112.  
  1113.           {
  1114.  
  1115.              doneports++;
  1116.  
  1117.              lastidx++;
  1118.  
  1119.              lastidx %= maxports;
  1120.  
  1121.           }
  1122.  
  1123.         else
  1124.  
  1125.           break;
  1126.  
  1127.      }
  1128.  
  1129.  
  1130.  
  1131.    if (save)
  1132.  
  1133.      lastidx = oldlastidx;
  1134.  
  1135.    else
  1136.  
  1137.      lastidx = (lastidx + 1) % maxports;
  1138.  
  1139.  
  1140.  
  1141.    if (doneports == maxports) return NULL;
  1142.  
  1143.  
  1144.  
  1145.    return p;
  1146.  
  1147. }
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155. inline unsigned long usecdiff(struct timeval *a, struct timeval *b)
  1156.  
  1157. {
  1158.  
  1159.    unsigned long s;
  1160.  
  1161.  
  1162.  
  1163.    s = b->tv_sec - a->tv_sec;
  1164.  
  1165.    s *= 1000000;
  1166.  
  1167.    s += b->tv_usec - a->tv_usec;
  1168.  
  1169.  
  1170.  
  1171.    return s;                           /* return the stupid microsecond diff */
  1172.  
  1173. }
  1174.  
  1175. void main(int argc, char *argv[])
  1176.  
  1177. {
  1178.  
  1179.    int lastsent = 0;
  1180.  
  1181.  
  1182.  
  1183.    char buf[3000];
  1184.  
  1185.  
  1186.  
  1187.    struct iphdr  *ip   = (struct iphdr *)(buf);
  1188.  
  1189.    struct tcphdr *tcp  = (struct tcphdr *)(buf+sizeof(struct iphdr));
  1190.  
  1191.    struct sockaddr_in from;
  1192.  
  1193.    int fromlen;
  1194.  
  1195.  
  1196.  
  1197.    struct portrec *readport;
  1198.  
  1199.  
  1200.  
  1201.    fd_set rset, wset;
  1202.  
  1203.    struct timeval waitsend, now, del;
  1204.  
  1205.    unsigned long udiff;
  1206.  
  1207.  
  1208.  
  1209.    int sendthreshold = 0;
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.    banner();
  1216.  
  1217.  
  1218.  
  1219.    if (parse_args(argc,argv))
  1220.  
  1221.      {
  1222.  
  1223.         usage(argv[0]);
  1224.  
  1225.         return;
  1226.  
  1227.      }
  1228.  
  1229.  
  1230.  
  1231.    if (resolve_one(dest_name,
  1232.  
  1233.                     &dest_addr,
  1234.  
  1235.                     "destination host")) exit(1);
  1236.  
  1237.  
  1238.  
  1239.    destaddr.sin_addr.s_addr = dest_addr;
  1240.  
  1241.    destaddr.sin_family = AF_INET;
  1242.  
  1243.    if (resolve_one(spoof_name,
  1244.  
  1245.                     &spoof_addr,
  1246.  
  1247.                     "source host")) exit(1);
  1248.  
  1249.  
  1250.  
  1251.    if ( build_ports(portstr) == -1)
  1252.  
  1253.      {
  1254.  
  1255.         printf("\n%s: bad port string\n",argv[0]);
  1256.  
  1257.         usage(argv[0]);
  1258.  
  1259.         return;
  1260.  
  1261.      }
  1262.  
  1263.  
  1264.  
  1265.    give_info();
  1266.  
  1267.  
  1268.  
  1269.    if ((tcpsock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
  1270.  
  1271.      {
  1272.  
  1273.         printf("\nerror: couldn't get TCP raw socket\n\n");
  1274.  
  1275.         exit(1);
  1276.  
  1277.      }
  1278.  
  1279.    if ((rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
  1280.  
  1281.      {
  1282.  
  1283.         printf("\nerror: couldn't get raw socket\n\n");
  1284.  
  1285.         exit(1);
  1286.  
  1287.      }
  1288.  
  1289.  
  1290.  
  1291.    /* well, let's get to it. */
  1292.  
  1293.  
  1294.  
  1295.    done = 0;
  1296.  
  1297.  
  1298.  
  1299.    printf("* BEGINNING SCAN\n");
  1300.  
  1301.    fflush(stdout);
  1302.  
  1303.    gettimeofday(&waitsend,NULL);
  1304.  
  1305.  
  1306.  
  1307.    while (!done)
  1308.  
  1309.      {
  1310.  
  1311.         if (nextport(1) == NULL)
  1312.  
  1313.           {
  1314.  
  1315.              alarm(0);             /* no more sends, now we just  */
  1316.  
  1317.              signal(SIGALRM,timeout); /* to wait  seconds */
  1318.  
  1319.              alarm(waitdelay);        /* before resetting and giving */
  1320.  
  1321.           }                           /* results.                    */
  1322.  
  1323.         FD_ZERO(&rset);
  1324.  
  1325.  
  1326.  
  1327.         FD_SET(tcpsock,&rset);
  1328.  
  1329.  
  1330.  
  1331.         gettimeofday(&now,NULL);
  1332.  
  1333.  
  1334.  
  1335.         udiff = usecdiff(&waitsend,&now);
  1336.  
  1337.  
  1338.  
  1339.         /* here comes the multiple choice select().
  1340.  
  1341.          * well, there are 3 states:
  1342.  
  1343.          * 1. already sent all the packets.
  1344.  
  1345.          * 2. didn't send all the packets, but it's not time for another send
  1346.  
  1347.          * 3. didn't send all the packets and it is time for another send.
  1348.  
  1349.          */
  1350.  
  1351.  
  1352.  
  1353.         if (nextport(1) != NULL)
  1354.  
  1355.           if (udiff > usecdelay)
  1356.  
  1357.           {
  1358.  
  1359.              FD_ZERO(&wset);
  1360.  
  1361.              FD_SET(rawsock,&wset);
  1362.  
  1363.              select(FD_SETSIZE,&rset,&wset,NULL,NULL);
  1364.  
  1365.           } else
  1366.  
  1367.           {
  1368.  
  1369.              del.tv_sec = 0;
  1370.  
  1371.              del.tv_usec = usecdelay;
  1372.  
  1373.              select(FD_SETSIZE,&rset,NULL,NULL,&del);
  1374.  
  1375.           }
  1376.  
  1377.         else
  1378.  
  1379.           select(FD_SETSIZE,&rset,NULL,NULL,NULL);
  1380.  
  1381.  
  1382.  
  1383.         if (FD_ISSET(tcpsock,&rset))   /* process the reply */
  1384.  
  1385.           {
  1386.  
  1387.              fromlen = sizeof(from);
  1388.  
  1389.  
  1390.  
  1391.              recvfrom(tcpsock,&buf,3000,0,
  1392.  
  1393.                       (struct sockaddr *)&from,&fromlen);
  1394.  
  1395.  
  1396.  
  1397.              if (from.sin_addr.s_addr == destaddr.sin_addr.s_addr)
  1398.  
  1399.                if (ntohs(tcp->th_dport) == STCP_PORT)
  1400.  
  1401.                {
  1402.  
  1403.                   printf("* got reply");
  1404.  
  1405.  
  1406.  
  1407.                   readport = portbynum(ntohs(tcp->th_sport));
  1408.  
  1409.  
  1410.  
  1411.                   if (readport == NULL)
  1412.  
  1413.                     printf(" -- bad port");
  1414.  
  1415.                   else
  1416.  
  1417.                     {
  1418.  
  1419.                        sendthreshold = 0;
  1420.  
  1421.                        if (!readport->state)
  1422.  
  1423.                          {
  1424.  
  1425.                             readport->ttl    = ip->ttl;
  1426.  
  1427.                             readport->window = tcp->th_win;
  1428.  
  1429.  
  1430.  
  1431.                             if (tcp->th_flags & TH_RST)
  1432.  
  1433.                               {
  1434.  
  1435.                                  readport->state = -1;
  1436.  
  1437.                                  printf(" (RST)");
  1438.  
  1439.                                  if (readport->ttl    < 65) printf(" (short ttl)");
  1440.  
  1441.                                  if (readport->window > 0) printf(" (big window)");
  1442.  
  1443.                               }
  1444.  
  1445.                             else
  1446.  
  1447.                               if (tcp->th_flags & (TH_ACK | TH_SYN))
  1448.  
  1449.                               {
  1450.  
  1451.                                  readport->state = 1;
  1452.  
  1453.                                  printf(" (SYN+ACK)");
  1454.  
  1455.                                  tcpip_send(rawsock,&destaddr,
  1456.  
  1457.                                             spoof_addr,destaddr.sin_addr.s_addr,
  1458.  
  1459.                                             STCP_PORT,readport->n,
  1460.  
  1461.                                             TH_RST,
  1462.  
  1463.                                             readport->seq++, 0,
  1464.  
  1465.                                             512,
  1466.  
  1467.                                             NULL,
  1468.  
  1469.                                             0);
  1470.  
  1471.                               }
  1472.  
  1473.                             else
  1474.  
  1475.                               {
  1476.  
  1477.                                  readport->state = 2;
  1478.  
  1479.                                  printf(" (UNEXPECTED)");
  1480.  
  1481.                                  tcpip_send(rawsock,&destaddr,
  1482.  
  1483.                                             spoof_addr,destaddr.sin_addr.s_addr,
  1484.  
  1485.                                             STCP_PORT,readport->n,
  1486.  
  1487.                                             TH_RST,
  1488.  
  1489.                                             readport->seq++, 0,
  1490.  
  1491.                                             512,
  1492.  
  1493.                                             NULL,
  1494.  
  1495.                                             0);
  1496.  
  1497.                               }
  1498.  
  1499.                          }
  1500.  
  1501.                        else
  1502.  
  1503.                          printf(" (duplicate)");
  1504.  
  1505.                     }
  1506.  
  1507.                   printf("\n");
  1508.  
  1509.                   fflush(stdout);
  1510.  
  1511.                }
  1512.  
  1513.           }
  1514.  
  1515.  
  1516.  
  1517.         if (nextport(1) != NULL)
  1518.  
  1519.           if (FD_ISSET(rawsock,&wset)) /* process the sends */
  1520.  
  1521.           {
  1522.  
  1523.              readport = nextport(0);
  1524.  
  1525.  
  1526.  
  1527.              destaddr.sin_port = htons(readport->n);
  1528.  
  1529.              printf("* sending to port %d ",ntohs(destaddr.sin_port));
  1530.  
  1531.              readport->seq = lrand48();
  1532.  
  1533.              readport->sends++;
  1534.  
  1535.  
  1536.  
  1537.              tcpip_send(rawsock,&destaddr,
  1538.  
  1539.                         spoof_addr,destaddr.sin_addr.s_addr,
  1540.  
  1541.                         STCP_PORT,ntohs(destaddr.sin_port),
  1542.  
  1543.                         scanflags,
  1544.  
  1545.                         readport->seq++, lrand48(),
  1546.  
  1547.                         512,
  1548.  
  1549.                         NULL,
  1550.  
  1551.                         0);
  1552.  
  1553.  
  1554.  
  1555.              gettimeofday(&waitsend,NULL);
  1556.  
  1557.              FD_ZERO(&wset);
  1558.  
  1559.  
  1560.  
  1561.              printf("\n");
  1562.  
  1563.  
  1564.  
  1565.              if ((++sendthreshold > STCP_THRESHOLD) && (slowfactor))
  1566.  
  1567.                {
  1568.  
  1569.                   printf("\n\n -- THRESHOLD CROSSED - SLOWING UP SENDS\n\n");
  1570.  
  1571.                   usecdelay *= slowfactor;
  1572.  
  1573.                   sendthreshold = 0;
  1574.  
  1575.                }
  1576.  
  1577.           }
  1578.  
  1579.      }
  1580.  
  1581. }
  1582.  
  1583.  
  1584.  
  1585. /*
  1586.  
  1587.  * tcp_pkt.c
  1588.  
  1589.  *
  1590.  
  1591.  * routines for creating TCP packets, and sending them into sockets.
  1592.  
  1593.  *
  1594.  
  1595.  * (version 0.3)
  1596.  
  1597.  *
  1598.  
  1599.  *
  1600.  
  1601.  * BUGFIX: - it seems like the TCP pseudo header checksum was
  1602.  
  1603.  *           acting up in serveral cases.
  1604.  
  1605.  * ADDED : - HEXDUMP macro.
  1606.  
  1607.  *         - packet dump handling
  1608.  
  1609.  */
  1610.  
  1611. /* remove inlines for smaller size but lower speed */
  1612.  
  1613. #include <netinet/in.h>
  1614.  
  1615. #include <string.h>
  1616.  
  1617. #include <sys/types.h>
  1618.  
  1619. #include <netinet/ip.h>
  1620.  
  1621. #include <netinet/tcp.h>
  1622.  
  1623. #define IPHDRSIZE sizeof(struct iphdr)
  1624.  
  1625. #define TCPHDRSIZE sizeof(struct tcphdr)
  1626.  
  1627. #define PSEUDOHDRSIZE sizeof(struct pseudohdr)
  1628.  
  1629. /* ********** RIPPED CODE START ******************************** */
  1630.  
  1631. /*
  1632.  
  1633.  * in_cksum --
  1634.  
  1635.  *  Checksum routine for Internet Protocol family headers (C Version)
  1636.  
  1637.  */
  1638.  
  1639. unsigned short in_cksum(addr, len)
  1640.  
  1641.     u_short *addr;
  1642.  
  1643.     int len;
  1644.  
  1645. {
  1646.  
  1647.     register int nleft = len;
  1648.  
  1649.     register u_short *w = addr;
  1650.  
  1651.     register int sum = 0;
  1652.  
  1653.     u_short answer = 0;
  1654.  
  1655.  
  1656.  
  1657.     /*
  1658.  
  1659.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  1660.  
  1661.      * sequential 16 bit words to it, and at the end, fold back all the
  1662.  
  1663.      * carry bits from the top 16 bits into the lower 16 bits.
  1664.  
  1665.      */
  1666.  
  1667.     while (nleft > 1)  {
  1668.  
  1669.         sum += *w++;
  1670.  
  1671.         nleft -= 2;
  1672.  
  1673.     }
  1674.  
  1675.  
  1676.  
  1677.     /* mop up an odd byte, if necessary */
  1678.  
  1679.     if (nleft == 1) {
  1680.  
  1681.         *(u_char *)(&answer) = *(u_char *)w ;
  1682.  
  1683.         sum += answer;
  1684.  
  1685.     }
  1686.  
  1687.  
  1688.  
  1689.     /* add back carry outs from top 16 bits to low 16 bits */
  1690.  
  1691.     sum = (sum >> 16) + (sum & 0xffff);   /* add hi 16 to low 16 */
  1692.  
  1693.     sum += (sum >> 16);                   /* add carry */
  1694.  
  1695.     answer = ~sum;                        /* truncate to 16 bits */
  1696.  
  1697.     return(answer);
  1698.  
  1699. }
  1700.  
  1701. /* ********** RIPPED CODE END ******************************** */
  1702.  
  1703. /*
  1704.  
  1705.  * HEXDUMP()
  1706.  
  1707.  *
  1708.  
  1709.  * not too much to explain
  1710.  
  1711.  */
  1712.  
  1713. inline void HEXDUMP(unsigned len, unsigned char *data)
  1714.  
  1715. {
  1716.  
  1717.    unsigned i;
  1718.  
  1719.    for (i=0;isaddr = s_addr;
  1720.  
  1721.         pseudo->daddr = t_addr;
  1722.  
  1723.         pseudo->protocol = IPPROTO_TCP;
  1724.  
  1725.         pseudo->tcplength = htons(TCPHDRSIZE+datasize);
  1726.  
  1727.  
  1728.  
  1729.         /* The TCP pseudo-header was created. */
  1730.  
  1731.  
  1732.  
  1733.         tcp->th_sport   = htons(s_port);
  1734.  
  1735.         tcp->th_dport   = htons(t_port);
  1736.  
  1737.         tcp->th_off     = 5;          /* 20 bytes, (no options) */
  1738.  
  1739.         tcp->th_flags   = tcpflags;
  1740.  
  1741.         tcp->th_seq     = htonl(seq);
  1742.  
  1743.         tcp->th_ack     = htonl(ack);
  1744.  
  1745.         tcp->th_win     = htons(win); /* we don't need any bigger, I guess. */
  1746.  
  1747.  
  1748.  
  1749.         /* The necessary TCP header fields are set. */
  1750.  
  1751.  
  1752.  
  1753.         tcp->th_sum = in_cksum(pseudo,PSEUDOHDRSIZE+TCPHDRSIZE+datasize);
  1754.  
  1755.  
  1756.  
  1757.         memset(packet,0,IPHDRSIZE);
  1758.  
  1759.         /* The pseudo-header is wiped to clear the IP header fields */
  1760.  
  1761.  
  1762.  
  1763.         ip->saddr    = s_addr;
  1764.  
  1765.         ip->daddr    = t_addr;
  1766.  
  1767.         ip->version  = 4;
  1768.  
  1769.         ip->ihl      = 5;
  1770.  
  1771.         ip->ttl      = 255;
  1772.  
  1773.         ip->id       = random()%1996;
  1774.  
  1775.         ip->protocol = IPPROTO_TCP; /* should be 6 */
  1776.  
  1777.         ip->tot_len  = htons(IPHDRSIZE + TCPHDRSIZE + datasize);
  1778.  
  1779.         ip->check    = in_cksum((char *)packet,IPHDRSIZE);
  1780.  
  1781.  
  1782.  
  1783.         /* The IP header is intact. The packet is ready. */
  1784.  
  1785. #ifdef TCP_PKT_DEBUG
  1786.  
  1787.         printf("Packet ready. Dump: \n");
  1788.  
  1789. #ifdef TCP_PKT_DEBUG_DATA
  1790.  
  1791.         HEXDUMP(IPHDRSIZE+TCPHDRSIZE+datasize,packet);
  1792.  
  1793. #else
  1794.  
  1795.         HEXDUMP(IPHDRSIZE+TCPHDRSIZE,packet);
  1796.  
  1797. #endif
  1798.  
  1799.         printf("\n");
  1800.  
  1801. #endif
  1802.  
  1803.         return sendto(socket, packet, IPHDRSIZE+TCPHDRSIZE+datasize, 0, (struct sockaddr *)address, sizeof(struct sockaddr));
  1804.  
  1805.  
  1806.  
  1807.         /* And off into the raw socket it goes. */
  1808.  
  1809.      }
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815. /*
  1816.  
  1817.  * resolve.c
  1818.  
  1819.  *
  1820.  
  1821.  * resolves an internet text address into (struct sockaddr_in).
  1822.  
  1823.  *
  1824.  
  1825.  * CHANGES: 1. added the RESOLVE_QUIET preprocessor conditions. Jan 1996
  1826.  
  1827.  *          2. added resolve_rns() to always provide both name/ip. March 1996
  1828.  
  1829.  */
  1830.  
  1831. #include <sys/types.h>
  1832.  
  1833. #include <string.h>
  1834.  
  1835. #include <netdb.h>
  1836.  
  1837. #include <stdio.h>
  1838.  
  1839. #include <netinet/in.h>
  1840.  
  1841. int resolve( const char *name, struct sockaddr_in *addr, int port )
  1842.  
  1843.      {
  1844.  
  1845.         struct hostent *host;
  1846.  
  1847.  
  1848.  
  1849.         /* clear everything in case I forget something */
  1850.  
  1851.         bzero(addr,sizeof(struct sockaddr_in));
  1852.  
  1853.  
  1854.  
  1855.         if (( host = gethostbyname(name) ) == NULL )  {
  1856.  
  1857. #ifndef RESOLVE_QUIET
  1858.  
  1859.            fprintf(stderr,"unable to resolve host \"%s\" -- ",name);
  1860.  
  1861.            perror("");
  1862.  
  1863. #endif
  1864.  
  1865.            return -1;
  1866.  
  1867.         }
  1868.  
  1869.  
  1870.  
  1871.         addr->sin_family = host->h_addrtype;
  1872.  
  1873.         memcpy((caddr_t)&addr->sin_addr,host->h_addr,host->h_length);
  1874.  
  1875.         addr->sin_port = htons(port);
  1876.  
  1877.  
  1878.  
  1879.         return 0;
  1880.  
  1881.      }
  1882.  
  1883. int resolve_rns( char *name , unsigned long addr )
  1884.  
  1885.      {
  1886.  
  1887.         struct hostent *host;
  1888.  
  1889.         unsigned long address;
  1890.  
  1891.  
  1892.  
  1893.         address = addr;
  1894.  
  1895.         host = gethostbyaddr((char *)&address,4,AF_INET);
  1896.  
  1897.         if (!host)  {
  1898.  
  1899. #ifndef RESOLVE_QUIET
  1900.  
  1901.            fprintf(stderr,"unable to resolve host \"%s\" -- ",inet_ntoa(addr));
  1902.  
  1903.            perror("");
  1904.  
  1905. #endif
  1906.  
  1907.            return -1;
  1908.  
  1909.         }
  1910.  
  1911.         strcpy(name,host->h_name);
  1912.  
  1913.  
  1914.  
  1915.         return 0;
  1916.  
  1917.      }
  1918.  
  1919.  
  1920.  
  1921. unsigned long addr_to_ulong(struct sockaddr_in *addr)
  1922.  
  1923.      {
  1924.  
  1925.         return addr->sin_addr.s_addr;
  1926.  
  1927.      }
  1928.