Exemple #1
0
void
handle_resolve_dns(int parc, char *parv[])
{
	char *id = rb_strdup(parv[1]);
	char qtype = *parv[2];
	char *record = parv[3];
	int aftype = AF_INET;

	switch(qtype)
	{
	case '6':
		aftype = AF_INET6;
	case '4':
		if(!lookup_ip(record, aftype, submit_dns_answer, id))
			submit_dns_answer(NULL, false, qtype, NULL);
		break;
	case 'S':
	case 'R':
		if(!lookup_hostname(record, submit_dns_answer, id))
			submit_dns_answer(NULL, false, qtype, NULL);
		break;
	default:
		warn_opers(L_CRIT, "DNS: handle_resolve_dns got an unknown query: %c", qtype);
		exit(EX_DNS_ERROR);
	}
}
Exemple #2
0
int
main(int argc, char *argv[])
{
    struct ovs_cmdl_context ctx = { .argc = 0, };
    set_program_name(argv[0]);
    vlog_set_levels(NULL, VLF_ANY_DESTINATION, VLL_EMER);
    parse_options(argc, argv);
    ctx.argc = argc - optind;
    ctx.argv = argv + optind;
    ovs_cmdl_run_command(&ctx, get_all_commands());
    return 0;
}

static void
parse_target(const char *s_, struct in_addr *addr,
             unsigned short int *min, unsigned short int *max)
{
    char *s = xstrdup(s_);
    char *colon;
    int error;

    colon = strchr(s, ':');
    if (colon) {
        *colon = '\0';
    }

    if (*s != '\0') {
        error = lookup_hostname(s, addr);
        if (error) {
            ovs_fatal(error, "failed to look up IP address for \"%s\"", s_);
        }
    } else {
        addr->s_addr = htonl(INADDR_ANY);
    }

    *min = *max = 0;
    if (colon && colon[1] != '\0') {
        const char *ports = colon + 1;
        if (ovs_scan(ports, "%hu-%hu", min, max)) {
            if (*min > *max) {
                ovs_fatal(0, "%s: minimum is greater than maximum", s_);
            }
        } else if (ovs_scan(ports, "%hu", min)) {
            *max = *min;
        } else {
            ovs_fatal(0, "%s: number or range expected", s_);
        }
    }

    free(s);
}
Exemple #3
0
/** Parse a string of the form "host[:port]" from <b>addrport</b>.  If
 * <b>address</b> is provided, set *<b>address</b> to a copy of the
 * host portion of the string.  If <b>addr</b> is provided, try to
 * resolve the host portion of the string and store it into
 * *<b>addr</b> (in host byte order).  If <b>port_out</b> is provided,
 * store the port number into *<b>port_out</b>, or 0 if no port is given.
 * If <b>port_out</b> is NULL, then there must be no port number in
 * <b>addrport</b>.
 * Return 0 on success, -1 on failure.
 */
