Re: dig vs ipv6 (scoped) addresses

2020-12-20 Thread Otto Moerbeek
On Sun, Dec 20, 2020 at 10:48:01AM +0100, Florian Obser wrote:

> On Thu, Dec 17, 2020 at 12:15:16PM +0100, Otto Moerbeek wrote:
> > Hi,
> 
> > 
> > as noted on misc dig does not like to talk to local link addresses.
> > This fixes that case. While investigating I also found another bug:
> 
> Thanks for looking into this. Looks like I got distracted while
> ripping out isc_sockaddr and did not fully clean it up. Probably
> because I found another isc_indirection to delete :/
> 
> I'd rather like to get rid of isc_sockaddr_fromin* completely, see
> diff at the end.
> 
> > selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
> > command line argument does not work as expected.
> 
> Nice catch.
> 
> > 
> > This fixes both. I did not test binding to a src address with this.
> > This is likely as broken as it was before.
> 
> My diff fixes that, too.
> 
> I still need to keep isc_sockaddr_fromin* because it's used for
> +subnet i.e. ecs. Which is broken, too. I'm having a look now.
> 
> > 
> > -Otto
> > 
> 
> > Index: lib/lwres/lwconfig.c
> > ===
> > RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
> > retrieving revision 1.6
> > diff -u -p -r1.6 lwconfig.c
> > --- lib/lwres/lwconfig.c25 Feb 2020 05:00:43 -  1.6
> > +++ lib/lwres/lwconfig.c17 Dec 2020 11:06:49 -
> > @@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t 
> >  
> > res = lwres_create_addr(word, , 1);
> > use_ipv4 = confdata->flags & LWRES_USEIPV4;
> > -   use_ipv6 = confdata->flags & LWRES_USEIPV4;
> > +   use_ipv6 = confdata->flags & LWRES_USEIPV6;
> > if (res == LWRES_R_SUCCESS &&
> > ((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
> > (address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {
> > 
> 
> OK florian for this

Committed

> 
> OK for this version for the rest?

A few nits inline. With those either addressed or ignored, OK,

-Otto
> 
> 
> diff --git dig.c dig.c
> index a0988a0567b..6b142a03239 100644
> --- dig.c
> +++ dig.c
> @@ -17,7 +17,10 @@
>  /* $Id: dig.c,v 1.18 2020/09/15 11:47:42 florian Exp $ */
>  
>  /*! \file */
> -#include 
> +#include 
> +#include 
> +
> +#include 
>  
>  #include 
>  #include 
> @@ -1275,10 +1278,7 @@ dash_option(char *option, char *next, dig_lookup_t 
> **lookup,
>   dns_rdatatype_t rdtype;
>   dns_rdataclass_t rdclass;
>   char textname[MXNAME];
> - struct in_addr in4;
> - struct in6_addr in6;
> - in_port_t srcport;
> - char *hash, *cmd;
> + char *cmd;
>   uint32_t num;
>   const char *errstr;
>  
> @@ -1346,28 +1346,39 @@ dash_option(char *option, char *next, dig_lookup_t 
> **lookup,
>   if (value == NULL)
>   goto invalid_option;
>   switch (opt) {
> - case 'b':
> + case 'b': {
> + struct addrinfo *ai = NULL, hints;
> + int error;
> + char *hash;
> +
> + memset(, 0, sizeof(hints));
> + hints.ai_flags = AI_NUMERICHOST;
> + hints.ai_socktype = SOCK_STREAM;

It does not realy matter for the rsult, but SOCK_DGRAM feels more
natural for DNS.

> +
>   hash = strchr(value, '#');
>   if (hash != NULL) {
> - num = strtonum(hash + 1, 0, MAXPORT, );
> - if (errstr != NULL)
> - fatal("port number is %s: '%s'", errstr,
> - hash + 1);
> - srcport = num;
>   *hash = '\0';
> + error = getaddrinfo(value, hash + 1, , );
> + *hash = '#';
>   } else
> - srcport = 0;
> - if (have_ipv6 && inet_pton(AF_INET6, value, ) == 1)
> - isc_sockaddr_fromin6(_address, , srcport);
> - else if (have_ipv4 && inet_pton(AF_INET, value, ) == 1)
> - isc_sockaddr_fromin(_address, , srcport);
> - else
> + error = getaddrinfo(value, NULL, , );
> +
> + if (error)
> + fatal("invalid address %s: %s", value,
> + gai_strerror(error));
> + if (ai == NULL || ai->ai_addrlen > sizeof(bind_address))
> + fatal("invalid address %s", value);
> + if (!have_ipv4 && ai->ai_family == AF_INET)
> + fatal("invalid address %s", value);

Please be more specific, like "%s: wrong address family"

> + if (!have_ipv6 && ai->ai_family == AF_INET6)
>   fatal("invalid address %s", value);

Same here
>  
> - if (hash != NULL)
> - *hash = '#';
> + memset(_address, 0, sizeof(bind_address));
> + memcpy(_address, ai->ai_addr, ai->ai_addrlen);
> +
>   specified_source = 1;
>   return (value_from_next);
> + }
>   case 'c':
>   

Re: dig vs ipv6 (scoped) addresses

2020-12-20 Thread Florian Obser
On Thu, Dec 17, 2020 at 12:15:16PM +0100, Otto Moerbeek wrote:
> Hi,

> 
> as noted on misc dig does not like to talk to local link addresses.
> This fixes that case. While investigating I also found another bug:

Thanks for looking into this. Looks like I got distracted while
ripping out isc_sockaddr and did not fully clean it up. Probably
because I found another isc_indirection to delete :/

I'd rather like to get rid of isc_sockaddr_fromin* completely, see
diff at the end.

> selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
> command line argument does not work as expected.

Nice catch.

> 
> This fixes both. I did not test binding to a src address with this.
> This is likely as broken as it was before.

My diff fixes that, too.

I still need to keep isc_sockaddr_fromin* because it's used for
+subnet i.e. ecs. Which is broken, too. I'm having a look now.

> 
>   -Otto
> 

> Index: lib/lwres/lwconfig.c
> ===
> RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 lwconfig.c
> --- lib/lwres/lwconfig.c  25 Feb 2020 05:00:43 -  1.6
> +++ lib/lwres/lwconfig.c  17 Dec 2020 11:06:49 -
> @@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t 
>  
>   res = lwres_create_addr(word, , 1);
>   use_ipv4 = confdata->flags & LWRES_USEIPV4;
> - use_ipv6 = confdata->flags & LWRES_USEIPV4;
> + use_ipv6 = confdata->flags & LWRES_USEIPV6;
>   if (res == LWRES_R_SUCCESS &&
>   ((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
>   (address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {
> 

OK florian for this

OK for this version for the rest?


diff --git dig.c dig.c
index a0988a0567b..6b142a03239 100644
--- dig.c
+++ dig.c
@@ -17,7 +17,10 @@
 /* $Id: dig.c,v 1.18 2020/09/15 11:47:42 florian Exp $ */
 
 /*! \file */
-#include 
+#include 
+#include 
+
+#include 
 
 #include 
 #include 
@@ -1275,10 +1278,7 @@ dash_option(char *option, char *next, dig_lookup_t 
**lookup,
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass;
char textname[MXNAME];
-   struct in_addr in4;
-   struct in6_addr in6;
-   in_port_t srcport;
-   char *hash, *cmd;
+   char *cmd;
uint32_t num;
const char *errstr;
 
@@ -1346,28 +1346,39 @@ dash_option(char *option, char *next, dig_lookup_t 
**lookup,
if (value == NULL)
goto invalid_option;
switch (opt) {
-   case 'b':
+   case 'b': {
+   struct addrinfo *ai = NULL, hints;
+   int error;
+   char *hash;
+
+   memset(, 0, sizeof(hints));
+   hints.ai_flags = AI_NUMERICHOST;
+   hints.ai_socktype = SOCK_STREAM;
+
hash = strchr(value, '#');
if (hash != NULL) {
-   num = strtonum(hash + 1, 0, MAXPORT, );
-   if (errstr != NULL)
-   fatal("port number is %s: '%s'", errstr,
-   hash + 1);
-   srcport = num;
*hash = '\0';
+   error = getaddrinfo(value, hash + 1, , );
+   *hash = '#';
} else
-   srcport = 0;
-   if (have_ipv6 && inet_pton(AF_INET6, value, ) == 1)
-   isc_sockaddr_fromin6(_address, , srcport);
-   else if (have_ipv4 && inet_pton(AF_INET, value, ) == 1)
-   isc_sockaddr_fromin(_address, , srcport);
-   else
+   error = getaddrinfo(value, NULL, , );
+
+   if (error)
+   fatal("invalid address %s: %s", value,
+   gai_strerror(error));
+   if (ai == NULL || ai->ai_addrlen > sizeof(bind_address))
+   fatal("invalid address %s", value);
+   if (!have_ipv4 && ai->ai_family == AF_INET)
+   fatal("invalid address %s", value);
+   if (!have_ipv6 && ai->ai_family == AF_INET6)
fatal("invalid address %s", value);
 
-   if (hash != NULL)
-   *hash = '#';
+   memset(_address, 0, sizeof(bind_address));
+   memcpy(_address, ai->ai_addr, ai->ai_addrlen);
+
specified_source = 1;
return (value_from_next);
+   }
case 'c':
if ((*lookup)->rdclassset) {
fprintf(stderr, ";; Warning, extra class option\n");
diff --git dighost.c dighost.c
index 52afde3d7d3..3974843600d 100644
--- dighost.c
+++ dighost.c
@@ -498,6 +498,7 @@ get_addresses(const char *hostname, in_port_t dstport,
 {
struct addrinfo *ai = NULL, *tmpai, hints;
int result, i;
+   char dport[sizeof("65535")];
 
REQUIRE(hostname != NULL);

Re: dig vs ipv6 (scoped) addresses

2020-12-19 Thread Jordan Geoghegan




On 12/18/20 5:04 PM, Jordan Geoghegan wrote:



On 12/17/20 3:15 AM, Otto Moerbeek wrote:

Hi,

as noted on misc dig does not like to talk to local link addresses.
This fixes that case. While investigating I also found another bug:
selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
command line argument does not work as expected.

This fixes both. I did not test binding to a src address with this.
This is likely as broken as it was before.

-Otto

Index: dig.c
===
RCS file: /cvs/src/usr.bin/dig/dig.c,v
retrieving revision 1.18
diff -u -p -r1.18 dig.c
--- dig.c    15 Sep 2020 11:47:42 -    1.18
+++ dig.c    17 Dec 2020 11:06:49 -
@@ -1358,7 +1358,7 @@ dash_option(char *option, char *next, di
  } else
  srcport = 0;
  if (have_ipv6 && inet_pton(AF_INET6, value, ) == 1)
-    isc_sockaddr_fromin6(_address, , srcport);
+    isc_sockaddr_fromin6(_address, , srcport, 0);
  else if (have_ipv4 && inet_pton(AF_INET, value, ) == 1)
  isc_sockaddr_fromin(_address, , srcport);
  else
Index: dighost.c
===
RCS file: /cvs/src/usr.bin/dig/dighost.c,v
retrieving revision 1.34
diff -u -p -r1.34 dighost.c
--- dighost.c    15 Sep 2020 11:47:42 -    1.34
+++ dighost.c    17 Dec 2020 11:06:49 -
@@ -540,7 +540,7 @@ get_addresses(const char *hostname, in_p
  struct sockaddr_in6 *sin6;
  sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
  isc_sockaddr_fromin6([i], >sin6_addr,
- dstport);
+ dstport, sin6->sin6_scope_id);
  }
  i++;
  @@ -972,7 +972,7 @@ parse_netprefix(struct sockaddr_storage
    if (inet_pton(AF_INET6, buf, ) == 1) {
  parsed = 1;
-    isc_sockaddr_fromin6(sa, , 0);
+    isc_sockaddr_fromin6(sa, , 0, 0);
  if (prefix_length > 128)
  prefix_length = 128;
  } else if (inet_pton(AF_INET, buf, ) == 1) {
Index: lib/isc/sockaddr.c
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/sockaddr.c,v
retrieving revision 1.14
diff -u -p -r1.14 sockaddr.c
--- lib/isc/sockaddr.c    28 Nov 2020 06:33:55 -    1.14
+++ lib/isc/sockaddr.c    17 Dec 2020 11:06:49 -
@@ -223,7 +223,7 @@ isc_sockaddr_anyofpf(struct sockaddr_sto
    void
  isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const 
struct in6_addr *ina6,

- in_port_t port)
+ in_port_t port, uint32_t scope)
  {
  struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sockaddr;
  memset(sockaddr, 0, sizeof(*sockaddr));
@@ -231,6 +231,7 @@ isc_sockaddr_fromin6(struct sockaddr_sto
  sin6->sin6_len = sizeof(*sin6);
  sin6->sin6_addr = *ina6;
  sin6->sin6_port = htons(port);
+    sin6->sin6_scope_id = scope;
  }
    int
Index: lib/isc/include/isc/sockaddr.h
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/include/isc/sockaddr.h,v
retrieving revision 1.7
diff -u -p -r1.7 sockaddr.h
--- lib/isc/include/isc/sockaddr.h    15 Sep 2020 11:47:42 -    1.7
+++ lib/isc/include/isc/sockaddr.h    17 Dec 2020 11:06:49 -
@@ -91,7 +91,7 @@ isc_sockaddr_fromin(struct sockaddr_stor
    void
  isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const 
struct in6_addr *ina6,

- in_port_t port);
+ in_port_t port, uint32_t scope);
  /*%<
   * Construct an struct sockaddr_storage from an IPv6 address and port.
   */
Index: lib/lwres/lwconfig.c
===
RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
retrieving revision 1.6
diff -u -p -r1.6 lwconfig.c
--- lib/lwres/lwconfig.c    25 Feb 2020 05:00:43 -    1.6
+++ lib/lwres/lwconfig.c    17 Dec 2020 11:06:49 -
@@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t
    res = lwres_create_addr(word, , 1);
  use_ipv4 = confdata->flags & LWRES_USEIPV4;
-    use_ipv6 = confdata->flags & LWRES_USEIPV4;
+    use_ipv6 = confdata->flags & LWRES_USEIPV6;
  if (res == LWRES_R_SUCCESS &&
  ((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
  (address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {



Hi Otto,

I just gave this diff a go and everything seems to be working fine. 
Dig is now using the proper DNS set in my resolv.conf:


$ ./dig openbsd.org

; <<>> dig 9.10.8-P1 <<>> openbsd.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3506
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openbsd.org.            IN    A

;; ANSWER SECTION:
openbsd.org.        28800    IN    A    129.128.5.194

;; Query time: 853 msec
;; SERVER: 

Re: dig vs ipv6 (scoped) addresses

2020-12-18 Thread Jordan Geoghegan




On 12/17/20 3:15 AM, Otto Moerbeek wrote:

Hi,

as noted on misc dig does not like to talk to local link addresses.
This fixes that case. While investigating I also found another bug:
selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
command line argument does not work as expected.

This fixes both. I did not test binding to a src address with this.
This is likely as broken as it was before.

-Otto

Index: dig.c
===
RCS file: /cvs/src/usr.bin/dig/dig.c,v
retrieving revision 1.18
diff -u -p -r1.18 dig.c
--- dig.c   15 Sep 2020 11:47:42 -  1.18
+++ dig.c   17 Dec 2020 11:06:49 -
@@ -1358,7 +1358,7 @@ dash_option(char *option, char *next, di
} else
srcport = 0;
if (have_ipv6 && inet_pton(AF_INET6, value, ) == 1)
-   isc_sockaddr_fromin6(_address, , srcport);
+   isc_sockaddr_fromin6(_address, , srcport, 0);
else if (have_ipv4 && inet_pton(AF_INET, value, ) == 1)
isc_sockaddr_fromin(_address, , srcport);
else
Index: dighost.c
===
RCS file: /cvs/src/usr.bin/dig/dighost.c,v
retrieving revision 1.34
diff -u -p -r1.34 dighost.c
--- dighost.c   15 Sep 2020 11:47:42 -  1.34
+++ dighost.c   17 Dec 2020 11:06:49 -
@@ -540,7 +540,7 @@ get_addresses(const char *hostname, in_p
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
isc_sockaddr_fromin6([i], >sin6_addr,
-dstport);
+dstport, sin6->sin6_scope_id);
}
i++;
  
@@ -972,7 +972,7 @@ parse_netprefix(struct sockaddr_storage
  
  	if (inet_pton(AF_INET6, buf, ) == 1) {

parsed = 1;
-   isc_sockaddr_fromin6(sa, , 0);
+   isc_sockaddr_fromin6(sa, , 0, 0);
if (prefix_length > 128)
prefix_length = 128;
} else if (inet_pton(AF_INET, buf, ) == 1) {
Index: lib/isc/sockaddr.c
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/sockaddr.c,v
retrieving revision 1.14
diff -u -p -r1.14 sockaddr.c
--- lib/isc/sockaddr.c  28 Nov 2020 06:33:55 -  1.14
+++ lib/isc/sockaddr.c  17 Dec 2020 11:06:49 -
@@ -223,7 +223,7 @@ isc_sockaddr_anyofpf(struct sockaddr_sto
  
  void

  isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-in_port_t port)
+in_port_t port, uint32_t scope)
  {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sockaddr;
memset(sockaddr, 0, sizeof(*sockaddr));
@@ -231,6 +231,7 @@ isc_sockaddr_fromin6(struct sockaddr_sto
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_addr = *ina6;
sin6->sin6_port = htons(port);
+   sin6->sin6_scope_id = scope;
  }
  
  int

Index: lib/isc/include/isc/sockaddr.h
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/include/isc/sockaddr.h,v
retrieving revision 1.7
diff -u -p -r1.7 sockaddr.h
--- lib/isc/include/isc/sockaddr.h  15 Sep 2020 11:47:42 -  1.7
+++ lib/isc/include/isc/sockaddr.h  17 Dec 2020 11:06:49 -
@@ -91,7 +91,7 @@ isc_sockaddr_fromin(struct sockaddr_stor
  
  void

  isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-in_port_t port);
+in_port_t port, uint32_t scope);
  /*%<
   * Construct an struct sockaddr_storage from an IPv6 address and port.
   */
Index: lib/lwres/lwconfig.c
===
RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
retrieving revision 1.6
diff -u -p -r1.6 lwconfig.c
--- lib/lwres/lwconfig.c25 Feb 2020 05:00:43 -  1.6
+++ lib/lwres/lwconfig.c17 Dec 2020 11:06:49 -
@@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t
  
  	res = lwres_create_addr(word, , 1);

use_ipv4 = confdata->flags & LWRES_USEIPV4;
-   use_ipv6 = confdata->flags & LWRES_USEIPV4;
+   use_ipv6 = confdata->flags & LWRES_USEIPV6;
if (res == LWRES_R_SUCCESS &&
((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
(address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {



Hi Otto,

I just gave this diff a go and everything seems to be working fine. Dig 
is now using the proper DNS set in my resolv.conf:


$ ./dig openbsd.org

; <<>> dig 9.10.8-P1 <<>> openbsd.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3506
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT 

dig vs ipv6 (scoped) addresses

2020-12-17 Thread Otto Moerbeek
Hi,

as noted on misc dig does not like to talk to local link addresses.
This fixes that case. While investigating I also found another bug:
selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
command line argument does not work as expected.

This fixes both. I did not test binding to a src address with this.
This is likely as broken as it was before.

-Otto

Index: dig.c
===
RCS file: /cvs/src/usr.bin/dig/dig.c,v
retrieving revision 1.18
diff -u -p -r1.18 dig.c
--- dig.c   15 Sep 2020 11:47:42 -  1.18
+++ dig.c   17 Dec 2020 11:06:49 -
@@ -1358,7 +1358,7 @@ dash_option(char *option, char *next, di
} else
srcport = 0;
if (have_ipv6 && inet_pton(AF_INET6, value, ) == 1)
-   isc_sockaddr_fromin6(_address, , srcport);
+   isc_sockaddr_fromin6(_address, , srcport, 0);
else if (have_ipv4 && inet_pton(AF_INET, value, ) == 1)
isc_sockaddr_fromin(_address, , srcport);
else
Index: dighost.c
===
RCS file: /cvs/src/usr.bin/dig/dighost.c,v
retrieving revision 1.34
diff -u -p -r1.34 dighost.c
--- dighost.c   15 Sep 2020 11:47:42 -  1.34
+++ dighost.c   17 Dec 2020 11:06:49 -
@@ -540,7 +540,7 @@ get_addresses(const char *hostname, in_p
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
isc_sockaddr_fromin6([i], >sin6_addr,
-dstport);
+dstport, sin6->sin6_scope_id);
}
i++;
 
@@ -972,7 +972,7 @@ parse_netprefix(struct sockaddr_storage 
 
if (inet_pton(AF_INET6, buf, ) == 1) {
parsed = 1;
-   isc_sockaddr_fromin6(sa, , 0);
+   isc_sockaddr_fromin6(sa, , 0, 0);
if (prefix_length > 128)
prefix_length = 128;
} else if (inet_pton(AF_INET, buf, ) == 1) {
Index: lib/isc/sockaddr.c
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/sockaddr.c,v
retrieving revision 1.14
diff -u -p -r1.14 sockaddr.c
--- lib/isc/sockaddr.c  28 Nov 2020 06:33:55 -  1.14
+++ lib/isc/sockaddr.c  17 Dec 2020 11:06:49 -
@@ -223,7 +223,7 @@ isc_sockaddr_anyofpf(struct sockaddr_sto
 
 void
 isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-in_port_t port)
+in_port_t port, uint32_t scope)
 {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sockaddr;
memset(sockaddr, 0, sizeof(*sockaddr));
@@ -231,6 +231,7 @@ isc_sockaddr_fromin6(struct sockaddr_sto
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_addr = *ina6;
sin6->sin6_port = htons(port);
+   sin6->sin6_scope_id = scope;
 }
 
 int
Index: lib/isc/include/isc/sockaddr.h
===
RCS file: /cvs/src/usr.bin/dig/lib/isc/include/isc/sockaddr.h,v
retrieving revision 1.7
diff -u -p -r1.7 sockaddr.h
--- lib/isc/include/isc/sockaddr.h  15 Sep 2020 11:47:42 -  1.7
+++ lib/isc/include/isc/sockaddr.h  17 Dec 2020 11:06:49 -
@@ -91,7 +91,7 @@ isc_sockaddr_fromin(struct sockaddr_stor
 
 void
 isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-in_port_t port);
+in_port_t port, uint32_t scope);
 /*%<
  * Construct an struct sockaddr_storage from an IPv6 address and port.
  */
Index: lib/lwres/lwconfig.c
===
RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
retrieving revision 1.6
diff -u -p -r1.6 lwconfig.c
--- lib/lwres/lwconfig.c25 Feb 2020 05:00:43 -  1.6
+++ lib/lwres/lwconfig.c17 Dec 2020 11:06:49 -
@@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t 
 
res = lwres_create_addr(word, , 1);
use_ipv4 = confdata->flags & LWRES_USEIPV4;
-   use_ipv6 = confdata->flags & LWRES_USEIPV4;
+   use_ipv6 = confdata->flags & LWRES_USEIPV6;
if (res == LWRES_R_SUCCESS &&
((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
(address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {