rtrace.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:4k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1996 NEC Corporation.  All rights reserved.                 */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("COPYRIGHT") included with this distribution.                   */
  6. #include "socks5p.h"
  7. #include "wrap.h"
  8. #include "libproto.h"
  9. #include "protocol.h"
  10. #include "addr.h"
  11. #include "share.h"
  12. /* #define EXITERROR(err) ( perror("Traceroute"), exit((err)) ) */
  13. #define EXITERROR(err) ( exit((err)) )
  14. static int verbose   = 0;
  15. static int noname    = 0;
  16. #ifdef TROUTEPROG
  17. static int ischild   = 0;
  18. static void StopChild() {
  19.     int childstat;
  20.     if (ischild > 0) {
  21. while (wait(&childstat) != ischild);
  22.      ischild   = 0;
  23.     }
  24. }
  25. static int Popen(const char *name) {
  26.     int pds[2];
  27.     if (pipe(pds)          < 0)         return -1;
  28.     if (dup2(pds[0], STDIN_FILENO) < 0) return -1;
  29.     close(pds[0]);
  30.     if ((ischild = fork()) < 0)         return -1;
  31.     
  32.     if (ischild == 0) {
  33.         close(STDIN_FILENO);
  34.         if (dup2(pds[1], STDOUT_FILENO) < 0) _exit(1);
  35.         if (dup2(pds[1], STDERR_FILENO) < 0) _exit(1);
  36.         close(pds[1]);
  37. if (noname) execlp(TROUTEPROG, "traceroute", "-n", (verbose?"-v":name), verbose?name:NULL, NULL);
  38. else        execlp(TROUTEPROG, "traceroute", (verbose?"-v":name), verbose?name:NULL, NULL);
  39.         _exit(1);
  40.     }
  41.     close(pds[1]);
  42.     return ischild;
  43. }
  44. static int TraceProxy(S5NetAddr *proxy) {
  45.     int childpid, ret;
  46.     
  47.     if ((childpid = Popen(lsAddr2Ascii(proxy))) < 0) return -1;
  48.     fprintf(stdout, "Traceroute to the proxy server %sn", lsAddr2Ascii(proxy));
  49.     ret = DataRelay(STDIN_FILENO, NULL, childpid);
  50.     StopChild();
  51.     return ret;
  52. }
  53. #endif
  54. /*
  55. static void SocksTrace(S5NetAddr *dst, S5NetAddr *proxy) {
  56.     u_char flag = (noname?SOCKS5_FLAG_NONAME:0)|(verbose?SOCKS5_FLAG_VERBOSE:0);
  57.     if (InitProxy(proxy, dst, SOCKS_TRACER, flag) < 0) {
  58.         fprintf(stdout, "Fail to connect to the proxy server %sn", lsAddr2Ascii(proxy));
  59. EXITERROR(-1);
  60.     }
  61.     DataRelay(0);
  62.     exit(0);
  63. }
  64. */
  65. void usage(char *progname) {
  66.     fprintf(stderr, "Usage: %s [-n] [-v] hostn", progname);
  67.     exit(-1);
  68. }
  69. int main(int argc, char *argv[]) {
  70.     char *hostname = NULL, *progname = NULL;
  71.     S5IOHandle fd;
  72.     S5NetAddr rsin;
  73.     lsSocksInfo *pcon;
  74.     struct hostent *rhp;
  75.     for (progname = *argv, argc--, argv++; argc > 0; argc--, argv++) {
  76. if (**argv == '-') {
  77.     if      (!strcmp(*argv, "-n")) noname  = 1;
  78.     else if (!strcmp(*argv, "-v")) verbose = 1;
  79.     else {
  80. fprintf(stderr, "%s: Unrecognized option %sn", progname, *argv);
  81. usage(progname);
  82.     }
  83. } else {
  84.     if (hostname != NULL) usage(progname);
  85.     hostname = *argv;
  86. }
  87.     }
  88.     if (hostname == NULL) usage(progname);
  89.     if (LIBPREFIX2(init)(NULL) != 0) EXITERROR(-1);
  90.     memset((char *)&rsin, 0, sizeof(S5NetAddr));
  91.     rsin.sin.sin_family = AF_INET;
  92.     if ((rsin.sin.sin_addr.s_addr = inet_addr(hostname)) == INVALIDADDR) {
  93.         if ((rhp = LIBPREFIX(gethostbyname)(hostname)) == NULL) EXITERROR(-1);
  94.         memcpy((char *)&rsin.sin.sin_addr.s_addr, (char *)rhp->h_addr_list[0], rhp->h_length);
  95.         rsin.sin.sin_family = rhp->h_addrtype;
  96.     }
  97.     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == S5InvalidIOHandle) return -1;
  98.     Signal(SIGPIPE, SIG_IGN);
  99.     if ((pcon = lsLibProtoExchg(fd, &rsin, SOCKS_TRACER)) == NULL) {
  100.         fprintf(stderr, "lsLibProtoExchg: Protocol exchange failed.n");
  101.         CLOSESOCKET(fd);
  102.         return -1;
  103.     }
  104.     if (!pcon->pri || pcon->pri->how == DIRECT || !lsAddrAddrComp(&rsin, &pcon->pri->prxyin)) {
  105.         LIBPREFIX(close)(fd);
  106. #ifndef TROUTEPROG
  107. fprintf(stderr, "Real traceroute unavailable.n");
  108. exit(0);
  109. #else
  110. if (noname) execlp(TROUTEPROG, "traceroute", "-n", (verbose?"-v":hostname), verbose?hostname:NULL, NULL);
  111. else        execlp(TROUTEPROG, "traceroute", (verbose?"-v":hostname), verbose?hostname:NULL, NULL);
  112. _exit(1);
  113. #endif
  114.     }
  115. #ifdef TROUTEPROG
  116.     if (TraceProxy(&pcon->pri->prxyin) < 0) {
  117.         LIBPREFIX(close)(fd);
  118. EXITERROR(-1);
  119.     }
  120. #endif
  121.     DataRelay(fd, &pcon->pri->cinfo, 0);
  122.     LIBPREFIX(close)(fd);
  123.     exit(0);
  124. }