Ejemplo n.º 1
0
static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb)
{
	struct sockaddr_in me;
	int fd = -1;

	if (phb->gai_cur == NULL) {
		int ret;
		char port[6];
		struct addrinfo hints;

		g_snprintf(port, sizeof(port), "%d", port_);

		memset(&hints, 0, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;

		if (!(ret = getaddrinfo(host, port, &hints, &phb->gai))) {
			phb->gai_cur = phb->gai;
		} else {
			event_debug("gai(): %s\n", gai_strerror(ret));
		}
	}

	for (; phb->gai_cur; phb->gai_cur = phb->gai_cur->ai_next) {
		if ((fd = socket(phb->gai_cur->ai_family, phb->gai_cur->ai_socktype, phb->gai_cur->ai_protocol)) < 0) {
			event_debug("socket failed: %d\n", errno);
			continue;
		}

		sock_make_nonblocking(fd);

		if (global.conf->iface_out) {
			me.sin_family = AF_INET;
			me.sin_port = 0;
			me.sin_addr.s_addr = inet_addr(global.conf->iface_out);

			if (bind(fd, (struct sockaddr *) &me, sizeof(me)) != 0) {
				event_debug("bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out);
			}
		}

		event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port_, fd);

		if (connect(fd, phb->gai_cur->ai_addr, phb->gai_cur->ai_addrlen) < 0 && !sockerr_again()) {
			event_debug("connect failed: %s\n", strerror(errno));
			closesocket(fd);
			fd = -1;
			continue;
		} else {
			phb->inpa = b_input_add(fd, B_EV_IO_WRITE, proxy_connected, phb);
			phb->fd = fd;

			break;
		}
	}

	if (fd < 0 && host) {
		phb_free(phb, TRUE);
	}

	return fd;
}
Ejemplo n.º 2
0
int
mono_get_address_info (const char *hostname, int port, int flags, MonoAddressInfo **result)
{
	char service_name [16];
	struct addrinfo hints, *res = NULL, *info;
	MonoAddressEntry *cur = NULL, *prev = NULL;
	MonoAddressInfo *addr_info;
	int ret;

	memset (&hints, 0, sizeof (struct addrinfo));
	*result = NULL;

	hints.ai_family = PF_UNSPEC;
	if (flags & MONO_HINT_IPV4)
		hints.ai_family = PF_INET;
	else if (flags & MONO_HINT_IPV6)
		hints.ai_family = PF_INET6;

	hints.ai_socktype = SOCK_STREAM;

	if (flags & MONO_HINT_CANONICAL_NAME)
		hints.ai_flags = AI_CANONNAME;

/* Some ancient libc don't define AI_ADDRCONFIG */
#ifdef AI_ADDRCONFIG
	if (flags & MONO_HINT_CONFIGURED_ONLY)
		hints.ai_flags = AI_ADDRCONFIG;
#endif
	sprintf (service_name, "%d", port);

	MONO_ENTER_GC_SAFE;
	ret = getaddrinfo (hostname, service_name, &hints, &info);
	MONO_EXIT_GC_SAFE;

	if (ret)
		return 1; /* FIXME propagate the error */

	res = info;
	*result = addr_info = g_new0 (MonoAddressInfo, 1);

	while (res) {
		cur = g_new0 (MonoAddressEntry, 1);
		cur->family = res->ai_family;
		cur->socktype = res->ai_socktype;
		cur->protocol = res->ai_protocol;
		if (cur->family == PF_INET) {
			cur->address_len = sizeof (struct in_addr);
			cur->address.v4 = ((struct sockaddr_in*)res->ai_addr)->sin_addr;
		} else if (cur->family == PF_INET6) {
			cur->address_len = sizeof (struct in6_addr);
			cur->address.v6 = ((struct sockaddr_in6*)res->ai_addr)->sin6_addr;
		} else {
			g_warning ("Cannot handle address family %d", cur->family);
			res = res->ai_next;
			g_free (cur);
			continue;
		}

		if (res->ai_canonname)
			cur->canonical_name = g_strdup (res->ai_canonname);

		if (prev)
			prev->next = cur;
		else
			addr_info->entries = cur;
			
		prev = cur;
		res = res->ai_next;
	}

	freeaddrinfo (info);
	return 0;
}
Ejemplo n.º 3
0
/**
 * Initiate a connection to a peer.
 * The obtained socket is then sent to the respective receiver.
 * This is typically called from the timer, but otherwise it can be called from any other process.
 * @param p - peer to connect to
 * @returns socket if OK, -1 on error
 */
int peer_connect(peer *p)
{
	int sock;
	unsigned int option = 1;

	struct addrinfo *ainfo=0,*res=0,*sainfo=0,hints;
	char buf[256],host[256],serv[256];
	int error;

	memset (&hints, 0, sizeof(hints));
	//hints.ai_protocol = IPPROTO_SCTP;
	//hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_ADDRCONFIG;
	hints.ai_socktype = SOCK_STREAM;

	sprintf(buf,"%d",p->port);

	error = getaddrinfo(p->fqdn.s, buf, &hints, &res);

	if (error!=0){
		LM_WARN("peer_connect(): Error opening connection to %.*s:%d >%s\n",
				p->fqdn.len,p->fqdn.s,p->port,gai_strerror(error));
		goto error;
	}

	for(ainfo = res;ainfo;ainfo = ainfo->ai_next)
	{
		if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen,
					host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){
			LM_WARN("peer_connect(): Trying to connect to %s port %s\n",
					host,serv);
		}

		if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) {
			LM_ERR("peer_connect(): error creating client socket to %s port %s >"
					" %s\n",host,serv,strerror(errno));
			continue;
		}

		/* try to set the local socket used to connect to the peer */
		if (p->src_addr.s && p->src_addr.len > 0) {
			LM_DBG("peer_connect(): connetting to peer via src addr=%.*s",p->src_addr.len, p->src_addr.s);
			memset (&hints, 0, sizeof(hints));
			hints.ai_flags = AI_NUMERICHOST;
			hints.ai_socktype = SOCK_STREAM;
			error = getaddrinfo(p->src_addr.s, NULL, &hints, &sainfo);

			if (error!=0){
				LM_WARN("peer_connect(): error getting client socket on %.*s:%s\n",
						p->src_addr.len,p->src_addr.s,gai_strerror(error));
			} else {
				if (bind(sock, sainfo->ai_addr, sainfo->ai_addrlen )) {
					LM_WARN("peer_connect(): error opening client socket on %.*s:%s\n",
							p->src_addr.len,p->src_addr.s,strerror(errno));
				}
			}
		}

		{// Connect with timeout
			int x;
			x=fcntl(sock,F_GETFL,0);
			fcntl(sock,F_SETFL,x | O_NONBLOCK);
			int res = connect(sock,ainfo->ai_addr,ainfo->ai_addrlen);
			if (res<0){
				if (errno==EINPROGRESS){
					struct timeval tv={
						.tv_sec = config->connect_timeout,
						.tv_usec = 0,
					};
					fd_set myset;
					FD_ZERO(&myset);
					FD_SET(sock, &myset);
					if (select(sock+1, NULL, &myset, NULL, &tv) > 0) {
						socklen_t lon = sizeof(int);
						int  valopt;
						getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon);
						if (valopt) {
							LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(valopt));
							close(sock);
							continue;
						}
					}else{
						LM_WARN("peer_connect(): Timeout or error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
						close(sock);
						continue;
					}
				}
			}else{
				LM_WARN("peer_connect(): Error opening connection to to %s port %s >%s\n",host,serv,strerror(errno));
				close(sock);
				continue;
			}

			x=fcntl(sock,F_GETFL,0);
			fcntl(sock,F_SETFL,x & (~O_NONBLOCK));
		}
		setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));

		LM_INFO("peer_connect(): Peer %.*s:%d connected\n",p->fqdn.len,p->fqdn.s,p->port);

		if (!send_fd(p->fd_exchange_pipe,sock,p)){
			LM_ERR("peer_connect(): [%.*s] Error sending fd to respective receiver\n",p->fqdn.len,p->fqdn.s);
			close(sock);
			goto error;
		}

		if (res) freeaddrinfo(res);
		return sock;
	}
