int tcp_con(const char *adr, int port) { static int s, ind; static struct sockaddr_in remoteAddr; static struct hostent *host; static struct in_addr RemoteIpAddress; int ret; #ifdef AF_INET6_IS_AVAILABLE static struct addrinfo hints, *res, *ressave; int n; char portstr[32]; #endif int is_localhost = 0; if(opt.arg_log) printf("conn=%s port=%d\n", adr, port); if(strcmp(adr,"localhost") == 0) is_localhost = 1; if(strcmp(adr,"127.0.0.1") == 0) is_localhost = 1; if(strcmp(adr,"::1") == 0) is_localhost = 1; if(pvb_com_con != NULL) { int use_plugin = 0; s = (pvb_com_con)(adr,port,&use_plugin); if(opt.arg_debug) printf("plugin returned use_plugin=%d\n", use_plugin); if(s > 0) { for(ind=1; ind<=MAX_TABS; ind++) { if(socket_array[ind] == -1) { socket_array[ind] = s; use_pvb_com_plugin[ind] = use_plugin; if(opt.arg_debug) printf("use_pvb_con_plugin[%d]=%d\n", ind, s); break; } } return ind; } } if(rl_ipversion == 4) { s = socket(AF_INET,SOCK_STREAM,0); if(s == -1) return -1; /* fill destblk structure */ host = gethostbyname(adr); if(host == NULL) { /* See if the host is specified in "dot address" form */ if(strchr(adr,'.') == NULL) return -1; RemoteIpAddress.s_addr = inet_addr(adr); if(RemoteIpAddress.s_addr == 0x0ffffffff) return -1; } else { memcpy(&RemoteIpAddress,host->h_addr,host->h_length); } memset(&remoteAddr,0,sizeof(remoteAddr)); remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = htons(port); remoteAddr.sin_addr = RemoteIpAddress; ret = connect_timed(s, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr), is_localhost); //if(ret == -1) if(ret < 0) { closesocket(s); return -1; } } else if(rl_ipversion == 6) { #ifdef AF_INET6_IS_AVAILABLE sprintf(portstr,"%d",port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; n = getaddrinfo(adr, portstr, &hints, &res); if(n != 0) { #ifndef PVWIN32 ::printf("tcp_con 1: error for %s port=%s : %s\n", adr, portstr, gai_strerror(n)); #endif return -1; } ressave = res; do { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if(s < 0) continue; // ignore this one if(::connect_timed(s, res->ai_addr, res->ai_addrlen, is_localhost) == 0) break; // success closesocket(s); s = -1; } while((res = res->ai_next) != NULL); if(res == NULL) ::printf("tcp_con 2: error for %s port=%s\n", adr, portstr); freeaddrinfo(ressave); #else ::printf("tcp_con 3:ERROR IPV6 not available on this platform\n"); #endif } else { printf("tcp_con 4: ipversion=%d is not supported\n", rl_ipversion); } for(ind=1; ind<=MAX_TABS; ind++) { if(socket_array[ind] == -1) { socket_array[ind] = s; use_pvb_com_plugin[ind] = 0; break; } } return ind; }
int client_open(int timeout) { int sin_size = sizeof (struct sockaddr_in); struct sockaddr_in sin_local; struct sockaddr_in sin_dst; int sock_fd; const char *dst_host; init_sockaddr_in(&sin_local, 0, 0); /* * create our local socket descriptor. pay attention: * * SVR4 STREAMS-based socket implementations check permissions * on binds to privileged ports relative to the credentials of * the socket creator. thus, if we want to bind to a privileged * port, we should become root before creating the socket. */ if (rlpr_client->proxyhost == 0 && rlpr_client->no_bind == 0) { /* * become root, but even if we can't become root (perhaps * because we're not setuid), keep on going anyway, since * some lpd implementations will allow connections from * non-privileged ports. */ toggle_root(); if (geteuid() != 0) msg(R_WARNING, 0, "cannot bind to privileged port: lpd may reject"); } sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd == -1) { if (geteuid() == 0) toggle_root(); msg(R_ERROR, errno, "socket create for connection to lpd"); return -1; } if (geteuid() == 0 && rlpr_client->no_bind == 0) { if (bind_try_range(&sin_local, sock_fd, R_LPD_SRC_PORT_LOW, R_LPD_SRC_PORT_HIGH) == 0) { toggle_root(); msg(R_FATAL, errno, "privileged bind failed (no ports left?)"); return -1; } toggle_root(); } /* * connect to the remote endpoint. for debugging purposes, * grab our local identity too. */ dst_host = rlpr_client->proxyhost ? rlpr_client->proxyhost : rlpr_client->printhost; if (init_sockaddr_in(&sin_dst, dst_host, rlpr_client->dst_port) == 0) return -1; if (connect_timed(sock_fd, &sin_dst, timeout) == -1) { msg(R_ERROR, errno, "connect to %s:%hi", dst_host, rlpr_client->dst_port); return -1; } if (getsockname(sock_fd, (struct sockaddr *)&sin_local, &sin_size) == -1) { msg(R_ERROR, errno, "getsockname on connection to lpd"); return -1; } rlpr_client->src_port = ntohs(sin_local.sin_port); msg(R_DEBUG, 0, "connected localhost:%hu -> %s:%hu", rlpr_client->src_port, dst_host, rlpr_client->dst_port); if (rlpr_client->proxyhost != 0) { size_t printhost_len = strlen(rlpr_client->printhost); msg(R_DEBUG, 0, "pointing proxy to %s...", rlpr_client->printhost); if (full_write(sock_fd, rlpr_client->printhost, printhost_len, 0) == 0 || full_write(sock_fd, "\n", 1, 0) == 0) { msg(R_ERROR, 0, "unable to send printhost name to proxyhost"); return -1; } } return sock_fd; }