On Sat, Jul 07, 2012 at 12:47:32PM +0200, Peter Hessler wrote:
> ressurecting an old patch.
> 
> OK from me, anyone else?

With my sysadmin-deplying-IPv6-at-my-dayjob hat, I'd love to see that
go in, but I can't test it before next week. 

I only had a quick glance at the code (never looked at rtadvd source
code before), didn't spot anything dubious...
> 
> 
> ----- Forwarded message from "Stephane A. Sezer" <s...@cd80.net> -----
> 
> Date: Thu, 23 Feb 2012 21:18:30 -0800
> From: "Stephane A. Sezer" <s...@cd80.net>
> To: tech@openbsd.org
> Subject: Re: rtadvd(8) patch 2/2 : finalize server-side RFC 6106 support
> List-ID: <tech.openbsd.org>
> X-Loop: tech@openbsd.org
> 
> On Fri, 27 Jan 2012 15:20:29 +0100
> "Stephane A. Sezer" <s...@cd80.net> wrote:
> 
> > Hello again tech@,
> > 
> > Here's also the updated version of a patch I wrote approx. one year ago
> > to support RFC 6106 in rtadvd(8). J.R. Oldroyd told me there was a bug
> > in the generation of the DNS search list and that the format of the
> > packets generated was not valid.
> > 
> > I fixed that, so here is the patch.
> > 
> > Regards,
> 
> Same thing here: updated patch that applies correctly on -current.
> 
> -- 
> Stephane A. Sezer
> 
> 
> Index: sys/netinet/icmp6.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/icmp6.h,v
> retrieving revision 1.33
> diff -u sys/netinet/icmp6.h
> --- sys/netinet/icmp6.h       22 Mar 2010 12:23:32 -0000      1.33
> +++ sys/netinet/icmp6.h       22 Feb 2012 03:52:17 -0000
> @@ -282,6 +282,8 @@
>  #define ND_OPT_PREFIX_INFORMATION    3
>  #define ND_OPT_REDIRECTED_HEADER     4
>  #define ND_OPT_MTU                   5
> +#define ND_OPT_RDNSS                 25
> +#define ND_OPT_DNSSL                 31
>  
>  struct nd_opt_prefix_info {  /* prefix information */
>       u_int8_t        nd_opt_pi_type;
> @@ -310,6 +312,22 @@
>       u_int8_t        nd_opt_mtu_len;
>       u_int16_t       nd_opt_mtu_reserved;
>       u_int32_t       nd_opt_mtu_mtu;
> +} __packed;
> +
> +struct nd_opt_rdnss {                /* RDNSS option */
> +     u_int8_t        nd_opt_rdnss_type;
> +     u_int8_t        nd_opt_rdnss_len;
> +     u_int16_t       nd_opt_rdnss_reserved;
> +     u_int32_t       nd_opt_rdnss_lifetime;
> +     /* followed by list of recursive DNS servers */
> +} __packed;
> +
> +struct nd_opt_dnssl {                /* DNSSL option */
> +     u_int8_t        nd_opt_dnssl_type;
> +     u_int8_t        nd_opt_dnssl_len;
> +     u_int16_t       nd_opt_dnssl_reserved;
> +     u_int32_t       nd_opt_dnssl_lifetime;
> +     /* followed by list of DNS search domains */
>  } __packed;
>  
>  /*
> Index: usr.sbin/rtadvd/config.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/config.c,v
> retrieving revision 1.26
> diff -u usr.sbin/rtadvd/config.c
> --- usr.sbin/rtadvd/config.c  23 Apr 2008 10:17:50 -0000      1.26
> +++ usr.sbin/rtadvd/config.c  22 Feb 2012 03:52:25 -0000
> @@ -109,6 +109,8 @@
>               fatal("malloc");
>  
>       TAILQ_INIT(&tmp->prefixes);
> +     TAILQ_INIT(&tmp->rdnsss);
> +     TAILQ_INIT(&tmp->dnssls);
>       SLIST_INIT(&tmp->soliciters);
>  
>       /* check if we are allowed to forward packets (if not determined) */
> @@ -323,6 +325,106 @@
>       if (tmp->pfxs == 0)
>               get_prefix(tmp);
>  
> +     tmp->rdnsscnt = 0;
> +     for (i = -1; i < MAXRDNSS; ++i) {
> +             struct rdnss *rds;
> +             char entbuf[256];
> +             char *tmpaddr;
> +
> +             makeentry(entbuf, sizeof(entbuf), i, "rdnss");
> +             addr = agetstr(entbuf, &bp);
> +             if (addr == NULL)
> +                     continue;
> +
> +             /* servers are separated by commas in the config file */
> +             val = 1;
> +             tmpaddr = addr;
> +             while (*tmpaddr++)
> +                     if (*tmpaddr == ',')
> +                             ++val;
> +
> +             rds = malloc(sizeof(struct rdnss) + val * sizeof(struct 
> in6_addr));
> +             if (rds == NULL)
> +                     fatal("malloc");
> +
> +             TAILQ_INSERT_TAIL(&tmp->rdnsss, rds, entry);
> +             tmp->rdnsscnt++;
> +
> +             rds->servercnt = val;
> +
> +             makeentry(entbuf, sizeof(entbuf), i, "rdnssltime");
> +             MAYHAVE(val, entbuf, (tmp->maxinterval * 3) / 2);
> +             if (val < tmp->maxinterval || val > tmp->maxinterval * 2) {
> +                     log_warnx("%s (%ld) on %s is invalid "
> +                         "(should be between %d and %d)",
> +                         entbuf, val, intface, tmp->maxinterval,
> +                         tmp->maxinterval * 2);
> +             }
> +             rds->lifetime = val;
> +
> +             val = 0;
> +             while ((tmpaddr = strsep(&addr, ","))) {
> +                     if (inet_pton(AF_INET6, tmpaddr, &rds->servers[val]) != 
> 1) {
> +                             log_warn("inet_pton failed for %s", tmpaddr);
> +                             exit(1);
> +                     }
> +                     val++;
> +             }
> +     }
> +
> +     tmp->dnsslcnt = 0;
> +     for (i = -1; i < MAXDNSSL; ++i) {
> +             struct dnssl *dsl;
> +             char entbuf[256];
> +             char *tmpsl;
> +
> +             makeentry(entbuf, sizeof(entbuf), i, "dnssl");
> +             addr = agetstr(entbuf, &bp);
> +             if (addr == NULL)
> +                     continue;
> +
> +             dsl = malloc(sizeof(struct dnssl));
> +             if (dsl == NULL)
> +                     fatal("malloc");
> +
> +             TAILQ_INIT(&dsl->dnssldoms);
> +
> +             while ((tmpsl = strsep(&addr, ","))) {
> +                     struct dnssldom *dnsd;
> +                     ssize_t len;
> +
> +                     len = strlen(tmpsl);
> +
> +                     /* if the domain is not "dot-terminated", add it */
> +                     if (tmpsl[len - 1] != '.')
> +                             len += 1;
> +
> +                     dnsd = malloc(sizeof(struct dnssldom) + len + 1);
> +                     if (dnsd == NULL)
> +                             fatal("malloc");
> +
> +                     dnsd->length = len;
> +                     strlcpy(dnsd->domain, tmpsl, len + 1);
> +                     dnsd->domain[len - 1] = '.';
> +                     dnsd->domain[len] = '\0';
> +
> +                     TAILQ_INSERT_TAIL(&dsl->dnssldoms, dnsd, entry);
> +             }
> +
> +             TAILQ_INSERT_TAIL(&tmp->dnssls, dsl, entry);
> +             tmp->dnsslcnt++;
> +
> +             makeentry(entbuf, sizeof(entbuf), i, "dnsslltime");
> +             MAYHAVE(val, entbuf, (tmp->maxinterval * 3) / 2);
> +             if (val < tmp->maxinterval || val > tmp->maxinterval * 2) {
> +                     log_warnx("%s (%ld) on %s is invalid "
> +                         "(should be between %d and %d)",
> +                         entbuf, val, intface, tmp->maxinterval,
> +                         tmp->maxinterval * 2);
> +             }
> +             dsl->lifetime = val;
> +     }
> +
>       MAYHAVE(val, "mtu", 0);
>       if (val < 0 || val > 0xffffffff) {
>               log_warnx("mtu (%ld) on %s out of range", val, intface);
> @@ -596,7 +698,12 @@
>       struct nd_router_advert *ra;
>       struct nd_opt_prefix_info *ndopt_pi;
>       struct nd_opt_mtu *ndopt_mtu;
> +     struct nd_opt_rdnss *ndopt_rdnss;
> +     struct nd_opt_dnssl *ndopt_dnssl;
>       struct prefix *pfx;
> +     struct rdnss *rds;
> +     struct dnssl *dsl;
> +     struct dnssldom *dnsd;
>  
>       /* calculate total length */
>       packlen = sizeof(struct nd_router_advert);
> @@ -613,7 +720,21 @@
>               packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
>       if (rainfo->linkmtu)
>               packlen += sizeof(struct nd_opt_mtu);
> +     TAILQ_FOREACH(rds, &rainfo->rdnsss, entry)
> +             packlen += sizeof(struct nd_opt_rdnss) + 16 * rds->servercnt;
> +     TAILQ_FOREACH(dsl, &rainfo->dnssls, entry) {
> +             size_t domains_size = 0;
>  
> +             packlen += sizeof(struct nd_opt_dnssl);
> +
> +             TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry)
> +                     domains_size += dnsd->length;
> +
> +             domains_size = (domains_size + 7) & ~7;
> +
> +             packlen += domains_size;
> +     }
> +
>       /* allocate memory for the packet */
>       if ((buf = malloc(packlen)) == NULL)
>               fatal("malloc");
> @@ -705,6 +826,62 @@
>               ndopt_pi->nd_opt_pi_prefix = pfx->prefix;
>  
>               buf += sizeof(struct nd_opt_prefix_info);
> +     }
> +
> +     TAILQ_FOREACH(rds, &rainfo->rdnsss, entry) {
> +             ndopt_rdnss = (struct nd_opt_rdnss *)buf;
> +             ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS;
> +             ndopt_rdnss->nd_opt_rdnss_len = 1 + rds->servercnt * 2;
> +             ndopt_rdnss->nd_opt_rdnss_reserved = 0;
> +             ndopt_rdnss->nd_opt_rdnss_lifetime = htonl(rds->lifetime);
> +
> +             buf += sizeof(struct nd_opt_rdnss);
> +
> +             memcpy(buf, rds->servers, rds->servercnt * 16);
> +             buf += rds->servercnt * 16;
> +     }
> +
> +     TAILQ_FOREACH(dsl, &rainfo->dnssls, entry) {
> +             u_int32_t size;
> +             char *curlabel_begin;
> +             char *curlabel_end;
> +
> +             ndopt_dnssl = (struct nd_opt_dnssl *)buf;
> +             ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL;
> +             ndopt_dnssl->nd_opt_dnssl_reserved = 0;
> +             ndopt_dnssl->nd_opt_dnssl_lifetime = htonl(dsl->lifetime);
> +
> +             size = 0;
> +             TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry)
> +                     size += dnsd->length;
> +             /* align size on the next 8 byte boundary */
> +             size = (size + 7) & ~7;
> +             ndopt_dnssl->nd_opt_dnssl_len = 1 + size / 8;
> +
> +             buf += sizeof(struct nd_opt_dnssl);
> +
> +             TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry) {
> +                     curlabel_begin = dnsd->domain;
> +                     while ((curlabel_end = strchr(curlabel_begin, '.')) &&
> +                         (curlabel_end - curlabel_begin) > 1)
> +                     {
> +                             size_t curlabel_size;
> +
> +                             curlabel_size = curlabel_end - curlabel_begin;
> +                             *buf = curlabel_size;
> +                             ++buf;
> +                             strncpy(buf, curlabel_begin, curlabel_size);
> +                             buf += curlabel_size;
> +                             curlabel_begin = curlabel_end + 1;
> +                     }
> +
> +                     /* null-terminate the current domain */
> +                     *buf++ = '\0';
> +             }
> +
> +             /* zero out the end of the current option */
> +             while ((int)buf % 8 != 0)
> +                     *buf++ = '\0';
>       }
>  
>       return;
> Index: usr.sbin/rtadvd/config.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/config.h,v
> retrieving revision 1.6
> diff -u usr.sbin/rtadvd/config.h
> --- usr.sbin/rtadvd/config.h  18 Jun 2003 02:26:58 -0000      1.6
> +++ usr.sbin/rtadvd/config.h  22 Feb 2012 03:52:25 -0000
> @@ -38,7 +38,9 @@
>  
>  
>  /*
> - * it is highly unlikely to have 100 prefix information options,
> + * it is highly unlikely to have 100 prefix, rdnss or dnssl information 
> options,
>   * so it should be okay to limit it
>   */
>  #define MAXPREFIX    100
> +#define MAXRDNSS     100
> +#define MAXDNSSL     100
> Index: usr.sbin/rtadvd/dump.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/dump.c,v
> retrieving revision 1.10
> diff -u usr.sbin/rtadvd/dump.c
> --- usr.sbin/rtadvd/dump.c    21 Jul 2008 19:14:15 -0000      1.10
> +++ usr.sbin/rtadvd/dump.c    22 Feb 2012 03:52:25 -0000
> @@ -103,6 +103,9 @@
>  {
>       struct rainfo *rai;
>       struct prefix *pfx;
> +     struct rdnss *rds;
> +     struct dnssl *dsl;
> +     struct dnssldom *dnsd;
>       char prefixbuf[INET6_ADDRSTRLEN];
>       int first;
>       struct timeval now;
> @@ -212,6 +215,29 @@
>                       free(vltime);
>                       free(pltime);
>                       free(flags);
> +             }
> +
> +             if (!TAILQ_EMPTY(&rai->rdnsss))
> +                     log_info("  Recursive DNS servers:");
> +             TAILQ_FOREACH(rds, &rai->rdnsss, entry) {
> +                     log_info("    Servers:");
> +                     for (first = 0; first < rds->servercnt; ++first) {
> +                             inet_ntop(AF_INET6, &rds->servers[first],
> +                                 prefixbuf, sizeof(prefixbuf));
> +                             log_info("      %s", prefixbuf);
> +                     }
> +                     log_info("    Lifetime: %u", rds->lifetime);
> +             }
> +
> +             if (!TAILQ_EMPTY(&rai->dnssls))
> +                     log_info("  DNS search lists:");
> +             TAILQ_FOREACH(dsl, &rai->dnssls, entry) {
> +                     log_info("    Domains:");
> +
> +                     TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry)
> +                             log_info("      %s", dnsd->domain);
> +
> +                     log_info("    Lifetime: %u", dsl->lifetime);
>               }
>       }
>  }
> Index: usr.sbin/rtadvd/rtadvd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.c,v
> retrieving revision 1.39
> diff -u usr.sbin/rtadvd/rtadvd.c
> --- usr.sbin/rtadvd/rtadvd.c  2 Mar 2011 17:30:48 -0000       1.39
> +++ usr.sbin/rtadvd/rtadvd.c  22 Feb 2012 03:52:26 -0000
> @@ -114,15 +114,22 @@
>  #define nd_opts_mtu          nd_opt_each.mtu
>  #define nd_opts_list         nd_opt_each.list
>  
> -#define NDOPT_FLAG_SRCLINKADDR 0x1
> -#define NDOPT_FLAG_TGTLINKADDR 0x2
> -#define NDOPT_FLAG_PREFIXINFO 0x4
> -#define NDOPT_FLAG_RDHDR 0x8
> -#define NDOPT_FLAG_MTU 0x10
> +#define NDOPT_FLAG_SRCLINKADDR       (1 << 0)
> +#define NDOPT_FLAG_TGTLINKADDR       (1 << 1)
> +#define NDOPT_FLAG_PREFIXINFO        (1 << 2)
> +#define NDOPT_FLAG_RDHDR     (1 << 3)
> +#define NDOPT_FLAG_MTU               (1 << 4)
> +#define NDOPT_FLAG_RDNSS     (1 << 5)
> +#define NDOPT_FLAG_DNSSL     (1 << 6)
>  
>  u_int32_t ndopt_flags[] = {
> -     0, NDOPT_FLAG_SRCLINKADDR, NDOPT_FLAG_TGTLINKADDR,
> -     NDOPT_FLAG_PREFIXINFO, NDOPT_FLAG_RDHDR, NDOPT_FLAG_MTU,
> +     [ND_OPT_SOURCE_LINKADDR]        = NDOPT_FLAG_SRCLINKADDR,
> +     [ND_OPT_TARGET_LINKADDR]        = NDOPT_FLAG_TGTLINKADDR,
> +     [ND_OPT_PREFIX_INFORMATION]     = NDOPT_FLAG_PREFIXINFO,
> +     [ND_OPT_REDIRECTED_HEADER]      = NDOPT_FLAG_RDHDR,
> +     [ND_OPT_MTU]                    = NDOPT_FLAG_MTU,
> +     [ND_OPT_RDNSS]                  = NDOPT_FLAG_RDNSS,
> +     [ND_OPT_DNSSL]                  = NDOPT_FLAG_DNSSL,
>  };
>  
>  int main(int, char *[]);
> @@ -804,8 +811,8 @@
>       SLIST_INIT(&ndopts.nd_opts_list);
>       if (nd6_options((struct nd_opt_hdr *)(ra + 1),
>                       len - sizeof(struct nd_router_advert),
> -                     &ndopts, NDOPT_FLAG_SRCLINKADDR |
> -                     NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU)) {
> +                     &ndopts, NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO
> +                     | NDOPT_FLAG_MTU | NDOPT_FLAG_RDNSS | 
> NDOPT_FLAG_DNSSL)) {
>               log_warnx("ND option check failed for an RA from %s on %s",
>                   inet_ntop(AF_INET6, &from->sin6_addr,
>                       ntopbuf, INET6_ADDRSTRLEN),
> @@ -1104,7 +1111,9 @@
>                       goto bad;
>               }
>  
> -             if (hdr->nd_opt_type > ND_OPT_MTU)
> +             if (hdr->nd_opt_type > ND_OPT_MTU &&
> +                 hdr->nd_opt_type != ND_OPT_RDNSS &&
> +                 hdr->nd_opt_type != ND_OPT_DNSSL)
>               {
>                       log_info("unknown ND option(type %d)",
>                           hdr->nd_opt_type);
> @@ -1121,7 +1130,10 @@
>                * Option length check.  Do it here for all fixed-length
>                * options.
>                */
> -             if ((hdr->nd_opt_type == ND_OPT_MTU &&
> +             if ((hdr->nd_opt_type == ND_OPT_RDNSS && (optlen < 24 ||
> +                 ((optlen - sizeof(struct nd_opt_rdnss)) % 16 != 0))) ||
> +                 (hdr->nd_opt_type == ND_OPT_DNSSL && optlen < 16) ||
> +                 (hdr->nd_opt_type == ND_OPT_MTU &&
>                   (optlen != sizeof(struct nd_opt_mtu))) ||
>                   ((hdr->nd_opt_type == ND_OPT_PREFIX_INFORMATION &&
>                   optlen != sizeof(struct nd_opt_prefix_info)))) {
> @@ -1133,6 +1145,8 @@
>               case ND_OPT_SOURCE_LINKADDR:
>               case ND_OPT_TARGET_LINKADDR:
>               case ND_OPT_REDIRECTED_HEADER:
> +             case ND_OPT_RDNSS:
> +             case ND_OPT_DNSSL:
>                       break;  /* we don't care about these options */
>               case ND_OPT_MTU:
>                       if (ndopts->nd_opt_array[hdr->nd_opt_type]) {
> @@ -1154,7 +1168,7 @@
>                               log_warn("malloc");
>                               goto bad;
>                       }
> -                     
> +
>                       pfx->opt = hdr;
>                       SLIST_INSERT_HEAD(&ndopts->nd_opts_list, pfx, entry);
>  
> Index: usr.sbin/rtadvd/rtadvd.conf
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.conf,v
> retrieving revision 1.6
> diff -u usr.sbin/rtadvd/rtadvd.conf
> --- usr.sbin/rtadvd/rtadvd.conf       19 Jul 2008 10:35:31 -0000      1.6
> +++ usr.sbin/rtadvd/rtadvd.conf       22 Feb 2012 03:52:26 -0000
> @@ -18,4 +18,5 @@
>  #   this part by hand, and then invoke rtadvd with the -s option.
>   
>  #ef0:\
> -#    :addr="2001:db8:ffff:1000::":prefixlen#64:
> +#    :addr="2001:db8:ffff:1000::":prefixlen#64:\
> +#    :rdnss="2001:db8:ffff:1000::1":dnssl="example.com":
> Index: usr.sbin/rtadvd/rtadvd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.conf.5,v
> retrieving revision 1.25
> diff -u usr.sbin/rtadvd/rtadvd.conf.5
> --- usr.sbin/rtadvd/rtadvd.conf.5     19 Sep 2010 21:59:23 -0000      1.25
> +++ usr.sbin/rtadvd/rtadvd.conf.5     22 Feb 2012 03:52:26 -0000
> @@ -216,6 +216,30 @@
>  will be set to the interface MTU automatically.
>  .El
>  .Pp
> +The following items are for ICMPv6 RDNSS option, used to give a list of
> +recursive DNS servers to hosts. If this item is omitted, no information
> +about DNS servers will be advertised.
> +.Bl -tag -width indent
> +.It Cm \&rdnss
> +(str) The list of advertised recursive DNS servers, separated by commas.
> +.It Cm \&rdnssltime
> +(num) Validity of the list of DNS servers
> +.Pq unit: seconds .
> +The default value is 1.5 * the value of maxinterval.
> +.El
> +.Pp
> +The following items are used for ICMPv6 DNSSL option which specifies a
> +list of DNS suffixes advertised to hosts. If this option is not
> +specified, not DNS suffix will be sent to hosts.
> +.Bl -tag -width indent
> +.It Cm \&dnssl
> +(str) The list of advertised DNS suffixes, separated by commas.
> +.It Cm \&dnsslltime
> +(num) Validity of the list of DNS suffixes
> +.Pq unit: seconds .
> +The default value is 1.5 * the value of maxinterval.
> +.El
> +.Pp
>  The following item controls ICMPv6 source link-layer address option,
>  which will be attached to router advertisement header.
>  As noted above, you can just omit the item, then
> @@ -272,6 +296,18 @@
>  .Bd -literal -offset indent
>  ef0:\e
>       :addr="2001:db8:ffff:1000::":prefixlen#64:
> +.Ed
> +.Pp
> +The following example configures two recursive DNS servers for the
> +.Li em0
> +interface and sets the DNS search suffix to
> +.Do
> +example.com
> +.Dc .
> +.Bd -literal -offset indent
> +em0:\e
> +     :rdnss="2001:db8:ffff:1000::1,2001:db8:ffff:1000::2":\e
> +     :dnssl="example.com":
>  .Ed
>  .Pp
>  The following example presents the default values in an explicit manner.
> Index: usr.sbin/rtadvd/rtadvd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.h,v
> retrieving revision 1.11
> diff -u usr.sbin/rtadvd/rtadvd.h
> --- usr.sbin/rtadvd/rtadvd.h  9 Jun 2008 22:53:24 -0000       1.11
> +++ usr.sbin/rtadvd/rtadvd.h  22 Feb 2012 03:52:26 -0000
> @@ -82,7 +82,28 @@
>       struct in6_addr prefix;
>  };
>  
> +struct rdnss {
> +     TAILQ_ENTRY(rdnss) entry;
>  
> +     u_int32_t lifetime;
> +     int servercnt;
> +     struct in6_addr servers[];
> +};
> +
> +struct dnssldom {
> +     TAILQ_ENTRY(dnssldom) entry;
> +
> +     u_int32_t length;
> +     char domain[];
> +};
> +
> +struct dnssl {
> +     TAILQ_ENTRY(dnssl) entry;
> +
> +     u_int32_t lifetime;
> +     TAILQ_HEAD(dnssldomlist, dnssldom) dnssldoms;
> +};
> +
>  struct soliciter {
>       SLIST_ENTRY(soliciter) entry;
>       struct sockaddr_in6 addr;
> @@ -118,6 +139,10 @@
>       u_int   hoplimit;       /* AdvCurHopLimit */
>       TAILQ_HEAD(prefixlist, prefix) prefixes; /* AdvPrefixList(link head) */
>       int     pfxs;           /* number of prefixes */
> +     TAILQ_HEAD(rdnsslist, rdnss) rdnsss; /* advertised recursive dns 
> servers */
> +     int     rdnsscnt;       /* number of rdnss entries */
> +     TAILQ_HEAD(dnssllist, dnssl) dnssls;
> +     int     dnsslcnt;
>       long    clockskew;      /* used for consisitency check of lifetimes */
> 
> 
> ----- End forwarded message -----
> 
> -- 
> Blood flows down one leg and up the other.
> 

-- 
Matthieu Herrb

Reply via email to