int
parse_addr_port(int severity, const char *addrport, char **address,
                uint32_t *addr, uint16_t *port_out)
{
  const char *colon;
  char *_address = NULL;
  int _port;
  int ok = 1;

  assert(addrport);

  colon = strchr(addrport, ':');
  if (colon) {
    _address = tor_strndup(addrport, colon-addrport);
    _port = (int) parse_long(colon+1,10,1,65535,NULL,NULL);
    if (!_port) {
      fprintf(stderr, "Port %s out of range\n", colon+1);
      ok = 0;
    }
    if (!port_out) {
      fprintf(stderr, "Port %s given on %s when not required\n",
	      colon+1, addrport);
      ok = 0;
    }
  } else {
    _address = strdup(addrport);
    _port = 0;
  }

  if (addr) {
    /* There's an addr pointer, so we need to resolve the hostname. */
    if (lookup_hostname(_address,addr)) {
      fprintf(stderr, "Couldn't look up %s\n", _address);
      ok = 0;
      *addr = 0;
    }
  }

  if (address && ok) {
    *address = _address;
  } else {
    if (address)
      *address = NULL;
    free(_address);
  }
  if (port_out)
    *port_out = ok ? ((uint16_t) _port) : 0;

  return ok ? 0 : -1;
}
static void
parse_target(const char *s_, struct in_addr *addr,
             unsigned short int *min, unsigned short int *max)
{
    char *s = xstrdup(s_);
    char *colon;
    int error;

    colon = strchr(s, ':');
    if (colon) {
        *colon = '\0';
    }

    if (*s != '\0') {
        error = lookup_hostname(s, addr);
        if (error) {
            ovs_fatal(error, "failed to look up IP address for \"%s\"", s_);
        }
    } else {
        addr->s_addr = htonl(INADDR_ANY);
    }

    *min = *max = 0;
    if (colon && colon[1] != '\0') {
        const char *ports = colon + 1;
        if (sscanf(ports, "%hu-%hu", min, max) == 2) {
            if (*min > *max) {
                ovs_fatal(0, "%s: minimum is greater than maximum", s_);
            }
        } else if (sscanf(ports, "%hu", min) == 1) {
            *max = *min;
        } else {
            ovs_fatal(0, "%s: number or range expected", s_);
        }
    }

    free(s);
}
Exemple #5
0
int xdebug_create_socket(const char *hostname, int dport)
{
	struct sockaddr    sa;
	struct sockaddr_in address;
	int                sockfd;
	int                status;
	struct timeval     timeout;
	int                actually_connected;
	socklen_t          size = sizeof(sa);
#if WIN32|WINNT
	WORD               wVersionRequested;
	WSADATA            wsaData;
	char               optval = 1;
	const char         yes = 1;
	u_long             no = 0;

	wVersionRequested = MAKEWORD(2, 2);
	WSAStartup(wVersionRequested, &wsaData);
#else
	long               optval = 1;
#endif
	memset(&address, 0, sizeof(address));
	lookup_hostname(hostname, &address.sin_addr);
	address.sin_family = AF_INET;
	address.sin_port = htons((unsigned short)dport);

	sockfd = socket(address.sin_family, SOCK_STREAM, 0);
	if (sockfd == SOCK_ERR) {
#ifndef DEBUGGER_FAIL_SILENTLY
#if WIN32|WINNT
		printf("create_debugger_socket(\"%s\", %d) socket: %d\n",
					hostname, dport, WSAGetLastError());
#else
		printf("create_debugger_socket(\"%s\", %d) socket: %s\n",
					hostname, dport, strerror(errno));
#endif
#endif
		return -1;
	}

	/* Put socket in non-blocking mode so we can use select for timeouts */
	timeout.tv_sec = 0;
	timeout.tv_usec = 200000;

#ifdef WIN32
	ioctlsocket(sockfd, FIONBIO, (u_long*)&yes);
#else
	fcntl(sockfd, F_SETFL, O_NONBLOCK);
#endif

	/* connect */
	status = connect(sockfd, (struct sockaddr*)&address, sizeof(address));
	if (status < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
		if (errno != WSAEINPROGRESS && errno != WSAEWOULDBLOCK) {
			close(sockfd);
			return -1;
		}
#else
		if (errno == EACCES) {
			close(sockfd);
			return -3;
		}
		if (errno != EINPROGRESS) {
			close(sockfd);
			return -1;
		}
#endif

		while (1) {
			fd_set rset, wset, eset;

			FD_ZERO(&rset);
			FD_SET(sockfd, &rset);
			FD_ZERO(&wset);
			FD_SET(sockfd, &wset);
			FD_ZERO(&eset);
			FD_SET(sockfd, &eset);

			if (select(sockfd+1, &rset, &wset, &eset, &timeout) == 0) {
				close(sockfd);
				return -2;
			}

			/* if our descriptor has an error */
			if (FD_ISSET(sockfd, &eset)) {
				close(sockfd);
				return -1;
			}

			/* if our descriptor is ready break out */
			if (FD_ISSET(sockfd, &wset) || FD_ISSET(sockfd, &rset)) {
				break;
			}
		}

		actually_connected = getpeername(sockfd, &sa, &size);
		if (actually_connected == -1) {
			close(sockfd);
			return -1;
		}
	}


#ifdef WIN32
	ioctlsocket(sockfd, FIONBIO, &no);
#else
	fcntl(sockfd, F_SETFL, 0);
#endif

	setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
	return sockfd;
}
Exemple #6
0
int lkboot_txn(const char *host, const char *_cmd, int txfd, const char *args) {
	msg_hdr_t hdr;
	in_addr_t addr;
	char cmd[128];
	char tmp[65536];
	off_t txlen = 0;
	int len;
	int s;

	if (txfd != -1) {
		txlen = lseek(txfd, 0, SEEK_END);
		if (txlen > (512*1024*1024)) {
			fprintf(stderr, "error: file too large\n");
			return -1;
		}
		lseek(txfd, 0, SEEK_SET);
	}

	len = snprintf(cmd, 128, "%s:%d:%s", _cmd, (int) txlen, args);
	if (len > 127) {
		fprintf(stderr, "error: command too large\n");
		return -1;
	}

	addr = lookup_hostname(host);
	if (addr == 0) {
		fprintf(stderr, "error: cannot find host '%s'\n", host);
		return -1;
	}
	if ((s = tcp_connect(addr, 1023)) < 0) {
		fprintf(stderr, "error: cannot connect to host '%s'\n", host);
		return -1;
	}

	hdr.opcode = MSG_CMD;
	hdr.extra = 0;
	hdr.length = len;
	if (write(s, &hdr, sizeof(hdr)) != sizeof(hdr)) goto iofail;
	if (write(s, cmd, len) != len) goto iofail;

	for (;;) {	
		if (readx(s, &hdr, sizeof(hdr))) goto iofail;
		switch (hdr.opcode) {
		case MSG_GO_AHEAD:
			if (upload(s, txfd, txlen)) goto fail;
			break;
		case MSG_OKAY:
			close(s);
			return 0;
		case MSG_FAIL:
			len = (hdr.length > 127) ? 127 : hdr.length;
			if (readx(s, cmd, len)) {
				cmd[0] = 0;
			} else {
				cmd[len] = 0;
			}
			fprintf(stderr,"error: remote failure: %s\n", cmd);
			goto fail;
		case MSG_SEND_DATA:
			len = hdr.length + 1;
			if (readx(s, tmp, len)) goto iofail;
			if (len > (REPLYMAX - replylen)) {
				fprintf(stderr, "error: too much reply data\n");
				goto fail;
			}
			memcpy(replybuf + replylen, tmp, len);
			replylen += len;
			break;
		default:
			fprintf(stderr, "error: unknown opcode %d\n", hdr.opcode);
			goto fail;
		}
	}

iofail:
	fprintf(stderr, "error: socket io\n");
fail:
	close(s);
	return -1;
}
Exemple #7
0
int lkboot_txn(const char *host, const char *_cmd, int txfd, const char *args) {
	msg_hdr_t hdr;
	in_addr_t addr;
	char cmd[128];
	char tmp[65536];
	off_t txlen = 0;
	int do_endian_swap = 0;
	int once = 1;
	int len;
	int s;

	if (txfd != -1) {
		txlen = lseek(txfd, 0, SEEK_END);
		if (txlen > (512*1024*1024)) {
			fprintf(stderr, "error: file too large\n");
			return -1;
		}
		lseek(txfd, 0, SEEK_SET);
	}

	if (!strcmp(_cmd, "fpga")) {
		/* if we were asked to send an fpga image, try to find the sync words and
		 * trim all the data before it
		 */
		txlen = trim_fpga_image(txfd, txlen);
		if (txlen < 0) {
			fprintf(stderr, "error: fpga image doesn't contain sync pattern\n");
			return -1;
		}

		/* it'll need a 4 byte endian swap as well */
		do_endian_swap = 1;
	}

	len = snprintf(cmd, 128, "%s:%d:%s", _cmd, (int) txlen, args);
	if (len > 127) {
		fprintf(stderr, "error: command too large\n");
		return -1;
	}

	addr = lookup_hostname(host);
	if (addr == 0) {
		fprintf(stderr, "error: cannot find host '%s'\n", host);
		return -1;
	}
	while ((s = tcp_connect(addr, 1023)) < 0) {
		if (once) {
			fprintf(stderr, "error: cannot connect to host '%s'. retrying...\n", host);
			once = 0;
		}
		usleep(100000);
	}

	hdr.opcode = MSG_CMD;
	hdr.extra = 0;
	hdr.length = len;
	if (write(s, &hdr, sizeof(hdr)) != sizeof(hdr)) goto iofail;
	if (write(s, cmd, len) != len) goto iofail;

	for (;;) {
		if (readx(s, &hdr, sizeof(hdr))) goto iofail;
		switch (hdr.opcode) {
		case MSG_GO_AHEAD:
			if (upload(s, txfd, txlen, do_endian_swap)) goto fail;
			break;
		case MSG_OKAY:
			close(s);
			return 0;
		case MSG_FAIL:
			len = (hdr.length > 127) ? 127 : hdr.length;
			if (readx(s, cmd, len)) {
				cmd[0] = 0;
			} else {
				cmd[len] = 0;
			}
			fprintf(stderr,"error: remote failure: %s\n", cmd);
			goto fail;
		case MSG_SEND_DATA:
			len = hdr.length + 1;
			if (readx(s, tmp, len)) goto iofail;
			if (len > (REPLYMAX - replylen)) {
				fprintf(stderr, "error: too much reply data\n");
				goto fail;
			}
			memcpy(replybuf + replylen, tmp, len);
			replylen += len;
			break;
		default:
			fprintf(stderr, "error: unknown opcode %d\n", hdr.opcode);
			goto fail;
		}
	}

iofail:
	fprintf(stderr, "error: socket io\n");
fail:
	close(s);
	return -1;
}
Exemple #8
0
static const char *get_ip_address(struct hostinfo *hi)
{
	lookup_hostname(hi);
	return hi->ip_address.buf;
}
Exemple #9
0
static const char *get_canon_hostname(struct hostinfo *hi)
{
	lookup_hostname(hi);
	return hi->canon_hostname.buf;
}
Exemple #10
0
int
thttpd_run(void)
    {
    char* cp;
    struct passwd* pwd;
    uid_t uid = 32767;
    gid_t gid = 32767;
    int num_ready;
    int cnum;
    connecttab* c;
    httpd_conn* hc;
    httpd_sockaddr sa4;
    httpd_sockaddr sa6;
    int gotv4, gotv6;
    struct timeval tv;
    
    cp = getenv( "GHTTPPORT" );
    if ( cp )
	port = atoi( cp );
    if( port == 0 )
	port = 9999;

    /* Read zone info now, in case we chroot(). */
    tzset();

    /* Look up hostname now, in case we chroot(). */
    lookup_hostname( &sa4, sizeof(sa4), &gotv4, &sa6, sizeof(sa6), &gotv6 );
    if ( ! ( gotv4 || gotv6 ) )
	{
	memset(&sa4, 0, sizeof sa4);
	gotv4 = 1;
	}

    /* Initialize the fdwatch package.  Have to do this before chroot,
    ** if /dev/poll is used.
    */
    max_connects = fdwatch_get_nfiles();
    if ( max_connects < 0 )
	{
	return;
	}
    max_connects -= SPARE_FDS;

    /* Set up to catch signals. */
#ifdef HAVE_SIGSET
    (void) sigset( SIGPIPE, SIG_IGN );          /* get EPIPE instead */
#else /* HAVE_SIGSET */
    (void) signal( SIGPIPE, SIG_IGN );          /* get EPIPE instead */
#endif /* HAVE_SIGSET */

    /* Initialize the timer package. */
    tmr_init();

    /* Initialize the HTTP layer.  Got to do this before giving up root,
    ** so that we can bind to a privileged port.
    */
    hs = httpd_initialize(
	hostname,
	gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0,
	port, cgi_pattern, cgi_limit, charset, p3p, max_age, "/", no_log, 
	no_symlink_check, do_vhost, do_global_passwd, url_pattern,
	local_pattern, no_empty_referers );
    if ( hs == (httpd_server*) 0 )
	exit( 1 );

    /* Set up the occasional timer. */
    if ( tmr_create( (struct timeval*) 0, occasional, JunkClientData, OCCASIONAL_TIME * 1000L, 1 ) == (Timer*) 0 )
	{
	return;
	}
    /* Set up the idle timer. */
    if ( tmr_create( (struct timeval*) 0, idle, JunkClientData, 5 * 1000L, 1 ) == (Timer*) 0 )
	{
	return;
	}
    start_time = stats_time = time( (time_t*) 0 );
    stats_connections = 0;
    stats_bytes = 0;
    stats_simultaneous = 0;

    /* Initialize our connections table. */
    connects = NEW( connecttab, max_connects );
    if ( connects == (connecttab*) 0 )
	{
	return;
	}
    for ( cnum = 0; cnum < max_connects; ++cnum )
	{
	connects[cnum].conn_state = CNST_FREE;
	connects[cnum].next_free_connect = cnum + 1;
	connects[cnum].hc = (httpd_conn*) 0;
	}
    connects[max_connects - 1].next_free_connect = -1;	/* end of link list */
    first_free_connect = 0;
    num_connects = 0;
    httpd_conn_count = 0;

    if ( hs != (httpd_server*) 0 )
	{
	if ( hs->listen4_fd != -1 )
	    fdwatch_add_fd( hs->listen4_fd, (void*) 0, FDW_READ );
	if ( hs->listen6_fd != -1 )
	    fdwatch_add_fd( hs->listen6_fd, (void*) 0, FDW_READ );
	}

    /* Main loop. */
    (void) gettimeofday( &tv, (struct timezone*) 0 );
    while ( ( ! terminate ) || num_connects > 0 )
	{

	/* Do the fd watch. */
	num_ready = fdwatch( tmr_mstimeout( &tv ) );
	if ( num_ready < 0 )
	    {
	    if ( errno == EINTR || errno == EAGAIN )
		continue;       /* try again */
	    return;
	    }
	(void) gettimeofday( &tv, (struct timezone*) 0 );

	if ( num_ready == 0 )
	    {
	    /* No fd's are ready - run the timers. */
	    tmr_run( &tv );
	    continue;
	    }

	/* Is it a new connection? */
	if ( hs != (httpd_server*) 0 && hs->listen6_fd != -1 &&
	     fdwatch_check_fd( hs->listen6_fd ) )
	    {
	    if ( handle_newconnect( &tv, hs->listen6_fd ) )
		/* Go around the loop and do another fdwatch, rather than
		** dropping through and processing existing connections.
		** New connections always get priority.
		*/
		continue;
	    }
	if ( hs != (httpd_server*) 0 && hs->listen4_fd != -1 &&
	     fdwatch_check_fd( hs->listen4_fd ) )
	    {
	    if ( handle_newconnect( &tv, hs->listen4_fd ) )
		/* Go around the loop and do another fdwatch, rather than
		** dropping through and processing existing connections.
		** New connections always get priority.
		*/
		continue;
	    }

	/* Find the connections that need servicing. */
	while ( ( c = (connecttab*) fdwatch_get_next_client_data() ) != (connecttab*) -1 )
	    {
	    if ( c == (connecttab*) 0 )
		continue;
	    hc = c->hc;
	    if ( ! fdwatch_check_fd( hc->conn_fd ) )
		/* Something went wrong. */
		clear_connection( c, &tv );
	    else
		switch ( c->conn_state )
		    {
		    case CNST_READING: handle_read( c, &tv ); break;
		    case CNST_SENDING: handle_send( c, &tv ); break;
		    case CNST_LINGERING: handle_linger( c, &tv ); break;
		    }
	    }
	tmr_run( &tv );
	}

    /* The main loop terminated. */
    shut_down();
    return 0;
    }
