137241896SHiroki Sato /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 437241896SHiroki Sato * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org> 537241896SHiroki Sato * All rights reserved. 637241896SHiroki Sato * 737241896SHiroki Sato * Redistribution and use in source and binary forms, with or without 837241896SHiroki Sato * modification, are permitted provided that the following conditions 937241896SHiroki Sato * are met: 1037241896SHiroki Sato * 1. Redistributions of source code must retain the above copyright 1137241896SHiroki Sato * notice, this list of conditions and the following disclaimer. 1237241896SHiroki Sato * 2. Redistributions in binary form must reproduce the above copyright 1337241896SHiroki Sato * notice, this list of conditions and the following disclaimer in the 1437241896SHiroki Sato * documentation and/or other materials provided with the distribution. 1537241896SHiroki Sato * 1637241896SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1737241896SHiroki Sato * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1837241896SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1937241896SHiroki Sato * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS 2037241896SHiroki Sato * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2137241896SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2237241896SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2337241896SHiroki Sato * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2437241896SHiroki Sato * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2537241896SHiroki Sato * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2637241896SHiroki Sato * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2737241896SHiroki Sato * 2837241896SHiroki Sato */ 2937241896SHiroki Sato 30*93e96d6cSElyes Haouas #include <sys/param.h> 3137241896SHiroki Sato #include <sys/queue.h> 3237241896SHiroki Sato #include <sys/socket.h> 3337241896SHiroki Sato #include <sys/stat.h> 3437241896SHiroki Sato #include <sys/un.h> 3537241896SHiroki Sato #include <sys/uio.h> 3637241896SHiroki Sato #include <net/if.h> 3737241896SHiroki Sato #include <net/if_dl.h> 3837241896SHiroki Sato #include <netinet/in.h> 3937241896SHiroki Sato #include <netinet/icmp6.h> 4037241896SHiroki Sato #include <fcntl.h> 4137241896SHiroki Sato #include <errno.h> 4237241896SHiroki Sato #include <netdb.h> 4337241896SHiroki Sato #include <unistd.h> 44aed37872SHiroki Sato #include <poll.h> 4537241896SHiroki Sato #include <signal.h> 4637241896SHiroki Sato #include <string.h> 4737241896SHiroki Sato #include <stdarg.h> 4837241896SHiroki Sato #include <stdio.h> 4937241896SHiroki Sato #include <stdlib.h> 5037241896SHiroki Sato #include <syslog.h> 5137241896SHiroki Sato 5237241896SHiroki Sato #include "rtadvd.h" 5337241896SHiroki Sato #include "if.h" 5437241896SHiroki Sato #include "pathnames.h" 5537241896SHiroki Sato #include "control.h" 5637241896SHiroki Sato 57aed37872SHiroki Sato #define CM_RECV_TIMEOUT 30 58aed37872SHiroki Sato 5937241896SHiroki Sato int 60aed37872SHiroki Sato cm_recv(int fd, char *buf) 6137241896SHiroki Sato { 6296aec9a5SConrad Meyer ssize_t n; 6337241896SHiroki Sato struct ctrl_msg_hdr *cm; 6437241896SHiroki Sato char *msg; 65aed37872SHiroki Sato struct pollfd pfds[1]; 66aed37872SHiroki Sato int i; 6737241896SHiroki Sato 6837241896SHiroki Sato syslog(LOG_DEBUG, "<%s> enter, fd=%d", __func__, fd); 6937241896SHiroki Sato 7037241896SHiroki Sato memset(buf, 0, CM_MSG_MAXLEN); 7137241896SHiroki Sato cm = (struct ctrl_msg_hdr *)buf; 7237241896SHiroki Sato msg = (char *)buf + sizeof(*cm); 7337241896SHiroki Sato 74aed37872SHiroki Sato pfds[0].fd = fd; 75aed37872SHiroki Sato pfds[0].events = POLLIN; 76aed37872SHiroki Sato 7737241896SHiroki Sato for (;;) { 78*93e96d6cSElyes Haouas i = poll(pfds, nitems(pfds), 79aed37872SHiroki Sato CM_RECV_TIMEOUT); 80aed37872SHiroki Sato 81aed37872SHiroki Sato if (i == 0) 82aed37872SHiroki Sato continue; 83aed37872SHiroki Sato 84aed37872SHiroki Sato if (i < 0) { 85aed37872SHiroki Sato syslog(LOG_ERR, "<%s> poll error: %s", 86aed37872SHiroki Sato __func__, strerror(errno)); 87aed37872SHiroki Sato continue; 88aed37872SHiroki Sato } 89aed37872SHiroki Sato 90aed37872SHiroki Sato if (pfds[0].revents & POLLIN) { 9137241896SHiroki Sato n = read(fd, cm, sizeof(*cm)); 9237241896SHiroki Sato if (n < 0 && errno == EAGAIN) { 9337241896SHiroki Sato syslog(LOG_DEBUG, 9437241896SHiroki Sato "<%s> waiting...", __func__); 9537241896SHiroki Sato continue; 9637241896SHiroki Sato } 9737241896SHiroki Sato break; 9837241896SHiroki Sato } 99aed37872SHiroki Sato } 10037241896SHiroki Sato 10196aec9a5SConrad Meyer if (n != (ssize_t)sizeof(*cm)) { 10237241896SHiroki Sato syslog(LOG_WARNING, 10337241896SHiroki Sato "<%s> received a too small message.", __func__); 104aed37872SHiroki Sato goto cm_recv_err; 10537241896SHiroki Sato } 10637241896SHiroki Sato if (cm->cm_len > CM_MSG_MAXLEN) { 10737241896SHiroki Sato syslog(LOG_WARNING, 10837241896SHiroki Sato "<%s> received a too large message.", __func__); 109aed37872SHiroki Sato goto cm_recv_err; 11037241896SHiroki Sato } 11137241896SHiroki Sato if (cm->cm_version != CM_VERSION) { 11237241896SHiroki Sato syslog(LOG_WARNING, 11337241896SHiroki Sato "<%s> version mismatch", __func__); 114aed37872SHiroki Sato goto cm_recv_err; 11537241896SHiroki Sato } 11637241896SHiroki Sato if (cm->cm_type >= CM_TYPE_MAX) { 11737241896SHiroki Sato syslog(LOG_WARNING, 11837241896SHiroki Sato "<%s> invalid msg type.", __func__); 119aed37872SHiroki Sato goto cm_recv_err; 12037241896SHiroki Sato } 12137241896SHiroki Sato 12237241896SHiroki Sato syslog(LOG_DEBUG, 12337241896SHiroki Sato "<%s> ctrl msg received: type=%d", __func__, 12437241896SHiroki Sato cm->cm_type); 12537241896SHiroki Sato 12696aec9a5SConrad Meyer if (cm->cm_len > sizeof(*cm)) { 12796aec9a5SConrad Meyer size_t msglen = cm->cm_len - sizeof(*cm); 12837241896SHiroki Sato 12937241896SHiroki Sato syslog(LOG_DEBUG, 13096aec9a5SConrad Meyer "<%s> ctrl msg has payload (len=%zu)", __func__, 13137241896SHiroki Sato msglen); 13237241896SHiroki Sato 13337241896SHiroki Sato for (;;) { 134*93e96d6cSElyes Haouas i = poll(pfds, nitems(pfds), 135aed37872SHiroki Sato CM_RECV_TIMEOUT); 136aed37872SHiroki Sato 137aed37872SHiroki Sato if (i == 0) 138aed37872SHiroki Sato continue; 139aed37872SHiroki Sato 140aed37872SHiroki Sato if (i < 0) { 141aed37872SHiroki Sato syslog(LOG_ERR, "<%s> poll error: %s", 142aed37872SHiroki Sato __func__, strerror(errno)); 143aed37872SHiroki Sato continue; 144aed37872SHiroki Sato } 145aed37872SHiroki Sato 146aed37872SHiroki Sato if (pfds[0].revents & POLLIN) { 14737241896SHiroki Sato n = read(fd, msg, msglen); 14837241896SHiroki Sato if (n < 0 && errno == EAGAIN) { 14937241896SHiroki Sato syslog(LOG_DEBUG, 15037241896SHiroki Sato "<%s> waiting...", __func__); 15137241896SHiroki Sato continue; 15237241896SHiroki Sato } 153aed37872SHiroki Sato } 15437241896SHiroki Sato break; 15537241896SHiroki Sato } 15696aec9a5SConrad Meyer if (n != (ssize_t)msglen) { 15737241896SHiroki Sato syslog(LOG_WARNING, 15837241896SHiroki Sato "<%s> payload size mismatch.", __func__); 159aed37872SHiroki Sato goto cm_recv_err; 16037241896SHiroki Sato } 16137241896SHiroki Sato buf[CM_MSG_MAXLEN - 1] = '\0'; 16237241896SHiroki Sato } 16337241896SHiroki Sato 16437241896SHiroki Sato return (0); 16537241896SHiroki Sato 166aed37872SHiroki Sato cm_recv_err: 16737241896SHiroki Sato close(fd); 16837241896SHiroki Sato return (-1); 16937241896SHiroki Sato } 17037241896SHiroki Sato 17137241896SHiroki Sato int 172aed37872SHiroki Sato cm_send(int fd, char *buf) 17337241896SHiroki Sato { 17437241896SHiroki Sato struct iovec iov[2]; 17537241896SHiroki Sato int iovcnt; 17637241896SHiroki Sato ssize_t len; 17737241896SHiroki Sato ssize_t iov_len_total; 17837241896SHiroki Sato struct ctrl_msg_hdr *cm; 17937241896SHiroki Sato char *msg; 18037241896SHiroki Sato 18137241896SHiroki Sato cm = (struct ctrl_msg_hdr *)buf; 18237241896SHiroki Sato msg = (char *)buf + sizeof(*cm); 18337241896SHiroki Sato 18437241896SHiroki Sato iovcnt = 1; 18537241896SHiroki Sato iov[0].iov_base = cm; 18637241896SHiroki Sato iov[0].iov_len = sizeof(*cm); 18737241896SHiroki Sato iov_len_total = iov[0].iov_len; 18837241896SHiroki Sato if (cm->cm_len > sizeof(*cm)) { 18937241896SHiroki Sato iovcnt++; 19037241896SHiroki Sato iov[1].iov_base = msg; 19137241896SHiroki Sato iov[1].iov_len = cm->cm_len - iov[0].iov_len; 19237241896SHiroki Sato iov_len_total += iov[1].iov_len; 19337241896SHiroki Sato } 19437241896SHiroki Sato 19537241896SHiroki Sato syslog(LOG_DEBUG, 19637241896SHiroki Sato "<%s> ctrl msg send: type=%d, count=%d, total_len=%zd", __func__, 19737241896SHiroki Sato cm->cm_type, iovcnt, iov_len_total); 19837241896SHiroki Sato 19937241896SHiroki Sato len = writev(fd, iov, iovcnt); 20037241896SHiroki Sato syslog(LOG_DEBUG, 20137241896SHiroki Sato "<%s> ctrl msg send: length=%zd", __func__, len); 20237241896SHiroki Sato 20337241896SHiroki Sato if (len == -1) { 20437241896SHiroki Sato syslog(LOG_DEBUG, 20537241896SHiroki Sato "<%s> write failed: (%d)%s", __func__, errno, 20637241896SHiroki Sato strerror(errno)); 20737241896SHiroki Sato close(fd); 20837241896SHiroki Sato return (-1); 20937241896SHiroki Sato } 21037241896SHiroki Sato 21137241896SHiroki Sato syslog(LOG_DEBUG, 21237241896SHiroki Sato "<%s> write length = %zd (actual)", __func__, len); 21337241896SHiroki Sato syslog(LOG_DEBUG, 21437241896SHiroki Sato "<%s> write length = %zd (expected)", __func__, iov_len_total); 21537241896SHiroki Sato 21637241896SHiroki Sato if (len != iov_len_total) { 21737241896SHiroki Sato close(fd); 21837241896SHiroki Sato return (-1); 21937241896SHiroki Sato } 22037241896SHiroki Sato 22137241896SHiroki Sato return (0); 22237241896SHiroki Sato } 22337241896SHiroki Sato 22437241896SHiroki Sato int 22537241896SHiroki Sato csock_accept(struct sockinfo *s) 22637241896SHiroki Sato { 22737241896SHiroki Sato struct sockaddr_un sun; 22837241896SHiroki Sato int flags; 22937241896SHiroki Sato int fd; 23037241896SHiroki Sato 23137241896SHiroki Sato sun.sun_len = sizeof(sun); 23237241896SHiroki Sato if ((fd = accept(s->si_fd, (struct sockaddr *)&sun, 23337241896SHiroki Sato (socklen_t *)&sun.sun_len)) == -1) { 23437241896SHiroki Sato if (errno != EWOULDBLOCK && errno != EINTR) 23537241896SHiroki Sato syslog(LOG_WARNING, "<%s> accept ", __func__); 23637241896SHiroki Sato syslog(LOG_WARNING, "<%s> Xaccept: %s", __func__, strerror(errno)); 23737241896SHiroki Sato return (-1); 23837241896SHiroki Sato } 23937241896SHiroki Sato if ((flags = fcntl(fd, F_GETFL, 0)) == -1) { 24037241896SHiroki Sato syslog(LOG_WARNING, "<%s> fcntl F_GETFL", __func__); 24137241896SHiroki Sato close(s->si_fd); 24237241896SHiroki Sato return (-1); 24337241896SHiroki Sato } 24437241896SHiroki Sato if ((flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1) { 24537241896SHiroki Sato syslog(LOG_WARNING, "<%s> fcntl F_SETFL", __func__); 24637241896SHiroki Sato return (-1); 24737241896SHiroki Sato } 24837241896SHiroki Sato syslog(LOG_DEBUG, "<%s> accept connfd=%d, listenfd=%d", __func__, 24937241896SHiroki Sato fd, s->si_fd); 25037241896SHiroki Sato 25137241896SHiroki Sato return (fd); 25237241896SHiroki Sato } 25337241896SHiroki Sato 25437241896SHiroki Sato int 25537241896SHiroki Sato csock_close(struct sockinfo *s) 25637241896SHiroki Sato { 25737241896SHiroki Sato close(s->si_fd); 25837241896SHiroki Sato unlink(s->si_name); 25937241896SHiroki Sato syslog(LOG_DEBUG, "<%s> remove %s", __func__, s->si_name); 26037241896SHiroki Sato return (0); 26137241896SHiroki Sato } 26237241896SHiroki Sato 26337241896SHiroki Sato int 26437241896SHiroki Sato csock_listen(struct sockinfo *s) 26537241896SHiroki Sato { 26637241896SHiroki Sato if (s->si_fd == -1) { 26737241896SHiroki Sato syslog(LOG_ERR, "<%s> listen failed", __func__); 26837241896SHiroki Sato return (-1); 26937241896SHiroki Sato } 27037241896SHiroki Sato if (listen(s->si_fd, SOCK_BACKLOG) == -1) { 27137241896SHiroki Sato syslog(LOG_ERR, "<%s> listen failed", __func__); 27237241896SHiroki Sato return (-1); 27337241896SHiroki Sato } 27437241896SHiroki Sato 27537241896SHiroki Sato return (0); 27637241896SHiroki Sato } 27737241896SHiroki Sato 27837241896SHiroki Sato int 27937241896SHiroki Sato csock_open(struct sockinfo *s, mode_t mode) 28037241896SHiroki Sato { 28137241896SHiroki Sato int flags; 28237241896SHiroki Sato struct sockaddr_un sun; 28337241896SHiroki Sato mode_t old_umask; 28437241896SHiroki Sato 28537241896SHiroki Sato if (s == NULL) { 28637241896SHiroki Sato syslog(LOG_ERR, "<%s> internal error.", __func__); 28737241896SHiroki Sato exit(1); 28837241896SHiroki Sato } 28937241896SHiroki Sato if (s->si_name == NULL) 29037241896SHiroki Sato s->si_name = _PATH_CTRL_SOCK; 29137241896SHiroki Sato 29237241896SHiroki Sato if ((s->si_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { 29337241896SHiroki Sato syslog(LOG_ERR, 29437241896SHiroki Sato "<%s> cannot open control socket", __func__); 29537241896SHiroki Sato return (-1); 29637241896SHiroki Sato } 29737241896SHiroki Sato memset(&sun, 0, sizeof(sun)); 29837241896SHiroki Sato sun.sun_family = AF_UNIX; 29937241896SHiroki Sato sun.sun_len = sizeof(sun); 30037241896SHiroki Sato strlcpy(sun.sun_path, s->si_name, sizeof(sun.sun_path)); 30137241896SHiroki Sato 30237241896SHiroki Sato if (unlink(s->si_name) == -1) 30337241896SHiroki Sato if (errno != ENOENT) { 30437241896SHiroki Sato syslog(LOG_ERR, 30537241896SHiroki Sato "<%s> unlink %s", __func__, s->si_name); 30637241896SHiroki Sato close(s->si_fd); 30737241896SHiroki Sato return (-1); 30837241896SHiroki Sato } 30937241896SHiroki Sato old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH); 31037241896SHiroki Sato if (bind(s->si_fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { 31137241896SHiroki Sato syslog(LOG_ERR, 31237241896SHiroki Sato "<%s> bind failed: %s", __func__, s->si_name); 31337241896SHiroki Sato close(s->si_fd); 31437241896SHiroki Sato umask(old_umask); 31537241896SHiroki Sato return (-1); 31637241896SHiroki Sato } 31737241896SHiroki Sato umask(old_umask); 31837241896SHiroki Sato if (chmod(s->si_name, mode) == -1) { 31937241896SHiroki Sato syslog(LOG_ERR, 32037241896SHiroki Sato "<%s> chmod failed: %s", __func__, s->si_name); 32137241896SHiroki Sato goto csock_open_err; 32237241896SHiroki Sato } 32337241896SHiroki Sato if ((flags = fcntl(s->si_fd, F_GETFL, 0)) == -1) { 32437241896SHiroki Sato syslog(LOG_ERR, 32537241896SHiroki Sato "<%s> fcntl F_GETFL failed: %s", __func__, s->si_name); 32637241896SHiroki Sato goto csock_open_err; 32737241896SHiroki Sato } 32837241896SHiroki Sato if ((flags = fcntl(s->si_fd, F_SETFL, flags | O_NONBLOCK)) == -1) { 32937241896SHiroki Sato syslog(LOG_ERR, 33037241896SHiroki Sato "<%s> fcntl F_SETFL failed: %s", __func__, s->si_name); 33137241896SHiroki Sato goto csock_open_err; 33237241896SHiroki Sato } 33337241896SHiroki Sato 33437241896SHiroki Sato return (s->si_fd); 33537241896SHiroki Sato 33637241896SHiroki Sato csock_open_err: 33737241896SHiroki Sato close(s->si_fd); 33837241896SHiroki Sato unlink(s->si_name); 33937241896SHiroki Sato return (-1); 34037241896SHiroki Sato } 34137241896SHiroki Sato 34237241896SHiroki Sato struct ctrl_msg_pl * 343aed37872SHiroki Sato cm_bin2pl(char *str, struct ctrl_msg_pl *cp) 34437241896SHiroki Sato { 34537241896SHiroki Sato size_t len; 34637241896SHiroki Sato size_t *lenp; 34737241896SHiroki Sato char *p; 34837241896SHiroki Sato 34937241896SHiroki Sato memset(cp, 0, sizeof(*cp)); 35037241896SHiroki Sato 35137241896SHiroki Sato p = str; 35237241896SHiroki Sato 35337241896SHiroki Sato lenp = (size_t *)p; 35437241896SHiroki Sato len = *lenp++; 35537241896SHiroki Sato p = (char *)lenp; 35637241896SHiroki Sato syslog(LOG_DEBUG, "<%s> len(ifname) = %zu", __func__, len); 35737241896SHiroki Sato if (len > 0) { 35837241896SHiroki Sato cp->cp_ifname = malloc(len + 1); 35937241896SHiroki Sato if (cp->cp_ifname == NULL) { 36037241896SHiroki Sato syslog(LOG_ERR, "<%s> malloc", __func__); 36137241896SHiroki Sato exit(1); 36237241896SHiroki Sato } 36337241896SHiroki Sato memcpy(cp->cp_ifname, p, len); 36437241896SHiroki Sato cp->cp_ifname[len] = '\0'; 36537241896SHiroki Sato p += len; 36637241896SHiroki Sato } 36737241896SHiroki Sato 36837241896SHiroki Sato lenp = (size_t *)p; 36937241896SHiroki Sato len = *lenp++; 37037241896SHiroki Sato p = (char *)lenp; 37137241896SHiroki Sato syslog(LOG_DEBUG, "<%s> len(key) = %zu", __func__, len); 37237241896SHiroki Sato if (len > 0) { 37337241896SHiroki Sato cp->cp_key = malloc(len + 1); 37437241896SHiroki Sato if (cp->cp_key == NULL) { 37537241896SHiroki Sato syslog(LOG_ERR, "<%s> malloc", __func__); 37637241896SHiroki Sato exit(1); 37737241896SHiroki Sato } 37837241896SHiroki Sato memcpy(cp->cp_key, p, len); 37937241896SHiroki Sato cp->cp_key[len] = '\0'; 38037241896SHiroki Sato p += len; 38137241896SHiroki Sato } 38237241896SHiroki Sato 38337241896SHiroki Sato lenp = (size_t *)p; 38437241896SHiroki Sato len = *lenp++; 38537241896SHiroki Sato p = (char *)lenp; 38637241896SHiroki Sato syslog(LOG_DEBUG, "<%s> len(val) = %zu", __func__, len); 38737241896SHiroki Sato if (len > 0) { 38837241896SHiroki Sato cp->cp_val = malloc(len + 1); 38937241896SHiroki Sato if (cp->cp_val == NULL) { 39037241896SHiroki Sato syslog(LOG_ERR, "<%s> malloc", __func__); 39137241896SHiroki Sato exit(1); 39237241896SHiroki Sato } 39337241896SHiroki Sato memcpy(cp->cp_val, p, len); 39437241896SHiroki Sato cp->cp_val[len] = '\0'; 39537241896SHiroki Sato cp->cp_val_len = len; 39637241896SHiroki Sato } else 39737241896SHiroki Sato cp->cp_val_len = 0; 39837241896SHiroki Sato 39937241896SHiroki Sato return (cp); 40037241896SHiroki Sato } 40137241896SHiroki Sato 40237241896SHiroki Sato size_t 403aed37872SHiroki Sato cm_pl2bin(char *str, struct ctrl_msg_pl *cp) 40437241896SHiroki Sato { 40537241896SHiroki Sato size_t len; 40637241896SHiroki Sato size_t *lenp; 40737241896SHiroki Sato char *p; 40837241896SHiroki Sato struct ctrl_msg_hdr *cm; 40937241896SHiroki Sato 41037241896SHiroki Sato len = sizeof(size_t); 41137241896SHiroki Sato if (cp->cp_ifname != NULL) 41237241896SHiroki Sato len += strlen(cp->cp_ifname); 41337241896SHiroki Sato len += sizeof(size_t); 41437241896SHiroki Sato if (cp->cp_key != NULL) 41537241896SHiroki Sato len += strlen(cp->cp_key); 41637241896SHiroki Sato len += sizeof(size_t); 41737241896SHiroki Sato if (cp->cp_val != NULL && cp->cp_val_len > 0) 41837241896SHiroki Sato len += cp->cp_val_len; 41937241896SHiroki Sato 42037241896SHiroki Sato if (len > CM_MSG_MAXLEN - sizeof(*cm)) { 42137241896SHiroki Sato syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)", 42237241896SHiroki Sato __func__, len); 42337241896SHiroki Sato return (0); 42437241896SHiroki Sato } 42537241896SHiroki Sato syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len); 42637241896SHiroki Sato memset(str, 0, len); 42737241896SHiroki Sato p = str; 42837241896SHiroki Sato lenp = (size_t *)p; 42937241896SHiroki Sato 43037241896SHiroki Sato if (cp->cp_ifname != NULL) { 43137241896SHiroki Sato *lenp++ = strlen(cp->cp_ifname); 43237241896SHiroki Sato p = (char *)lenp; 43337241896SHiroki Sato memcpy(p, cp->cp_ifname, strlen(cp->cp_ifname)); 43437241896SHiroki Sato p += strlen(cp->cp_ifname); 43537241896SHiroki Sato } else { 43637241896SHiroki Sato *lenp++ = '\0'; 43737241896SHiroki Sato p = (char *)lenp; 43837241896SHiroki Sato } 43937241896SHiroki Sato 44037241896SHiroki Sato lenp = (size_t *)p; 44137241896SHiroki Sato if (cp->cp_key != NULL) { 44237241896SHiroki Sato *lenp++ = strlen(cp->cp_key); 44337241896SHiroki Sato p = (char *)lenp; 44437241896SHiroki Sato memcpy(p, cp->cp_key, strlen(cp->cp_key)); 44537241896SHiroki Sato p += strlen(cp->cp_key); 44637241896SHiroki Sato } else { 44737241896SHiroki Sato *lenp++ = '\0'; 44837241896SHiroki Sato p = (char *)lenp; 44937241896SHiroki Sato } 45037241896SHiroki Sato 45137241896SHiroki Sato lenp = (size_t *)p; 45237241896SHiroki Sato if (cp->cp_val != NULL && cp->cp_val_len > 0) { 45337241896SHiroki Sato *lenp++ = cp->cp_val_len; 45437241896SHiroki Sato p = (char *)lenp; 45537241896SHiroki Sato memcpy(p, cp->cp_val, cp->cp_val_len); 45637241896SHiroki Sato p += cp->cp_val_len; 45737241896SHiroki Sato } else { 45837241896SHiroki Sato *lenp++ = '\0'; 45937241896SHiroki Sato p = (char *)lenp; 46037241896SHiroki Sato } 46137241896SHiroki Sato 46237241896SHiroki Sato return (len); 46337241896SHiroki Sato } 46437241896SHiroki Sato 46537241896SHiroki Sato size_t 466aed37872SHiroki Sato cm_str2bin(char *bin, void *str, size_t len) 46737241896SHiroki Sato { 46837241896SHiroki Sato struct ctrl_msg_hdr *cm; 46937241896SHiroki Sato 47037241896SHiroki Sato syslog(LOG_DEBUG, "<%s> enter", __func__); 47137241896SHiroki Sato 47237241896SHiroki Sato if (len > CM_MSG_MAXLEN - sizeof(*cm)) { 47337241896SHiroki Sato syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)", 47437241896SHiroki Sato __func__, len); 47537241896SHiroki Sato return (0); 47637241896SHiroki Sato } 47737241896SHiroki Sato syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len); 47837241896SHiroki Sato memcpy(bin, (char *)str, len); 47937241896SHiroki Sato 48037241896SHiroki Sato return (len); 48137241896SHiroki Sato } 48237241896SHiroki Sato 48337241896SHiroki Sato void * 484aed37872SHiroki Sato cm_bin2str(char *bin, void *str, size_t len) 48537241896SHiroki Sato { 48637241896SHiroki Sato 48737241896SHiroki Sato syslog(LOG_DEBUG, "<%s> enter", __func__); 48837241896SHiroki Sato 48937241896SHiroki Sato memcpy((char *)str, bin, len); 49037241896SHiroki Sato 49137241896SHiroki Sato return (str); 49237241896SHiroki Sato } 493