~ubuntu-branches/ubuntu/utopic/wide-dhcpv6/utopic

« back to all changes in this revision

Viewing changes to common.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeremie Corbier
  • Date: 2006-09-20 14:36:12 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920143612-0su164vhla1o01qr
Tags: 20060902-1
* New upstream release.
* debian/wide-dhcpv6-*.init.d:
  -> LSB compliant init scripts.
* debian/patches:
  -> Added 02_CVS-20060920.dpatch:
    + Update to CVS 20060920.
    + Fix a memory violation in lease management.
    + Fix a bug that dhcp6s inserts SIP server addresses into DNS server
      address option.
    + Fix a bug that status-code option might include a unexpected garbage
      value.
    + Fix dhcp6s documentation: you need to provide a preferred-lifetime for
      each address-prefix (Closes: #387416).
  -> Removed 02_remove-if-USE_POOL-macros.dpatch
  -> Removed 03_pid_dump.dpatch
  -> Removed 07_cftoken.l-bison.dpatch
  -> Removed 08_support-include-statement.dpatch
     All merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
349
349
        return (memcmp(vb1->dv_buf, vb2->dv_buf, vb1->dv_len));
350
350
}
351
351
 
 
352
static int
 
353
dhcp6_get_addr(optlen, cp, type, list)
 
354
        int optlen;
 
355
        void *cp;
 
356
        dhcp6_listval_type_t type;
 
357
        struct dhcp6_list *list;
 
358
{
 
359
        void *val;
 
360
        int option;
 
361
 
 
362
        if (optlen % sizeof(struct in6_addr) || optlen == 0) {
 
363
                dprintf(LOG_INFO, FNAME,
 
364
                    "malformed DHCP option: type %d, len %d", type, optlen);
 
365
                return -1;
 
366
        }
 
367
        for (val = cp; val < cp + optlen; val += sizeof(struct in6_addr)) {
 
368
                struct in6_addr valaddr;
 
369
 
 
370
                memcpy(&valaddr, val, sizeof(valaddr));
 
371
                if (dhcp6_find_listval(list,
 
372
                    DHCP6_LISTVAL_ADDR6, &valaddr, 0)) {
 
373
                        dprintf(LOG_INFO, FNAME, "duplicated %s address (%s)",
 
374
                            dhcp6optstr(type), in6addr2str(&valaddr, 0));
 
375
                        continue;
 
376
                }
 
377
 
 
378
                if (dhcp6_add_listval(list, DHCP6_LISTVAL_ADDR6,
 
379
                    &valaddr, NULL) == NULL) {
 
380
                        dprintf(LOG_ERR, FNAME,
 
381
                            "failed to copy %s address", dhcp6optstr(type));
 
382
                        return -1;
 
383
                }
 
384
        }
 
385
 
 
386
        return 0;
 
387
}
 
388
 
 
389
static int
 
390
dhcp6_set_addr(type, list, p, optep, len)
 
391
        dhcp6_listval_type_t type;
 
392
        struct dhcp6_list *list;
 
393
        struct dhcp6opt **p, *optep;
 
394
        int *len;
 
395
{
 
396
        struct in6_addr *in6;
 
397
        char *tmpbuf;
 
398
        struct dhcp6_listval *d;
 
399
        int optlen;
 
400
 
 
401
        if (TAILQ_EMPTY(list))
 
402
                return 0;
 
403
 
 
404
        tmpbuf = NULL;
 
405
        optlen = dhcp6_count_list(list) * sizeof(struct in6_addr);
 
406
        if ((tmpbuf = malloc(optlen)) == NULL) {
 
407
                dprintf(LOG_ERR, FNAME,
 
408
                    "memory allocation failed for %s options",
 
409
                    dhcp6optstr(type));
 
410
                return -1;
 
411
        }
 
412
        in6 = (struct in6_addr *)tmpbuf;
 
413
        for (d = TAILQ_FIRST(list); d; d = TAILQ_NEXT(d, link), in6++)
 
414
                memcpy(in6, &d->val_addr6, sizeof(*in6));
 
415
        if (copy_option(type, optlen, tmpbuf, p, optep, len) != 0) {
 
416
                free(tmpbuf);
 
417
                return -1;
 
418
        }
 
419
 
 
420
        free(tmpbuf);
 
421
        return 0;
 
422
}
 
