This has been committed, many thanks for the diffs and sorry for the delay.


On 2012 Feb 23 (Thu) at 21:18:30 -0800 (-0800), Stephane A. Sezer wrote:
: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 */
:

-- 
[Crash programs] fail because they are based on the theory that, with
nine women pregnant, you can get a baby a month.
                -- Wernher von Braun

Reply via email to