error:
	if (res) freeaddrinfo(res);
	return -1;
}
Ejemplo n.º 4
0
static int
init_server(int argc, char *argv[])
{
	int sd;
	int res;
	struct addrinfo hints;
	struct addrinfo *addr_i;
	struct addrinfo *hostaddr = 0;

	char *host = 0;
	char *service = SERVICE_NAME;

	memset(&hints, 0, sizeof (hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;

	if (argc > 1) {
		if (strcmp(argv[1], "-") != 0) {
			host = argv[1];
		}
		if (argc > 2) {
			service = argv[2];
		}
	}

	printf("resolving %s/%s ... ", host == 0 ? "*" : host, service);
	fflush(stdout);
	res = getaddrinfo(host, service, &hints, &hostaddr);
	if (res == EAI_NONAME) {
		hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV;
		res = getaddrinfo(host, service, &hints, &hostaddr);
	}

	if (res != 0 || hostaddr == 0) {
		printf("failed\n");
		return -1;
	}

	printf("success\n");

	for (addr_i = hostaddr; addr_i != 0; addr_i = addr_i->ai_next) {
		char name[128];
		char serv_name[64];
		getnameinfo(addr_i->ai_addr, addr_i->ai_addrlen,
			name, sizeof(name), serv_name, sizeof(serv_name),
			NI_NUMERICHOST | NI_NUMERICSERV);
		printf("binding %s/%s ... ", name, serv_name);
		if ((sd = socket(addr_i->ai_family, addr_i->ai_socktype, 0)) == -1) {
			perror("");
			continue;
		}

		if (bind(sd, (struct sockaddr *)addr_i->ai_addr, addr_i->ai_addrlen) == -1) {
			perror("");
			close(sd);
			continue;
		}

		printf("success\n");
		break;
	}

	freeaddrinfo(hostaddr);

	return addr_i == 0 ? -1 : sd; 
}
Ejemplo n.º 5
0
Archivo: tftp.c Proyecto: solb/nettftp
// Runs the interactive loop and all file transfers.
// Returns: exit status
int main(void)
{
    // Used to control DNS resolution requests:
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    // Bind to an ephemeral network port:
    struct addrinfo *server = NULL;
    int sfd = openudp(0);
    if(sfd < 0)
        handle_error("bind()");

    // Allocate (small) space to store user input:
    char *buf = malloc(1);
    size_t cap = 1;
    char *cmd; // First word of buf
    size_t len; // Length of cmd

    // Main input loop, which normally only breaks upon a GFO:
    do
    {
        // Keep prompting until the user brings us back something good:
        do
        {
            printf("%s", SHL_PS1);
            readin(&buf, &cap);
        }
        while(homog(buf, ' '));

        // Cleave off the command (first word):
        cmd = strtok(buf, " ");
        len = strlen(cmd);

        if(strncmp(cmd, CMD_CON, len) == 0)
        {
            // Read the arguments:
            const char *hostname = strtok(NULL, " ");
            const char *tmp = strtok(NULL, " ");
            in_port_t port = PORT_UNPRIVILEGED;
            if(tmp)
                port = atoi(tmp);

            // Ensure a hostname or IP has been provided:
            if(!hostname)
            {
                usage(CMD_CON, "hostname", "port");
                continue;
            }

            // Avoid leaking any existing address:
            if(server)
            {
                freeaddrinfo(server);
                server = NULL;
            }

            // Try to resolve the requested hostname:
            if(getaddrinfo(hostname, NULL, &hints, &server))
            {
                fprintf(stderr, "Unable to resolve hostname\n");
                freeaddrinfo(server);
                server = NULL;
                continue;
            }
            ((struct sockaddr_in *)server->ai_addr)->sin_port = htons(port);
        }
        else if(strncmp(cmd, CMD_GET, len) == 0 || strncmp(cmd, CMD_PUT, len) == 0)
        {
            bool putting = strncmp(cmd, CMD_PUT, 1) == 0;

            // Ensure we're already connected to a server:
            if(!server)
            {
                noconn(cmd);
                continue;
            }

            // Make sure we were given a path argument:
            char *pathname = strtok(NULL, "");
            if(!pathname)
            {
                usage(putting ? CMD_PUT : CMD_GET, "pathname", NULL);
                continue;
            }

            // Since basename() might modify pathname, copy it:
            char filename[strlen(pathname)+1];
            memcpy(filename, pathname, sizeof filename);

            int fd;
            if(putting)
            {
                // Try opening the file for reading:
                if((fd = open(pathname, O_RDONLY)) < 0)
                {
                    fprintf(stderr, "local: Unable to read specified file\n");
                    continue;
                }

                // Send a request and record the port used to acknowledge:
                struct sockaddr_in dest_addr;
                sendreq(sfd, basename(filename), OPC_WRQ, server->ai_addr);
                uint8_t *rmtack = recvpkta(sfd, &dest_addr);
                if(iserr(rmtack))
                {
                    fprintf(stderr, "remote: %s\n", strerr(rmtack));
                    free(rmtack);
                    continue;
                }
                free(rmtack);

                // Transmit the file:
                sendfile(sfd, fd, &dest_addr);
            }
            else // getting
            {
                // Try opening a file of that name for writing:
                if((fd = open(basename(filename), O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
                {
                    fprintf(stderr, "local: Unable to create the new file\n");
                    continue;
                }

                // Send a request and await the incoming file:
                sendreq(sfd, pathname, OPC_RRQ, server->ai_addr);
                const char *res = recvfile(sfd, fd);
                if(res)
                {
                    fprintf(stderr, "remote: %s\n", res);
                    close(fd);
                    fd = -1;
                    unlink(basename(filename));
                }
            }

            if(fd >= 0)
                close(fd);
        }
        else if(strncmp(cmd, CMD_HLP, len) == 0)
        {
            printf("Commands may be abbreviated.  Commands are:\n\n");
            printf("%s\t\tconnect to remote tftp\n", CMD_CON);
            printf("%s\t\tsend file\n", CMD_PUT);
            printf("%s\t\treceive file\n", CMD_GET);
            printf("%s\t\texit tftp\n", CMD_GFO);
            printf("%s\t\tprint help information\n", CMD_HLP);
        }
        else if(strncmp(cmd, CMD_GFO, len) != 0)
        {
            fprintf(stderr, "%s: unknown directive\n", cmd);
            fprintf(stderr, "Try ? for help.\n");
        }
    }
    while(strncmp(cmd, CMD_GFO, len) != 0);

    free(buf);
    if(server)
        freeaddrinfo(server);

    return 0;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{

    if(argc != 2) {
        printf("\nUsage:\n\nserver portnumber\n\n");
        return -1;
    }
    
    char* port_number = (char *)malloc(sizeof(argv[1]));
    memcpy(port_number, argv[1], sizeof(argv[1]));
    printf("Port number: %s\n", port_number);

    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;
    struct sigaction sa;
    int yes=1;
    char s[INET6_ADDRSTRLEN];
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, port_number, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("server: socket");
            continue;
        }

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    if (p == NULL)  {
        fprintf(stderr, "server: failed to bind\n");
        return 2;
    }

    freeaddrinfo(servinfo); // all done with this structure

    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections...\n");

    while(1) {  // main accept() loop
        sin_size = sizeof their_addr;
        
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if (new_fd == -1) {
            perror("accept");
            continue;
        }

        inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&their_addr),
            s, sizeof s);
        printf("server: got connection from %s\n", s);

        if (!fork()) { // this is the child process
            close(sockfd); // child doesn't need the listener
            //read in data
            //do appropriate action
            lab_1_request *request = (lab_1_request *)malloc(sizeof(lab_1_request));
            int num_bytes;
            if(num_bytes = recv(new_fd, request, sizeof(lab_1_request), 0) == -1) {
                perror("read error");
                exit(-1);
            }
            
            printf("Read %d bytes\n", num_bytes);
            
            to_host_byte_order(request);

            displayBuffer((char *) request, num_bytes);
            printf("\nReceived from client:\n");
            printf("Message size: %d\n", request->total_message_length);
            printf("Request id: %d\n", request->request_id);
            printf("Operation: %d\n", request->operation);
            printf("Message: %s\n\n", request->message);

            if(request->operation == VLENGTH_REQUEST) {
                vowel_length(new_fd, request);
            } else if (request->operation == VOWEL_REMOVAL_REQUEST) {
                remove_vowels(new_fd, request);
            } else {
                printf("Invalid request id\n");
            }
            close(new_fd);
            exit(0);
        }
        close(new_fd);  // parent doesn't need this
    }
    
    free(port_number);

    return 0;
}
Ejemplo n.º 7
0
/* Make ospf6d's server socket. */
int
ospf6_serv_sock (uint64_t host_num)
{
  struct in6_addr * sv_addr;
  char  s_addr[INET6_ADDRSTRLEN+1];
  int status;
  
  if (ospf6d_privs.change (ZPRIVS_RAISE))
    zlog_err ("ospf6_serv_sock: could not raise privs");

  sv_addr = get_sv_addr(); 

  inet_ntop(AF_INET6, sv_addr, s_addr, INET6_ADDRSTRLEN+1);
  printf("done getting sv addr: %s\n", s_addr);

  // Set up socket address info
  struct addrinfo hints, *addr;
  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_INET6;     // IPv6
  hints.ai_socktype = SOCK_STREAM;  // TCP
  char port_str[8];
  sprintf(port_str, "%u", SV_SISIS_PORT);
  if((status = getaddrinfo(s_addr, port_str, &hints, &addr)) != 0)
  {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    exit(1);
  }

  ospf6_sock = socket (addr->ai_family, addr->ai_socktype, addr->ai_protocol);
  printf("creating socket %d\n", ospf6_sock);
  if (ospf6_sock < 0)
    {
      zlog_warn ("Network: can't create OSPF6 socket.");
      if (ospf6d_privs.change (ZPRIVS_LOWER))
        zlog_err ("ospf_sock_init: could not lower privs");
      return -1;
    }

  if (connect(ospf6_sock, addr->ai_addr, addr->ai_addrlen) == -1)
  {
    close(ospf6_sock);
    perror("connect");
  }

  if (ospf6d_privs.change (ZPRIVS_LOWER))
      zlog_err ("ospf_sock_init: could not lower privs");

  sleep(1);  // wait for all other processes to register

  /* set socket options */
//#if 1
//  sockopt_reuseaddr (ospf6_sock);
//#else
//  ospf6_set_reuseaddr ();
//#endif /*1*/
//  ospf6_reset_mcastloop ();
//  ospf6_set_pktinfo ();
//  ospf6_set_checksum ();

  /* setup global in6_addr, allspf6 and alldr6 for later use */
  inet_pton (AF_INET6, ALLSPFROUTERS6, &allspfrouters6);
  inet_pton (AF_INET6, ALLDROUTERS6, &alldrouters6);

  return 0;
}
Ejemplo n.º 8
0
int main(int argc, char **argv){
	if(argc != 10){
	  printf("Usage: hostname port packet_loss_ratio corruption_ratio continuous_transmission simulation_runtime byte_count wireless_connection active_queue_management\n");
	  return 0;
	}
	char address[256];
	char port[6];
	memset(address, 0, sizeof(address));
	memset(port, 0, sizeof(port));
	strcpy(address, argv[1]);
	strcpy(port, argv[2]);
	if(atoi(port) > 65535){
	  printf("Port range exceeded (65535).\n");
	  return 0;
	}

	uint8_t ploss = atoi(argv[3]);
	if(ploss > 100){
	  printf("Packet loss ratio cannot exceed 100 percent.\n");
	  return 0;
	}

	uint8_t corr = atoi(argv[4]);
	if(corr > 100){
	  printf("Corruption ratio cannot exceed 100 percent.\n");
	  return 0;
	}

	struct addrinfo hints;
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	int status;
	struct addrinfo* servinfo = NULL;
        /* Get information about all IP addresses to choose from. */
        if((status = getaddrinfo(address,port, &hints, &servinfo)) != 0){
                fprintf(stderr,"Error in getaddrinfo: %s\n", gai_strerror(status));
                exit(1);
        }

        struct addrinfo *p = servinfo;
        void* addr;
        char* ipver;

        printf("These are the addresses which were resolved:\n");
        int i = 0;
        while(p != NULL){
         if(p->ai_family == AF_INET) {
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
         }else{
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
         }
	 char ipstr[INET6_ADDRSTRLEN];
         inet_ntop(p->ai_family,addr,ipstr,sizeof(ipstr));
         printf("%i) %s: %s\n",i, ipver,ipstr);
         p = p->ai_next;
         i++;
        }

        printf("Choose one: ");
        char iface[2];
        iface[0] = getchar();
        iface[1] = '\0';
        int j = atoi(iface);
        if((iface[0]<48)||(iface[0]>57) || j >= i){
         printf("Not a destination - exiting.\n");
         exit(1);
        }

        int k;
        p = servinfo;
        for(k = 0; k < j && k < i; k++){
         if(p->ai_next != NULL)
          p = p->ai_next;
        }

	if(!set_parameters(p, ploss, corr, atoi(argv[5]), atoi(argv[6]), atoi(argv[7]), atoi(argv[8]), atoi(argv[9]))){
	  printf("Could not set network parameters.\n");
	  return -1;
	}

	char* buf = malloc(atoi(argv[7]));
	push_data_to_output_buffer(buf, atoi(argv[7]));

	if(!syn_init()){
	  printf("Could not establish connection to sleepy server.\n");
	  return -1;
	}

	loop();

	return 0;
}
Ejemplo n.º 9
0
static int statsd_network_init(struct pollfd **ret_fds, /* {{{ */
                               size_t *ret_fds_num) {
  struct pollfd *fds = NULL;
  size_t fds_num = 0;

  struct addrinfo *ai_list;
  int status;

  char const *node = (conf_node != NULL) ? conf_node : STATSD_DEFAULT_NODE;
  char const *service =
      (conf_service != NULL) ? conf_service : STATSD_DEFAULT_SERVICE;

  struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
                              .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
                              .ai_socktype = SOCK_DGRAM};

  status = getaddrinfo(node, service, &ai_hints, &ai_list);
  if (status != 0) {
    ERROR("statsd plugin: getaddrinfo (\"%s\", \"%s\") failed: %s", node,
          service, gai_strerror(status));
    return status;
  }

  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
       ai_ptr = ai_ptr->ai_next) {
    int fd;
    struct pollfd *tmp;

    char str_node[NI_MAXHOST];
    char str_service[NI_MAXSERV];

    fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
    if (fd < 0) {
      ERROR("statsd plugin: socket(2) failed: %s", STRERRNO);
      continue;
    }

    /* allow multiple sockets to use the same PORT number */
    int yes = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
      ERROR("statsd plugin: setsockopt (reuseaddr): %s", STRERRNO);
      close(fd);
      continue;
    }

    getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, str_node, sizeof(str_node),
                str_service, sizeof(str_service),
                NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV);
    DEBUG("statsd plugin: Trying to bind to [%s]:%s ...", str_node,
          str_service);

    status = bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
    if (status != 0) {
      ERROR("statsd plugin: bind(2) to [%s]:%s failed: %s", str_node,
            str_service, STRERRNO);
      close(fd);
      continue;
    }

    tmp = realloc(fds, sizeof(*fds) * (fds_num + 1));
    if (tmp == NULL) {
      ERROR("statsd plugin: realloc failed.");
      close(fd);
      continue;
    }
    fds = tmp;
    tmp = fds + fds_num;
    fds_num++;

    memset(tmp, 0, sizeof(*tmp));
    tmp->fd = fd;
    tmp->events = POLLIN | POLLPRI;
    INFO("statsd plugin: Listening on [%s]:%s.", str_node, str_service);
  }

  freeaddrinfo(ai_list);

  if (fds_num == 0) {
    ERROR("statsd plugin: Unable to create listening socket for [%s]:%s.",
          (node != NULL) ? node : "::", service);
    return ENOENT;
  }

  *ret_fds = fds;
  *ret_fds_num = fds_num;
  return 0;
} /* }}} int statsd_network_init */

static void *statsd_network_thread(void *args) /* {{{ */
{
  struct pollfd *fds = NULL;
  size_t fds_num = 0;
  int status;

  status = statsd_network_init(&fds, &fds_num);
  if (status != 0) {
    ERROR("statsd plugin: Unable to open listening sockets.");
    pthread_exit((void *)0);
  }

  while (!network_thread_shutdown) {
    status = poll(fds, (nfds_t)fds_num, /* timeout = */ -1);
    if (status < 0) {

      if ((errno == EINTR) || (errno == EAGAIN))
        continue;

      ERROR("statsd plugin: poll(2) failed: %s", STRERRNO);
      break;
    }

    for (size_t i = 0; i < fds_num; i++) {
      if ((fds[i].revents & (POLLIN | POLLPRI)) == 0)
        continue;

      statsd_network_read(fds[i].fd);
      fds[i].revents = 0;
    }
  } /* while (!network_thread_shutdown) */

  /* Clean up */
  for (size_t i = 0; i < fds_num; i++)
    close(fds[i].fd);
  sfree(fds);

  return (void *)0;
} /* }}} void *statsd_network_thread */