423
 
 
424
static int
 
425
dhcp6_get_domain(optlen, cp, type, list)
 
426
        int optlen;
 
427
        void *cp;
 
428
        dhcp6_listval_type_t type;
 
429
        struct dhcp6_list *list;
 
430
{
 
431
        void *val;
 
432
 
 
433
        val = cp;
 
434
        while (val < cp + optlen) {
 
435
                struct dhcp6_vbuf vb;
 
436
                char name[MAXDNAME + 1];
 
437
 
 
438
                if (dnsdecode((u_char **)(void *)&val,
 
439
                    (u_char *)(cp + optlen), name, sizeof(name)) == NULL) {
 
440
                        dprintf(LOG_INFO, FNAME, "failed to "
 
441
                            "decode a %s domain name",
 
442
                            dhcp6optstr(type));
 
443
                        dprintf(LOG_INFO, FNAME,
 
444
                            "malformed DHCP option: type %d, len %d",
 
445
                             type, optlen);
 
446
                        return -1;
 
447
                }
 
448
 
 
449
                vb.dv_len = strlen(name) + 1;
 
450
                vb.dv_buf = name;
 
451
 
 
452
                if (dhcp6_add_listval(list,
 
453
                    DHCP6_LISTVAL_VBUF, &vb, NULL) == NULL) {
 
454
                        dprintf(LOG_ERR, FNAME, "failed to "
 
455
                            "copy a %s domain name", dhcp6optstr(type));
 
456
                        return -1;
 
457
                }
 
458
        }
 
459
 
 
460
        return 0;
 
461
}
 
462
 
 
463
static int
 
464
dhcp6_set_domain(type, list, p, optep, len)
 
465
        dhcp6_listval_type_t type;
 
466
        struct dhcp6_list *list;
 
467
        struct dhcp6opt **p, *optep;
 
468
        int *len;
 
469
{
 
470
        int optlen = 0;
 
471
        struct dhcp6_listval *d;
 
472
        char *tmpbuf;
 
473
        char name[MAXDNAME], *cp, *ep;
 
474
 
 
475
        if (TAILQ_EMPTY(list))
 
476
                return 0;
 
477
 
 
478
        for (d = TAILQ_FIRST(list); d; d = TAILQ_NEXT(d, link))
 
479
                optlen += (d->val_vbuf.dv_len + 1);
 
480
 
 
481
        if (optlen == 0) {
 
482
                return 0;
 
483
        }
 
484
 
 
485
        tmpbuf = NULL;
 
486
        if ((tmpbuf = malloc(optlen)) == NULL) {
 
487
                dprintf(LOG_ERR, FNAME, "memory allocation failed for "
 
488
                    "%s domain options", dhcp6optstr(type));
 
489
                return -1;
 
490
        }
 
491
        cp = tmpbuf;
 
492
        ep = cp + optlen;
 
493
        for (d = TAILQ_FIRST(list); d; d = TAILQ_NEXT(d, link)) {
 
494
                int nlen;
 
495
 
 
496
                nlen = dnsencode((const char *)d->val_vbuf.dv_buf,
 
497
                    name, sizeof (name));
 
498
                if (nlen < 0) {
 
499
                        dprintf(LOG_ERR, FNAME,
 
500
                            "failed to encode a %s domain name",
 
501
                            dhcp6optstr(type));
 
502
                        free(tmpbuf);
 
503
                        return -1;
 
504
                }
 
505
                if (ep - cp < nlen) {
 
506
                        dprintf(LOG_ERR, FNAME,
 
507
                            "buffer length for %s domain name is too short",
 
508
                            dhcp6optstr(type));
 
509
                        free(tmpbuf);
 
510
                        return -1;
 
511
                }
 
512
                memcpy(cp, name, nlen);
 
513
                cp += nlen;
 
514
        }
 
515
        if (copy_option(type, optlen, tmpbuf, p, optep, len) != 0) {
 
516
                free(tmpbuf);
 
517
                return -1;
 
518
        }
 
519
        free(tmpbuf);
 
520
 
 
521
        return 0;
 
522
}
 
523
 
352
524
struct dhcp6_event *
353
525
dhcp6_create_event(ifp, state)
354
526
        struct dhcp6_if *ifp;
1001
1173
        TAILQ_INIT(&optinfo->dnsname_list);
