1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright (c) 2001 by Sun Microsystems, Inc.
  24  * All rights reserved.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <alloca.h>
  32 #include <strings.h>
  33 #include <sys/types.h>
  34 #include <arpa/inet.h>
  35 #include <sys/socket.h>
  36 #include <fcntl.h>
  37 #include <errno.h>
  38 #include <dhcp_svc_confopt.h>
  39 #include <dhcp_svc_private.h>
  40 #include <dhcp_svc_public.h>
  41 #include <libinetutil.h>
  42 
  43 /*
  44  * Argument: resource, and path in that resource.
  45  */
  46 int
  47 main(int argc, char *argv[])
  48 {
  49         int                     nmods, i, error;
  50         boolean_t               dsp_valid = B_FALSE;
  51         char                    **mods, **listpp;
  52         uint32_t                count;
  53         dsvc_datastore_t        dsp;
  54         dsvc_handle_t           handle;
  55         char                    cid[DN_MAX_CID_LEN * 2 + 1];
  56         uint_t                  cidlen;
  57         char                    cip[INET_ADDRSTRLEN], sip[INET_ADDRSTRLEN];
  58         uint32_t                query;
  59         dt_rec_t                dt, *dtp, *ntp;
  60         dt_rec_list_t           *resdtp, *wtp;
  61         dn_rec_t                dn, *dnp;
  62         dn_rec_list_t           *resdnp, *wnp;
  63 
  64         if (argc != 3) {
  65                 (void) fprintf(stderr, "Usage: %s <resource> <path>\n",
  66                     argv[0]);
  67                 return (1);
  68         }
  69 
  70         /* enumerate_dd() */
  71         (void) printf("enumerate_dd: ... ");
  72         error = enumerate_dd(&mods, &nmods);
  73         (void) printf("%s\n", dhcpsvc_errmsg(error));
  74 
  75         if (error != DSVC_SUCCESS)
  76                 return (1);
  77 
  78         (void) printf("enumerate_dd: count of modules: %d\n", nmods);
  79         for (i = 0; i < nmods; i++) {
  80                 (void) printf("    %d is: %s\n", i, mods[i]);
  81                 if (strcmp(argv[1], mods[i]) == 0) {
  82                         dsp.d_location = argv[2];
  83                         dsp.d_resource = strdup(mods[i]);
  84                         dsp.d_conver = DSVC_CUR_CONVER;
  85                         dsp_valid = B_TRUE;
  86                 }
  87                 free(mods[i]);
  88         }
  89         free(mods);
  90 
  91         if (!dsp_valid) {
  92                 (void) printf("%s: no module for resource `%s'\n", argv[0],
  93                     argv[1]);
  94                 return (1);
  95         }
  96 
  97         (void) printf("\nstarting testing on %s, tables @ %s\n",
  98             argv[1], argv[2]);
  99 
 100         /*
 101          * Using the datastore struct we built from arguments, begin poking
 102          * at the user selected public module.
 103          */
 104 
 105         /* status_dd */
 106         (void) printf("status_dd: ... ");
 107         error = status_dd(&dsp);
 108         (void) printf("%s\n", dhcpsvc_errmsg(error));
 109 
 110         (void) printf("Datastore version is %d\n", dsp.d_conver);
 111 
 112         /* mklocation_dd */
 113         (void) printf("mklocation_dd of %s: ... ", dsp.d_location);
 114         error = mklocation_dd(&dsp);
 115         (void) printf("%s\n", dhcpsvc_errmsg(error));
 116 
 117         /* list_dd - dhcptab */
 118         (void) printf("\nlist_dd of dhcptab containers: ... ");
 119         error = list_dd(&dsp, DSVC_DHCPTAB, &listpp, &count);
 120         (void) printf("    %s\n", dhcpsvc_errmsg(error));
 121         if (error == DSVC_SUCCESS) {
 122                 (void) printf("    %d dhcptab container(s): ", count);
 123                 for (i = 0; i < count; i++) {
 124                         (void) printf("%s ", listpp[i] != NULL ?
 125                             listpp[i] : "NULL");
 126                         free(listpp[i]);
 127                 }
 128                 (void) printf("\n");
 129                 free(listpp);
 130         } else {
 131                 (void) printf("list_dd: listpp: 0x%p, count: %d\n",
 132                     (void *)listpp, count);
 133         }
 134 
 135         /* open_dd - dhcptab (create) */
 136         (void) printf("open_dd: dhcptab: ... ");
 137         error = open_dd(&handle, &dsp, DSVC_DHCPTAB, "dhcptab",
 138             DSVC_CREATE | DSVC_READ | DSVC_WRITE);
 139         (void) printf("%s\n", dhcpsvc_errmsg(error));
 140         if (error != DSVC_SUCCESS)
 141                 return (1);
 142 
 143         /* add_dd_entry - dhcptab */
 144         {
 145                 dt_rec_t recs[5];
 146 
 147                 (void) strcpy(recs[0].dt_key, "172.21.0.0");
 148                 recs[0].dt_type = DT_MACRO;
 149                 recs[0].dt_value = ":Router=172.21.0.1:Subnet=255.255.0.0:";
 150 
 151                 (void) strcpy(recs[1].dt_key, "172.20.64.0");
 152                 recs[1].dt_type = DT_MACRO;
 153                 recs[1].dt_value =
 154                     ":Router=172.20.64.2:Subnet=255.255.255.192:";
 155 
 156                 (void) strcpy(recs[2].dt_key, "172.20.64.64");
 157                 recs[2].dt_type = DT_MACRO;
 158                 recs[2].dt_value =
 159                     ":Router=172.20.64.65:Subnet=255.255.255.192:";
 160 
 161                 (void) strcpy(recs[3].dt_key, "172.20.64.128");
 162                 recs[3].dt_type = DT_MACRO;
 163                 recs[3].dt_value =
 164                     ":Router=172.20.64.129:Subnet=255.255.255.128:";
 165 
 166                 (void) strcpy(recs[4].dt_key, "172.22.0.0");
 167                 recs[4].dt_type = DT_MACRO;
 168                 recs[4].dt_value =
 169                     ":Router=172.22.0.1:Subnet=255.255.0.0:MTU=4532:";
 170 
 171                 (void) printf("add_dd_entry: ... key type value\n");
 172                 for (i = 0; i < sizeof (recs) / sizeof (dt_rec_t); i++) {
 173                         (void) printf("    %s %c %s ... ",
 174                             recs[i].dt_key, recs[i].dt_type, recs[i].dt_value);
 175                         error = add_dd_entry(handle, &recs[i]);
 176                         (void) printf("%s\n", dhcpsvc_errmsg(error));
 177                         if (error != DSVC_SUCCESS)
 178                                 break;
 179                 }
 180         }
 181 
 182         /* lookup_dd - dhcptab - macro called '172.20.64.128', then delete it */
 183 
 184         DSVC_QINIT(query);
 185         DSVC_QEQ(query, DT_QKEY);
 186         DSVC_QEQ(query, DT_QTYPE);
 187 
 188         (void) memset(&dt, 0, sizeof (dt));
 189         (void) strcpy(dt.dt_key, "172.20.64.128");
 190         dt.dt_type = 'm';
 191 
 192         (void) printf("lookup_dd: macro %s ... ", dt.dt_key);
 193         error = lookup_dd(handle, B_FALSE, query, -1, &dt, (void **)&resdtp,
 194             &count);
 195         (void) printf("%s\n", dhcpsvc_errmsg(error));
 196 
 197         if (error == DSVC_SUCCESS) {
 198                 if (count != 1) {
 199                         (void) printf("lookup_dd: expected 1 record,  got %d\n",
 200                             count);
 201                 }
 202 
 203                 for (i = 0, wtp = resdtp; i < count && wtp != NULL; i++) {
 204                         dtp = wtp->dtl_rec;
 205                         (void) printf("    %s %c %s\n",
 206                             dtp->dt_key, dtp->dt_type, dtp->dt_value);
 207                         wtp = wtp->dtl_next;
 208                 }
 209                 free_dd_list(handle, resdtp);
 210         }
 211 
 212         /* Delete it */
 213         (void) printf("delete_dd_entry: %s ... ", dt.dt_key);
 214         error = delete_dd_entry(handle, &dt);
 215         (void) printf("%s\n", dhcpsvc_errmsg(error));
 216 
 217 
 218         /*
 219          * lookup_dd - dhcptab - macro called '172.21.0.0', and modify its
 220          * definition and replace the value.
 221          */
 222 
 223         DSVC_QINIT(query);
 224         DSVC_QEQ(query, DT_QKEY);
 225 
 226         (void) memset(&dt, 0, sizeof (dt));
 227         (void) strcpy(dt.dt_key, "172.21.0.0");
 228 
 229         (void) printf("lookup_dd: macro %s ... ", dt.dt_key);
 230         error = lookup_dd(handle, B_FALSE, query, 1, &dt, (void **)&resdtp,
 231             &count);
 232         (void) printf("%s\n", dhcpsvc_errmsg(error));
 233 
 234         if (error == DSVC_SUCCESS) {
 235                 if (count != 1) {
 236                         (void) printf("lookup_dd: expected 1 record, "
 237                             "got %d\n", count);
 238                 } else {
 239                         dtp = resdtp->dtl_rec;
 240                         (void) printf("    %s %c %s\n", dtp->dt_key,
 241                             dtp->dt_type, dtp->dt_value);
 242 
 243                         ntp = alloc_dtrec(dtp->dt_key, dtp->dt_type,
 244                             ":Subnet=255.255.0.0:Router=172.21.0.1 "
 245                             "172.21.0.2:MTU=1500:");
 246                         if (ntp != NULL) {
 247                                 ntp->dt_sig = dtp->dt_sig;
 248 
 249                                 /* Modify it */
 250                                 (void) printf("modify_dd_entry: macro %s ... ",
 251                                     dt.dt_key);
 252                                 error = modify_dd_entry(handle, dtp, ntp);
 253                                 (void) printf("%s\n", dhcpsvc_errmsg(error));
 254                                 free_dd(handle, ntp);
 255                         }
 256                 }
 257                 free_dd_list(handle, resdtp);
 258         }
 259 
 260         /* lookup_dd - all records */
 261 
 262         DSVC_QINIT(query);
 263 
 264         (void) printf("lookup_dd: all records ... ");
 265         error = lookup_dd(handle, B_FALSE, query, -1, &dt, (void **)&resdtp,
 266             &count);
 267         (void) printf("%s\n", dhcpsvc_errmsg(error));
 268         if (error == DSVC_SUCCESS) {
 269                 for (i = 0, wtp = resdtp; i < count && wtp != NULL; i++) {
 270                         dtp = wtp->dtl_rec;
 271                         (void) printf("    %s %c %s\n", dtp->dt_key,
 272                             dtp->dt_type, dtp->dt_value);
 273                         wtp = wtp->dtl_next;
 274                 }
 275                 free_dd_list(handle, resdtp);
 276         }
 277 
 278         /* close_dd - dhcptab */
 279         (void) printf("close_dd: dhcptab ... ");
 280         error = close_dd(&handle);
 281         (void) printf("%s\n", dhcpsvc_errmsg(error));
 282 
 283         /* list_dd - dhcp network containers */
 284         (void) printf("list_dd: dhcptab ... ");
 285         error = list_dd(&dsp, DSVC_DHCPTAB, &listpp, &count);
 286         (void) printf("%s\n", dhcpsvc_errmsg(error));
 287         if (error == DSVC_SUCCESS) {
 288                 (void) printf("    %d dhcp network container(s): ", count);
 289                 for (i = 0; i < count; i++) {
 290                         (void) printf("%s ", listpp[i] != NULL ?
 291                             listpp[i] : "NULL");
 292                         free(listpp[i]);
 293                 }
 294                 free(listpp);
 295                 (void) printf("\n");
 296         } else {
 297                 (void) printf("list_dd: listpp: 0x%p, count: %d\n",
 298                     (void *)listpp, count);
 299         }
 300 
 301         /* remove_dd - dhcptab */
 302         (void) printf("remove_dd: dhcptab ... ");
 303         error = remove_dd(&dsp, DSVC_DHCPTAB, NULL);
 304         (void) printf("%s\n", dhcpsvc_errmsg(error));
 305 
 306         /* open_dd - 129.148.5.0 create */
 307         (void) printf("\nopen_dd: 129.148.5.0: ... ");
 308         error = open_dd(&handle, &dsp, DSVC_DHCPNETWORK, "129.148.5.0",
 309             DSVC_CREATE | DSVC_READ | DSVC_WRITE);
 310         (void) printf("%s\n", dhcpsvc_errmsg(error));
 311         if (error  != DSVC_SUCCESS)
 312                 return (1);
 313 
 314         /* add_dd_entry - 129.148.5.0 */
 315         {
 316                 uchar_t cid0[7] = { 0x01, 0x08, 0x00, 0x20, 0x00, 0x00, 0x01 };
 317                 dn_rec_t recs[5] = { 0 };
 318 
 319                 recs[0].dn_cid_len = sizeof (cid0);
 320                 recs[0].dn_flags = 2;
 321                 recs[0].dn_cip.s_addr = 0x81940502;
 322                 recs[0].dn_sip.s_addr = 0x81940501;
 323                 (void) memcpy(recs[0].dn_cid, cid0, sizeof (cid0));
 324                 (void) strlcpy(recs[0].dn_macro, "myserv", DSVC_MAX_MACSYM_LEN);
 325                 (void) strlcpy(recs[0].dn_comment, "dave", DN_MAX_COMMENT_LEN);
 326 
 327                 recs[1].dn_cid_len = 1;
 328                 recs[1].dn_flags = 1;
 329                 recs[1].dn_cip.s_addr = 0x81940503;
 330                 recs[1].dn_sip.s_addr = 0x81940501;
 331                 (void) strlcpy(recs[1].dn_macro, "myserv", DSVC_MAX_MACSYM_LEN);
 332                 (void) strlcpy(recs[1].dn_comment, "meem", DN_MAX_COMMENT_LEN);
 333 
 334                 recs[2].dn_cid_len = 1;
 335                 recs[2].dn_cip.s_addr = 0x81940504;
 336                 recs[2].dn_sip.s_addr = 0x81940501;
 337                 (void) strlcpy(recs[2].dn_macro, "myserv", DSVC_MAX_MACSYM_LEN);
 338                 (void) strlcpy(recs[2].dn_comment, "cpj", DN_MAX_COMMENT_LEN);
 339 
 340                 recs[3].dn_cid_len = 1;
 341                 recs[3].dn_cip.s_addr = 0x81940505;
 342                 recs[3].dn_sip.s_addr = 0x81940501;
 343                 (void) strlcpy(recs[3].dn_macro, "myserv", DSVC_MAX_MACSYM_LEN);
 344                 (void) strlcpy(recs[3].dn_comment, "mwc", DN_MAX_COMMENT_LEN);
 345 
 346                 recs[4].dn_cid_len = 1;
 347                 recs[4].dn_cip.s_addr = 0x81940506;
 348                 recs[4].dn_sip.s_addr = 0x81940501;
 349                 (void) strlcpy(recs[4].dn_macro, "myserv", DSVC_MAX_MACSYM_LEN);
 350                 (void) strlcpy(recs[4].dn_comment, "markh", DN_MAX_COMMENT_LEN);
 351 
 352                 (void) printf("add_dd_entry: ... cid flag cip sip lease "
 353                     "macro comment\n");
 354                 for (i = 0; i < sizeof (recs) / sizeof (dn_rec_t); i++) {
 355                         cidlen = sizeof (cid);
 356                         (void) octet_to_hexascii(recs[i].dn_cid,
 357                             recs[i].dn_cid_len, cid, &cidlen);
 358                         (void) printf("    %s %d %s %s %u %s %s ... ",
 359                             cid, recs[i].dn_flags,
 360                             inet_ntop(AF_INET, &recs[i].dn_cip, cip,
 361                             INET_ADDRSTRLEN),
 362                             inet_ntop(AF_INET, &recs[i].dn_sip, sip,
 363                             INET_ADDRSTRLEN),
 364                             recs[i].dn_lease, recs[i].dn_macro,
 365                             recs[i].dn_comment);
 366 
 367                         error = add_dd_entry(handle, &recs[i]);
 368                         (void) printf("%s\n", dhcpsvc_errmsg(error));
 369                         if (error != DSVC_SUCCESS)
 370                                 break;
 371                 }
 372         }
 373 
 374         /* lookup_dd - lookup all records. */
 375         DSVC_QINIT(query);
 376 
 377         (void) printf("lookup_dd: 129.148.5.0 ... ");
 378         error = lookup_dd(handle, B_FALSE, query, -1, &dn, (void **)&resdnp,
 379             &count);
 380         (void) printf("%s\n", dhcpsvc_errmsg(error));
 381         if (error == DSVC_SUCCESS) {
 382                 for (i = 0, wnp = resdnp; i < count && wnp != NULL; i++) {
 383                         dnp = wnp->dnl_rec;
 384                         cidlen = sizeof (cid);
 385                         (void) octet_to_hexascii(dnp->dn_cid,
 386                             dnp->dn_cid_len, cid, &cidlen);
 387                         (void) inet_ntop(AF_INET, &dnp->dn_cip,
 388                             cip, INET_ADDRSTRLEN);
 389                         (void) inet_ntop(AF_INET, &dnp->dn_sip,
 390                             sip, INET_ADDRSTRLEN);
 391                         (void) printf("    %s %02u %s %s %u '%s' #%s\n",
 392                             cid, dnp->dn_flags, cip, sip, dnp->dn_lease,
 393                             dnp->dn_macro, dnp->dn_comment);
 394                         wnp = wnp->dnl_next;
 395                 }
 396                 free_dd_list(handle, resdnp);
 397         }
 398 
 399         /* delete_dd_entry - 129.148.5.3 */
 400         dn.dn_sig = 0;
 401         dn.dn_cip.s_addr = ntohl(inet_addr("129.148.5.3"));
 402         (void) printf("delete_dd_entry: 129.148.5.3 ... ");
 403         error = delete_dd_entry(handle, &dn);
 404         (void) printf("%s\n", dhcpsvc_errmsg(error));
 405 
 406         /*
 407          * lookup_dd - 129.148.5.0 - record with cid of 01080020000001, modify
 408          * flags to MANUAL+BOOTP, lease to -1, macro to foobar, and server to
 409          * 129.148.174.27.
 410          */
 411         DSVC_QINIT(query);
 412         DSVC_QEQ(query, DN_QCID);
 413 
 414         (void) memset(&dn, 0, sizeof (dn));
 415         dn.dn_cid[0] = 0x1;
 416         dn.dn_cid[1] = 0x8;
 417         dn.dn_cid[2] = 0x0;
 418         dn.dn_cid[3] = 0x20;
 419         dn.dn_cid[4] = 0x0;
 420         dn.dn_cid[5] = 0x0;
 421         dn.dn_cid[6] = 0x1;
 422         dn.dn_cid_len = 7;
 423 
 424         (void) printf("lookup_dd: 01080020000001 ... ");
 425         error = lookup_dd(handle, B_FALSE, query, 1, &dn, (void **)&resdnp,
 426             &count);
 427         (void) printf("%s\n", dhcpsvc_errmsg(error));
 428 
 429         if (error == DSVC_SUCCESS) {
 430                 if (count != 1) {
 431                         (void) printf("lookup_dd: expected 1 record, got %d\n",
 432                             count);
 433                 } else {
 434                         dnp = resdnp->dnl_rec;
 435                         dn = *dnp; /* struct copy */
 436 
 437                         dn.dn_flags = DN_FMANUAL | DN_FBOOTP_ONLY;
 438                         dn.dn_lease = DHCP_PERM;
 439                         (void) strcpy(dn.dn_macro, "foobar");
 440                         dn.dn_sip.s_addr = ntohl(inet_addr("129.148.174.27"));
 441 
 442                         /* Modify it */
 443                         (void) printf("modify_dd_entry: 01080020000001 ... ");
 444                         error = modify_dd_entry(handle, dnp, &dn);
 445                         (void) printf("%s\n", dhcpsvc_errmsg(error));
 446                 }
 447                 free_dd_list(handle, resdnp);
 448         }
 449 
 450         /* lookup_dd - lookup all fields with DN_FMANUAL set */
 451 
 452         DSVC_QINIT(query);
 453         DSVC_QEQ(query, DN_QFMANUAL);
 454 
 455         (void) memset(&dn, 0, sizeof (dn));
 456         dn.dn_flags = DN_FMANUAL;
 457 
 458         (void) printf("lookup_dd: F_MANUAL ... ");
 459         error = lookup_dd(handle, B_FALSE, query, 1, &dn, (void **)&resdnp,
 460             &count);
 461         (void) printf("%s\n", dhcpsvc_errmsg(error));
 462 
 463         if (error == DSVC_SUCCESS) {
 464                 if (count != 1) {
 465                         (void) printf("lookup_dd: expected 1 record, "
 466                             "got %d\n", count);
 467                 } else {
 468                         dnp = resdnp->dnl_rec;
 469                         cidlen = sizeof (cid);
 470                         (void) octet_to_hexascii(dnp->dn_cid,
 471                             dnp->dn_cid_len, cid, &cidlen);
 472                         (void) inet_ntop(AF_INET, &dnp->dn_cip,
 473                             cip, INET_ADDRSTRLEN);
 474                         (void) inet_ntop(AF_INET, &dnp->dn_sip,
 475                             sip, INET_ADDRSTRLEN);
 476                         (void) printf("    %s %02u %s %s %u '%s' #%s\n",
 477                             cid, dnp->dn_flags, cip, sip, dnp->dn_lease,
 478                             dnp->dn_macro, dnp->dn_comment);
 479                 }
 480                 free_dd_list(handle, resdnp);
 481         }
 482 
 483         /* lookup_dd - lookup all records. */
 484 
 485         DSVC_QINIT(query);
 486 
 487         (void) printf("lookup_dd: 129.148.5.0  ...");
 488         error = lookup_dd(handle, B_FALSE, query, -1, &dn, (void **)&resdnp,
 489             &count);
 490         (void) printf("%s\n", dhcpsvc_errmsg(error));
 491 
 492         if (error == DSVC_SUCCESS) {
 493                 for (i = 0, wnp = resdnp; i < count && wnp != NULL; i++) {
 494                         cidlen = sizeof (cid);
 495                         dnp = wnp->dnl_rec;
 496                         (void) octet_to_hexascii(dnp->dn_cid,
 497                             dnp->dn_cid_len, cid, &cidlen);
 498                         (void) inet_ntop(AF_INET, &dnp->dn_cip,
 499                             cip, INET_ADDRSTRLEN);
 500                         (void) inet_ntop(AF_INET, &dnp->dn_sip,
 501                             sip, INET_ADDRSTRLEN);
 502                         (void) printf("    %s %02u %s %s %u '%s' #%s\n",
 503                             cid, dnp->dn_flags, cip, sip, dnp->dn_lease,
 504                             dnp->dn_macro, dnp->dn_comment);
 505                         wnp = wnp->dnl_next;
 506                 }
 507                 free_dd_list(handle, resdnp);
 508         }
 509 
 510         /* close_dd - 129.148.5.0 */
 511         (void) printf("close_dd: 129.148.5.0 ... ");
 512         error = close_dd(&handle);
 513         (void) printf("%s\n", dhcpsvc_errmsg(error));
 514 
 515         /* list_dd - dhcp network containers */
 516         (void) printf("list_dd: ... ");
 517         error = list_dd(&dsp, DSVC_DHCPNETWORK, &listpp, &count);
 518         (void) printf("%s\n", dhcpsvc_errmsg(error));
 519         if (error == DSVC_SUCCESS) {
 520                 (void) printf("    %d dhcp network container(s): ", count);
 521                 for (i = 0; i < count; i++) {
 522                         (void) printf("%s ", listpp[i] != NULL ?
 523                             listpp[i] : "NULL");
 524                         free(listpp[i]);
 525                 }
 526                 free(listpp);
 527                 (void) printf("\n");
 528         } else {
 529                 (void) printf("list_dd: listpp: 0x%p, count: %d\n",
 530                     (void *)listpp, count);
 531         }
 532 
 533         /* remove_dd - 129.148.5.0 */
 534         (void) printf("remove_dd_entry: 129.148.5.0 ... ");
 535         error = remove_dd(&dsp, DSVC_DHCPNETWORK, "129.148.5.0");
 536         (void) printf("%s\n", dhcpsvc_errmsg(error));
 537 
 538         return (0);
 539 }