static int statsd_config_timer_percentile(oconfig_item_t *ci) /* {{{ */
{
  double percent = NAN;
  double *tmp;
  int status;

  status = cf_util_get_double(ci, &percent);
  if (status != 0)
    return status;

  if ((percent <= 0.0) || (percent >= 100)) {
    ERROR("statsd plugin: The value for \"%s\" must be between 0 and 100, "
          "exclusively.",
          ci->key);
    return ERANGE;
  }

  tmp =
      realloc(conf_timer_percentile,
              sizeof(*conf_timer_percentile) * (conf_timer_percentile_num + 1));
  if (tmp == NULL) {
    ERROR("statsd plugin: realloc failed.");
    return ENOMEM;
  }
  conf_timer_percentile = tmp;
  conf_timer_percentile[conf_timer_percentile_num] = percent;
  conf_timer_percentile_num++;

  return 0;
} /* }}} int statsd_config_timer_percentile */
Ejemplo n.º 10
0
static int
run ()
{
  unsigned long long timeoutlong = 0;
  unsigned long long timeout_spdy = 0;
  long timeout_curl = -1;
	struct timeval timeout;
	int ret;
	int ret_curl;
	int ret_spdy;
	fd_set rs;
	fd_set ws;
	fd_set es;
	int maxfd = -1;
	int maxfd_curl = -1;
	struct SPDY_Daemon *daemon;
  CURLMsg *msg;
  int msgs_left;
  struct Proxy *proxy;
  struct sockaddr_in *addr;
  struct addrinfo hints;
  char service[NI_MAXSERV];
  struct addrinfo *gai;
  enum SPDY_IO_SUBSYSTEM io = glob_opt.notls ? SPDY_IO_SUBSYSTEM_RAW : SPDY_IO_SUBSYSTEM_OPENSSL;
  enum SPDY_DAEMON_FLAG flags = SPDY_DAEMON_FLAG_NO;
  
	signal(SIGPIPE, SIG_IGN);
	
  if (signal(SIGINT, catch_signal) == SIG_ERR)
    PRINT_VERBOSE("signal failed");
    
  srand(time(NULL));
  if(init_parse_uri(&uri_preg))
    DIE("Regexp compilation failed");
    
	SPDY_init();
  
  if(glob_opt.nodelay)
    flags |= SPDY_DAEMON_FLAG_NO_DELAY;
  
  if(NULL == glob_opt.listen_host)
	{
    daemon = SPDY_start_daemon(glob_opt.listen_port,
								glob_opt.cert,
								glob_opt.cert_key,
								&new_session_cb,
								&session_closed_cb,
								&standard_request_handler,
								NULL,
								NULL,
								SPDY_DAEMON_OPTION_SESSION_TIMEOUT,
								1800,
                SPDY_DAEMON_OPTION_IO_SUBSYSTEM,
                io,
                SPDY_DAEMON_OPTION_FLAGS,
                flags,
								SPDY_DAEMON_OPTION_END);
  }
  else
  {
    snprintf (service, sizeof(service), "%u", glob_opt.listen_port);
    memset (&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    
    ret = getaddrinfo(glob_opt.listen_host, service, &hints, &gai);
    if(ret != 0)
      DIE("problem with specified host");
    
    addr = (struct sockaddr_in *) gai->ai_addr;
    
    daemon = SPDY_start_daemon(0,
								glob_opt.cert,
								glob_opt.cert_key,
								&new_session_cb,
								&session_closed_cb,
								&standard_request_handler,
								NULL,
								NULL,
								SPDY_DAEMON_OPTION_SESSION_TIMEOUT,
								1800,
                SPDY_DAEMON_OPTION_IO_SUBSYSTEM,
                io,
                SPDY_DAEMON_OPTION_FLAGS,
                flags,
                SPDY_DAEMON_OPTION_SOCK_ADDR,
                addr,
								SPDY_DAEMON_OPTION_END);
  }
	
	if(NULL==daemon){
		printf("no daemon\n");
		return 1;
	}
	
	multi_handle = curl_multi_init();
	if(NULL==multi_handle)
		DIE("no multi_handle");
  
	timeout.tv_usec = 0;

	do
	{
		FD_ZERO(&rs);
		FD_ZERO(&ws);
		FD_ZERO(&es);
    
    ret_spdy = SPDY_get_timeout(daemon, &timeout_spdy);
    if(SPDY_NO == ret_spdy || timeout_spdy > 5000)
      timeoutlong = 5000;
    else
      timeoutlong = timeout_spdy;
    PRINT_VERBOSE2("SPDY timeout %i; %i", timeout_spdy, ret_spdy);
    
    if(CURLM_OK != (ret_curl = curl_multi_timeout(multi_handle, &timeout_curl)))
    {
      PRINT_VERBOSE2("curl_multi_timeout failed (%i)", ret_curl);
      //curl_timeo = timeoutlong;
    }
    else if(timeoutlong > timeout_curl)
      timeoutlong = timeout_curl;
      
    PRINT_VERBOSE2("curl timeout %i", timeout_curl);
      
    timeout.tv_sec = timeoutlong / 1000;
		timeout.tv_usec = (timeoutlong % 1000) * 1000;
    
		maxfd = SPDY_get_fdset (daemon,
								&rs,
								&ws, 
								&es);	
		assert(-1 != maxfd);

		if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &rs,
								&ws, 
								&es, &maxfd_curl)))
		{
			PRINT_INFO2("curl_multi_fdset failed (%i)", ret);
			abort();
		}
    
    if(maxfd_curl > maxfd)
      maxfd = maxfd_curl;
      
    PRINT_VERBOSE2("timeout before %i %i", timeout.tv_sec, timeout.tv_usec);
    ret = select(maxfd+1, &rs, &ws, &es, &timeout);
    PRINT_VERBOSE2("timeout after %i %i; ret is %i", timeout.tv_sec, timeout.tv_usec, ret);
		
		/*switch(ret) {
			case -1:
				PRINT_INFO2("select error: %i", errno);
				break;
			case 0:
				break;
			default:*/
      
      //the second part should not happen with current implementation
      if(ret > 0 || (SPDY_YES == ret_spdy && 0 == timeout_spdy))
      {
				PRINT_VERBOSE("run spdy");
				SPDY_run(daemon);
        call_spdy_run = false;
      }
        
      if(ret > 0 || (CURLM_OK == ret_curl && 0 == timeout_curl) || call_curl_run)
      {
				PRINT_VERBOSE("run curl");
				if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running))
					&& CURLM_CALL_MULTI_PERFORM != ret)
				{
					PRINT_INFO2("curl_multi_perform failed (%i)", ret);
					abort();
				}
        call_curl_run = false;
      }
			/*break;
		}*/
    
    while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
      if (msg->msg == CURLMSG_DONE) {
        if(CURLE_OK == msg->data.result)
        {
          if(CURLE_OK != (ret = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &proxy)))
          {
            PRINT_INFO2("err %i",ret);
            abort();
          }

          proxy->done = true;
          call_spdy_run = true;
        }
        else
        {
          PRINT_VERBOSE2("bad curl result for '%s'", proxy->url);
          proxy->done = true;
          call_spdy_run = true;
          //TODO spdy should be notified to send RST_STREAM
        }
      }
      else PRINT_INFO("shouldn't happen");
    }
    
    if(call_spdy_run)
    {
      PRINT_VERBOSE("second call to SPDY_run");
      SPDY_run(daemon);
      call_spdy_run = false;
    }
    
    if(glob_opt.verbose)
    {
      
    struct timespec ts;
    if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
    PRINT_VERBOSE2("time now %i %i", ts.tv_sec, ts.tv_nsec);
    }
  }
  while(loop);
	
	curl_multi_cleanup(multi_handle);

	SPDY_stop_daemon(daemon);
	
	SPDY_deinit();
  
  deinit_parse_uri(&uri_preg);
	
	return 0;
}
Ejemplo n.º 11
0
int authenticate_user(

  struct batch_request *preq,  /* I */
  struct credential    *pcred,
  char   **autherr) /* O */

  {
  int    rc;
  char   uath[PBS_MAXUSER + PBS_MAXHOSTNAME + 1];
  time_t time_now = time(NULL);
  char   error_msg[1024];
  long   acl_enabled = FALSE;

#ifdef MUNGE_AUTH
 
  if (strncmp(preq->rq_user, pcred->username, PBS_MAXUSER))
    {
    /* extra check for munge */
    struct array_strings *my_acl = NULL;
    char uh[PBS_MAXUSER + PBS_MAXHOSTNAME + 2];

    sprintf(uh, "%s@%s", preq->rq_user, pcred->hostname);
    
    get_svr_attr_arst(SRV_ATR_authusers, &my_acl); 
    if ((acl_check_my_array_string(my_acl, uh, ACL_User_Host)) == 0)
      {
      *autherr = strdup("User not in authorized user list.");
      sprintf(error_msg, "%s Requested user %s: requested from host %s",
                     *autherr, preq->rq_user, preq->rq_host);
      log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, error_msg);
      return(PBSE_BADCRED);
      }
    }
#else
  if (strncmp(preq->rq_user, pcred->username, PBS_MAXUSER))
    {
    *autherr = strdup("Users do not match");
    sprintf(error_msg, "%s: Requested user %s: credential user %s: requested from host %s",
                   *autherr, preq->rq_user, pcred->username, preq->rq_host);
    log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, error_msg);
    return(PBSE_BADCRED);
    }
#endif

  if (strncmp(preq->rq_host, pcred->hostname, PBS_MAXHOSTNAME))
    {
    struct sockaddr_in *sai1;
    struct sockaddr_in *sai2;
    struct addrinfo    *addr_info1 = NULL;
    struct addrinfo    *addr_info2 = NULL;

    sai1 = get_cached_addrinfo(preq->rq_host);
    sai2 = get_cached_addrinfo(pcred->hostname);

    if ((sai1 == NULL) &&
        (getaddrinfo(preq->rq_host, NULL, NULL, &addr_info1) == PBSE_NONE))
      {
      sai1 = (struct sockaddr_in *)addr_info1->ai_addr;
      insert_addr_name_info(preq->rq_host, addr_info1->ai_canonname, sai1);
      }

    if ((sai2 == NULL) &&
        (getaddrinfo(pcred->hostname, NULL, NULL, &addr_info2) == PBSE_NONE))
      {
      sai2 = (struct sockaddr_in *)addr_info2->ai_addr;
      insert_addr_name_info(pcred->hostname, addr_info2->ai_canonname, sai2);
      }

    if ((sai1 == NULL) ||
        (sai2 == NULL) ||
        (memcmp(sai1, sai2, sizeof(struct sockaddr_in))))
      {
      *autherr = strdup("Hosts do not match");
      
      sprintf(error_msg, "%s: Requested host %s: credential host: %s",
        *autherr, preq->rq_host, pcred->hostname);
      log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, error_msg);
    
      if (addr_info1 != NULL)
        freeaddrinfo(addr_info1);
      if (addr_info2 != NULL)
        freeaddrinfo(addr_info2);
      
      return(PBSE_BADCRED);
      }
      
    if (addr_info1 != NULL)
      freeaddrinfo(addr_info1);
    if (addr_info2 != NULL)
      freeaddrinfo(addr_info2);
    }

  if (pcred->timestamp)
    {
    long lifetime = 0;
    if (get_svr_attr_l(SRV_ATR_CredentialLifetime, &lifetime) == PBSE_NONE)
      {
      /* use configured value if set */
      }
    else 
      {
      /* if not use the default */
      lifetime = CREDENTIAL_LIFETIME;
      }

    /* negative values mean that credentials have an infinite lifetime */
    if (lifetime > -1)
      {
      if ((pcred->timestamp - CREDENTIAL_TIME_DELTA > time_now) ||
          (pcred->timestamp + lifetime < time_now))
        {
        return(PBSE_EXPIRED);
        }
      }

    }

  /* If Server's Acl_User enabled, check if user in list */
  get_svr_attr_l(SRV_ATR_AclUserEnabled, &acl_enabled);
  if (acl_enabled)
    {
    struct array_strings *acl_users = NULL;
    snprintf(uath, sizeof(uath), "%s@%s", preq->rq_user, preq->rq_host);
    
    get_svr_attr_arst(SRV_ATR_AclUsers, &acl_users);
    if (acl_check_my_array_string(acl_users, uath, ACL_User) == 0)
      {

#ifdef __CYGWIN__
  if (!IamAdminByName(preq->rq_user) || (strcasecmp(preq->rq_host, server_host) != 0))
    {
	return(PBSE_PERM);
    }
#else /* __CYGWIN__ */
#ifdef PBS_ROOT_ALWAYS_ADMIN

      if ((strcmp(preq->rq_user, PBS_DEFAULT_ADMIN) != 0) ||
          (strcasecmp(preq->rq_host, server_host) != 0))
        {
        return(PBSE_PERM);
        }

#else /* PBS_ROOT_ALWAYS_ADMIN */
      return(PBSE_PERM);

#endif /* PBS_ROOT_ALWAYS_ADMIN */
#endif /* __CYGWIN__ */

      }
    }

  /* A site stub for additional checking */

  rc = site_allow_u(preq->rq_user, preq->rq_host);

  return(rc);
  }  /* END authenticate_user() */