1002
1174
        TAILQ_INIT(&optinfo->ntp_list);
1003
1175
        TAILQ_INIT(&optinfo->prefix_list);
 
1176
        TAILQ_INIT(&optinfo->nis_list);
 
1177
        TAILQ_INIT(&optinfo->nisname_list);
 
1178
        TAILQ_INIT(&optinfo->nisp_list);
 
1179
        TAILQ_INIT(&optinfo->nispname_list);
 
1180
        TAILQ_INIT(&optinfo->bcmcs_list);
 
1181
        TAILQ_INIT(&optinfo->bcmcsname_list);
1004
1182
 
1005
1183
        optinfo->authproto = DHCP6_AUTHPROTO_UNDEF;
1006
1184
        optinfo->authalgorithm = DHCP6_AUTHALG_UNDEF;
1032
1210
        dhcp6_clear_list(&optinfo->dnsname_list);
1033
1211
        dhcp6_clear_list(&optinfo->ntp_list);
1034
1212
        dhcp6_clear_list(&optinfo->prefix_list);
 
1213
        dhcp6_clear_list(&optinfo->nis_list);
 
1214
        dhcp6_clear_list(&optinfo->nisname_list);
 
1215
        dhcp6_clear_list(&optinfo->nisp_list);
 
1216
        dhcp6_clear_list(&optinfo->nispname_list);
 
1217
        dhcp6_clear_list(&optinfo->bcmcs_list);
 
1218
        dhcp6_clear_list(&optinfo->bcmcsname_list);
1035
1219
 
1036
1220
        if (optinfo->relaymsg_msg != NULL)
1037
1221
                free(optinfo->relaymsg_msg);
1072
1256
                goto fail;
1073
1257
        if (dhcp6_copy_list(&dst->prefix_list, &src->prefix_list))
1074
1258
                goto fail;
 
1259
        if (dhcp6_copy_list(&dst->nis_list, &src->nis_list))
 
1260
                goto fail;
 
1261
        if (dhcp6_copy_list(&dst->nisname_list, &src->nisname_list))
 
1262
                goto fail;
 
1263
        if (dhcp6_copy_list(&dst->nisp_list, &src->nisp_list))
 
1264
                goto fail;
 
1265
        if (dhcp6_copy_list(&dst->nispname_list, &src->nispname_list))
 
1266
                goto fail;
 
1267
        if (dhcp6_copy_list(&dst->bcmcs_list, &src->bcmcs_list))
 
1268
                goto fail;
 
1269
        if (dhcp6_copy_list(&dst->bcmcsname_list, &src->bcmcsname_list))
 
1270
                goto fail;
1075
1271
        dst->elapsed_time = src->elapsed_time;
1076
1272
        dst->refreshtime = src->refreshtime;
1077
1273
        dst->pref = src->pref;
1364
1560
                        optinfo->ifidopt_len = optlen;
1365
1561
                        break;
1366
1562
                case DH6OPT_SIP_SERVER_D:
1367
 
                        val = cp;
1368
 
                        while (val < cp + optlen) {
1369
 
                                struct dhcp6_vbuf vb;
1370
 
                                char name[MAXDNAME + 1];
1371
 
 
1372
 
                                if (dnsdecode((u_char **)(void *)&val,
1373
 
                                    (u_char *)(cp + optlen), name,
1374
 
                                    sizeof(name)) == NULL) {
1375
 
                                        dprintf(LOG_INFO, FNAME, "failed to "
1376
 
                                            "decode a SIP domain name");
1377
 
                                        goto malformed; /* or proceed? */
1378
 
                                }
1379
 
 
1380
 
                                vb.dv_len = strlen(name) + 1;
1381
 
                                vb.dv_buf = name;
1382
 
 
1383
 
                                if (dhcp6_add_listval(&optinfo->sipname_list,
1384
 
                                    DHCP6_LISTVAL_VBUF, &vb, NULL) == NULL) {
1385
 
                                        dprintf(LOG_ERR, FNAME, "failed to "
1386
 
                                            "copy a SIP domain name");
1387
 
                                        goto fail;
1388
 
                                }
1389
 
                        }
 
1563
                        if (dhcp6_get_domain(optlen, cp, opt,
 
1564
                            &optinfo->sipname_list) == -1)
 
1565
                                goto fail;
 
