control_server.c revision 224144
1/*- 2 * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 21 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: head/usr.sbin/rtadvd/control_server.c 224144 2011-07-17 19:24:54Z hrs $ 27 * 28 */ 29 30#include <sys/queue.h> 31#include <sys/types.h> 32#include <sys/socket.h> 33#include <sys/stat.h> 34#include <sys/un.h> 35#include <sys/uio.h> 36#include <net/if.h> 37#include <net/if_dl.h> 38#include <netinet/in.h> 39#include <netinet/icmp6.h> 40#include <fcntl.h> 41#include <errno.h> 42#include <netdb.h> 43#include <unistd.h> 44#include <signal.h> 45#include <string.h> 46#include <stdarg.h> 47#include <stdio.h> 48#include <stdlib.h> 49#include <syslog.h> 50 51#include "pathnames.h" 52#include "rtadvd.h" 53#include "if.h" 54#include "control.h" 55#include "control_server.h" 56#include "timer.h" 57 58static char *do_reload_ifname; 59static int do_reload; 60static int do_shutdown; 61 62void set_do_reload(int sig __unused) { do_reload = 1; } 63void set_do_reload_ifname(char *ifname){ do_reload_ifname = ifname; } 64void set_do_shutdown(int sig __unused) { do_shutdown = 1; } 65void reset_do_reload(void) { do_reload = 0; do_reload_ifname = NULL; } 66void reset_do_shutdown(void) { do_shutdown = 0; } 67int is_do_reload(void) { return (do_reload); } 68int is_do_shutdown(void) { return (do_shutdown); } 69char *reload_ifname(void) { return (do_reload_ifname); } 70 71#define DEF_PL_HANDLER(key) { #key, cmsg_getprop_##key } 72 73static int cmsg_getprop_echo(struct ctrl_msg_pl *); 74static int cmsg_getprop_version(struct ctrl_msg_pl *); 75static int cmsg_getprop_ifilist(struct ctrl_msg_pl *); 76static int cmsg_getprop_ifi(struct ctrl_msg_pl *); 77static int cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *); 78static int cmsg_getprop_rai(struct ctrl_msg_pl *); 79static int cmsg_getprop_pfx(struct ctrl_msg_pl *); 80static int cmsg_getprop_rdnss(struct ctrl_msg_pl *); 81static int cmsg_getprop_dnssl(struct ctrl_msg_pl *); 82static int cmsg_getprop_rti(struct ctrl_msg_pl *); 83 84static int cmsg_setprop_reload(struct ctrl_msg_pl *); 85static int cmsg_setprop_enable(struct ctrl_msg_pl *); 86static int cmsg_setprop_disable(struct ctrl_msg_pl *); 87 88static struct dispatch_table { 89 const char *dt_comm; 90 int (*dt_act)(struct ctrl_msg_pl *cp); 91} getprop_dtable[] = { 92 { "", cmsg_getprop_echo }, 93 DEF_PL_HANDLER(echo), 94 DEF_PL_HANDLER(version), 95 DEF_PL_HANDLER(ifilist), 96 DEF_PL_HANDLER(ifi), 97 DEF_PL_HANDLER(ifi_ra_timer), 98 DEF_PL_HANDLER(rai), 99 DEF_PL_HANDLER(rti), 100 DEF_PL_HANDLER(pfx), 101 DEF_PL_HANDLER(rdnss), 102 DEF_PL_HANDLER(dnssl), 103}; 104 105static int 106cmsg_getprop_echo(struct ctrl_msg_pl *cp) 107{ 108 109 syslog(LOG_DEBUG, "<%s> enter", __func__); 110 cp->cp_val = strdup(""); 111 cp->cp_val_len = strlen(cp->cp_val) + 1; 112 113 return (0); 114} 115 116static int 117cmsg_getprop_version(struct ctrl_msg_pl *cp) 118{ 119 120 syslog(LOG_DEBUG, "<%s> enter", __func__); 121 cp->cp_val = strdup(CM_VERSION_STR); 122 cp->cp_val_len = strlen(cp->cp_val) + 1; 123 124 return (0); 125} 126 127static int 128cmsg_getprop_ifilist(struct ctrl_msg_pl *cp) 129{ 130 struct ifinfo *ifi; 131 char *p; 132 size_t len; 133 134 syslog(LOG_DEBUG, "<%s> enter", __func__); 135 136 len = 0; 137 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 138 len += strlen(ifi->ifi_ifname) + 1; 139 } 140 141 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 142 143 p = malloc(len); 144 if (p == NULL) 145 exit(1); 146 memset(p, 0, len); 147 cp->cp_val = p; 148 149 if (len > 0) 150 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 151 syslog(LOG_DEBUG, "<%s> add ifname=%s(%d)", 152 __func__, ifi->ifi_ifname, ifi->ifi_ifindex); 153 strcpy(p, ifi->ifi_ifname); 154 p += strlen(ifi->ifi_ifname) + 1; 155 } 156 cp->cp_val_len = p - cp->cp_val; 157 158 return (0); 159} 160 161static int 162cmsg_getprop_ifi(struct ctrl_msg_pl *cp) 163{ 164 struct ifinfo *ifi; 165 char *p; 166 size_t len; 167 168 syslog(LOG_DEBUG, "<%s> enter", __func__); 169 170 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 171 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 172 break; 173 } 174 if (ifi == NULL) { 175 syslog(LOG_ERR, "<%s> %s not found", __func__, 176 cp->cp_ifname); 177 return (1); 178 } 179 180 p = malloc(sizeof(*ifi)); 181 if (p == NULL) 182 exit(1); 183 len = cmsg_str2bin(p, ifi, sizeof(*ifi)); 184 185 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 186 187 if (len == 0) 188 return (1); 189 190 cp->cp_val = p; 191 cp->cp_val_len = len; 192 193 return (0); 194} 195 196static int 197cmsg_getprop_rai(struct ctrl_msg_pl *cp) 198{ 199 struct ifinfo *ifi; 200 struct rainfo *rai; 201 char *p; 202 size_t len; 203 204 syslog(LOG_DEBUG, "<%s> enter", __func__); 205 206 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 207 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 208 break; 209 } 210 if (ifi == NULL) { 211 syslog(LOG_ERR, "<%s> %s not found", __func__, 212 cp->cp_ifname); 213 return (1); 214 } 215 if ((rai = ifi->ifi_rainfo) == NULL) { 216 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 217 cp->cp_ifname); 218 return (1); 219 } 220 221 p = malloc(sizeof(*rai)); 222 if (p == NULL) 223 exit(1); 224 len = cmsg_str2bin(p, rai, sizeof(*rai)); 225 226 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 227 228 if (len == 0) 229 return (1); 230 231 cp->cp_val = p; 232 cp->cp_val_len = len; 233 234 return (0); 235} 236 237static int 238cmsg_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp) 239{ 240 struct ifinfo *ifi; 241 struct rainfo *rai; 242 struct rtadvd_timer *rtimer; 243 char *p; 244 size_t len; 245 246 syslog(LOG_DEBUG, "<%s> enter", __func__); 247 248 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 249 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 250 break; 251 } 252 if (ifi == NULL) { 253 syslog(LOG_ERR, "<%s> %s not found", __func__, 254 cp->cp_ifname); 255 return (1); 256 } 257 if ((rai = ifi->ifi_rainfo) == NULL) { 258 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 259 cp->cp_ifname); 260 return (1); 261 } 262 if ((rtimer = ifi->ifi_ra_timer) == NULL) { 263 syslog(LOG_ERR, "<%s> %s has no ifi_ra_timer", __func__, 264 cp->cp_ifname); 265 return (1); 266 } 267 p = malloc(sizeof(*rtimer)); 268 if (p == NULL) 269 exit(1); 270 len = cmsg_str2bin(p, rtimer, sizeof(*rtimer)); 271 272 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 273 274 if (len == 0) 275 return (1); 276 277 cp->cp_val = p; 278 cp->cp_val_len = len; 279 280 return (0); 281} 282 283static int 284cmsg_getprop_rti(struct ctrl_msg_pl *cp) 285{ 286 struct ifinfo *ifi; 287 struct rainfo *rai; 288 struct rtinfo *rti; 289 char *p; 290 size_t len; 291 292 syslog(LOG_DEBUG, "<%s> enter", __func__); 293 294 len = 0; 295 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 296 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 297 break; 298 } 299 if (ifi == NULL) { 300 syslog(LOG_ERR, "<%s> %s not found", __func__, 301 cp->cp_ifname); 302 return (1); 303 } 304 if (ifi->ifi_rainfo == NULL) { 305 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 306 cp->cp_ifname); 307 return (1); 308 } 309 rai = ifi->ifi_rainfo; 310 TAILQ_FOREACH(rti, &rai->rai_route, rti_next) { 311 len += sizeof(*rti); 312 } 313 314 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 315 316 p = malloc(len); 317 if (p == NULL) 318 exit(1); 319 memset(p, 0, len); 320 cp->cp_val = p; 321 322 if (len > 0) 323 TAILQ_FOREACH(rti, &rai->rai_route, rti_next) { 324 memcpy(p, rti, sizeof(*rti)); 325 p += sizeof(*rti); 326 } 327 cp->cp_val_len = p - cp->cp_val; 328 329 return (0); 330} 331 332static int 333cmsg_getprop_pfx(struct ctrl_msg_pl *cp) 334{ 335 struct ifinfo *ifi; 336 struct rainfo *rai; 337 struct prefix *pfx; 338 char *p; 339 size_t len; 340 341 syslog(LOG_DEBUG, "<%s> enter", __func__); 342 343 len = 0; 344 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 345 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 346 break; 347 } 348 if (ifi == NULL) { 349 syslog(LOG_ERR, "<%s> %s not found", __func__, 350 cp->cp_ifname); 351 return (1); 352 } 353 if (ifi->ifi_rainfo == NULL) { 354 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 355 cp->cp_ifname); 356 return (1); 357 } 358 rai = ifi->ifi_rainfo; 359 TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) { 360 len += sizeof(*pfx); 361 } 362 363 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 364 365 p = malloc(len); 366 if (p == NULL) 367 exit(1); 368 memset(p, 0, len); 369 cp->cp_val = p; 370 371 if (len > 0) 372 TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) { 373 memcpy(p, pfx, sizeof(*pfx)); 374 p += sizeof(*pfx); 375 } 376 cp->cp_val_len = p - cp->cp_val; 377 378 return (0); 379} 380 381static int 382cmsg_getprop_rdnss(struct ctrl_msg_pl *cp) 383{ 384 struct ifinfo *ifi; 385 struct rainfo *rai; 386 struct rdnss *rdn; 387 struct rdnss_addr *rda; 388 char *p; 389 size_t len; 390 uint16_t *rdn_cnt; 391 uint16_t *rda_cnt; 392 393 syslog(LOG_DEBUG, "<%s> enter", __func__); 394 395 len = 0; 396 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 397 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 398 break; 399 } 400 if (ifi == NULL) { 401 syslog(LOG_ERR, "<%s> %s not found", __func__, 402 cp->cp_ifname); 403 return (1); 404 } 405 if (ifi->ifi_rainfo == NULL) { 406 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 407 cp->cp_ifname); 408 return (1); 409 } 410 rai = ifi->ifi_rainfo; 411 412 len = sizeof(*rdn_cnt); 413 TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) { 414 len += sizeof(*rdn); 415 len += sizeof(*rda_cnt); 416 TAILQ_FOREACH(rda, &rdn->rd_list, ra_next) { 417 len += sizeof(*rda); 418 } 419 } 420 421 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 422 423 p = malloc(len); 424 if (p == NULL) 425 exit(1); 426 memset(p, 0, len); 427 cp->cp_val = p; 428 429 rdn_cnt = (uint16_t *)p; 430 p += sizeof(*rdn_cnt); 431 TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) { 432 *rdn_cnt += 1; 433 memcpy(p, rdn, sizeof(*rdn)); 434 p += sizeof(*rdn); 435 436 rda_cnt = (uint16_t *)p; 437 p += sizeof(*rda_cnt); 438 TAILQ_FOREACH(rda, &rdn->rd_list, ra_next) { 439 *rda_cnt += 1; 440 memcpy(p, rda, sizeof(*rda)); 441 p += sizeof(*rda); 442 } 443 } 444 syslog(LOG_DEBUG, "<%s> rdn_cnt = %d", __func__, *rdn_cnt); 445 cp->cp_val_len = p - cp->cp_val; 446 447 return (0); 448} 449 450static int 451cmsg_getprop_dnssl(struct ctrl_msg_pl *cp) 452{ 453 struct ifinfo *ifi; 454 struct rainfo *rai; 455 struct dnssl *dns; 456 struct dnssl_addr *dna; 457 char *p; 458 size_t len; 459 uint16_t *dns_cnt; 460 uint16_t *dna_cnt; 461 462 syslog(LOG_DEBUG, "<%s> enter", __func__); 463 464 len = 0; 465 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 466 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 467 break; 468 } 469 if (ifi == NULL) { 470 syslog(LOG_ERR, "<%s> %s not found", __func__, 471 cp->cp_ifname); 472 return (1); 473 } 474 if (ifi->ifi_rainfo == NULL) { 475 syslog(LOG_ERR, "<%s> %s has no rainfo", __func__, 476 cp->cp_ifname); 477 return (1); 478 } 479 rai = ifi->ifi_rainfo; 480 481 len = sizeof(*dns_cnt); 482 TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) { 483 len += sizeof(*dns); 484 len += sizeof(*dna_cnt); 485 TAILQ_FOREACH(dna, &dns->dn_list, da_next) { 486 len += sizeof(*dna); 487 } 488 } 489 490 syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len); 491 492 p = malloc(len); 493 if (p == NULL) 494 exit(1); 495 memset(p, 0, len); 496 cp->cp_val = p; 497 498 dns_cnt = (uint16_t *)cp->cp_val; 499 p += sizeof(*dns_cnt); 500 TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) { 501 (*dns_cnt)++; 502 memcpy(p, dns, sizeof(*dns)); 503 p += sizeof(*dns); 504 505 dna_cnt = (uint16_t *)p; 506 p += sizeof(*dna_cnt); 507 TAILQ_FOREACH(dna, &dns->dn_list, da_next) { 508 (*dna_cnt)++; 509 memcpy(p, dna, sizeof(*dna)); 510 p += sizeof(*dna); 511 } 512 } 513 cp->cp_val_len = p - cp->cp_val; 514 515 return (0); 516} 517 518int 519cmsg_getprop(struct ctrl_msg_pl *cp) 520{ 521 size_t i; 522 523 syslog(LOG_DEBUG, "<%s> enter", __func__); 524 525 if (cp == NULL) 526 return (1); 527 528 for (i = 0; 529 i < sizeof(getprop_dtable) / sizeof(getprop_dtable[0]); 530 i++) { 531 if (strcmp(cp->cp_key, getprop_dtable[i].dt_comm) == 0) 532 return (getprop_dtable[i].dt_act(cp)); 533 } 534 return (1); 535} 536 537int 538cmsg_setprop(struct ctrl_msg_pl *cp) 539{ 540 syslog(LOG_DEBUG, "<%s> enter", __func__); 541 542 if (cp == NULL || cp->cp_key == NULL) 543 return (1); 544 545 if (strncmp(cp->cp_key, "reload", sizeof("reload")) == 0) 546 cmsg_setprop_reload(cp); 547 else if (strncmp(cp->cp_key, "shutdown", sizeof("shutdown")) == 0) 548 set_do_shutdown(0); 549 else if (strncmp(cp->cp_key, "enable", sizeof("enable")) == 0) 550 cmsg_setprop_enable(cp); 551 else if (strncmp(cp->cp_key, "disable", sizeof("disable")) == 0) 552 cmsg_setprop_disable(cp); 553 else if (strncmp(cp->cp_key, "echo", 8) == 0) 554 ; /* do nothing */ 555 else 556 return (1); 557 558 return (0); 559} 560 561static int 562cmsg_setprop_reload(struct ctrl_msg_pl *cp) 563{ 564 565 syslog(LOG_DEBUG, "<%s> enter", __func__); 566 567 set_do_reload_ifname(cp->cp_ifname); 568 set_do_reload(1); 569 570 return (0); 571} 572 573static int 574cmsg_setprop_enable(struct ctrl_msg_pl *cp) 575{ 576 struct ifinfo *ifi; 577 578 syslog(LOG_DEBUG, "<%s> enter", __func__); 579 580 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 581 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 582 break; 583 } 584 if (ifi == NULL) { 585 syslog(LOG_ERR, "<%s> %s not found", __func__, 586 cp->cp_ifname); 587 return (1); 588 } 589 590 ifi->ifi_persist = 1; 591 set_do_reload_ifname(ifi->ifi_ifname); 592 set_do_reload(0); 593 594 return (0); 595} 596 597static int 598cmsg_setprop_disable(struct ctrl_msg_pl *cp) 599{ 600 struct ifinfo *ifi; 601 602 syslog(LOG_DEBUG, "<%s> enter", __func__); 603 604 TAILQ_FOREACH(ifi, &ifilist, ifi_next) { 605 if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0) 606 break; 607 } 608 if (ifi == NULL) { 609 syslog(LOG_ERR, "<%s> %s not found", __func__, 610 cp->cp_ifname); 611 return (1); 612 } 613 614 ifi->ifi_persist = 0; 615 616 return (0); 617} 618 619int 620cmsg_handler_server(int fd) 621{ 622 int state; 623 char *msg; 624 struct ctrl_msg_hdr *cm; 625 struct ctrl_msg_pl cp; 626 char buf[CM_MSG_MAXLEN]; 627 char pbuf[CM_MSG_MAXLEN]; 628 int error; 629 630 syslog(LOG_DEBUG, "<%s> enter", __func__); 631 632 memset(buf, 0, sizeof(buf)); 633 memset(pbuf, 0, sizeof(pbuf)); 634 cm = (struct ctrl_msg_hdr *)buf; 635 msg = (char *)buf + sizeof(*cm); 636 637 state = CM_STATE_INIT; 638 while (state != CM_STATE_EOM) { 639 syslog(LOG_DEBUG, "<%s> state = %d", __func__, state); 640 641 switch (state) { 642 case CM_STATE_INIT: 643 state = CM_STATE_MSG_RECV; 644 break; 645 case CM_STATE_MSG_DISPATCH: 646 cm->cm_version = CM_VERSION; 647 error = cmsg_send(fd, buf); 648 if (error) 649 syslog(LOG_WARNING, 650 "<%s> cmsg_send()", __func__); 651 state = CM_STATE_EOM; 652 break; 653 case CM_STATE_ACK_WAIT: 654 error = cmsg_recv(fd, buf); 655 if (error) { 656 syslog(LOG_ERR, 657 "<%s> cmsg_recv()", __func__); 658 close(fd); 659 return (-1); 660 } 661 662 switch (cm->cm_type) { 663 case CM_TYPE_ACK: 664 break; 665 case CM_TYPE_ERR: 666 syslog(LOG_DEBUG, 667 "<%s> CM_TYPE_ERR", __func__); 668 close(fd); 669 return (-1); 670 default: 671 syslog(LOG_DEBUG, 672 "<%s> unknown status", __func__); 673 close(fd); 674 return (-1); 675 } 676 state = CM_STATE_EOM; 677 break; 678 case CM_STATE_MSG_RECV: 679 error = cmsg_recv(fd, buf); 680 681 if (error) { 682 syslog(LOG_ERR, 683 "<%s> cmsg_recv()", __func__); 684 close(fd); 685 return (-1); 686 } 687 memset(&cp, 0, sizeof(cp)); 688 689 syslog(LOG_DEBUG, 690 "<%s> cm->cm_type = %d", __func__, cm->cm_type); 691 syslog(LOG_DEBUG, 692 "<%s> cm->cm_len = %zu", __func__, cm->cm_len); 693 694 switch (cm->cm_type) { 695 case CM_TYPE_EOM: 696 state = CM_STATE_EOM; 697 case CM_TYPE_NUL: 698 cm->cm_type = CM_TYPE_ACK; 699 cm->cm_len = sizeof(*cm); 700 break; 701 case CM_TYPE_REQ_GET_PROP: 702 cmsg_bin2pl(msg, &cp); 703 error = cmsg_getprop(&cp); 704 if (error) { 705 cm->cm_type = CM_TYPE_ERR; 706 cm->cm_len = sizeof(*cm); 707 } else { 708 cm->cm_type = CM_TYPE_ACK; 709 cm->cm_len = sizeof(*cm); 710 cm->cm_len += cmsg_pl2bin(msg, &cp); 711 } 712 if (cp.cp_val != NULL) 713 free(cp.cp_val); 714 break; 715 case CM_TYPE_REQ_SET_PROP: 716 cmsg_bin2pl(msg, &cp); 717 error = cmsg_setprop(&cp); 718 if (error) { 719 cm->cm_type = CM_TYPE_ERR; 720 cm->cm_len = sizeof(*cm); 721 } else { 722 cm->cm_type = CM_TYPE_ACK; 723 cm->cm_len = sizeof(*cm); 724 } 725 break; 726 default: 727 cm->cm_type = CM_TYPE_ERR; 728 cm->cm_len = sizeof(*cm); 729 } 730 731 switch (cm->cm_type) { 732 case CM_TYPE_ERR: 733 case CM_TYPE_ACK: 734 state = CM_STATE_MSG_DISPATCH; 735 break; 736 } 737 } 738 } 739 syslog(LOG_DEBUG, "<%s> leave", __func__); 740 741 return (0); 742} 743