Ejemplo n.º 12
0
int main(int argc, char **argv) {
	int sfd, s, val, volume;
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	struct sockaddr *sa;
	socklen_t salen;
	char buf[BUFSIZE];
	ssize_t nsend;

	if (argc != 3) {
		printf("Usage: %s port_serveur volume\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	volume = atoi(argv[2]);
	if (volume == 0 || volume > BUFSIZE) {
		fprintf(stderr, "Donnez un volume inferieur a %d octets\n", BUFSIZE);
		exit(EXIT_FAILURE);
	}

	/* Initialisation du buffer */
	memset(buf, 'a', volume);

	/*
	 * Obtention de l'adresse IP du distant, a partir de son nom par
	 * consultation du fichier /etc/hosts ou de la base hosts des NIS
	 * ou du DNS (Domain Name Service)
	 * cf. man getaddrinfo(3)
	 */
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;          /* IPv4 ou IPv6 */
	hints.ai_socktype = SOCK_DGRAM;       /* Datagram socket */
	hints.ai_flags = 0;
	hints.ai_protocol = 0;                /* Any protocol */

	s = getaddrinfo("224.2.2.10", argv[1], &hints, &result);
	if (s != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
		exit(EXIT_FAILURE);
	}

	/* getaddrinfo() retourne une liste de structures d'adresses.
	   On essaie chaque adresse jusqu'a ce que socket(2) reussisse. */
	for (rp = result; rp != NULL; rp = rp->ai_next) {
		/* Ouverture de la socket */
		sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (sfd >= 0)
			break;
	}
	if (rp == NULL) {     /* Aucune adresse valide */
		fprintf(stderr, "Impossible d'ouvrir une socket vers %s\n", argv[1]);
		perror("socket");
		exit(EXIT_FAILURE);
	}

	/*
	 * Construction de la structure d'adresse du distant
	 */
	sa=malloc(rp->ai_addrlen);
	memcpy(sa, rp->ai_addr, rp->ai_addrlen);
	salen=rp->ai_addrlen;

	freeaddrinfo(result); /* Plus besoin */

	/* Permettons le broadcast (IPv4 only) */
	val = 1;
	if (setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)) < 0) {
		perror("setsockopt");
		exit(EXIT_FAILURE);
	}

	for(;;){
		char *pt;
		pt = fgets(buf, volume, stdin);
		if(pt == NULL){
			printf("Sortie du client\n");
			exit(EXIT_SUCCESS);
		}

		/* Envoi donnees */
		nsend = sendto(sfd, buf, volume, 0, sa, salen);
		if (nsend <= 0)
			perror("sendto");
	}
	exit(EXIT_SUCCESS);
}
Ejemplo n.º 13
0
int SocketAndSendto(int bcast, int reply, const char* dest)
{
    int sockfd;
    struct addrinfo hints, *servinfo, *p;
    int retval;
    int numbytes;
    int broadcast = 1;
    char* packet;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = (bcast) ? AF_INET : AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((retval = getaddrinfo(dest, "49364", &hints, &servinfo)) != 0)
    {
        printfLog("client: getaddrinfo(): %s", gai_strerror(retval));
        return 4;
    }

    for(p = servinfo; p != NULL; p = p->ai_next)
    {   // Loop through all results from getaddrinfo() and use the first one that works.
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
        {
            printLogError("client: socket()", errno);
            continue;
        }

        break;
    }

    if (p == NULL)
    {
        printLog("client: failed to create socket");
        return 5;
    }

    if(bcast)
        if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1)
        {
            printLogError("client: setsockopt(SO_BROADCAST)", errno);
            return 6;
        }

    packet = encapPacket(reply, hostname);
    printfLog("client: sent %s: %d bytes to %s", ((reply) ? "response" : "request"), strlen(packet), dest);
    if(packet)
    {
        if ((numbytes = sendto(sockfd, packet, strlen(packet), 0, p->ai_addr, p->ai_addrlen)) == -1)
        {
            printLogError("client: sendto()", errno);
            return 7;
        }
        free(packet);
    }

    freeaddrinfo(servinfo);

    close(sockfd);

    return 0;
}
Ejemplo n.º 14
0
string get_reply(string ip, string msg){
	int sockfd;
	struct addrinfo hints, *servinfo, *p;
	int rv;
	int numbytes;

	//add thread id to the end of message
	msg = msg + "_" + uint_to_str((unsigned int)pthread_self());
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	if ((rv = getaddrinfo(ip.c_str(), SERVERPORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return "";
	}

	// loop through all the results and make a socket
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
				p->ai_protocol)) == -1) {
			perror("talker: socket");
			continue;
		}

		break;
	}

	if (p == NULL) {
		fprintf(stderr, "talker: failed to bind socket\n");
		return "";
	}

	if ((numbytes = sendto(sockfd, msg.c_str(), strlen(msg.c_str()), 0,
			 p->ai_addr, p->ai_addrlen)) == -1) {
		perror("talker: sendto");
		return "";
	}
	freeaddrinfo(servinfo);
	close(sockfd);
	cond_wait cw;
	time(&cw.time);
	if (pthread_mutex_init(cw.mutex, NULL) != 0) {
		perror("pthread_mutex_init() error");
		return "";
	}
	if (pthread_cond_init(cw.cond, NULL) != 0) {
		perror("pthread_cond_init() error");
		return "";
	}
	if (pthread_mutex_lock(cw.mutex) != 0) {
		perror("pthread_mutex_lock() error");
		return "";
	}
	cw.thread_id = (unsigned int)pthread_self();
	waiting_list.push_back(cw);
	//cout<<"TID:"<<cw.thread_id<<","<<cw.cond<<","<<cw.mutex<<endl;
	if (pthread_cond_wait(cw.cond, cw.mutex) != 0) {
	    perror("pthread_cond_timedwait() error");
	    return "";
	}
	//cout<<"out of wait & wls="<<waiting_list.size()<<endl;
	string ret;
	for(int i = 0; i < waiting_list.size(); i++){
		if(waiting_list[i].thread_id == (unsigned int)pthread_self()){
			ret = waiting_list[i].return_val;
			waiting_list.erase(waiting_list.begin() + i);
			break;
		}
	}
	//cout<<"out of for & wls="<<waiting_list.size()<<endl;
	return ret;
}
Ejemplo n.º 15
0
int _pam_parse (int argc, const char **argv) {
    int ctrl = 0;
    const char *current_secret = NULL;

    /* otherwise the list will grow with each call */
    memset(tac_srv, 0, sizeof(tacplus_server_t) * TAC_PLUS_MAXSERVERS);
    tac_srv_no = 0;

    tac_service[0] = 0;
    tac_protocol[0] = 0;
    tac_prompt[0] = 0;
    tac_login[0] = 0;

    for (ctrl = 0; argc-- > 0; ++argv) {
        if (!strcmp (*argv, "debug")) { /* all */
            ctrl |= PAM_TAC_DEBUG;
        } else if (!strcmp (*argv, "use_first_pass")) {
            ctrl |= PAM_TAC_USE_FIRST_PASS;
        } else if (!strcmp (*argv, "try_first_pass")) { 
            ctrl |= PAM_TAC_TRY_FIRST_PASS;
        } else if (!strncmp (*argv, "service=", 8)) { /* author & acct */
            xstrcpy (tac_service, *argv + 8, sizeof(tac_service));
        } else if (!strncmp (*argv, "protocol=", 9)) { /* author & acct */
            xstrcpy (tac_protocol, *argv + 9, sizeof(tac_protocol));
        } else if (!strncmp (*argv, "prompt=", 7)) { /* authentication */
            xstrcpy (tac_prompt, *argv + 7, sizeof(tac_prompt));
            /* Replace _ with space */
            int chr;
            for (chr = 0; chr < strlen(tac_prompt); chr++) {
                if (tac_prompt[chr] == '_') {
                    tac_prompt[chr] = ' ';
                }
            }
        } else if (!strncmp (*argv, "login="******"acct_all")) {
            ctrl |= PAM_TAC_ACCT;
        } else if (!strncmp (*argv, "server=", 7)) { /* authen & acct */
            if(tac_srv_no < TAC_PLUS_MAXSERVERS) { 
                struct addrinfo hints, *servers, *server;
                int rv;
                char *port, server_buf[256];

                memset(&hints, 0, sizeof hints);
                hints.ai_family = AF_UNSPEC;  /* use IPv4 or IPv6, whichever */
                hints.ai_socktype = SOCK_STREAM;

                if (strlen(*argv + 7) >= sizeof(server_buf)) {
                    _pam_log(LOG_ERR, "server address too long, sorry");
                    continue;
                }
                strcpy(server_buf, *argv + 7);

                port = strchr(server_buf, ':');
                if (port != NULL) {
                    *port = '\0';
					port++;
                }
                if ((rv = getaddrinfo(server_buf, (port == NULL) ? "49" : port, &hints, &servers)) == 0) {
                    for(server = servers; server != NULL && tac_srv_no < TAC_PLUS_MAXSERVERS; server = server->ai_next) {
                        tac_srv[tac_srv_no].addr = server;
                        tac_srv[tac_srv_no].key = current_secret;
                        tac_srv_no++;
                    }
                } else {
                    _pam_log (LOG_ERR,
                        "skip invalid server: %s (getaddrinfo: %s)",
                        server_buf, gai_strerror(rv));
                }
            } else {
                _pam_log(LOG_ERR, "maximum number of servers (%d) exceeded, skipping",
                    TAC_PLUS_MAXSERVERS);
            }
        } else if (!strncmp (*argv, "secret=", 7)) {
            int i;

            current_secret = *argv + 7;     /* points right into argv (which is const) */

            /* if 'secret=' was given after a 'server=' parameter, fill in the current secret */
            for(i = tac_srv_no-1; i >= 0; i--) {
                if (tac_srv[i].key != NULL)
                    break;

                tac_srv[i].key = current_secret;
            }
        } else if (!strncmp (*argv, "timeout=", 8)) {
            /* FIXME atoi() doesn't handle invalid numeric strings well */
            tac_timeout = atoi(*argv + 8);

            if (tac_timeout < 0)
                tac_timeout = 0;
        } else {
            _pam_log (LOG_WARNING, "unrecognized option: %s", *argv);
        }
    }

    if (ctrl & PAM_TAC_DEBUG) {
        int n;

        _pam_log(LOG_DEBUG, "%d servers defined", tac_srv_no);

        for(n = 0; n < tac_srv_no; n++) {
            _pam_log(LOG_DEBUG, "server[%d] { addr=%s, key='%s' }", n, tac_ntop(tac_srv[n].addr->ai_addr), tac_srv[n].key);
        }

        _pam_log(LOG_DEBUG, "tac_service='%s'", tac_service);
        _pam_log(LOG_DEBUG, "tac_protocol='%s'", tac_protocol);
        _pam_log(LOG_DEBUG, "tac_prompt='%s'", tac_prompt);
        _pam_log(LOG_DEBUG, "tac_login='******'", tac_login);
    }

    return ctrl;
}    /* _pam_parse */
Ejemplo n.º 16
0
/*
 * Set up mandatory non-version specific NFS mount options.
 *
 * Returns 1 if successful; otherwise zero.
 */
static int nfs_validate_options(struct nfsmount_info *mi)
{
	struct addrinfo hint = {
		.ai_protocol	= (int)IPPROTO_UDP,
	};
	sa_family_t family;
	int error;

	if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL))
		return 0;

	if (!nfs_nfs_proto_family(mi->options, &family))
		return 0;

	hint.ai_family = (int)family;
	error = getaddrinfo(mi->hostname, NULL, &hint, &mi->address);
	if (error != 0) {
		nfs_error(_("%s: Failed to resolve server %s: %s"),
			progname, mi->hostname, gai_strerror(error));
		mi->address = NULL;
		return 0;
	}

	if (!nfs_set_version(mi))
		return 0;

	if (!nfs_append_sloppy_option(mi->options))
		return 0;

	if (!nfs_append_addr_option(mi->address->ai_addr,
					mi->address->ai_addrlen, mi->options))
		return 0;

	return 1;
}

/*
 * Get NFS/mnt server addresses from mount options
 *
 * Returns 1 and fills in @nfs_saddr, @nfs_salen, @mnt_saddr, and @mnt_salen
 * if all goes well; otherwise zero.
 */
static int nfs_extract_server_addresses(struct mount_options *options,
					struct sockaddr *nfs_saddr,
					socklen_t *nfs_salen,
					struct sockaddr *mnt_saddr,
					socklen_t *mnt_salen)
{
	char *option;

	option = po_get(options, "addr");
	if (option == NULL)
		return 0;
	if (!nfs_string_to_sockaddr(option, nfs_saddr, nfs_salen))
		return 0;

	option = po_get(options, "mountaddr");
	if (option == NULL) {
		memcpy(mnt_saddr, nfs_saddr, *nfs_salen);
		*mnt_salen = *nfs_salen;
	} else if (!nfs_string_to_sockaddr(option, mnt_saddr, mnt_salen))
		return 0;

	return 1;
}
Ejemplo n.º 17
0
/**
 *  Create a new socket and TCP connect to an address/port
 *  @param addr the address string
 *  @param port the TCP port
 *  @param sock returns the new socket
 *  @return completion code
 */
int Socket_new(char* addr, int port, int* sock)
{
	int type = SOCK_STREAM;
	struct sockaddr_in address;
#if defined(AF_INET6)
	struct sockaddr_in6 address6;
#endif
	int rc = SOCKET_ERROR;
#if defined(WIN32) || defined(WIN64)
	short family;
#else
	sa_family_t family = AF_INET;
#endif
	struct addrinfo *result = NULL;
	struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};

	FUNC_ENTRY;
	*sock = -1;

	if (addr[0] == '[')
	  ++addr;

	if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0)
	{
		struct addrinfo* res = result;

		/* prefer ip4 addresses */
		while (res)
		{
			if (res->ai_family == AF_INET)
			{
				result = res;
				break;
			}
			res = res->ai_next;
		}

		if (result == NULL)
			rc = -1;
		else
#if defined(AF_INET6)
		if (result->ai_family == AF_INET6)
		{
			address6.sin6_port = htons(port);
			address6.sin6_family = family = AF_INET6;
			address6.sin6_addr = ((struct sockaddr_in6*)(result->ai_addr))->sin6_addr;
		}
		else
#endif
		if (result->ai_family == AF_INET)
		{
			address.sin_port = htons(port);
			address.sin_family = family = AF_INET;
			address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
		}
		else
			rc = -1;

    freeaddrinfo(result);
	}
  else
  	Log(TRACE_MIN, -1, "getaddrinfo failed for addr %s with rc %d", addr, rc);

	if (rc != 0)
		Log(LOG_ERROR, -1, "%s is not a valid IP address", addr);
	else
	{
		*sock =	socket(family, type, 0);
		if (*sock == INVALID_SOCKET)
			rc = Socket_error("socket", *sock);
		else
		{
#if defined(NOSIGPIPE)
			int opt = 1;

			if (setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0)
				Log(TRACE_MIN, -1, "Could not set SO_NOSIGPIPE for socket %d", *sock);
#endif

			Log(TRACE_MIN, -1, "New socket %d for %s, port %d",	*sock, addr, port);
			if (Socket_addSocket(*sock) == SOCKET_ERROR)
				rc = Socket_error("setnonblocking", *sock);
			else
			{
				/* this could complete immmediately, even though we are non-blocking */
				if (family == AF_INET)
					rc = connect(*sock, (struct sockaddr*)&address, sizeof(address));
	#if defined(AF_INET6)
				else
					rc = connect(*sock, (struct sockaddr*)&address6, sizeof(address6));
	#endif
				if (rc == SOCKET_ERROR)
					rc = Socket_error("connect", *sock);
				if (rc == EINPROGRESS || rc == EWOULDBLOCK)
				{
					int* pnewSd = (int*)malloc(sizeof(int));
					*pnewSd = *sock;
					ListAppend(s.connect_pending, pnewSd, sizeof(int));
					Log(TRACE_MIN, 15, "Connect pending");
				}
			}
		}
	}
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 18
0
int main(int argc, char **argv)
{
	int timeout = 3;
	int opt;
	char ipaddr[INET6_ADDRSTRLEN];
	void *addr;
	struct addrinfo *res, *rp;
	struct sigaction sa = {	.sa_handler = &abort_query };
	struct addrinfo hints = {
		.ai_family   = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM,
		.ai_protocol = IPPROTO_TCP,
		.ai_flags    = 0
	};

	while ((opt = getopt(argc, argv, "46t:h")) > -1)
	{
		switch ((char)opt)
		{
			case '4':
				hints.ai_family = AF_INET;
				break;

			case '6':
				hints.ai_family = AF_INET6;
				break;

			case 't':
				timeout = atoi(optarg);
				if (timeout <= 0)
					show_usage();
				break;

			case 'h':
				show_usage();
				break;
		}
	}

	if (!argv[optind])
		show_usage();

	sigaction(SIGALRM, &sa, NULL);
	alarm(timeout);

	if (getaddrinfo(argv[optind], NULL, &hints, &res))
		exit(2);

	for (rp = res; rp != NULL; rp = rp->ai_next)
	{
		addr = (rp->ai_family == AF_INET)
			? (void *)&((struct sockaddr_in *)rp->ai_addr)->sin_addr
			: (void *)&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr
		;

		if (!inet_ntop(rp->ai_family, addr, ipaddr, INET6_ADDRSTRLEN - 1))
			exit(3);

		printf("%s\n", ipaddr);
	}

	freeaddrinfo(res);
	exit(0);
}
Ejemplo n.º 19
0
static int uh_socket_bind(
	fd_set *serv_fds, int *max_fd, const char *host, const char *port,
	struct addrinfo *hints, int do_tls, struct config *conf
) {
	int sock = -1;
	int yes = 1;
	int status;
	int bound = 0;

	int tcp_ka_idl = 1;
	int tcp_ka_int = 1;
	int tcp_ka_cnt = 3;

	struct listener *l = NULL;
	struct addrinfo *addrs = NULL, *p = NULL;

	if( (status = getaddrinfo(host, port, hints, &addrs)) != 0 )
	{
		fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(status));
	}

	/* try to bind a new socket to each found address */
	for( p = addrs; p; p = p->ai_next )
	{
		/* get the socket */
		if( (sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1 )
		{
			perror("socket()");
			goto error;
		}

		/* "address already in use" */
		if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) )
		{
			perror("setsockopt()");
			goto error;
		}

		/* TCP keep-alive */
		if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) ||
		    setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,  &tcp_ka_idl, sizeof(tcp_ka_idl)) ||
		    setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)) ||
		    setsockopt(sock, SOL_TCP, TCP_KEEPCNT,   &tcp_ka_cnt, sizeof(tcp_ka_cnt)) )
		{
		    fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n",
		    	strerror(errno));
		}

		/* required to get parallel v4 + v6 working */
		if( p->ai_family == AF_INET6 )
		{
			if( setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) == -1 )
			{
				perror("setsockopt()");
				goto error;
			}
		}

		/* bind */
		if( bind(sock, p->ai_addr, p->ai_addrlen) == -1 )
		{
			perror("bind()");
			goto error;
		}

		/* listen */
		if( listen(sock, UH_LIMIT_CLIENTS) == -1 )
		{
			perror("listen()");
			goto error;
		}

		/* add listener to global list */
		if( ! (l = uh_listener_add(sock, conf)) )
		{
			fprintf(stderr, "uh_listener_add(): Failed to allocate memory\n");
			goto error;
		}