1566
                        break;
 
1567
                case DH6OPT_DNSNAME:
 
1568
                        if (dhcp6_get_domain(optlen, cp, opt,
 
1569
                            &optinfo->dnsname_list) == -1)
 
1570
                                goto fail;
 
1571
                        break;
 
1572
                case DH6OPT_NIS_DOMAIN_NAME:
 
1573
                        if (dhcp6_get_domain(optlen, cp, opt,
 
1574
                            &optinfo->nisname_list) == -1)
 
1575
                                goto fail;
 
1576
                        break;
 
1577
                case DH6OPT_NISP_DOMAIN_NAME:
 
1578
                        if (dhcp6_get_domain(optlen, cp, opt,
 
1579
                            &optinfo->nispname_list) == -1)
 
1580
                                goto fail;
 
1581
                        break;
 
1582
                case DH6OPT_BCMCS_SERVER_D:
 
1583
                        if (dhcp6_get_domain(optlen, cp, opt,
 
1584
                            &optinfo->bcmcsname_list) == -1)
 
1585
                                goto fail;
1390
1586
                        break;
1391
1587
                case DH6OPT_SIP_SERVER_A:
1392
 
                        if (optlen % sizeof(struct in6_addr) || optlen == 0)
1393
 
                                goto malformed;
1394
 
                        for (val = cp; val < cp + optlen;
1395
 
                             val += sizeof(struct in6_addr)) {
1396
 
                                memcpy(&valaddr, val, sizeof(valaddr));
1397
 
                                if (dhcp6_find_listval(&optinfo->sip_list,
1398
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, 0)) {
1399
 
                                        dprintf(LOG_INFO, FNAME, "duplicated "
1400
 
                                            "SIP server address (%s)",
1401
 
                                            in6addr2str(&valaddr, 0));
1402
 
                                        goto nextsip;
1403
 
                                }
1404
 
 
1405
 
                                if (dhcp6_add_listval(&optinfo->sip_list,
1406
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, NULL)
1407
 
                                    == NULL) {
1408
 
                                        dprintf(LOG_ERR, FNAME,
1409
 
                                            "failed to copy "
1410
 
                                            "SIP server address");
1411
 
                                        goto fail;
1412
 
                                }
1413
 
                          nextsip:
1414
 
                                ;
1415
 
                        }
 
1588
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1589
                            &optinfo->sip_list) == -1)
 
1590
                                goto fail;
1416
1591
                        break;
1417
1592
                case DH6OPT_DNS:
1418
 
                        if (optlen % sizeof(struct in6_addr) || optlen == 0)
1419
 
                                goto malformed;
1420
 
                        for (val = cp; val < cp + optlen;
1421
 
                             val += sizeof(struct in6_addr)) {
1422
 
                                memcpy(&valaddr, val, sizeof(valaddr));
1423
 
                                if (dhcp6_find_listval(&optinfo->dns_list,
1424
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, 0)) {
1425
 
                                        dprintf(LOG_INFO, FNAME, "duplicated "
1426
 
                                            "DNS address (%s)",
1427
 
                                            in6addr2str(&valaddr, 0));
1428
 
                                        goto nextdns;
1429
 
                                }
1430
 
 
1431
 
                                if (dhcp6_add_listval(&optinfo->dns_list,
1432
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, NULL)
1433
 
                                    == NULL) {
1434
 
                                        dprintf(LOG_ERR, FNAME,
1435
 
                                            "failed to copy DNS address");
1436
 
                                        goto fail;
1437
 
                                }
1438
 
                          nextdns:
1439
 
                                ;
1440
 
                        }
1441
 
                        break;
1442
 
                case DH6OPT_DNSNAME:
1443
 
                        val = cp;
1444
 
                        while (val < cp + optlen) {
1445
 
                                struct dhcp6_vbuf vb;
1446
 
                                char name[MAXDNAME + 1];
1447
 
 
1448
 
                                if (dnsdecode((u_char **)(void *)&val,
1449
 
                                    (u_char *)(cp + optlen), name,
1450
 
                                    sizeof(name)) == NULL) {
1451
 
                                        dprintf(LOG_INFO, FNAME, "failed to "
1452
 
                                            "decode a DNS name");
1453
 
                                        goto malformed; /* or proceed? */
1454
 
                                }
1455
 
 
1456
 
                                vb.dv_len = strlen(name) + 1;
1457
 
                                vb.dv_buf = name;
1458
 
 
1459
 
                                if (dhcp6_add_listval(&optinfo->dnsname_list,
1460
 
                                    DHCP6_LISTVAL_VBUF, &vb, NULL) == NULL) {
1461
 
                                        dprintf(LOG_ERR, FNAME, "failed to "
1462
 
                                            "copy a DNS name");
1463
 
                                        goto fail;
1464
 
                                }
1465
 
                        }
1466
 
                        break;
1467
 
#ifdef USE_DH6OPT_NTP
 
1593
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1594
                            &optinfo->dns_list) == -1)
 
1595
                                goto fail;
 
1596
                        break;
 
1597
                case DH6OPT_NIS_SERVERS:
 
1598
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1599
                            &optinfo->nis_list) == -1)
 
1600
                                goto fail;
 
1601
                        break;
 
1602
                case DH6OPT_NISP_SERVERS:
 
1603
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1604
                            &optinfo->nisp_list) == -1)
 
1605
                                goto fail;
 
1606
                        break;
 
1607
                case DH6OPT_BCMCS_SERVER_A:
 
1608
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1609
                            &optinfo->bcmcs_list) == -1)
 
1610
                                goto fail;
 
1611
                        break;
1468
1612
                case DH6OPT_NTP:
1469
 
                        if (optlen % sizeof(struct in6_addr) || optlen == 0)
1470
 
                                goto malformed;
1471
 
                        for (val = cp; val < cp + optlen;
1472
 
                             val += sizeof(struct in6_addr)) {
1473
 
                                memcpy(&valaddr, val, sizeof(valaddr));
1474
 
                                if (dhcp6_find_listval(&optinfo->ntp_list,
1475
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, 0)) {
1476
 
                                        dprintf(LOG_INFO, FNAME, "duplicated "
1477
 
                                            "NTP server address (%s)",
1478
 
                                            in6addr2str(&valaddr, 0));
1479
 
                                        goto nextntp;
1480
 
                                }
1481
 
 
1482
 
                                if (dhcp6_add_listval(&optinfo->ntp_list,
1483
 
                                    DHCP6_LISTVAL_ADDR6, &valaddr, NULL)
1484
 
                                    == NULL) {
1485
 
                                        dprintf(LOG_ERR, FNAME, "failed to "
1486
 
                                            "copy NTP server address");
1487
 
                                        goto fail;
1488
 
                                }
1489
 
                          nextntp:
1490
 
                                ;
1491
 
                        }
 
1613
                        if (dhcp6_get_addr(optlen, cp, opt,
 
1614
                            &optinfo->ntp_list) == -1)
 
1615
                                goto fail;
1492
1616
                        break;
1493
 
#endif
1494
1617
                case DH6OPT_IA_PD:
1495
1618
                        if (optlen + sizeof(struct dhcp6opt) <
1496
1619
                            sizeof(optia))
1529
1652
                        dhcp6_clear_list(&sublist);
1530
1653
 
1531
1654
                        break;
1532
 
#ifdef USE_DH6OPT_REFRESHTIME
1533
1655
                case DH6OPT_REFRESHTIME:
1534
1656
                        if (optlen != 4)
1535
1657
                                goto malformed;
1556
1678
                        } else
1557
1679
                                optinfo->refreshtime = (int64_t)val32;
1558
1680
                        break;
1559
 
#else
1560
 
                        val32 = val32; /* XXX deceive compiler */
1561
 
#endif
1562
1681
                case DH6OPT_IA_NA:
1563
1682
                        if (optlen + sizeof(struct dhcp6opt) <
1564
1683
                            sizeof(optia))
2095
2214
                free(tmpbuf);
2096
2215
        }
2097
2216
 
2098
 
        optlen = 0;
2099
 
        for (d = TAILQ_FIRST(&optinfo->sipname_list); d;
2100
 
            d = TAILQ_NEXT(d, link)) {
2101
 
                optlen += (d->val_vbuf.dv_len + 1);
2102
 
        }
