www.pudn.com > socks5.zip > rtrace.c


/* Copyright (c) 1996 NEC Corporation.  All rights reserved.                 */ 
/*                                                                           */ 
/* The redistribution, use and modification in source or binary forms of     */ 
/* this software is subject to the conditions set forth in the copyright     */ 
/* document ("COPYRIGHT") included with this distribution.                   */ 
#include "socks5p.h" 
#include "wrap.h" 
#include "libproto.h" 
#include "protocol.h" 
#include "addr.h" 
#include "share.h" 
 
/* #define EXITERROR(err)	( perror("Traceroute"), exit((err)) ) */ 
#define EXITERROR(err)	( exit((err)) ) 
 
static int verbose   = 0; 
static int noname    = 0; 
 
#ifdef TROUTEPROG 
static int ischild   = 0; 
 
static void StopChild() { 
    int childstat; 
 
    if (ischild > 0) { 
	while (wait(&childstat) != ischild); 
    	ischild   = 0; 
    } 
} 
 
static int Popen(const char *name) { 
    int pds[2]; 
 
    if (pipe(pds)          < 0)         return -1; 
    if (dup2(pds[0], STDIN_FILENO) < 0) return -1; 
    close(pds[0]); 
 
    if ((ischild = fork()) < 0)         return -1; 
     
    if (ischild == 0) { 
        close(STDIN_FILENO); 
        if (dup2(pds[1], STDOUT_FILENO) < 0) _exit(1); 
        if (dup2(pds[1], STDERR_FILENO) < 0) _exit(1); 
        close(pds[1]); 
 
	if (noname) execlp(TROUTEPROG, "traceroute", "-n", (verbose?"-v":name), verbose?name:NULL, NULL); 
	else        execlp(TROUTEPROG, "traceroute", (verbose?"-v":name), verbose?name:NULL, NULL); 
	 
        _exit(1); 
    } 
 
    close(pds[1]); 
 
    return ischild; 
} 
 
static int TraceProxy(S5NetAddr *proxy) { 
    int childpid, ret; 
     
    if ((childpid = Popen(lsAddr2Ascii(proxy))) < 0) return -1; 
 
    fprintf(stdout, "Traceroute to the proxy server %s\n", lsAddr2Ascii(proxy)); 
 
    ret = DataRelay(STDIN_FILENO, NULL, childpid); 
    StopChild(); 
    return ret; 
} 
#endif 
 
/* 
static void SocksTrace(S5NetAddr *dst, S5NetAddr *proxy) { 
    u_char flag = (noname?SOCKS5_FLAG_NONAME:0)|(verbose?SOCKS5_FLAG_VERBOSE:0); 
 
    if (InitProxy(proxy, dst, SOCKS_TRACER, flag) < 0) { 
        fprintf(stdout, "Fail to connect to the proxy server %s\n", lsAddr2Ascii(proxy)); 
	EXITERROR(-1); 
    } 
 
    DataRelay(0); 
    exit(0); 
} 
*/ 
 
void usage(char *progname) { 
    fprintf(stderr, "Usage: %s [-n] [-v] host\n", progname); 
    exit(-1); 
} 
 
int main(int argc, char *argv[]) { 
    char *hostname = NULL, *progname = NULL; 
    S5IOHandle fd; 
    S5NetAddr rsin; 
    lsSocksInfo *pcon; 
    struct hostent *rhp; 
 
    for (progname = *argv, argc--, argv++; argc > 0; argc--, argv++) { 
	if (**argv == '-') { 
	    if      (!strcmp(*argv, "-n")) noname  = 1; 
	    else if (!strcmp(*argv, "-v")) verbose = 1; 
	    else { 
		fprintf(stderr, "%s: Unrecognized option %s\n", progname, *argv); 
		usage(progname); 
	    } 
	} else { 
	    if (hostname != NULL) usage(progname); 
	    hostname = *argv; 
	} 
    } 
 
    if (hostname == NULL) usage(progname); 
    if (LIBPREFIX2(init)(NULL) != 0) EXITERROR(-1); 
 
    memset((char *)&rsin, 0, sizeof(S5NetAddr)); 
    rsin.sin.sin_family = AF_INET; 
 
    if ((rsin.sin.sin_addr.s_addr = inet_addr(hostname)) == INVALIDADDR) { 
        if ((rhp = LIBPREFIX(gethostbyname)(hostname)) == NULL) EXITERROR(-1); 
 
        memcpy((char *)&rsin.sin.sin_addr.s_addr, (char *)rhp->h_addr_list[0], rhp->h_length); 
        rsin.sin.sin_family = rhp->h_addrtype; 
    } 
 
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == S5InvalidIOHandle) return -1; 
    Signal(SIGPIPE, SIG_IGN); 
 
    if ((pcon = lsLibProtoExchg(fd, &rsin, SOCKS_TRACER)) == NULL) { 
        fprintf(stderr, "lsLibProtoExchg: Protocol exchange failed.\n"); 
        CLOSESOCKET(fd); 
        return -1; 
    } 
 
    if (!pcon->pri || pcon->pri->how == DIRECT || !lsAddrAddrComp(&rsin, &pcon->pri->prxyin)) { 
        LIBPREFIX(close)(fd); 
#ifndef TROUTEPROG 
	fprintf(stderr, "Real traceroute unavailable.\n"); 
	exit(0); 
#else 
	if (noname) execlp(TROUTEPROG, "traceroute", "-n", (verbose?"-v":hostname), verbose?hostname:NULL, NULL); 
	else        execlp(TROUTEPROG, "traceroute", (verbose?"-v":hostname), verbose?hostname:NULL, NULL); 
 
	_exit(1); 
#endif 
    } 
 
#ifdef TROUTEPROG 
    if (TraceProxy(&pcon->pri->prxyin) < 0) { 
        LIBPREFIX(close)(fd); 
	EXITERROR(-1); 
    } 
#endif 
 
    DataRelay(fd, &pcon->pri->cinfo, 0); 
    LIBPREFIX(close)(fd); 
 
    exit(0); 
}