#ifdef HAVE_TLS
		/* init TLS */
		l->tls = do_tls ? conf->tls : NULL;
#endif

		/* add socket to server fd set */
		FD_SET(sock, serv_fds);
		fd_cloexec(sock);
		*max_fd = max(*max_fd, sock);

		bound++;
		continue;

		error:
		if( sock > 0 )
			close(sock);
	}

	freeaddrinfo(addrs);

	return bound;
}
Ejemplo n.º 20
0
/*
 * Main program for the ssh client.
 */
int
main(int ac, char **av)
{
	int i, r, opt, exit_status, use_syslog;
	char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile;
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
	struct stat st;
	struct passwd *pw;
	int dummy, timeout_ms;
	extern int optind, optreset;
	extern char *optarg;

	struct servent *sp;
	Forward fwd;

	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
	sanitise_stdfd();

	__progname = ssh_get_progname(av[0]);

#ifndef HAVE_SETPROCTITLE
	/* Prepare for later setproctitle emulation */
	/* Save argv so it isn't clobbered by setproctitle() emulation */
	saved_av = xcalloc(ac + 1, sizeof(*saved_av));
	for (i = 0; i < ac; i++)
		saved_av[i] = xstrdup(av[i]);
	saved_av[i] = NULL;
	compat_init_setproctitle(ac, av);
	av = saved_av;
#endif

	/*
	 * Discard other fds that are hanging around. These can cause problem
	 * with backgrounded ssh processes started by ControlPersist.
	 */
	closefrom(STDERR_FILENO + 1);

	/*
	 * Save the original real uid.  It will be needed later (uid-swapping
	 * may clobber the real uid).
	 */
	original_real_uid = getuid();
	original_effective_uid = geteuid();

	/*
	 * Use uid-swapping to give up root privileges for the duration of
	 * option processing.  We will re-instantiate the rights when we are
	 * ready to create the privileged port, and will permanently drop
	 * them when the port has been created (actually, when the connection
	 * has been made, as we may need to create the port several times).
	 */
	PRIV_END;

#ifdef HAVE_SETRLIMIT
	/* If we are installed setuid root be careful to not drop core. */
	if (original_real_uid != original_effective_uid) {
		struct rlimit rlim;
		rlim.rlim_cur = rlim.rlim_max = 0;
		if (setrlimit(RLIMIT_CORE, &rlim) < 0)
			fatal("setrlimit failed: %.100s", strerror(errno));
	}
#endif
	/* Get user data. */
	pw = getpwuid(original_real_uid);
	if (!pw) {
		logit("No user exists for uid %lu", (u_long)original_real_uid);
		exit(255);
	}
	/* Take a copy of the returned structure. */
	pw = pwcopy(pw);

	/*
	 * Set our umask to something reasonable, as some files are created
	 * with the default umask.  This will make them world-readable but
	 * writable only by the owner, which is ok for all files for which we
	 * don't set the modes explicitly.
	 */
	umask(022);

	/*
	 * Initialize option structure to indicate that no values have been
	 * set.
	 */
	initialize_options(&options);

	/* Parse command-line arguments. */
	host = NULL;
	use_syslog = 0;
	logfile = NULL;
	argv0 = av[0];

 again:
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
	    "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
		switch (opt) {
		case '1':
			options.protocol = SSH_PROTO_1;
			break;
		case '2':
			options.protocol = SSH_PROTO_2;
			break;
		case '4':
			options.address_family = AF_INET;
			break;
		case '6':
			options.address_family = AF_INET6;
			break;
		case 'n':
			stdin_null_flag = 1;
			break;
		case 'f':
			fork_after_authentication_flag = 1;
			stdin_null_flag = 1;
			break;
		case 'x':
			options.forward_x11 = 0;
			break;
		case 'X':
			options.forward_x11 = 1;
			break;
		case 'y':
			use_syslog = 1;
			break;
		case 'E':
			logfile = xstrdup(optarg);
			break;
		case 'Y':
			options.forward_x11 = 1;
			options.forward_x11_trusted = 1;
			break;
		case 'g':
			options.gateway_ports = 1;
			break;
		case 'O':
			if (stdio_forward_host != NULL)
				fatal("Cannot specify multiplexing "
				    "command with -W");
			else if (muxclient_command != 0)
				fatal("Multiplexing command already specified");
			if (strcmp(optarg, "check") == 0)
				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
			else if (strcmp(optarg, "forward") == 0)
				muxclient_command = SSHMUX_COMMAND_FORWARD;
			else if (strcmp(optarg, "exit") == 0)
				muxclient_command = SSHMUX_COMMAND_TERMINATE;
			else if (strcmp(optarg, "stop") == 0)
				muxclient_command = SSHMUX_COMMAND_STOP;
			else if (strcmp(optarg, "cancel") == 0)
				muxclient_command = SSHMUX_COMMAND_CANCEL_FWD;
			else
				fatal("Invalid multiplex command.");
			break;
		case 'P':	/* deprecated */
			options.use_privileged_port = 0;
			break;
		case 'Q':	/* deprecated */
			cp = NULL;
			if (strcasecmp(optarg, "cipher") == 0)
				cp = cipher_alg_list();
			else if (strcasecmp(optarg, "mac") == 0)
				cp = mac_alg_list();
			else if (strcasecmp(optarg, "kex") == 0)
				cp = kex_alg_list();
			else if (strcasecmp(optarg, "key") == 0)
				cp = key_alg_list();
			if (cp == NULL)
				fatal("Unsupported query \"%s\"", optarg);
			printf("%s\n", cp);
			free(cp);
			exit(0);
			break;
		case 'a':
			options.forward_agent = 0;
			break;
		case 'A':
			options.forward_agent = 1;
			break;
		case 'k':
			options.gss_deleg_creds = 0;
			break;
		case 'K':
			options.gss_authentication = 1;
			options.gss_deleg_creds = 1;
			break;
		case 'i':
			if (stat(optarg, &st) < 0) {
				fprintf(stderr, "Warning: Identity file %s "
				    "not accessible: %s.\n", optarg,
				    strerror(errno));
				break;
			}
			add_identity_file(&options, NULL, optarg, 1);
			break;
		case 'I':
#ifdef ENABLE_PKCS11
			options.pkcs11_provider = xstrdup(optarg);
#else
			fprintf(stderr, "no support for PKCS#11.\n");
#endif
			break;
		case 't':
			if (options.request_tty == REQUEST_TTY_YES)
				options.request_tty = REQUEST_TTY_FORCE;
			else
				options.request_tty = REQUEST_TTY_YES;
			break;
		case 'v':
			if (debug_flag == 0) {
				debug_flag = 1;
				options.log_level = SYSLOG_LEVEL_DEBUG1;
			} else {
				if (options.log_level < SYSLOG_LEVEL_DEBUG3)
					options.log_level++;
			}
			break;
		case 'V':
			if (options.version_addendum &&
			    *options.version_addendum != '\0')
				fprintf(stderr, "%s%s %s, %s\n", SSH_RELEASE,
				    options.hpn_disabled ? "" : SSH_VERSION_HPN,
				    options.version_addendum,
				    SSLeay_version(SSLEAY_VERSION));
			else
				fprintf(stderr, "%s%s, %s\n", SSH_RELEASE,
				    options.hpn_disabled ? "" : SSH_VERSION_HPN,
				    SSLeay_version(SSLEAY_VERSION));
			if (opt == 'V')
				exit(0);
			break;
		case 'w':
			if (options.tun_open == -1)
				options.tun_open = SSH_TUNMODE_DEFAULT;
			options.tun_local = a2tun(optarg, &options.tun_remote);
			if (options.tun_local == SSH_TUNID_ERR) {
				fprintf(stderr,
				    "Bad tun device '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'W':
			if (stdio_forward_host != NULL)
				fatal("stdio forward already specified");
			if (muxclient_command != 0)
				fatal("Cannot specify stdio forward with -O");
			if (parse_forward(&fwd, optarg, 1, 0)) {
				stdio_forward_host = fwd.listen_host;
				stdio_forward_port = fwd.listen_port;
				free(fwd.connect_host);
			} else {
				fprintf(stderr,
				    "Bad stdio forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			options.request_tty = REQUEST_TTY_NO;
			no_shell_flag = 1;
			options.clear_forwardings = 1;
			options.exit_on_forward_failure = 1;
			break;
		case 'q':
			options.log_level = SYSLOG_LEVEL_QUIET;
			break;
		case 'e':
			if (optarg[0] == '^' && optarg[2] == 0 &&
			    (u_char) optarg[1] >= 64 &&
			    (u_char) optarg[1] < 128)
				options.escape_char = (u_char) optarg[1] & 31;
			else if (strlen(optarg) == 1)
				options.escape_char = (u_char) optarg[0];
			else if (strcmp(optarg, "none") == 0)
				options.escape_char = SSH_ESCAPECHAR_NONE;
			else {
				fprintf(stderr, "Bad escape character '%s'.\n",
				    optarg);
				exit(255);
			}
			break;
		case 'c':
			if (ciphers_valid(optarg)) {
				/* SSH2 only */
				options.ciphers = xstrdup(optarg);
				options.cipher = SSH_CIPHER_INVALID;
			} else {
				/* SSH1 only */
				options.cipher = cipher_number(optarg);
				if (options.cipher == -1) {
					fprintf(stderr,
					    "Unknown cipher type '%s'\n",
					    optarg);
					exit(255);
				}
				if (options.cipher == SSH_CIPHER_3DES)
					options.ciphers = "3des-cbc";
				else if (options.cipher == SSH_CIPHER_BLOWFISH)
					options.ciphers = "blowfish-cbc";
				else
					options.ciphers = (char *)-1;
			}
			break;
		case 'm':
			if (mac_valid(optarg))
				options.macs = xstrdup(optarg);
			else {
				fprintf(stderr, "Unknown mac type '%s'\n",
				    optarg);
				exit(255);
			}
			break;
		case 'M':
			if (options.control_master == SSHCTL_MASTER_YES)
				options.control_master = SSHCTL_MASTER_ASK;
			else
				options.control_master = SSHCTL_MASTER_YES;
			break;
		case 'p':
			options.port = a2port(optarg);
			if (options.port <= 0) {
				fprintf(stderr, "Bad port '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'l':
			options.user = optarg;
			break;

		case 'L':
			if (parse_forward(&fwd, optarg, 0, 0))
				add_local_forward(&options, &fwd);
			else {
				fprintf(stderr,
				    "Bad local forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			break;

		case 'R':
			if (parse_forward(&fwd, optarg, 0, 1)) {
				add_remote_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad remote forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'D':
			if (parse_forward(&fwd, optarg, 1, 0)) {
				add_local_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad dynamic forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'C':
			options.compression = 1;
			break;
		case 'N':
			no_shell_flag = 1;
			options.request_tty = REQUEST_TTY_NO;
			break;
		case 'T':
			options.request_tty = REQUEST_TTY_NO;
#ifdef	NONE_CIPHER_ENABLED
			/*
			 * Ensure that the user does not try to backdoor a
			 * NONE cipher switch on an interactive session by
			 * explicitly disabling it if the user asks for a
			 * session without a tty.
			 */
			options.none_switch = 0;
#endif
			break;
		case 'o':
			dummy = 1;
			line = xstrdup(optarg);
			if (process_config_line(&options, host ? host : "",
			    line, "command-line", 0, &dummy, SSHCONF_USERCONF)
			    != 0)
				exit(255);
			free(line);
			break;
		case 's':
			subsystem_flag = 1;
			break;
		case 'S':
			if (options.control_path != NULL)
				free(options.control_path);
			options.control_path = xstrdup(optarg);
			break;
		case 'b':
			options.bind_address = optarg;
			break;
		case 'F':
			config = optarg;
			break;
		default:
			usage();
		}
	}

	ac -= optind;
	av += optind;

	if (ac > 0 && !host) {
		if (strrchr(*av, '@')) {
			p = xstrdup(*av);
			cp = strrchr(p, '@');
			if (cp == NULL || cp == p)
				usage();
			options.user = p;
			*cp = '\0';
			host = ++cp;
		} else
			host = *av;
		if (ac > 1) {
			optind = optreset = 1;
			goto again;
		}
		ac--, av++;
	}

	/* Check that we got a host name. */
	if (!host)
		usage();

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Initialize the command to execute on remote host. */
	buffer_init(&command);

	/*
	 * Save the command to execute on the remote host in a buffer. There
	 * is no limit on the length of the command, except by the maximum
	 * packet size.  Also sets the tty flag if there is no command.
	 */
	if (!ac) {
		/* No command specified - execute shell on a tty. */
		if (subsystem_flag) {
			fprintf(stderr,
			    "You must specify a subsystem to invoke.\n");
			usage();
		}
	} else {
		/* A command has been specified.  Store it into the buffer. */
		for (i = 0; i < ac; i++) {
			if (i)
				buffer_append(&command, " ", 1);
			buffer_append(&command, av[i], strlen(av[i]));
		}
	}

	/* Cannot fork to background if no command. */
	if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
	    !no_shell_flag)
		fatal("Cannot fork into background without a command "
		    "to execute.");

	/*
	 * Initialize "log" output.  Since we are the client all output
	 * goes to stderr unless otherwise specified by -y or -E.
	 */
	if (use_syslog && logfile != NULL)
		fatal("Can't specify both -y and -E");
	if (logfile != NULL) {
		log_redirect_stderr_to(logfile);
		free(logfile);
	}
	log_init(argv0,
	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
	    SYSLOG_FACILITY_USER, !use_syslog);

	if (debug_flag)
		logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION));

	/*
	 * Read per-user configuration file.  Ignore the system wide config
	 * file if the user specifies a config file on the command line.
	 */
	if (config != NULL) {
		if (strcasecmp(config, "none") != 0 &&
		    !read_config_file(config, host, &options, SSHCONF_USERCONF))
			fatal("Can't open user config file %.100s: "
			    "%.100s", config, strerror(errno));
	} else {
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
		    _PATH_SSH_USER_CONFFILE);
		if (r > 0 && (size_t)r < sizeof(buf))
			(void)read_config_file(buf, host, &options,
			     SSHCONF_CHECKPERM|SSHCONF_USERCONF);

		/* Read systemwide configuration file after user config. */
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
		    &options, 0);
	}

	/* Fill configuration defaults. */
	fill_default_options(&options);

	channel_set_af(options.address_family);

	/* reinit */
	log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);

	if (options.request_tty == REQUEST_TTY_YES ||
	    options.request_tty == REQUEST_TTY_FORCE)
		tty_flag = 1;

	/* Allocate a tty by default if no command specified. */
	if (buffer_len(&command) == 0)
		tty_flag = options.request_tty != REQUEST_TTY_NO;

	/* Force no tty */
	if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
		tty_flag = 0;
	/* Do not allocate a tty if stdin is not a tty. */
	if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
	    options.request_tty != REQUEST_TTY_FORCE) {
		if (tty_flag)
			logit("Pseudo-terminal will not be allocated because "
			    "stdin is not a terminal.");
		tty_flag = 0;
	}

	seed_rng();

	if (options.user == NULL)
		options.user = xstrdup(pw->pw_name);

	/* Get default port if port has not been set. */
	if (options.port == 0) {
		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
		options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
	}

	/* preserve host name given on command line for %n expansion */
	host_arg = host;
	if (options.hostname != NULL) {
		host = percent_expand(options.hostname,
		    "h", host, (char *)NULL);
	}

	if (gethostname(thishost, sizeof(thishost)) == -1)
		fatal("gethostname: %s", strerror(errno));
	strlcpy(shorthost, thishost, sizeof(shorthost));
	shorthost[strcspn(thishost, ".")] = '\0';
	snprintf(portstr, sizeof(portstr), "%d", options.port);

	if (options.local_command != NULL) {
		debug3("expanding LocalCommand: %s", options.local_command);
		cp = options.local_command;
		options.local_command = percent_expand(cp, "d", pw->pw_dir,
		    "h", host, "l", thishost, "n", host_arg, "r", options.user,
		    "p", portstr, "u", pw->pw_name, "L", shorthost,
		    (char *)NULL);
		debug3("expanded LocalCommand: %s", options.local_command);
		free(cp);
	}

	/* Find canonic host name. */
	if (strchr(host, '.') == 0) {
		struct addrinfo hints;
		struct addrinfo *ai = NULL;
		int errgai;
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = options.address_family;
		hints.ai_flags = AI_CANONNAME;
		hints.ai_socktype = SOCK_STREAM;
		errgai = getaddrinfo(host, NULL, &hints, &ai);
		if (errgai == 0) {
			if (ai->ai_canonname != NULL)
				host = xstrdup(ai->ai_canonname);
			freeaddrinfo(ai);
		}
	}

	/* force lowercase for hostkey matching */
	if (options.host_key_alias != NULL) {
		for (p = options.host_key_alias; *p; p++)
			if (isupper(*p))
				*p = (char)tolower(*p);
	}

	if (options.proxy_command != NULL &&
	    strcmp(options.proxy_command, "none") == 0) {
		free(options.proxy_command);
		options.proxy_command = NULL;
	}
	if (options.control_path != NULL &&
	    strcmp(options.control_path, "none") == 0) {
		free(options.control_path);
		options.control_path = NULL;
	}

	if (options.control_path != NULL) {
		cp = tilde_expand_filename(options.control_path,
		    original_real_uid);
		free(options.control_path);
		options.control_path = percent_expand(cp, "h", host,
		    "l", thishost, "n", host_arg, "r", options.user,
		    "p", portstr, "u", pw->pw_name, "L", shorthost,
		    (char *)NULL);
		free(cp);
	}
	if (muxclient_command != 0 && options.control_path == NULL)
		fatal("No ControlPath specified for \"-O\" command");
	if (options.control_path != NULL)
		muxclient(options.control_path);

	timeout_ms = options.connection_timeout * 1000;

	/* Open a connection to the remote host. */
	if (ssh_connect(host, &hostaddr, options.port,
	    options.address_family, options.connection_attempts, &timeout_ms,
	    options.tcp_keep_alive, 
#ifdef HAVE_CYGWIN
	    options.use_privileged_port,
#else
	    original_effective_uid == 0 && options.use_privileged_port,
#endif
	    options.proxy_command) != 0)
		exit(255);

	if (timeout_ms > 0)
		debug3("timeout: %d ms remain after connect", timeout_ms);

	/*
	 * If we successfully made the connection, load the host private key
	 * in case we will need it later for combined rsa-rhosts
	 * authentication. This must be done before releasing extra
	 * privileges, because the file is only readable by root.
	 * If we cannot access the private keys, load the public keys
	 * instead and try to execute the ssh-keysign helper instead.
	 */
	sensitive_data.nkeys = 0;
	sensitive_data.keys = NULL;
	sensitive_data.external_keysign = 0;
	if (options.rhosts_rsa_authentication ||
	    options.hostbased_authentication) {
		sensitive_data.nkeys = 7;
		sensitive_data.keys = xcalloc(sensitive_data.nkeys,
		    sizeof(Key));
		for (i = 0; i < sensitive_data.nkeys; i++)
			sensitive_data.keys[i] = NULL;

		PRIV_START;
		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
		    _PATH_HOST_KEY_FILE, "", NULL, NULL);
		sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
		    _PATH_HOST_DSA_KEY_FILE, "", NULL);
#ifdef OPENSSL_HAS_ECC
		sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
#endif
		sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
		    _PATH_HOST_RSA_KEY_FILE, "", NULL);
		sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
		    _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
#ifdef OPENSSL_HAS_ECC
		sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
#endif
		sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
		    _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
		PRIV_END;

		if (options.hostbased_authentication == 1 &&
		    sensitive_data.keys[0] == NULL &&
		    sensitive_data.keys[4] == NULL &&
		    sensitive_data.keys[5] == NULL &&
		    sensitive_data.keys[6] == NULL) {
			sensitive_data.keys[1] = key_load_cert(
			    _PATH_HOST_DSA_KEY_FILE);
#ifdef OPENSSL_HAS_ECC
			sensitive_data.keys[2] = key_load_cert(
			    _PATH_HOST_ECDSA_KEY_FILE);
#endif
			sensitive_data.keys[3] = key_load_cert(
			    _PATH_HOST_RSA_KEY_FILE);
			sensitive_data.keys[4] = key_load_public(
			    _PATH_HOST_DSA_KEY_FILE, NULL);
#ifdef OPENSSL_HAS_ECC
			sensitive_data.keys[5] = key_load_public(
			    _PATH_HOST_ECDSA_KEY_FILE, NULL);
#endif
			sensitive_data.keys[6] = key_load_public(
			    _PATH_HOST_RSA_KEY_FILE, NULL);
			sensitive_data.external_keysign = 1;
		}
	}
	/*
	 * Get rid of any extra privileges that we may have.  We will no
	 * longer need them.  Also, extra privileges could make it very hard
	 * to read identity files and other non-world-readable files from the
	 * user's home directory if it happens to be on a NFS volume where
	 * root is mapped to nobody.
	 */
	if (original_effective_uid == 0) {
		PRIV_START;
		permanently_set_uid(pw);
	}

	/*
	 * Now that we are back to our own permissions, create ~/.ssh
	 * directory if it doesn't already exist.
	 */
	if (config == NULL) {
		r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
		    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
		if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
#ifdef WITH_SELINUX
			ssh_selinux_setfscreatecon(buf);
#endif
			if (mkdir(buf, 0700) < 0)
				error("Could not create directory '%.200s'.",
				    buf);
#ifdef WITH_SELINUX
			ssh_selinux_setfscreatecon(NULL);
#endif
		}
	}
	/* load options.identity_files */
	load_public_identity_files();

	/* Expand ~ in known host file names. */
	tilde_expand_paths(options.system_hostfiles,
	    options.num_system_hostfiles);
	tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);

	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
	signal(SIGCHLD, main_sigchld_handler);

	/* Log into the remote system.  Never returns if the login fails. */
	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
	    options.port, pw, timeout_ms);

	if (packet_connection_is_on_socket()) {
		verbose("Authenticated to %s ([%s]:%d).", host,
		    get_remote_ipaddr(), get_remote_port());
	} else {
		verbose("Authenticated to %s (via proxy).", host);
	}

	/* We no longer need the private host keys.  Clear them now. */
	if (sensitive_data.nkeys != 0) {
		for (i = 0; i < sensitive_data.nkeys; i++) {
			if (sensitive_data.keys[i] != NULL) {
				/* Destroys contents safely */
				debug3("clear hostkey %d", i);
				key_free(sensitive_data.keys[i]);
				sensitive_data.keys[i] = NULL;
			}
		}
		free(sensitive_data.keys);
	}
	for (i = 0; i < options.num_identity_files; i++) {
		free(options.identity_files[i]);
		options.identity_files[i] = NULL;
		if (options.identity_keys[i]) {
			key_free(options.identity_keys[i]);
			options.identity_keys[i] = NULL;
		}
	}

	exit_status = compat20 ? ssh_session2() : ssh_session();
	packet_close();

	if (options.control_path != NULL && muxserver_sock != -1)
		unlink(options.control_path);

	/* Kill ProxyCommand if it is running. */
	ssh_kill_proxy_command();

	return exit_status;
}
Ejemplo n.º 21
0
int main(void)
{
    fd_set master;    // master file descriptor list
    fd_set read_fds;  // temp file descriptor list for select()
    int fdmax;        // maximum file descriptor number

    int listener;     // listening socket descriptor
    int newfd;        // newly accept()ed socket descriptor
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;

    char buf[256];    // buffer for client data
    int nbytes;

	char remoteIP[INET6_ADDRSTRLEN];

    int yes=1;        // for setsockopt() SO_REUSEADDR, below
    int i, j, rv;

	struct addrinfo hints, *ai, *p;

    FD_ZERO(&master);    // clear the master and temp sets
    FD_ZERO(&read_fds);

	// get us a socket and bind it
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
		fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
		exit(1);
	}
	
	for(p = ai; p != NULL; p = p->ai_next) {
    	listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (listener < 0) { 
			continue;
		}
		
		// lose the pesky "address already in use" error message
		setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

		if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
			close(listener);
			continue;
		}

		break;
	}

	// if we got here, it means we didn't get bound
	if (p == NULL) {
		fprintf(stderr, "selectserver: failed to bind\n");
		exit(2);
	}

	freeaddrinfo(ai); // all done with this

    // listen
    if (listen(listener, 10) == -1) {
        perror("listen");
        exit(3);
    }

    // add the listener to the master set
    FD_SET(listener, &master);

    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one

    // main loop
    for(;;) {
        read_fds = master; // copy it
        if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            exit(4);
        }

        // run through the existing connections looking for data to read
        for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
                if (i == listener) {
                    // handle new connections
                    addrlen = sizeof remoteaddr;
					newfd = accept(listener,
						(struct sockaddr *)&remoteaddr,
						&addrlen);

					if (newfd == -1) {
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }
                        printf("selectserver: new connection from %s on "
                            "socket %d\n",
							inet_ntop(remoteaddr.ss_family,
								get_in_addr((struct sockaddr*)&remoteaddr),
								remoteIP, INET6_ADDRSTRLEN),
							newfd);
                    }
                } else {
                    // handle data from a client
                    if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
                        // got error or connection closed by client
                        if (nbytes == 0) {
                            // connection closed
                            printf("selectserver: socket %d hung up\n", i);
                        } else {
                            perror("recv");
                        }
                        close(i); // bye!
                        FD_CLR(i, &master); // remove from master set
                    } else {
                        // we got some data from a client
                        for(j = 0; j <= fdmax; j++) {
                            // send to everyone!
                            if (FD_ISSET(j, &master)) {
                                // except the listener and ourselves
                                if (j != listener && j != i) {
                                    if (send(j, buf, nbytes, 0) == -1) {
                                        perror("send");
                                    }
                                }
                            }
                        }
                    }
                } // END handle data from client
            } // END got new incoming connection
        } // END looping through file descriptors
    } // END for(;;)--and you thought it would never end!
    
    return 0;
}
Ejemplo n.º 22
0
bool VETCSocket::connectBE()
{
	if (m_serverIP == nullptr || m_serverPort == nullptr)
		return false;

	WSADATA wsaData;

	m_socket = INVALID_SOCKET;
	struct addrinfo *result = NULL, *ptr = NULL, hints;

	int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (res != 0)
		return false;

	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	res = getaddrinfo(m_serverIP, m_serverPort, &hints, &result);
	if (res != 0)
	{
		WSACleanup();
		return false;
	}

	for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
	{
		m_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);

		if (m_socket == INVALID_SOCKET)
		{
			WSACleanup();
			return false;
		}

		res = connect(m_socket, ptr->ai_addr, (int)ptr->ai_addrlen);
		if (res == SOCKET_ERROR)
		{
			closesocket(m_socket);
			m_socket = INVALID_SOCKET;
		}
	}

	freeaddrinfo(result);
	if (m_socket == INVALID_SOCKET)
	{
		WSACleanup();
		return false;
	}

	u_long iMode = 1;
	res = ioctlsocket(m_socket, FIONBIO, &iMode);
	if (res == SOCKET_ERROR)
	{
		closesocket(m_socket);
		WSACleanup();
		return false;
	}

	char value = 1;
	setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));
	return true;
}
Ejemplo n.º 23
0
	struct addrinfo hints, *res;
	int gai_error;
	isc_sockaddr_t sa;
	isc_sockaddrlist_t servers;
	isc_result_t result;
	size_t namelen;
	isc_buffer_t b;
	dns_fixedname_t fname;
	dns_name_t *name = NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_protocol = IPPROTO_UDP;
	hints.ai_flags = AI_NUMERICHOST;
	gai_error = getaddrinfo(addrstr, "53", &hints, &res);
	if (gai_error != 0) {
		fprintf(stderr, "getaddrinfo failed: %s\n",
			gai_strerror(gai_error));
		exit(1);
	}
	INSIST(res->ai_addrlen <= sizeof(sa.type));
	memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
	freeaddrinfo(res);
	sa.length = res->ai_addrlen;
	ISC_LINK_INIT(&sa, link);
	ISC_LIST_INIT(servers);
	ISC_LIST_APPEND(servers, &sa, link);

	if (namespace != NULL) {
		namelen = strlen(namespace);
Ejemplo n.º 24
0
int main(int argc, char* argv[])
{
if ( argc<4 )
{
usage(argv[0]);
return EXIT_FAILURE;
}

int retVal;
struct addrinfo hints,*addrinfo;

ZeroMemory(&hints,sizeof(hints));

WSADATA wsaData;
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != NO_ERROR )
{
fprintf( stderr, "Error in WSAStartup():%d\n",WSAGetLastError());
return EXIT_FAILURE;
}
//
// Get MAC address of remote host (assume link local IpV6 address)
//

hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

retVal = getaddrinfo(argv[2],0, &hints, &addrinfo);
if ( retVal!=0 )
{
WSACleanup();
fprintf( stderr, "Error in getaddrinfo():%d\n",WSAGetLastError());
exit(EXIT_FAILURE);
}

//
// Open WinPCap adapter
//
if ( (pcap_handle = pcap_open_live (argv[1], 1514, PCAP_OPENFLAG_PROMISCUOUS, 
100, (char*)errbuf)) == NULL )
{
freeaddrinfo(addrinfo);
WSACleanup();
fprintf(stderr, "Error opening device: %s\n",argv[1]);
return EXIT_FAILURE;
}

ZeroMemory(packet,sizeof(packet));
struct sockaddr_in6 *sa = (struct sockaddr_in6 *) addrinfo->ai_addr;

// fill ethernet header
eth_hdr->ether_dhost[0] = eth_hdr->ether_shost[0] = 0;// assume address like 
00:something;
eth_hdr->ether_dhost[1] = eth_hdr->ether_shost[1] = sa->sin6_addr.u.Byte[9];
eth_hdr->ether_dhost[2] = eth_hdr->ether_shost[2] = sa->sin6_addr.u.Byte[10];
eth_hdr->ether_dhost[3] = eth_hdr->ether_shost[3] = sa->sin6_addr.u.Byte[13];
eth_hdr->ether_dhost[4] = eth_hdr->ether_shost[4] = sa->sin6_addr.u.Byte[14];
eth_hdr->ether_dhost[5] = eth_hdr->ether_shost[5] = sa->sin6_addr.u.Byte[15];
eth_hdr->ether_type = 0xdd86;


// fill IP header
// source ip == destination ip

memcpy(ip6_hdr->ip_src.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));