2103
 
        if (optlen) {
2104
 
                char name[MAXDNAME], *cp, *ep;
2105
 
                tmpbuf = NULL;
2106
 
 
2107
 
                if ((tmpbuf = malloc(optlen)) == NULL) {
2108
 
                        dprintf(LOG_ERR, FNAME,
2109
 
                            "memory allocation failed for "
2110
 
                            "SIP server domain options");
2111
 
                        goto fail;
2112
 
                }
2113
 
                cp = tmpbuf;
2114
 
                ep = cp + optlen;
2115
 
                for (d = TAILQ_FIRST(&optinfo->sipname_list); d;
2116
 
                     d = TAILQ_NEXT(d, link)) {
2117
 
                        int nlen;
2118
 
 
2119
 
                        nlen = dnsencode((const char *)d->val_vbuf.dv_buf,
2120
 
                            name, sizeof (name));
2121
 
                        if (nlen < 0) {
2122
 
                                dprintf(LOG_ERR, FNAME,
2123
 
                                    "failed to encode a SIP server "
2124
 
                                    "domain name");
2125
 
                                goto fail;
2126
 
                        }
2127
 
                        if (ep - cp < nlen) {
2128
 
                                dprintf(LOG_ERR, FNAME,
2129
 
                                    "buffer length for SIP server "
2130
 
                                    "domain name is too short");
2131
 
                                goto fail;
2132
 
                        }
2133
 
                        memcpy(cp, name, nlen);
2134
 
                        cp += nlen;
2135
 
                }
2136
 
                if (copy_option(DH6OPT_SIP_SERVER_D, optlen, tmpbuf, &p,
2137
 
                    optep, &len) != 0) {
2138
 
                        goto fail;
2139
 
                }
2140
 
                free(tmpbuf);
2141
 
        }
2142
 
        if (!TAILQ_EMPTY(&optinfo->sip_list)) {
2143
 
                struct in6_addr *in6;
2144
 
 
2145
 
                tmpbuf = NULL;
2146
 
                optlen = dhcp6_count_list(&optinfo->sip_list) *
2147
 
                        sizeof(struct in6_addr);
2148
 
                if ((tmpbuf = malloc(optlen)) == NULL) {
2149
 
                        dprintf(LOG_ERR, FNAME,
2150
 
                            "memory allocation failed for SIP server options");
2151
 
                        goto fail;
2152
 
                }
2153
 
                in6 = (struct in6_addr *)tmpbuf;
2154
 
                for (d = TAILQ_FIRST(&optinfo->sip_list); d;
2155
 
                     d = TAILQ_NEXT(d, link), in6++) {
2156
 
                        memcpy(in6, &d->val_addr6, sizeof(*in6));
2157
 
                }
2158
 
                if (copy_option(DH6OPT_SIP_SERVER_A, optlen, tmpbuf, &p,
2159
 
                    optep, &len) != 0) {
2160
 
                        goto fail;
2161
 
                }
2162
 
                free(tmpbuf);
2163
 
        }
2164
 
 
2165
 
        if (!TAILQ_EMPTY(&optinfo->dns_list)) {
2166
 
                struct in6_addr *in6;
2167
 
 
2168
 
                tmpbuf = NULL;
2169
 
                optlen = dhcp6_count_list(&optinfo->dns_list) *
2170
 
                        sizeof(struct in6_addr);
2171
 
                if ((tmpbuf = malloc(optlen)) == NULL) {
2172
 
                        dprintf(LOG_ERR, FNAME,
2173
 
                            "memory allocation failed for DNS options");
2174
 
                        goto fail;
2175
 
                }
2176
 
                in6 = (struct in6_addr *)tmpbuf;
2177
 
                for (d = TAILQ_FIRST(&optinfo->dns_list); d;
2178
 
                     d = TAILQ_NEXT(d, link), in6++) {
2179
 
                        memcpy(in6, &d->val_addr6, sizeof(*in6));
2180
 
                }
2181
 
                if (copy_option(DH6OPT_DNS, optlen, tmpbuf, &p,
2182
 
                    optep, &len) != 0) {
2183
 
                        goto fail;
2184
 
                }
2185
 
                free(tmpbuf);
2186
 
        }
2187
 
 
2188
 
        optlen = 0;
2189
 
        for (d = TAILQ_FIRST(&optinfo->dnsname_list); d;
2190
 
            d = TAILQ_NEXT(d, link)) {
2191
 
                optlen += (d->val_vbuf.dv_len + 1);
2192
 
        }
