diff --git a/tpws/params.h b/tpws/params.h index c6c8aeb..309cfca 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -74,6 +74,7 @@ struct params_s struct sockaddr_in connect_bind4; struct sockaddr_in6 connect_bind6; + char connect_bind6_ifname[IF_NAMESIZE]; int debug; diff --git a/tpws/tpws.c b/tpws/tpws.c index 2b1991f..14ea24f 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -797,7 +797,13 @@ void parse_params(int argc, char *argv[]) else if (inet_pton(AF_INET6, optarg, ¶ms.connect_bind6.sin6_addr)) { params.connect_bind6.sin6_family = AF_INET6; - if (p && *p) params.connect_bind6.sin6_scope_id=if_nametoindex(p); + if (p && *p) + { + // copy interface name for delayed resolution + strncpy(params.connect_bind6_ifname,p,sizeof(params.connect_bind6_ifname)); + params.connect_bind6_ifname[sizeof(params.connect_bind6_ifname)-1]=0; + } + } else { diff --git a/tpws/tpws_conn.c b/tpws/tpws_conn.c index 70b05cf..1222c0a 100644 --- a/tpws/tpws_conn.c +++ b/tpws/tpws_conn.c @@ -403,6 +403,17 @@ static int connect_remote(const struct sockaddr *remote_addr, bool bApplyConnect } else if(remote_addr->sa_family == params.connect_bind6.sin6_family) { + if (*params.connect_bind6_ifname && !params.connect_bind6.sin6_scope_id) + { + params.connect_bind6.sin6_scope_id=if_nametoindex(params.connect_bind6_ifname); + if (!params.connect_bind6.sin6_scope_id) + { + fprintf(stderr, "interface name not found : %s\n", params.connect_bind6_ifname); + close(remote_fd); + return -1; + } + } + if (bind(remote_fd, (struct sockaddr *)¶ms.connect_bind6, sizeof(struct sockaddr_in6)) == -1) { perror("bind on connect");