memcpy(ip6_hdr->ip_dst.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));
ip6_hdr->ip_hl = 255;
ip6_hdr->ip_nh = IPPROTO_TCP;
ip6_hdr->ip_len = htons (20);
ip6_hdr->ip_flags[0] = 0x06 << 4;
srand((unsigned int) time(0));
// fill tcp header
tcp_hdr->th_sport = tcp_hdr->th_dport = htons (atoi(argv[3])); // source 
port equal to destination
tcp_hdr->th_seq = rand();
tcp_hdr->th_ack = rand();
tcp_hdr->th_off = htons(5);
tcp_hdr->th_win = rand();
tcp_hdr->th_sum = 0;
tcp_hdr->th_urp = htons(10);
tcp_hdr->th_off = 5;
tcp_hdr->th_flags = 2;
// calculate tcp checksum
int chsum = libnet_in_cksum ((u_int16_t *) & ip6_hdr->ip_src, 32);
chsum += ntohs (IPPROTO_TCP + sizeof (struct libnet_tcp_hdr));
chsum += libnet_in_cksum ((u_int16_t *) tcp_hdr, sizeof (struct 
libnet_tcp_hdr));
tcp_hdr->th_sum = LIBNET_CKSUM_CARRY (chsum);
// send data to wire
retVal = pcap_sendpacket (pcap_handle, (u_char *) packet, sizeof(packet));
if ( retVal == -1 )
{
fprintf(stderr,"Error writing packet to wire!!\n");
}
//
// close adapter, free mem.. etc..
//
pcap_close(pcap_handle);
freeaddrinfo(addrinfo);
WSACleanup();
return EXIT_SUCCESS;
}
Ejemplo n.º 25
0
SOCKET ConnectToService()
{
   // Connection
   SOCKET theSocket = INVALID_SOCKET;
   struct addrinfo *result = NULL,
      *ptr = NULL,
      hints;

   ZeroMemory(&hints,sizeof(hints));
   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_protocol = IPPROTO_TCP;

   // Resolve the server address and port
   int getaddrinfoRet = getaddrinfo("localhost",_1WIRE_SERVICE_PORT,&hints,&result);
   if (getaddrinfoRet != 0)
   {
      Log(LOG_ERROR,"getaddrinfo failed with error: %d\n", getaddrinfoRet);
      return INVALID_SOCKET;
   }

   // Attempt to connect to an address until one succeeds
   for(ptr=result;ptr!=NULL;ptr=ptr->ai_next)
   {
      // Create a SOCKET for connecting to server
      theSocket = socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol);
      if (theSocket == INVALID_SOCKET)
      {
         Log(LOG_ERROR,"socket function failed with error = %d\n", WSAGetLastError());
         return INVALID_SOCKET;
      }

      // Connect to server
	  if (connect(theSocket, ptr->ai_addr, static_cast<int>(ptr->ai_addrlen)) == SOCKET_ERROR)
      {
         Log(LOG_ERROR,"1Wire: connect function failed with error: %ld\n", WSAGetLastError());
         closesocket(theSocket);
         theSocket = INVALID_SOCKET;
         continue;
      }
      break;
   }

   freeaddrinfo(result);

   if (theSocket==INVALID_SOCKET)
   {
      return INVALID_SOCKET;
   }

   // Set receive timeout
   struct timeval tv;
   tv.tv_sec = 10*1000;  /* 10 Secs Timeout */
   if (setsockopt(theSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&tv,sizeof(struct timeval))==SOCKET_ERROR)
   {
      Log(LOG_ERROR,"setsockopt failed with error: %u\n", WSAGetLastError());
      closesocket(theSocket);
      return INVALID_SOCKET;
   }

   return theSocket;
}
Ejemplo n.º 26
0
/** Resolve the host IP
 * @param host     host or ip address
 * @param port     port
 * @param rc       return value pointer
 * @param l        logger
 * @return         JK_FALSE: some kind of error occured
 *                 JK_TRUE: success
 */