2193
 
        if (optlen) {
2194
 
                char name[MAXDNAME], *cp, *ep;
2195
 
                tmpbuf = NULL;
2196
 
 
2197
 
                if ((tmpbuf = malloc(optlen)) == NULL) {
2198
 
                        dprintf(LOG_ERR, FNAME,
2199
 
                            "memory allocation failed for DNS name options");
2200
 
                        goto fail;
2201
 
                }
2202
 
                cp = tmpbuf;
2203
 
                ep = cp + optlen;
2204
 
                for (d = TAILQ_FIRST(&optinfo->dnsname_list); d;
2205
 
                     d = TAILQ_NEXT(d, link)) {
2206
 
                        int nlen;
2207
 
 
2208
 
                        nlen = dnsencode((const char *)d->val_vbuf.dv_buf,
2209
 
                            name, sizeof (name));
2210
 
                        if (nlen < 0) {
2211
 
                                dprintf(LOG_ERR, FNAME,
2212
 
                                    "failed to encode a DNS name");
2213
 
                                goto fail;
2214
 
                        }
2215
 
                        if (ep - cp < nlen) {
2216
 
                                dprintf(LOG_ERR, FNAME,
2217
 
                                    "buffer length for DNS name is too short");
2218
 
                                goto fail;
2219
 
                        }
2220
 
                        memcpy(cp, name, nlen);
2221
 
                        cp += nlen;
2222
 
                }
2223
 
                if (copy_option(DH6OPT_DNSNAME, optlen, tmpbuf, &p,
2224
 
                    optep, &len) != 0) {
2225
 
                        goto fail;
2226
 
                }
2227
 
                free(tmpbuf);
2228
 
        }
2229
 
 
2230
 
#ifdef USE_DH6OPT_NTP
2231
 
        if (!TAILQ_EMPTY(&optinfo->ntp_list)) {
2232
 
                struct in6_addr *in6;
2233
 
 
2234
 
                tmpbuf = NULL;
2235
 
                optlen = dhcp6_count_list(&optinfo->ntp_list) *
2236
 
                        sizeof(struct in6_addr);
2237
 
                if ((tmpbuf = malloc(optlen)) == NULL) {
2238
 
                        dprintf(LOG_ERR, FNAME,
2239
 
                            "memory allocation failed for NTP options");
2240
 
                        goto fail;
2241
 
                }
2242
 
                in6 = (struct in6_addr *)tmpbuf;
2243
 
                for (d = TAILQ_FIRST(&optinfo->ntp_list); d;
2244
 
                     d = TAILQ_NEXT(d, link), in6++) {
2245
 
                        memcpy(in6, &d->val_addr6, sizeof(*in6));
2246
 
                }
2247
 
                if (copy_option(DH6OPT_NTP, optlen, tmpbuf, &p,
2248
 
                    optep, &len) != 0) {
2249
 
                        goto fail;
2250
 
                }
2251
 
                free(tmpbuf);
2252
 
        }
2253
 
#endif
 
2217
        if (dhcp6_set_domain(DH6OPT_SIP_SERVER_D, &optinfo->sipname_list,
 
2218
            &p, optep, &len) != 0)
 
2219
                goto fail;
 
2220
 
 
2221
        if (dhcp6_set_addr(DH6OPT_SIP_SERVER_A, &optinfo->sip_list,
 
2222
            &p, optep, &len) != 0)
 
2223
                goto fail;
 
2224
 
 
2225
        if (dhcp6_set_addr(DH6OPT_DNS, &optinfo->sip_list,
 
2226
            &p, optep, &len) != 0)
 
2227
                goto fail;
 
2228
 
 
2229
        if (dhcp6_set_domain(DH6OPT_DNSNAME, &optinfo->dnsname_list,
 
2230
            &p, optep, &len) != 0)
 
2231
                goto fail;
 
2232
 
 
2233
        if (dhcp6_set_addr(DH6OPT_NIS_SERVERS, &optinfo->nis_list,
 
2234
            &p, optep, &len) != 0)
 
2235
                goto fail;
 
2236
 
 
2237
        if (dhcp6_set_addr(DH6OPT_NISP_SERVERS, &optinfo->nisp_list,
 
2238
            &p, optep, &len) != 0)
 
2239
                goto fail;
 
