version 1.294, 2009/01/22 09:49:57 |
version 1.295, 2009/02/12 03:00:56 |
|
|
} |
} |
|
|
static int |
static int |
channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, |
channel_setup_fwd_listener(int type, const char *listen_addr, |
|
u_short listen_port, int *allocated_listen_port, |
const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
{ |
{ |
Channel *c; |
Channel *c; |
|
|
struct addrinfo hints, *ai, *aitop; |
struct addrinfo hints, *ai, *aitop; |
const char *host, *addr; |
const char *host, *addr; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
|
in_port_t *lport_p; |
|
|
host = (type == SSH_CHANNEL_RPORT_LISTENER) ? |
host = (type == SSH_CHANNEL_RPORT_LISTENER) ? |
listen_addr : host_to_connect; |
listen_addr : host_to_connect; |
|
|
} |
} |
return 0; |
return 0; |
} |
} |
|
if (allocated_listen_port != NULL) |
|
*allocated_listen_port = 0; |
for (ai = aitop; ai; ai = ai->ai_next) { |
for (ai = aitop; ai; ai = ai->ai_next) { |
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
switch (ai->ai_family) { |
|
case AF_INET: |
|
lport_p = &((struct sockaddr_in *)ai->ai_addr)-> |
|
sin_port; |
|
break; |
|
case AF_INET6: |
|
lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> |
|
sin6_port; |
|
break; |
|
default: |
continue; |
continue; |
|
} |
|
/* |
|
* If allocating a port for -R forwards, then use the |
|
* same port for all address families. |
|
*/ |
|
if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && |
|
allocated_listen_port != NULL && *allocated_listen_port > 0) |
|
*lport_p = htons(*allocated_listen_port); |
|
|
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), |
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), |
strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { |
strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { |
error("channel_setup_fwd_listener: getnameinfo failed"); |
error("channel_setup_fwd_listener: getnameinfo failed"); |
|
|
|
|
channel_set_reuseaddr(sock); |
channel_set_reuseaddr(sock); |
|
|
debug("Local forwarding listening on %s port %s.", ntop, strport); |
debug("Local forwarding listening on %s port %s.", |
|
ntop, strport); |
|
|
/* Bind the socket to the address. */ |
/* Bind the socket to the address. */ |
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { |
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { |
|
|
close(sock); |
close(sock); |
continue; |
continue; |
} |
} |
|
|
|
/* |
|
* listen_port == 0 requests a dynamically allocated port - |
|
* record what we got. |
|
*/ |
|
if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && |
|
allocated_listen_port != NULL && |
|
*allocated_listen_port == 0) { |
|
*allocated_listen_port = get_sock_port(sock, 1); |
|
debug("Allocated listen port %d", |
|
*allocated_listen_port); |
|
} |
|
|
/* Allocate a channel number for the socket. */ |
/* Allocate a channel number for the socket. */ |
c = channel_new("port listener", type, sock, sock, -1, |
c = channel_new("port listener", type, sock, sock, -1, |
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
|
|
const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
{ |
{ |
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, |
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, |
listen_host, listen_port, host_to_connect, port_to_connect, |
listen_host, listen_port, NULL, host_to_connect, port_to_connect, |
gateway_ports); |
gateway_ports); |
} |
} |
|
|
/* protocol v2 remote port fwd, used by sshd */ |
/* protocol v2 remote port fwd, used by sshd */ |
int |
int |
channel_setup_remote_fwd_listener(const char *listen_address, |
channel_setup_remote_fwd_listener(const char *listen_address, |
u_short listen_port, int gateway_ports) |
u_short listen_port, int *allocated_listen_port, int gateway_ports) |
{ |
{ |
return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, |
return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, |
listen_address, listen_port, NULL, 0, gateway_ports); |
listen_address, listen_port, allocated_listen_port, |
|
NULL, 0, gateway_ports); |
} |
} |
|
|
/* |
/* |