int jk_resolve(const char *host, int port, jk_sockaddr_t *saddr,
               void *pool, int prefer_ipv6, jk_logger_t *l)
{
    int family = JK_INET;
    struct in_addr iaddr;

    JK_TRACE_ENTER(l);

    memset(saddr, 0, sizeof(jk_sockaddr_t));
    if (*host >= '0' && *host <= '9' && strspn(host, "0123456789.") == strlen(host)) {

        /* If we found only digits we use inet_addr() */
        iaddr.s_addr = jk_inet_addr(host);
        memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr));
    }
    else {
#ifdef HAVE_APR
        apr_sockaddr_t *remote_sa, *temp_sa;

        if (!jk_apr_pool) {
            if (apr_pool_create(&jk_apr_pool, (apr_pool_t *)pool) != APR_SUCCESS) {
                JK_TRACE_EXIT(l);
                return JK_FALSE;
            }
        }
        apr_pool_clear(jk_apr_pool);
        if (apr_sockaddr_info_get(&remote_sa, host, APR_UNSPEC, (apr_port_t)port,
                                  0, jk_apr_pool) != APR_SUCCESS) {
            JK_TRACE_EXIT(l);
            return JK_FALSE;
        }

        /* Check if we have multiple address matches
         */
        if (remote_sa->next) {
            /* Since we are only handling JK_INET (IPV4) address (in_addr_t) */
            /* make sure we find one of those.                               */
            temp_sa = remote_sa;
#if APR_HAVE_IPV6
            if (prefer_ipv6) {
                while ((NULL != temp_sa) && (APR_INET6 != temp_sa->family))
                    temp_sa = temp_sa->next;
            }
#endif
            if (NULL != temp_sa) {
                remote_sa = temp_sa;
            }
            else {
                while ((NULL != temp_sa) && (APR_INET != temp_sa->family))
                    temp_sa = temp_sa->next;
#if APR_HAVE_IPV6
                if (NULL == temp_sa) {
                    temp_sa = remote_sa;
                    while ((NULL != temp_sa) && (APR_INET6 != temp_sa->family))
                        temp_sa = temp_sa->next;
                }
#endif
            }
            /* if temp_sa is set, we have a valid address otherwise, just return */
            if (NULL != temp_sa) {
                remote_sa = temp_sa;
            }
            else {
                JK_TRACE_EXIT(l);
                return JK_FALSE;
            }
        }
        if (remote_sa->family == APR_INET) {
            saddr->sa.sin = remote_sa->sa.sin;
            family = JK_INET;
        }
#if APR_HAVE_IPV6
        else {
            saddr->sa.sin6 = remote_sa->sa.sin6;
            family = JK_INET6;
        }
#endif
#else /* HAVE_APR */
        /* Without APR go the classic way.
         */
#if defined(HAVE_GETADDRINFO)
        /* TODO:
         * 1. Check for numeric IPV6 addresses
         * 2. Do we need to set service name for getaddrinfo?
         */
        struct addrinfo hints, *ai_list, *ai = NULL;
        int error;
        char  pbuf[12];
        char *pbufptr = NULL;

        memset(&hints, 0, sizeof(hints));
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        
#if JK_HAVE_IPV6
        if (strchr(host, ':')) {
            /* If host name contains collon this must be IPV6 address.
             * Set prefer_ipv6 flag in this case if it wasn't set already
             */
            prefer_ipv6 = 1;            
        }
        if (prefer_ipv6)
            hints.ai_family = JK_INET6;
        else
#endif
            hints.ai_family = JK_INET;
        if (port > 0) {
            snprintf(pbuf, sizeof(pbuf), "%d", port);
            pbufptr = pbuf;
        }
        error = getaddrinfo(host, pbufptr, &hints, &ai_list);
#if JK_HAVE_IPV6
        /* XXX:
         * Is the check for EAI_FAMILY/WSAEAFNOSUPPORT correct
         * way to retry the IPv4 address?
         */
        if (error == EAI_FAMILY && prefer_ipv6) {
            hints.ai_family = JK_INET;
            error = getaddrinfo(host, pbufptr, &hints, &ai_list);
        }
#endif
        if (error) {
            JK_TRACE_EXIT(l);
            errno = error;
            return JK_FALSE;
        }
#if JK_HAVE_IPV6
        if (prefer_ipv6) {
            ai = ai_list;
            while (ai) {
                if (ai->ai_family == JK_INET6) {
                    /* ignore elements without required address info */
                    if((ai->ai_addr != NULL) && (ai->ai_addrlen > 0)) {                        
                        family = JK_INET6;
                        break;
                    }
                }
                ai = ai->ai_next;
            }
        }
#endif
        if (ai == NULL) {
            ai = ai_list;
            while (ai) {
                if (ai->ai_family == JK_INET) {
                    /* ignore elements without required address info */
                    if((ai->ai_addr != NULL) && (ai->ai_addrlen > 0)) {                        
                        family = JK_INET;
                        break;
                    }
                }
                ai = ai->ai_next;
            }
        }
        if (ai == NULL) {
            /* No address found
             * XXX: Use better error code?
             */
            freeaddrinfo(ai_list);
            JK_TRACE_EXIT(l);
            errno = ENOENT;
            return JK_FALSE;
        }
        memcpy(&(saddr->sa), ai->ai_addr, ai->ai_addrlen);
        freeaddrinfo(ai_list);
#else /* HAVE_GETADDRINFO */
        struct hostent *hoste;

        /* XXX : WARNING : We should really use gethostbyname_r in multi-threaded env */
        /* Fortunatly when APR is available, ie under Apache 2.0, we use it */
#if defined(NETWARE) && !defined(__NOVELL_LIBC__)
        hoste = gethostbyname((char*)host);
#else
        hoste = gethostbyname(host);
#endif
        if (!hoste) {
            JK_TRACE_EXIT(l);
            return JK_FALSE;
        }
        iaddr = *((struct in_addr *)hoste->h_addr_list[0]);
        memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr));