Exemple #11
0
int
main( int argc, char** argv )
    {
    char* cp;
    struct passwd* pwd;
    uid_t uid;
    gid_t gid;
    char cwd[MAXPATHLEN];
    FILE* logfp;
    int num_ready;
    int cnum, ridx;
    connecttab* c;
    httpd_conn* hc;
    httpd_sockaddr sa4;
    httpd_sockaddr sa6;
    int gotv4, gotv6;
    struct timeval tv;

    argv0 = argv[0];

    cp = strrchr( argv0, '/' );
    if ( cp != (char*) 0 )
	++cp;
    else
	cp = argv0;
    openlog( cp, LOG_NDELAY|LOG_PID, LOG_FACILITY );

    /* Handle command-line arguments. */
    parse_args( argc, argv );

    /* Check port number. */
    if ( port <= 0 )
	{
	syslog( LOG_CRIT, "illegal port number" );
	(void) fprintf( stderr, "%s: illegal port number\n", argv0 );
	exit( 1 );
	}

    /* Read zone info now, in case we chroot(). */
    tzset();

    /* Look up hostname now, in case we chroot(). */
    lookup_hostname( &sa4, sizeof(sa4), &gotv4, &sa6, sizeof(sa6), &gotv6 );
    if ( ! ( gotv4 || gotv6 ) )
	{
	syslog( LOG_ERR, "can't find any valid address" );
	(void) fprintf( stderr, "%s: can't find any valid address\n", argv0 );
	exit( 1 );
	}

    /* Throttle file. */
    numthrottles = 0;
    maxthrottles = 0;
    throttles = (throttletab*) 0;
    if ( throttlefile != (char*) 0 )
	read_throttlefile( throttlefile );

    /* Log file. */
    if ( logfile != (char*) 0 )
	{
	if ( strcmp( logfile, "/dev/null" ) == 0 )
	    {
	    no_log = 1;
	    logfp = (FILE*) 0;
	    }
	else
	    {
	    logfp = fopen( logfile, "a" );
	    if ( logfp == (FILE*) 0 )
		{
		syslog( LOG_CRIT, "%.80s - %m", logfile );
		perror( logfile );
		exit( 1 );
		}
	    (void) fcntl( fileno( logfp ), F_SETFD, 1 );
	    }
	}
    else
	logfp = (FILE*) 0;

    /* Figure out uid/gid from user. */
    pwd = getpwnam( user );
    if ( pwd == (struct passwd*) 0 )
	{
	syslog( LOG_CRIT, "unknown user - '%.80s'", user );
	(void) fprintf( stderr, "%s: unknown user - '%s'\n", argv0, user );
	exit( 1 );
	}
    uid = pwd->pw_uid;
    gid = pwd->pw_gid;

    /* Switch directories if requested. */
    if ( dir != (char*) 0 )
	{
	if ( chdir( dir ) < 0 )
	    {
	    syslog( LOG_CRIT, "chdir - %m" );
	    perror( "chdir" );
	    exit( 1 );
	    }
	}
#ifdef USE_USER_DIR
    else if ( getuid() == 0 )
	{
	/* No explicit directory was specified, we're root, and the
	** USE_USER_DIR option is set - switch to the specified user's
	** home dir.
	*/
	if ( chdir( pwd->pw_dir ) < 0 )
	    {
	    syslog( LOG_CRIT, "chdir - %m" );
	    perror( "chdir" );
	    exit( 1 );
	    }
	}
#endif /* USE_USER_DIR */

    /* Get current directory. */
    (void) getcwd( cwd, sizeof(cwd) - 1 );
    if ( cwd[strlen( cwd ) - 1] != '/' )
	(void) strcat( cwd, "/" );

    if ( ! debug )
	{
	/* We're not going to use stdin stdout or stderr from here on, so close
	** them to save file descriptors.
	*/
	(void) fclose( stdin );
	(void) fclose( stdout );
	(void) fclose( stderr );

	/* Daemonize - make ourselves a subprocess. */
#ifdef HAVE_DAEMON
	if ( daemon( 1, 1 ) < 0 )
	    {
	    syslog( LOG_CRIT, "daemon - %m" );
	    exit( 1 );
	    }
#else /* HAVE_DAEMON */
	switch ( fork() )
	    {
	    case 0:
	    break;
	    case -1:
	    syslog( LOG_CRIT, "fork - %m" );
	    exit( 1 );
	    default:
	    exit( 0 );
	    }
#ifdef HAVE_SETSID
        (void) setsid();
#endif /* HAVE_SETSID */
#endif /* HAVE_DAEMON */
	}
    else
	{
	/* Even if we don't daemonize, we still want to disown our parent
	** process.
	*/
#ifdef HAVE_SETSID
        (void) setsid();
#endif /* HAVE_SETSID */
	}

    if ( pidfile != (char*) 0 )
	{
	/* Write the PID file. */
	FILE* pidfp = fopen( pidfile, "w" );
	if ( pidfp == (FILE*) 0 )
	    {
	    syslog( LOG_CRIT, "%.80s - %m", pidfile );
	    exit( 1 );
	    }
	(void) fprintf( pidfp, "%d\n", (int) getpid() );
	(void) fclose( pidfp );
	}

    /* Chroot if requested. */
    if ( do_chroot )
	{
	if ( chroot( cwd ) < 0 )
	    {
	    syslog( LOG_CRIT, "chroot - %m" );
	    perror( "chroot" );
	    exit( 1 );
	    }
	(void) strcpy( cwd, "/" );
	/* Always chdir to / after a chroot. */
	if ( chdir( cwd ) < 0 )
	    {
	    syslog( LOG_CRIT, "chroot chdir - %m" );
	    perror( "chroot chdir" );
	    exit( 1 );
	    }
	}

    /* Set up to catch signals. */
    (void) signal( SIGTERM, handle_term );
    (void) signal( SIGINT, handle_term );
    (void) signal( SIGPIPE, SIG_IGN );          /* get EPIPE instead */
    (void) signal( SIGHUP, handle_hup );
    got_usr1 = 0;
    (void) signal( SIGUSR1, handle_usr1 );
    (void) signal( SIGUSR2, handle_usr2 );

    /* Initialize the timer package. */
    tmr_init();

    /* Initialize the HTTP layer.  Got to do this before giving up root,
    ** so that we can bind to a privileged port.
    */
    hs = httpd_initialize(
	hostname,
	gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0,
	port, cgi_pattern, charset, cwd, no_log, logfp, no_symlink, do_vhost,
	do_global_passwd, url_pattern, local_pattern, no_empty_referers );
    if ( hs == (httpd_server*) 0 )
	exit( 1 );

    /* Set up the occasional timer. */
    if ( tmr_create( (struct timeval*) 0, occasional, JunkClientData, OCCASIONAL_TIME * 1000L, 1 ) == (Timer*) 0 )
	{
	syslog( LOG_CRIT, "tmr_create(occasional) failed" );
	exit( 1 );
	}
    if ( numthrottles > 0 )
	{
	/* Set up the throttles timer. */
	if ( tmr_create( (struct timeval*) 0, update_throttles, JunkClientData, THROTTLE_TIME * 1000L, 1 ) == (Timer*) 0 )
	    {
	    syslog( LOG_CRIT, "tmr_create(update_throttles) failed" );
	    exit( 1 );
	    }
	}
#ifdef STATS_TIME
    /* Set up the stats timer. */
    if ( tmr_create( (struct timeval*) 0, show_stats, JunkClientData, STATS_TIME * 1000L, 1 ) == (Timer*) 0 )
	{
	syslog( LOG_CRIT, "tmr_create(show_stats) failed" );
	exit( 1 );
	}
#endif /* STATS_TIME */
    start_time = stats_time = time( (time_t*) 0 );
    stats_connections = stats_bytes = 0L;
    stats_simultaneous = 0;

    /* If we're root, try to become someone else. */
    if ( getuid() == 0 )
	{
	/* Set aux groups to null. */
	if ( setgroups( 0, (const gid_t*) 0 ) < 0 )
	    {
	    syslog( LOG_CRIT, "setgroups - %m" );
	    exit( 1 );
	    }
	/* Set primary group. */
	if ( setgid( gid ) < 0 )
	    {
	    syslog( LOG_CRIT, "setgid - %m" );
	    exit( 1 );
	    }
	/* Try setting aux groups correctly - not critical if this fails. */
	if ( initgroups( user, gid ) < 0 )
	    syslog( LOG_WARNING, "initgroups - %m" );
#ifdef HAVE_SETLOGIN
	/* Set login name. */
        (void) setlogin( user );
#endif /* HAVE_SETLOGIN */
	/* Set uid. */
	if ( setuid( uid ) < 0 )
	    {
	    syslog( LOG_CRIT, "setuid - %m" );
	    exit( 1 );
	    }
	/* Check for unnecessary security exposure. */
	if ( ! do_chroot )
	    syslog(
		LOG_CRIT,
		"started as root without requesting chroot(), warning only" );
	}

    /* Initialize our connections table. */
    maxconnects = fdwatch_get_nfiles();
    if ( maxconnects < 0 )
	{
	syslog( LOG_CRIT, "fdwatch initialization failure" );
	exit( 1 );
	}
    maxconnects -= SPARE_FDS;
    connects = NEW( connecttab, maxconnects );
    if ( connects == (connecttab*) 0 )
	{
	syslog( LOG_CRIT, "out of memory allocating a connecttab" );
	exit( 1 );
	}
    for ( cnum = 0; cnum < maxconnects; ++cnum )
	{
	connects[cnum].conn_state = CNST_FREE;
	connects[cnum].hc = (httpd_conn*) 0;
	}
    numconnects = 0;
    httpd_conn_count = 0;

    if ( hs != (httpd_server*) 0 )
	{
	if ( hs->listen4_fd != -1 )
	    fdwatch_add_fd( hs->listen4_fd, (void*) 0, FDW_READ );
	if ( hs->listen6_fd != -1 )
	    fdwatch_add_fd( hs->listen6_fd, (void*) 0, FDW_READ );
	}

    /* Main loop. */
    (void) gettimeofday( &tv, (struct timezone*) 0 );
    while ( ( ! terminate ) || numconnects > 0 )
	{
	/* Do the fd watch. */
	num_ready = fdwatch( tmr_mstimeout( &tv ) );
	if ( num_ready < 0 )
	    {
	    if ( errno == EINTR )
		continue;       /* try again */
	    syslog( LOG_ERR, "fdwatch - %m" );
	    exit( 1 );
	    }
	(void) gettimeofday( &tv, (struct timezone*) 0 );
	if ( num_ready == 0 )
	    {
	    /* No fd's are ready - run the timers. */
	    tmr_run( &tv );
	    continue;
	    }

	/* Is it a new connection? */
	if ( hs != (httpd_server*) 0 && hs->listen6_fd != -1 && 
	     fdwatch_check_fd( hs->listen6_fd ) )
	    {
	    if ( handle_newconnect( &tv, hs->listen6_fd ) )
		/* Go around the loop and do another fdwatch, rather than
		** dropping through and processing existing connections.
		** New connections always get priority.
		*/
		continue;
	    }
	if ( hs != (httpd_server*) 0 && hs->listen4_fd != -1 && 
	     fdwatch_check_fd( hs->listen4_fd ) )
	    {
	    if ( handle_newconnect( &tv, hs->listen4_fd ) )
		/* Go around the loop and do another fdwatch, rather than
		** dropping through and processing existing connections.
		** New connections always get priority.
		*/
		continue;
	    }

	/* Find the connections that need servicing. */
	for ( ridx = 0; ridx < num_ready; ++ridx )
	    {
	    c = (connecttab*) fdwatch_get_client_data( ridx );
	    if ( c == (connecttab*) 0 )
		continue;
	    hc = c->hc;
	    if ( c->conn_state == CNST_READING &&
		 fdwatch_check_fd( hc->conn_fd ) )
		handle_read( c, &tv );
	    else if ( c->conn_state == CNST_SENDING &&
		 fdwatch_check_fd( hc->conn_fd ) )
		handle_send( c, &tv );
	    else if ( c->conn_state == CNST_LINGERING &&
		 fdwatch_check_fd( hc->conn_fd ) )
		handle_linger( c, &tv );
	    }
	tmr_run( &tv );

	if ( got_usr1 && ! terminate )
	    {
	    terminate = 1;
	    if ( hs != (httpd_server*) 0 )
		{
		httpd_terminate( hs );
		hs = (httpd_server*) 0;
		}
	    }
	}

    /* The main loop terminated. */
    shut_down();
    syslog( LOG_NOTICE, "exiting" );
    closelog();
    exit( 0 );
    }