2240
 
 
2241
        if (dhcp6_set_domain(DH6OPT_NIS_DOMAIN_NAME, &optinfo->nisname_list,
 
2242
            &p, optep, &len) != 0)
 
2243
                goto fail;
 
2244
 
 
2245
        if (dhcp6_set_domain(DH6OPT_NISP_DOMAIN_NAME, &optinfo->nispname_list,
 
2246
            &p, optep, &len) != 0)
 
2247
                goto fail;
 
2248
 
 
2249
        if (dhcp6_set_addr(DH6OPT_NTP, &optinfo->ntp_list,
 
2250
            &p, optep, &len) != 0)
 
2251
                goto fail;
 
2252
 
 
2253
        if (dhcp6_set_domain(DH6OPT_BCMCS_SERVER_D, &optinfo->bcmcsname_list,
 
2254
            &p, optep, &len) != 0)
 
2255
                goto fail;
 
2256
 
 
2257
        if (dhcp6_set_addr(DH6OPT_BCMCS_SERVER_A, &optinfo->bcmcs_list,
 
2258
            &p, optep, &len) != 0)
 
2259
                goto fail;
2254
2260
 
2255
2261
        for (op = TAILQ_FIRST(&optinfo->iapd_list); op;
2256
2262
            op = TAILQ_NEXT(op, link)) {
2296
2302
                }
2297
2303
        }
2298
2304
 
2299
 
#ifdef USE_DH6OPT_REFRESHTIME
2300
2305
        if (optinfo->refreshtime != DH6OPT_REFRESHTIME_UNDEF) {
2301
2306
                u_int32_t p32 = (u_int32_t)optinfo->refreshtime;
2302
2307
 
2306
2311
                        goto fail;
2307
2312
                }
2308
2313
        }
2309
 
#endif
2310
2314
 
2311
2315
        if (optinfo->authproto != DHCP6_AUTHPROTO_UNDEF) {
2312
2316
                struct dhcp6opt_auth *auth;
2851
2855
        case DH6OPT_RECONF_MSG:
2852
2856
                return ("reconfigure message");
2853
2857
        case DH6OPT_SIP_SERVER_D:
2854
 
                return ("SIP server domain name ");
 
2858
                return ("SIP domain name");
2855
2859
        case DH6OPT_SIP_SERVER_A:
2856
2860
                return ("SIP server address");
2857
2861
        case DH6OPT_DNS:
2858
2862
                return ("DNS");
2859
2863
        case DH6OPT_DNSNAME:
2860
2864
                return ("domain search list");
2861
 
#ifdef USE_DH6OPT_NTP
2862
2865
        case DH6OPT_NTP:
2863
2866
                return ("NTP server");
2864
 
#endif
2865
2867
        case DH6OPT_IA_PD:
2866
2868
                return ("IA_PD");
2867
2869
        case DH6OPT_IA_PD_PREFIX:
2868
2870
                return ("IA_PD prefix");
2869
 
#ifdef USE_DH6OPT_REFRESHTIME
2870
2871
        case DH6OPT_REFRESHTIME:
2871
2872
                return ("information refresh time");
2872
 
#endif
 
2873
        case DH6OPT_NIS_SERVERS:
 
2874
                return ("NIS servers");
 
2875
        case DH6OPT_NISP_SERVERS:
 
2876
                return ("NIS+ servers");
 
2877
        case DH6OPT_NIS_DOMAIN_NAME:
 
2878
                return ("NIS domain name");
 
2879
        case DH6OPT_NISP_DOMAIN_NAME:
 
2880
                return ("NIS+ domain name");
 
2881
        case DH6OPT_BCMCS_SERVER_D:
 
2882
                return ("BCMCS domain name");
 
2883
        case DH6OPT_BCMCS_SERVER_A:
 
2884
                return ("BCMCS server address");
 
2885
        case DH6OPT_GEOCONF_CIVIC:
 
2886
                return ("Geoconf Civic");
 
2887
        case DH6OPT_REMOTE_ID:
 
2888
                return ("remote ID");
 
2889
        case DH6OPT_SUBSCRIBER_ID:
 
2890
                return ("subscriber ID");
 
2891
        case DH6OPT_CLIENT_FQDN:
 
2892
                return ("client FQDN");
2873
2893
        default:
2874
2894
                snprintf(genstr, sizeof(genstr), "opt_%d", type);
2875
2895
                return (genstr);