#endif /* HAVE_GETADDRINFO */
#endif /* HAVE_APR */
    }

    if (family == JK_INET) {
        saddr->ipaddr_ptr = &(saddr->sa.sin.sin_addr);
        saddr->ipaddr_len = (int)sizeof(struct in_addr);
        saddr->salen      = (int)sizeof(struct sockaddr_in);
    }
#if JK_HAVE_IPV6
    else {
        saddr->ipaddr_ptr = &(saddr->sa.sin6.sin6_addr);
        saddr->ipaddr_len = (int)sizeof(struct in6_addr);
        saddr->salen      = (int)sizeof(struct sockaddr_in6);
    }
#endif
    saddr->sa.sin.sin_family = family;
    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
    saddr->sa.sin.sin_port = htons(port);
    saddr->port   = port;
    saddr->family = family;

    JK_TRACE_EXIT(l);
    return JK_TRUE;
}
Ejemplo n.º 27
0
int
tcp_listen(char *host, char *serv, size_t *addrlenp)
{
    int fd;
    int on = 1;
#ifdef HAVE_GETADDRINFO
    /*
     * Inspired by example code from W. Richard Stevens: UNIX Network
     * Programming, Vol. 1
     */
    int err;
    struct addrinfo hints, *first_ai, *ai;
    /* Crap necessary for OpenBSD, see below */
    int try_v6only_off = 1, v6only_stuck = 0;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((err = getaddrinfo(host, serv, &hints, &first_ai)) != 0)
	cant_listen(host, serv, gai_strerror(err));
    assert(first_ai);

again:
    for (ai = first_ai; ai; ai = ai->ai_next) {
	fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	if (fd < 0)
	    continue;		/* error, try next one */

#ifdef IPV6_V6ONLY
	if (ai->ai_family == AF_INET6 && try_v6only_off) {
	    int off = 0;

	    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
			   &off, sizeof(off)) < 0) {
		/*
		 * IPV6_V6ONLY is stuck on, violating RFC 3493 (gee,
		 * thanks, OpenBSD!).  Address is good only for IPv6,
		 * not for IPv4.  Means we can't have both on this
		 * system.  Continue looking for one that's good for
		 * IPv4.
		 */
		v6only_stuck = 1;
		close(fd);
		continue;
	    }
	}
#else
	(void)try_v6only_off;
#endif

	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0)
	    break;		/* success */

	close(fd);		/* error, close and try next one */
    }

    /* More crap for OpenBSD */
    if (ai == NULL && v6only_stuck) {
	/*
	 * No go.  But we skipped IPv6 addresses that don't work for
	 * IPv4, but could for IPv6.  Try again without skipping
	 * these.
	 */
	try_v6only_off = 0;
	goto again;
    }

    if (ai == NULL)	     /* errno from final socket() or bind() */
	cant_listen(host, serv, strerror(errno));

    if (listen(fd, SOMAXCONN) < 0)
	cant_listen(host, serv, strerror(errno));

    if (addrlenp)
	*addrlenp = ai->ai_addrlen;

    freeaddrinfo(first_ai);

#else  /* !HAVE_GETADDRINFO */
    struct sockaddr_in sin;
    struct hostent *hp;
    struct servent *sp;

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    if (!host)
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
    else if (isdigit(*host))
	sin.sin_addr.s_addr = inet_addr(host);
    else {
	hp = gethostbyname(host);
	if (!hp)
	    cant_listen(host, serv, strerror(errno));
	memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
    }
    if (isdigit(*serv))
	sin.sin_port = htons(atoi(serv));
    else {
	sp = getservbyname(serv, "tcp");
	if (!sp)
	    cant_listen(host, serv, strerror(errno));
	sin.sin_port = sp->s_port;
    }
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	cant_listen(host, serv, strerror(errno));
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	cant_listen(host, serv, strerror(errno));
    if (listen(fd, SOMAXCONN) < 0)
	cant_listen(host, serv, strerror(errno));

    if (addrlenp)
	*addrlenp = sizeof(struct sockaddr_in);

#endif /* !HAVE_GETADDRINFO */

    return fd;
}
Ejemplo n.º 28
0
int main(int argc, char *argv[])
{
	struct addrinfo *srv_addr, hints;
	int err;
	enum clnt_stat stat;
	nfs_ctx *ctx = NULL;

	LOOKUP3args largs;
	LINK3args lnk;

	if(argc < 5) {
		fprintf(stderr, "Not enough arguments\nThis tests the asynchronous "
				"libnfsclient NFS LINK call interface and "
				" callback\n"
				"USAGE: nfs_link <server> <remote_file_dir> "
				"<linkname> <target>\n");
		return 0;
	}

	/* First resolve server name */
	hints.ai_family = AF_INET;
	hints.ai_protocol = 0;
	hints.ai_socktype = 0;
	hints.ai_flags = 0;

	fprintf(stdout, "Resolving name %s\n", argv[1]);
	if((err = getaddrinfo(argv[1], NULL, &hints, &srv_addr)) != 0) {
		fprintf(stderr, "%s: Cannot resolve name: %s: %s\n",
				argv[0], argv[1], gai_strerror(err));
		return -1;
	}
	
	fprintf(stdout, "Creating nfs client context..\n");
	ctx = nfs_init((struct sockaddr_in *)srv_addr->ai_addr, IPPROTO_TCP, 0);
	if(ctx == NULL) {
		fprintf(stderr, "%s: Cant init nfs context\n", argv[0]);
		return 0;
	}

	freeaddrinfo(srv_addr);
	mntfh.fhandle3_len = 0;
	fprintf(stdout, "Sending mount call\n");
	stat = mount3_mnt(&argv[2], ctx, nfs_mnt_cb, NULL);
	if(stat == RPC_SUCCESS)
		fprintf(stderr, "NFS MOUNT Call sent successfully\n");
	else {
		fprintf(stderr, "Could not send NFS MOUNT call\n");
		return 0;
	}

	largs.what.dir.data.data_len = mntfh.fhandle3_len;
	largs.what.dir.data.data_val = mntfh.fhandle3_val;
	largs.what.name = argv[4];

	lfh.fhandle3_len = 0;
	fprintf(stdout, "Sending lookup call..\n");
	stat = nfs3_lookup(&largs, ctx, nfs_lookup_cb, NULL);
	if(stat == RPC_SUCCESS)
		fprintf(stderr, "NFS LOOKUP Call sent successfully\n");
	else {
		fprintf(stderr, "Could not send NFS LOOKUP call\n");
		return 0;
	}

	fprintf(stdout, "Waiting for lookup reply..\n");
	nfs_complete(ctx, RPC_BLOCKING_WAIT);

	fprintf(stdout, "Lookup reply received..\n");
	lnk.file.data.data_len = lfh.fhandle3_len;
	lnk.file.data.data_val = lfh.fhandle3_val;
	lnk.link.dir.data.data_len = mntfh.fhandle3_len;
	lnk.link.dir.data.data_val = mntfh.fhandle3_val;
	lnk.link.name = argv[3];
	fprintf(stdout, "Sending link call..\n");
	stat = nfs3_link(&lnk, ctx, nfs_link_cb, NULL);
	if(stat == RPC_SUCCESS)
		fprintf(stderr, "NFS LINK Call sent successfully\n");
	else {
		fprintf(stderr, "Could not send NFS LINK call\n");
		return 0;
	}

	fprintf(stdout, "Waiting for link reply..\n");
	nfs_complete(ctx, RPC_BLOCKING_WAIT);

	fprintf(stdout, "Received link reply..\n");
	free_LOOKUP3res(lookupres);
	
	return 0;
}
void
create_listens(char hostname[], char port[], int af) {

  struct addrinfo hints;
  struct addrinfo *local_res;
  struct addrinfo *local_res_temp;
  int count, error;
  int on = 1;
  SOCKET temp_socket;
  struct listen_elt *temp_elt;

  if (debug) {
    fprintf(stderr,
	    "%s: called with host '%s' port '%s' family %s(%d)\n",
	    __FUNCTION__,
            hostname,
	    port,
	    inet_ftos(af),
            af);
    fflush(stderr);
  }
 memset(&hints,0,sizeof(hints));
  hints.ai_family = af;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;
  hints.ai_flags = AI_PASSIVE;

  count = 0;
  do {
    error = getaddrinfo((char *)hostname,
                        (char *)port,
                        &hints,
                        &local_res);
    count += 1;
    if (error == EAI_AGAIN) {
      if (debug) {
        fprintf(stderr,
		"%s: Sleeping on getaddrinfo EAI_AGAIN\n",
		__FUNCTION__);
        fflush(stderr);
      }
      sleep(1);
    }
  } while ((error == EAI_AGAIN) && (count <= 5));

  if (error) {
    if (debug) {
      
      fprintf(stderr,
	      "%s: could not resolve remote '%s' port '%s' af %d\n"
	      "\tgetaddrinfo returned %s (%d)\n",
	      __FUNCTION__,
	      hostname,
	      port,
	      af,
	      gai_strerror(error),
	      error);
      
    }
    return;
  }

  if (debug) {
    dump_addrinfo(stderr, local_res, hostname, port, af);
  }

  local_res_temp = local_res;

  while (local_res_temp != NULL) {

    temp_socket = socket(local_res_temp->ai_family,SOCK_STREAM,0);

    if (temp_socket == INVALID_SOCKET) {
      if (debug) {
	fprintf(stderr,
		"%s could not allocate a socket: %s (errno %d)\n",
		__FUNCTION__,
		strerror(errno),
		errno);
	fflush(stderr);
      }
      local_res_temp = local_res_temp->ai_next;
      continue;
    }

    /* happiness and joy, keep going */
    if (setsockopt(temp_socket,
		   SOL_SOCKET, 
		   SO_REUSEADDR, 
		   (char *)&on , 
		   sizeof(on)) == SOCKET_ERROR) {
      if (debug) {
	fprintf(stderr,
		"%s: warning: could not set SO_REUSEADDR: %s (errno %d)\n",
		__FUNCTION__,
		strerror(errno),
		errno);
	fflush(stderr);
      }
    }
    /* still happy and joyful */

    if ((bind(temp_socket,
	      local_res_temp->ai_addr, 
	      local_res_temp->ai_addrlen) != SOCKET_ERROR) &&
	(listen(temp_socket,128) != SOCKET_ERROR))  {

      /* OK, now add to the list */
      temp_elt = (struct listen_elt *)malloc(sizeof(struct listen_elt));
      if (temp_elt) {
	temp_elt->fd = temp_socket;
	if (listen_list) {
	  temp_elt->next = listen_list;
	}
	else {
	  temp_elt->next = NULL;
	}
	listen_list = temp_elt;
      }
      else {
	fprintf(stderr,
		"%s: could not malloc a listen_elt\n",
		__FUNCTION__);
	fflush(stderr);
	exit(1);
      }
    }
    else {
      /* we consider a bind() or listen() failure a transient and try
	 the next address */
      if (debug) {
	fprintf(stderr,
		"%s: warning: bind or listen call failure: %s (errno %d)\n",
		__FUNCTION__,
		strerror(errno),
		errno);
	fflush(stderr);
      }
      close(temp_socket);
    }
    local_res_temp = local_res_temp->ai_next;
  }

}
Ejemplo n.º 30
0
int main() {
    /* ================
     * resolve hostname
     * ================ */
    struct addrinfo hints = { 0 };
    struct addrinfo* result = NULL;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    int ret = getaddrinfo("api.ipify.org", NULL, &hints, &result);
    if (ret != 0) {
        fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret));
        return 1;
    }

    /* ================
     * connect to host
     * ================ */
    struct sockaddr* address = result->ai_addr;
    if (address == NULL || address->sa_family != AF_INET) {
        fprintf(stderr, "invalid address");
        return 1;
    }
    ((struct sockaddr_in*)address)->sin_port = htobe16(80);
    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ((ret = connect(fd, address, sizeof(struct sockaddr_in))) != 0) {
        perror("connect failed:");
        return 1;
    }

    /* ================
     * send request
     * ================ */
    const char message[] =
        "GET /?format=json HTTP/1.1\r\n"
        "Host: api.ipify.org\r\n"
        "Connection: close\r\n\r\n";
    const size_t message_size = sizeof(message) - 1;
    for (size_t sent_size = 0; sent_size < message_size;) {
        ret = send(fd, message + sent_size, message_size - sent_size, 0);
        if (ret < 0) {
            perror("send failed:");
            return 1;
        } else if (ret == 0) {
            fprintf(stderr, "remote shutdown");
            return 1;
        }
        sent_size += ret;
    }

    /* ================
     * receive response
     * ================ */
    char buffer[1025] = { 0 };
    const size_t buffer_size = sizeof(buffer) - 1;
    for (size_t received_size = 0; received_size < buffer_size;) {
        ret = recv(fd, buffer + received_size, buffer_size - received_size, 0);
        if (ret <= 0) {
            break;
        }
        received_size += ret;
    }

    /* ================
     * print response and free resources
     * ================ */
    printf("%s\n", buffer);
    close(fd);
    freeaddrinfo(result);
    return 0;
}