int main(int argc, char *argv[])
    {
    const char *args = "hnp:s:d:SDxor:L";
    static int SORT_ROW = 1;
    static int EXT_VIEW = 0;
    static int RESOLVE = 1;
    static int no_hdr = 0;
    static char PROTOCOL[4];
    FILE *f;
    char line[200];
    char src[50];
    char dst[50];
    char buf[100];
    char buf2[100];
    
    char *pa[MAX_CONN][ROWS];
    char *store;
    int index,a,b,c,j,r;
    
    // check parameters
    while ((c = getopt(argc, argv, args)) != -1 ) {
	switch (c) {
	case 'h':
	    display_help();
	    return 1;
	case '?':
	    display_help();
	    return 1;
	case 'n':
	    RESOLVE = 0;
	    break;
	case 'p':
	    strcpy (PROTOCOL, optarg);
	    break;
	case 's':
	    strcpy (SRC_IP, optarg);
	    lookup_ip(SRC_IP);
	    break;
	case 'd':
	    strcpy (DST_IP, optarg);
	    lookup_ip(DST_IP);
	    break;    
	case 'S':
	    DNAT = 0;
	    break;
	case 'D':
	    SNAT = 0;
	    break;
	case 'L':
	    SNAT = 0;
	    DNAT = 0;
	    LOCAL = 1;
	    break;
	case 'x':
	    EXT_VIEW = 1;
	    break;
	case 'o':
	    no_hdr = 1;
	    break;
	case 'r':
	    if (optarg == NULL || optarg == '\0') {
		display_help();
		return 1;
		}
	    if (strcmp(optarg, "scr") == 0) SORT_ROW = 1; //default
	    if (strcmp(optarg, "dst") == 0) SORT_ROW = 2;
	    if (strcmp(optarg, "src-port") == 0) SORT_ROW = 3; 
	    if (strcmp(optarg, "dst-port") == 0) SORT_ROW = 4; 
	    if (strcmp(optarg, "state") == 0) SORT_ROW = 5;
	    break; 
	}
    }
    
    // some checking for IPTables and read file
    f=fopen("/proc/net/ip_conntrack","r");
    if (!f) {
	printf("Make sure netfilter/IPtables is enabled by kernel or modules.\n");
	return 1;
	}
    
    // process conntrack table
    if (!no_hdr) {
	if (!EXT_VIEW) {
	    printf("%-6s%-31s%-31s%-6s\n","Proto","NATed Address","Foreign Address","State");
	} else {
	    printf("%-6s%-41s%-41s%-6s\n","Proto","NATed Address","Foreign Address","State");
	    }
	}

    while (fgets(line,1000,f)!=NULL) 
	{
	if ((!strcmp(PROTOCOL, "tcp")) || (!strcmp(PROTOCOL, ""))) {
	    if(match(line, "tcp")) {
		protocol_tcp(line);
		}
	    }
	    
	if ((!strcmp(PROTOCOL, "udp")) || (!strcmp(PROTOCOL, ""))) {
	    if((match(line, "udp")) && (match(line, "UNREPLIED"))) {
		protocol_udp_unr(line);
		}
	    if((match(line, "udp")) && (match(line, "ASSURED"))) {
		protocol_udp_ass(line);
		}
	    if((match(line, "udp")) && (!match(line, "ASSURED")) && (!match(line, "UNREPLIED"))) {
		protocol_udp(line); 
		}
	    }
	        
	if ((!strcmp(PROTOCOL, "icmp")) || (!strcmp(PROTOCOL, ""))) {
	    if((match(line, "icmp")) && (match(line, "UNREPLIED"))) {
		protocol_icmp_unr(line);
		}
	    if((match(line, "icmp")) && (!match(line, "UNREPLIED"))) {
		protocol_icmp_rep(line);
		}
	    }
	}
    fclose(f);
    
    // create array pointed to main connection array
    for (index = 0; index < connection_index; index++)	{
	for (j=0; j<ROWS; j++) {
	    pa[index][j] = &connection_table[index][j][0];
	    }
	}
    // sort by protocol and defined row
    for (a = 0;a < connection_index-1; a++) {
	for (b = a+1; b < connection_index; b++) {
	    r = strcmp(pa[a][0], pa[b][0]);
	    if (r > 0) {
		for (j=0;j<ROWS-1;j++) {
		    store = pa[a][j];
		    pa[a][j] = pa[b][j];
		    pa[b][j] = store;
		    }
		}	    
	    if (r == 0) {
		if (strcmp(pa[a][SORT_ROW], pa[b][SORT_ROW]) > 0) {
		    for (j=0;j<ROWS;j++) {
			store = pa[a][j];
			pa[a][j] = pa[b][j];
			pa[b][j] = store;
			}
		    }
		}
	    }
	}
    // print connections
    for (index = 0; index < connection_index; index++) {  
	if (RESOLVE) {
	    lookup_hostname(pa[index][1]);
	    lookup_hostname(pa[index][2]);
	    if (strlen(pa[index][3]) > 0 || strlen(pa[index][4]) > 0) {
		lookup_portname(pa[index][3], pa[index][0]);
		lookup_portname(pa[index][4], pa[index][0]);
	    	}
	    }
	if (!EXT_VIEW) {
	    strcpy(buf ,""); 
	    strncat(buf, pa[index][1], 29 - strlen(pa[index][3]));    
	    sprintf(buf2, "%s:%s", buf, pa[index][3]);
	    sprintf(src , "%-31s", buf2);
	    strcpy(buf ,""); 
	    strncat(buf, pa[index][2], 29 - strlen(pa[index][4]));    
	    sprintf(buf2, "%s:%s", buf, pa[index][4]);
	    sprintf(dst , "%-31s", buf2);
	} else {
	    strcpy(buf ,""); 
	    strncat(buf, pa[index][1], 39 - strlen(pa[index][3]));    
	    sprintf(buf2, "%s:%s", buf, pa[index][3]);
	    sprintf(src , "%-41s", buf2);
	    strcpy(buf ,""); 
	    strncat(buf, pa[index][2], 39 - strlen(pa[index][4]));    
	    sprintf(buf2, "%s:%s", buf, pa[index][4]);
	    sprintf(dst , "%-41s", buf2);
	    }
	printf("%-6s%s%s%-11s\n", pa[index][0], src, dst, pa[index][5]);
	}
    return(0);
    }